blob: 871602b9cbfbb28d0b6d4eb5d082bbfe7f624656 [file] [log] [blame]
Etan Cohen2b1b03b2017-06-08 11:27:50 -07001#!/usr/bin/python3.4
2#
3# Copyright 2017 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import queue
18import time
19
20from acts import asserts
Xianyuan Jia63751fb2020-11-17 00:07:40 +000021from acts_contrib.test_utils.net import connectivity_const as cconsts
22from acts_contrib.test_utils.wifi.aware import aware_const as aconsts
23from acts_contrib.test_utils.wifi.aware import aware_test_utils as autils
24from acts_contrib.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest
Etan Cohen2b1b03b2017-06-08 11:27:50 -070025
26
27class LatencyTest(AwareBaseTest):
Jaineel7e67a3f2019-08-28 15:58:49 -070028 """Set of tests for Wi-Fi Aware to measure latency of Aware operations."""
29 SERVICE_NAME = "GoogleTestServiceXY"
Etan Cohen2b1b03b2017-06-08 11:27:50 -070030
Jaineel7e67a3f2019-08-28 15:58:49 -070031 # number of second to 'reasonably' wait to make sure that devices synchronize
32 # with each other - useful for OOB test cases, where the OOB discovery would
33 # take some time
34 WAIT_FOR_CLUSTER = 5
Etan Cohen2b1b03b2017-06-08 11:27:50 -070035
Jaineel7e67a3f2019-08-28 15:58:49 -070036 def start_discovery_session(self, dut, session_id, is_publish, dtype):
37 """Start a discovery session
Etan Cohen2b1b03b2017-06-08 11:27:50 -070038
39 Args:
40 dut: Device under test
41 session_id: ID of the Aware session in which to start discovery
42 is_publish: True for a publish session, False for subscribe session
43 dtype: Type of the discovery session
44
45 Returns:
46 Discovery session started event.
47 """
Jaineel7e67a3f2019-08-28 15:58:49 -070048 config = {}
49 config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype
50 config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceXY"
Etan Cohen2b1b03b2017-06-08 11:27:50 -070051
Jaineel7e67a3f2019-08-28 15:58:49 -070052 if is_publish:
53 disc_id = dut.droid.wifiAwarePublish(session_id, config)
54 event_name = aconsts.SESSION_CB_ON_PUBLISH_STARTED
55 else:
56 disc_id = dut.droid.wifiAwareSubscribe(session_id, config)
57 event_name = aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED
Etan Cohen2b1b03b2017-06-08 11:27:50 -070058
Jaineel7e67a3f2019-08-28 15:58:49 -070059 event = autils.wait_for_event(dut, event_name)
60 return disc_id, event
Etan Cohen2b1b03b2017-06-08 11:27:50 -070061
Jaineel7e67a3f2019-08-28 15:58:49 -070062 def run_synchronization_latency(self, results, do_unsolicited_passive,
63 dw_24ghz, dw_5ghz, num_iterations,
64 startup_offset, timeout_period):
65 """Run the synchronization latency test with the specified DW intervals.
Etan Cohen04b89522017-06-19 17:07:47 -070066 There is no direct measure of synchronization. Instead starts a discovery
67 session as soon as possible and measures both probability of discovery
68 within a timeout period and the actual discovery time (not necessarily
69 accurate).
70
71 Args:
72 results: Result array to be populated - will add results (not erase it)
73 do_unsolicited_passive: True for unsolicited/passive, False for
74 solicited/active.
75 dw_24ghz: DW interval in the 2.4GHz band.
76 dw_5ghz: DW interval in the 5GHz band.
77 startup_offset: The start-up gap (in seconds) between the two devices
78 timeout_period: Time period over which to measure synchronization
79 """
Jaineel7e67a3f2019-08-28 15:58:49 -070080 key = "%s_dw24_%d_dw5_%d_offset_%d" % ("unsolicited_passive"
81 if do_unsolicited_passive else
82 "solicited_active", dw_24ghz,
83 dw_5ghz, startup_offset)
84 results[key] = {}
85 results[key]["num_iterations"] = num_iterations
Etan Cohen04b89522017-06-19 17:07:47 -070086
Jaineel7e67a3f2019-08-28 15:58:49 -070087 p_dut = self.android_devices[0]
88 p_dut.pretty_name = "Publisher"
89 s_dut = self.android_devices[1]
90 s_dut.pretty_name = "Subscriber"
Etan Cohen04b89522017-06-19 17:07:47 -070091
Jaineel7e67a3f2019-08-28 15:58:49 -070092 # override the default DW configuration
93 autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz)
94 autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz)
Etan Cohen04b89522017-06-19 17:07:47 -070095
Jaineel7e67a3f2019-08-28 15:58:49 -070096 latencies = []
97 failed_discoveries = 0
98 for i in range(num_iterations):
99 # Publisher+Subscriber: attach and wait for confirmation
100 p_id = p_dut.droid.wifiAwareAttach(False)
101 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED)
102 time.sleep(startup_offset)
103 s_id = s_dut.droid.wifiAwareAttach(False)
104 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED)
Etan Cohen04b89522017-06-19 17:07:47 -0700105
Jaineel7e67a3f2019-08-28 15:58:49 -0700106 # start publish
107 p_disc_id, p_disc_event = self.start_discovery_session(
108 p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED
109 if do_unsolicited_passive else aconsts.PUBLISH_TYPE_SOLICITED)
Etan Cohen04b89522017-06-19 17:07:47 -0700110
Jaineel7e67a3f2019-08-28 15:58:49 -0700111 # start subscribe
112 s_disc_id, s_session_event = self.start_discovery_session(
113 s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE
114 if do_unsolicited_passive else aconsts.SUBSCRIBE_TYPE_ACTIVE)
Etan Cohen04b89522017-06-19 17:07:47 -0700115
Jaineel7e67a3f2019-08-28 15:58:49 -0700116 # wait for discovery (allow for failures here since running lots of
117 # samples and would like to get the partial data even in the presence of
118 # errors)
119 try:
120 discovery_event = s_dut.ed.pop_event(
121 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, timeout_period)
122 s_dut.log.info(
123 "[Subscriber] SESSION_CB_ON_SERVICE_DISCOVERED: %s",
124 discovery_event["data"])
125 except queue.Empty:
126 s_dut.log.info("[Subscriber] Timed out while waiting for "
127 "SESSION_CB_ON_SERVICE_DISCOVERED")
128 failed_discoveries = failed_discoveries + 1
129 continue
130 finally:
131 # destroy sessions
132 p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id)
133 s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id)
134 p_dut.droid.wifiAwareDestroy(p_id)
135 s_dut.droid.wifiAwareDestroy(s_id)
Etan Cohen04b89522017-06-19 17:07:47 -0700136
Jaineel7e67a3f2019-08-28 15:58:49 -0700137 # collect latency information
138 latencies.append(
139 discovery_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS] -
140 s_session_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS])
141 self.log.info("Latency #%d = %d" % (i, latencies[-1]))
Etan Cohen04b89522017-06-19 17:07:47 -0700142
Jaineel7e67a3f2019-08-28 15:58:49 -0700143 autils.extract_stats(
144 s_dut,
145 data=latencies,
146 results=results[key],
147 key_prefix="",
148 log_prefix="Subscribe Session Sync/Discovery (%s, dw24=%d, dw5=%d)"
149 % ("Unsolicited/Passive" if do_unsolicited_passive else
150 "Solicited/Active", dw_24ghz, dw_5ghz))
151 results[key]["num_failed_discovery"] = failed_discoveries
Etan Cohen04b89522017-06-19 17:07:47 -0700152
Jaineel7e67a3f2019-08-28 15:58:49 -0700153 def run_discovery_latency(self, results, do_unsolicited_passive, dw_24ghz,
154 dw_5ghz, num_iterations):
155 """Run the service discovery latency test with the specified DW intervals.
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700156
157 Args:
158 results: Result array to be populated - will add results (not erase it)
159 do_unsolicited_passive: True for unsolicited/passive, False for
160 solicited/active.
161 dw_24ghz: DW interval in the 2.4GHz band.
162 dw_5ghz: DW interval in the 5GHz band.
163 """
Jaineel7e67a3f2019-08-28 15:58:49 -0700164 key = "%s_dw24_%d_dw5_%d" % ("unsolicited_passive"
165 if do_unsolicited_passive else
166 "solicited_active", dw_24ghz, dw_5ghz)
167 results[key] = {}
168 results[key]["num_iterations"] = num_iterations
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700169
Jaineel7e67a3f2019-08-28 15:58:49 -0700170 p_dut = self.android_devices[0]
171 p_dut.pretty_name = "Publisher"
172 s_dut = self.android_devices[1]
173 s_dut.pretty_name = "Subscriber"
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700174
Jaineel7e67a3f2019-08-28 15:58:49 -0700175 # override the default DW configuration
176 autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz)
177 autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz)
Etan Cohen9b11b182017-06-12 09:51:12 -0700178
Jaineel7e67a3f2019-08-28 15:58:49 -0700179 # Publisher+Subscriber: attach and wait for confirmation
180 p_id = p_dut.droid.wifiAwareAttach(False)
181 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED)
182 time.sleep(self.device_startup_offset)
183 s_id = s_dut.droid.wifiAwareAttach(False)
184 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED)
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700185
Jaineel7e67a3f2019-08-28 15:58:49 -0700186 # start publish
187 p_disc_event = self.start_discovery_session(
188 p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED
189 if do_unsolicited_passive else aconsts.PUBLISH_TYPE_SOLICITED)
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700190
Jaineel7e67a3f2019-08-28 15:58:49 -0700191 # wait for for devices to synchronize with each other - used so that first
192 # discovery isn't biased by synchronization.
193 time.sleep(self.WAIT_FOR_CLUSTER)
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700194
Jaineel7e67a3f2019-08-28 15:58:49 -0700195 # loop, perform discovery, and collect latency information
196 latencies = []
197 failed_discoveries = 0
198 for i in range(num_iterations):
199 # start subscribe
200 s_disc_id, s_session_event = self.start_discovery_session(
201 s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE
202 if do_unsolicited_passive else aconsts.SUBSCRIBE_TYPE_ACTIVE)
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700203
Jaineel7e67a3f2019-08-28 15:58:49 -0700204 # wait for discovery (allow for failures here since running lots of
205 # samples and would like to get the partial data even in the presence of
206 # errors)
207 try:
208 discovery_event = s_dut.ed.pop_event(
209 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED,
210 autils.EVENT_TIMEOUT)
211 except queue.Empty:
212 s_dut.log.info("[Subscriber] Timed out while waiting for "
213 "SESSION_CB_ON_SERVICE_DISCOVERED")
214 failed_discoveries = failed_discoveries + 1
215 continue
216 finally:
217 # destroy subscribe
218 s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id)
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700219
Jaineel7e67a3f2019-08-28 15:58:49 -0700220 # collect latency information
221 latencies.append(
222 discovery_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS] -
223 s_session_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS])
224 self.log.info("Latency #%d = %d" % (i, latencies[-1]))
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700225
Jaineel7e67a3f2019-08-28 15:58:49 -0700226 autils.extract_stats(
227 s_dut,
228 data=latencies,
229 results=results[key],
230 key_prefix="",
231 log_prefix="Subscribe Session Discovery (%s, dw24=%d, dw5=%d)" %
232 ("Unsolicited/Passive" if do_unsolicited_passive else
233 "Solicited/Active", dw_24ghz, dw_5ghz))
234 results[key]["num_failed_discovery"] = failed_discoveries
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700235
Jaineel7e67a3f2019-08-28 15:58:49 -0700236 # clean up
237 p_dut.droid.wifiAwareDestroyAll()
238 s_dut.droid.wifiAwareDestroyAll()
Etan Cohen9b11b182017-06-12 09:51:12 -0700239
Jaineel7e67a3f2019-08-28 15:58:49 -0700240 def run_message_latency(self, results, dw_24ghz, dw_5ghz, num_iterations):
241 """Run the message tx latency test with the specified DW intervals.
Etan Cohen7185c482017-06-12 14:30:59 -0700242
243 Args:
244 results: Result array to be populated - will add results (not erase it)
245 dw_24ghz: DW interval in the 2.4GHz band.
246 dw_5ghz: DW interval in the 5GHz band.
247 """
Jaineel7e67a3f2019-08-28 15:58:49 -0700248 key = "dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz)
249 results[key] = {}
250 results[key]["num_iterations"] = num_iterations
Etan Cohen7185c482017-06-12 14:30:59 -0700251
Jaineel7e67a3f2019-08-28 15:58:49 -0700252 p_dut = self.android_devices[0]
253 s_dut = self.android_devices[1]
Etan Cohen7185c482017-06-12 14:30:59 -0700254
Jaineel7e67a3f2019-08-28 15:58:49 -0700255 # override the default DW configuration
256 autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz)
257 autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz)
Etan Cohen7185c482017-06-12 14:30:59 -0700258
Jaineel7e67a3f2019-08-28 15:58:49 -0700259 # Start up a discovery session
260 (p_id, s_id, p_disc_id, s_disc_id,
261 peer_id_on_sub) = autils.create_discovery_pair(
262 p_dut,
263 s_dut,
264 p_config=autils.create_discovery_config(
265 self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED),
266 s_config=autils.create_discovery_config(
267 self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE),
268 device_startup_offset=self.device_startup_offset)
Etan Cohen7185c482017-06-12 14:30:59 -0700269
Jaineel7e67a3f2019-08-28 15:58:49 -0700270 latencies = []
271 failed_tx = 0
272 messages_rx = 0
273 missing_rx = 0
274 corrupted_rx = 0
275 for i in range(num_iterations):
276 # send message
277 msg_s2p = "Message Subscriber -> Publisher #%d" % i
278 next_msg_id = self.get_next_msg_id()
279 s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub,
280 next_msg_id, msg_s2p, 0)
Etan Cohen7185c482017-06-12 14:30:59 -0700281
Jaineel7e67a3f2019-08-28 15:58:49 -0700282 # wait for Tx confirmation
283 try:
284 sub_tx_msg_event = s_dut.ed.pop_event(
285 aconsts.SESSION_CB_ON_MESSAGE_SENT,
286 2 * autils.EVENT_TIMEOUT)
287 latencies.append(sub_tx_msg_event["data"][
288 aconsts.SESSION_CB_KEY_LATENCY_MS])
289 except queue.Empty:
290 s_dut.log.info("[Subscriber] Timed out while waiting for "
291 "SESSION_CB_ON_MESSAGE_SENT")
292 failed_tx = failed_tx + 1
293 continue
Etan Cohen7185c482017-06-12 14:30:59 -0700294
Jaineel7e67a3f2019-08-28 15:58:49 -0700295 # wait for Rx confirmation (and validate contents)
296 try:
297 pub_rx_msg_event = p_dut.ed.pop_event(
298 aconsts.SESSION_CB_ON_MESSAGE_RECEIVED,
299 2 * autils.EVENT_TIMEOUT)
300 messages_rx = messages_rx + 1
301 if (pub_rx_msg_event["data"]
302 [aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] != msg_s2p):
303 corrupted_rx = corrupted_rx + 1
304 except queue.Empty:
305 s_dut.log.info("[Publisher] Timed out while waiting for "
306 "SESSION_CB_ON_MESSAGE_RECEIVED")
307 missing_rx = missing_rx + 1
308 continue
Etan Cohen7185c482017-06-12 14:30:59 -0700309
Jaineel7e67a3f2019-08-28 15:58:49 -0700310 autils.extract_stats(
311 s_dut,
312 data=latencies,
313 results=results[key],
314 key_prefix="",
315 log_prefix="Subscribe Session Discovery (dw24=%d, dw5=%d)" %
316 (dw_24ghz, dw_5ghz))
317 results[key]["failed_tx"] = failed_tx
318 results[key]["messages_rx"] = messages_rx
319 results[key]["missing_rx"] = missing_rx
320 results[key]["corrupted_rx"] = corrupted_rx
Etan Cohen7185c482017-06-12 14:30:59 -0700321
Jaineel7e67a3f2019-08-28 15:58:49 -0700322 # clean up
323 p_dut.droid.wifiAwareDestroyAll()
324 s_dut.droid.wifiAwareDestroyAll()
Etan Cohen7185c482017-06-12 14:30:59 -0700325
Jaineel7e67a3f2019-08-28 15:58:49 -0700326 def run_ndp_oob_latency(self, results, dw_24ghz, dw_5ghz, num_iterations):
327 """Runs the NDP setup with OOB (out-of-band) discovery latency test.
Etan Cohen8e9104f2017-06-13 08:33:52 -0700328
329 Args:
330 results: Result array to be populated - will add results (not erase it)
331 dw_24ghz: DW interval in the 2.4GHz band.
332 dw_5ghz: DW interval in the 5GHz band.
333 """
Jaineel7e67a3f2019-08-28 15:58:49 -0700334 key_avail = "on_avail_dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz)
335 key_link_props = "link_props_dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz)
336 results[key_avail] = {}
337 results[key_link_props] = {}
338 results[key_avail]["num_iterations"] = num_iterations
Etan Cohen8e9104f2017-06-13 08:33:52 -0700339
Jaineel7e67a3f2019-08-28 15:58:49 -0700340 init_dut = self.android_devices[0]
341 init_dut.pretty_name = 'Initiator'
342 resp_dut = self.android_devices[1]
343 resp_dut.pretty_name = 'Responder'
Etan Cohen8e9104f2017-06-13 08:33:52 -0700344
Jaineel7e67a3f2019-08-28 15:58:49 -0700345 # override the default DW configuration
346 autils.config_power_settings(init_dut, dw_24ghz, dw_5ghz)
347 autils.config_power_settings(resp_dut, dw_24ghz, dw_5ghz)
Etan Cohen8e9104f2017-06-13 08:33:52 -0700348
Jaineel7e67a3f2019-08-28 15:58:49 -0700349 # Initiator+Responder: attach and wait for confirmation & identity
350 init_id = init_dut.droid.wifiAwareAttach(True)
351 autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED)
352 init_ident_event = autils.wait_for_event(
353 init_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED)
354 init_mac = init_ident_event['data']['mac']
355 time.sleep(self.device_startup_offset)
356 resp_id = resp_dut.droid.wifiAwareAttach(True)
357 autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED)
358 resp_ident_event = autils.wait_for_event(
359 resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED)
360 resp_mac = resp_ident_event['data']['mac']
Etan Cohen8e9104f2017-06-13 08:33:52 -0700361
Jaineel7e67a3f2019-08-28 15:58:49 -0700362 # wait for for devices to synchronize with each other - there are no other
363 # mechanisms to make sure this happens for OOB discovery (except retrying
364 # to execute the data-path request)
365 time.sleep(autils.WAIT_FOR_CLUSTER)
Etan Cohen8e9104f2017-06-13 08:33:52 -0700366
Jaineel7e67a3f2019-08-28 15:58:49 -0700367 on_available_latencies = []
368 link_props_latencies = []
369 ndp_setup_failures = 0
370 for i in range(num_iterations):
371 # Responder: request network
372 resp_req_key = autils.request_network(
373 resp_dut,
374 resp_dut.droid.wifiAwareCreateNetworkSpecifierOob(
375 resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, None))
Etan Cohen8e9104f2017-06-13 08:33:52 -0700376
Jaineel7e67a3f2019-08-28 15:58:49 -0700377 # Initiator: request network
378 init_req_key = autils.request_network(
379 init_dut,
380 init_dut.droid.wifiAwareCreateNetworkSpecifierOob(
381 init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, None))
Etan Cohen8e9104f2017-06-13 08:33:52 -0700382
Jaineel7e67a3f2019-08-28 15:58:49 -0700383 # Initiator & Responder: wait for network formation
384 got_on_available = False
385 got_on_link_props = False
386 while not got_on_available or not got_on_link_props:
387 try:
388 nc_event = init_dut.ed.pop_event(
389 cconsts.EVENT_NETWORK_CALLBACK,
390 autils.EVENT_NDP_TIMEOUT)
391 if nc_event["data"][
392 cconsts.
393 NETWORK_CB_KEY_EVENT] == cconsts.NETWORK_CB_AVAILABLE:
394 got_on_available = True
395 on_available_latencies.append(
396 nc_event["data"][cconsts.NETWORK_CB_KEY_CURRENT_TS]
397 -
398 nc_event["data"][cconsts.NETWORK_CB_KEY_CREATE_TS])
399 elif (nc_event["data"][cconsts.NETWORK_CB_KEY_EVENT] ==
400 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED):
401 got_on_link_props = True
402 link_props_latencies.append(
403 nc_event["data"][cconsts.NETWORK_CB_KEY_CURRENT_TS]
404 -
405 nc_event["data"][cconsts.NETWORK_CB_KEY_CREATE_TS])
406 except queue.Empty:
407 ndp_setup_failures = ndp_setup_failures + 1
408 init_dut.log.info(
409 "[Initiator] Timed out while waiting for "
410 "EVENT_NETWORK_CALLBACK")
411 break
Etan Cohen8e9104f2017-06-13 08:33:52 -0700412
Jaineel7e67a3f2019-08-28 15:58:49 -0700413 # clean-up
414 init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key)
415 resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key)
Etan Cohen8e9104f2017-06-13 08:33:52 -0700416
Jaineel7e67a3f2019-08-28 15:58:49 -0700417 # wait to make sure previous NDP terminated, otherwise its termination
418 # time will be counted in the setup latency!
419 time.sleep(2)
Etan Cohen1ff5c8e2017-07-10 18:04:38 -0700420
Jaineel7e67a3f2019-08-28 15:58:49 -0700421 autils.extract_stats(
422 init_dut,
423 data=on_available_latencies,
424 results=results[key_avail],
425 key_prefix="",
426 log_prefix="NDP setup OnAvailable(dw24=%d, dw5=%d)" % (dw_24ghz,
427 dw_5ghz))
428 autils.extract_stats(
429 init_dut,
430 data=link_props_latencies,
431 results=results[key_link_props],
432 key_prefix="",
433 log_prefix="NDP setup OnLinkProperties (dw24=%d, dw5=%d)" %
434 (dw_24ghz, dw_5ghz))
435 results[key_avail]["ndp_setup_failures"] = ndp_setup_failures
Etan Cohen8e9104f2017-06-13 08:33:52 -0700436
Jaineel7e67a3f2019-08-28 15:58:49 -0700437 def run_end_to_end_latency(self, results, dw_24ghz, dw_5ghz,
438 num_iterations, startup_offset, include_setup):
439 """Measure the latency for end-to-end communication link setup:
Etan Cohen3704c262018-05-01 14:38:23 -0700440 - Start Aware
441 - Discovery
442 - Message from Sub -> Pub
443 - Message from Pub -> Sub
444 - NDP setup
445
446 Args:
447 results: Result array to be populated - will add results (not erase it)
448 dw_24ghz: DW interval in the 2.4GHz band.
449 dw_5ghz: DW interval in the 5GHz band.
450 startup_offset: The start-up gap (in seconds) between the two devices
451 include_setup: True to include the cluster setup in the latency
452 measurements.
453 """
Jaineel7e67a3f2019-08-28 15:58:49 -0700454 key = "dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz)
455 results[key] = {}
456 results[key]["num_iterations"] = num_iterations
Etan Cohen3704c262018-05-01 14:38:23 -0700457
Jaineel7e67a3f2019-08-28 15:58:49 -0700458 p_dut = self.android_devices[0]
459 p_dut.pretty_name = "Publisher"
460 s_dut = self.android_devices[1]
461 s_dut.pretty_name = "Subscriber"
Etan Cohen3704c262018-05-01 14:38:23 -0700462
Jaineel7e67a3f2019-08-28 15:58:49 -0700463 # override the default DW configuration
464 autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz)
465 autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz)
Etan Cohen3704c262018-05-01 14:38:23 -0700466
Jaineel7e67a3f2019-08-28 15:58:49 -0700467 latencies = []
Etan Cohen3704c262018-05-01 14:38:23 -0700468
Jaineel7e67a3f2019-08-28 15:58:49 -0700469 # allow for failures here since running lots of samples and would like to
470 # get the partial data even in the presence of errors
471 failures = 0
Etan Cohen3704c262018-05-01 14:38:23 -0700472
Jaineel7e67a3f2019-08-28 15:58:49 -0700473 if not include_setup:
474 # Publisher+Subscriber: attach and wait for confirmation
475 p_id = p_dut.droid.wifiAwareAttach(False)
476 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED)
477 time.sleep(startup_offset)
478 s_id = s_dut.droid.wifiAwareAttach(False)
479 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED)
Etan Cohen3704c262018-05-01 14:38:23 -0700480
Jaineel7e67a3f2019-08-28 15:58:49 -0700481 for i in range(num_iterations):
482 while (True): # for pseudo-goto/finalize
483 timestamp_start = time.perf_counter()
Etan Cohen3704c262018-05-01 14:38:23 -0700484
Jaineel7e67a3f2019-08-28 15:58:49 -0700485 if include_setup:
486 # Publisher+Subscriber: attach and wait for confirmation
487 p_id = p_dut.droid.wifiAwareAttach(False)
488 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED)
489 time.sleep(startup_offset)
490 s_id = s_dut.droid.wifiAwareAttach(False)
491 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED)
Etan Cohen3704c262018-05-01 14:38:23 -0700492
Jaineel7e67a3f2019-08-28 15:58:49 -0700493 # start publish
494 p_disc_id, p_disc_event = self.start_discovery_session(
495 p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED)
Etan Cohen3704c262018-05-01 14:38:23 -0700496
Jaineel7e67a3f2019-08-28 15:58:49 -0700497 # start subscribe
498 s_disc_id, s_session_event = self.start_discovery_session(
499 s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE)
Etan Cohen3704c262018-05-01 14:38:23 -0700500
Jaineel7e67a3f2019-08-28 15:58:49 -0700501 # wait for discovery (allow for failures here since running lots of
502 # samples and would like to get the partial data even in the presence of
503 # errors)
504 try:
505 event = s_dut.ed.pop_event(
506 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED,
507 autils.EVENT_TIMEOUT)
508 s_dut.log.info(
509 "[Subscriber] SESSION_CB_ON_SERVICE_DISCOVERED: %s",
510 event["data"])
511 peer_id_on_sub = event['data'][
512 aconsts.SESSION_CB_KEY_PEER_ID]
513 except queue.Empty:
514 s_dut.log.info("[Subscriber] Timed out while waiting for "
515 "SESSION_CB_ON_SERVICE_DISCOVERED")
516 failures = failures + 1
517 break
Etan Cohen3704c262018-05-01 14:38:23 -0700518
Jaineel7e67a3f2019-08-28 15:58:49 -0700519 # message from Sub -> Pub
520 msg_s2p = "Message Subscriber -> Publisher #%d" % i
521 next_msg_id = self.get_next_msg_id()
522 s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub,
523 next_msg_id, msg_s2p, 0)
Etan Cohen3704c262018-05-01 14:38:23 -0700524
Jaineel7e67a3f2019-08-28 15:58:49 -0700525 # wait for Tx confirmation
526 try:
527 s_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_SENT,
528 autils.EVENT_TIMEOUT)
529 except queue.Empty:
530 s_dut.log.info("[Subscriber] Timed out while waiting for "
531 "SESSION_CB_ON_MESSAGE_SENT")
532 failures = failures + 1
533 break
Etan Cohen3704c262018-05-01 14:38:23 -0700534
Jaineel7e67a3f2019-08-28 15:58:49 -0700535 # wait for Rx confirmation (and validate contents)
536 try:
537 event = p_dut.ed.pop_event(
538 aconsts.SESSION_CB_ON_MESSAGE_RECEIVED,
539 autils.EVENT_TIMEOUT)
540 peer_id_on_pub = event['data'][
541 aconsts.SESSION_CB_KEY_PEER_ID]
542 if (event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING]
543 != msg_s2p):
544 p_dut.log.info(
545 "[Publisher] Corrupted input message - %s", event)
546 failures = failures + 1
547 break
548 except queue.Empty:
549 p_dut.log.info("[Publisher] Timed out while waiting for "
550 "SESSION_CB_ON_MESSAGE_RECEIVED")
551 failures = failures + 1
552 break
Etan Cohen3704c262018-05-01 14:38:23 -0700553
Jaineel7e67a3f2019-08-28 15:58:49 -0700554 # message from Pub -> Sub
555 msg_p2s = "Message Publisher -> Subscriber #%d" % i
556 next_msg_id = self.get_next_msg_id()
557 p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub,
558 next_msg_id, msg_p2s, 0)
Etan Cohen3704c262018-05-01 14:38:23 -0700559
Jaineel7e67a3f2019-08-28 15:58:49 -0700560 # wait for Tx confirmation
561 try:
562 p_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_SENT,
563 autils.EVENT_TIMEOUT)
564 except queue.Empty:
565 p_dut.log.info("[Publisher] Timed out while waiting for "
566 "SESSION_CB_ON_MESSAGE_SENT")
567 failures = failures + 1
568 break
Etan Cohen3704c262018-05-01 14:38:23 -0700569
Jaineel7e67a3f2019-08-28 15:58:49 -0700570 # wait for Rx confirmation (and validate contents)
571 try:
572 event = s_dut.ed.pop_event(
573 aconsts.SESSION_CB_ON_MESSAGE_RECEIVED,
574 autils.EVENT_TIMEOUT)
575 if (event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING]
576 != msg_p2s):
577 s_dut.log.info(
578 "[Subscriber] Corrupted input message - %s", event)
579 failures = failures + 1
580 break
581 except queue.Empty:
582 s_dut.log.info("[Subscriber] Timed out while waiting for "
583 "SESSION_CB_ON_MESSAGE_RECEIVED")
584 failures = failures + 1
585 break
Etan Cohen3704c262018-05-01 14:38:23 -0700586
Jaineel7e67a3f2019-08-28 15:58:49 -0700587 # create NDP
Etan Cohen3704c262018-05-01 14:38:23 -0700588
Jaineel7e67a3f2019-08-28 15:58:49 -0700589 # Publisher: request network
590 p_req_key = autils.request_network(
591 p_dut,
592 p_dut.droid.wifiAwareCreateNetworkSpecifier(
593 p_disc_id, peer_id_on_pub, None))
594
595 # Subscriber: request network
596 s_req_key = autils.request_network(
597 s_dut,
598 s_dut.droid.wifiAwareCreateNetworkSpecifier(
599 s_disc_id, peer_id_on_sub, None))
600
601 # Publisher & Subscriber: wait for network formation
602 try:
603 p_net_event = autils.wait_for_event_with_keys(
604 p_dut, cconsts.EVENT_NETWORK_CALLBACK,
605 autils.EVENT_TIMEOUT,
606 (cconsts.NETWORK_CB_KEY_EVENT,
607 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
608 (cconsts.NETWORK_CB_KEY_ID, p_req_key))
609 s_net_event = autils.wait_for_event_with_keys(
610 s_dut, cconsts.EVENT_NETWORK_CALLBACK,
611 autils.EVENT_TIMEOUT,
612 (cconsts.NETWORK_CB_KEY_EVENT,
613 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
614 (cconsts.NETWORK_CB_KEY_ID, s_req_key))
615 except:
616 failures = failures + 1
617 break
618
619 p_aware_if = p_net_event["data"][
620 cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
621 s_aware_if = s_net_event["data"][
622 cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
623
624 p_ipv6 = \
625 p_dut.droid.connectivityGetLinkLocalIpv6Address(p_aware_if).split("%")[
626 0]
627 s_ipv6 = \
628 s_dut.droid.connectivityGetLinkLocalIpv6Address(s_aware_if).split("%")[
629 0]
630
631 p_dut.log.info("[Publisher] IF=%s, IPv6=%s", p_aware_if,
632 p_ipv6)
633 s_dut.log.info("[Subscriber] IF=%s, IPv6=%s", s_aware_if,
634 s_ipv6)
635
636 latencies.append(time.perf_counter() - timestamp_start)
637 break
638
639 # destroy sessions
640 p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id)
641 s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id)
642 if include_setup:
643 p_dut.droid.wifiAwareDestroy(p_id)
644 s_dut.droid.wifiAwareDestroy(s_id)
645
646 autils.extract_stats(
Etan Cohen3704c262018-05-01 14:38:23 -0700647 p_dut,
Jaineel7e67a3f2019-08-28 15:58:49 -0700648 data=latencies,
649 results=results[key],
650 key_prefix="",
651 log_prefix="End-to-End(dw24=%d, dw5=%d)" % (dw_24ghz, dw_5ghz))
652 results[key]["failures"] = failures
Etan Cohen3704c262018-05-01 14:38:23 -0700653
Jaineel7e67a3f2019-08-28 15:58:49 -0700654 ########################################################################
Etan Cohen3704c262018-05-01 14:38:23 -0700655
Jaineel7e67a3f2019-08-28 15:58:49 -0700656 def test_synchronization_default_dws(self):
657 """Measure the device synchronization for default dws. Loop over values
Etan Cohen04b89522017-06-19 17:07:47 -0700658 from 0 to 4 seconds."""
Jaineel7e67a3f2019-08-28 15:58:49 -0700659 results = {}
660 for startup_offset in range(5):
661 self.run_synchronization_latency(
662 results=results,
663 do_unsolicited_passive=True,
664 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
665 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
666 num_iterations=10,
667 startup_offset=startup_offset,
668 timeout_period=20)
669 asserts.explicit_pass(
670 "test_synchronization_default_dws finished", extras=results)
Etan Cohen04b89522017-06-19 17:07:47 -0700671
Jaineel7e67a3f2019-08-28 15:58:49 -0700672 def test_synchronization_non_interactive_dws(self):
673 """Measure the device synchronization for non-interactive dws. Loop over
Etan Cohen04b89522017-06-19 17:07:47 -0700674 values from 0 to 4 seconds."""
Jaineel7e67a3f2019-08-28 15:58:49 -0700675 results = {}
676 for startup_offset in range(5):
677 self.run_synchronization_latency(
678 results=results,
679 do_unsolicited_passive=True,
680 dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE,
681 dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE,
682 num_iterations=10,
683 startup_offset=startup_offset,
684 timeout_period=20)
685 asserts.explicit_pass(
686 "test_synchronization_non_interactive_dws finished",
687 extras=results)
Etan Cohen04b89522017-06-19 17:07:47 -0700688
Jaineel7e67a3f2019-08-28 15:58:49 -0700689 def test_discovery_latency_default_dws(self):
690 """Measure the service discovery latency with the default DW configuration.
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700691 """
Jaineel7e67a3f2019-08-28 15:58:49 -0700692 results = {}
Etan Cohen9b11b182017-06-12 09:51:12 -0700693 self.run_discovery_latency(
694 results=results,
695 do_unsolicited_passive=True,
Jaineel7e67a3f2019-08-28 15:58:49 -0700696 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
697 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
698 num_iterations=100)
699 asserts.explicit_pass(
700 "test_discovery_latency_default_parameters finished",
701 extras=results)
Etan Cohen7185c482017-06-12 14:30:59 -0700702
Jaineel7e67a3f2019-08-28 15:58:49 -0700703 def test_discovery_latency_non_interactive_dws(self):
704 """Measure the service discovery latency with the DW configuration for non
705 -interactive mode (lower power)."""
706 results = {}
707 self.run_discovery_latency(
708 results=results,
709 do_unsolicited_passive=True,
710 dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE,
711 dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE,
712 num_iterations=100)
713 asserts.explicit_pass(
714 "test_discovery_latency_non_interactive_dws finished",
715 extras=results)
716
717 def test_discovery_latency_all_dws(self):
718 """Measure the service discovery latency with all DW combinations (low
719 iteration count)"""
720 results = {}
721 for dw24 in range(1, 6): # permitted values: 1-5
722 for dw5 in range(0, 6): # permitted values: 0, 1-5
723 self.run_discovery_latency(
724 results=results,
725 do_unsolicited_passive=True,
726 dw_24ghz=dw24,
727 dw_5ghz=dw5,
728 num_iterations=10)
729 asserts.explicit_pass(
730 "test_discovery_latency_all_dws finished", extras=results)
731
732 def test_message_latency_default_dws(self):
733 """Measure the send message latency with the default DW configuration. Test
Etan Cohen7185c482017-06-12 14:30:59 -0700734 performed on non-queued message transmission - i.e. waiting for confirmation
735 of reception (ACK) before sending the next message."""
Jaineel7e67a3f2019-08-28 15:58:49 -0700736 results = {}
737 self.run_message_latency(
738 results=results,
739 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
740 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
741 num_iterations=100)
742 asserts.explicit_pass(
743 "test_message_latency_default_dws finished", extras=results)
Etan Cohen7185c482017-06-12 14:30:59 -0700744
Jaineel7e67a3f2019-08-28 15:58:49 -0700745 def test_message_latency_non_interactive_dws(self):
746 """Measure the send message latency with the DW configuration for
Etan Cohen7185c482017-06-12 14:30:59 -0700747 non-interactive mode. Test performed on non-queued message transmission -
748 i.e. waiting for confirmation of reception (ACK) before sending the next
749 message."""
Jaineel7e67a3f2019-08-28 15:58:49 -0700750 results = {}
751 self.run_message_latency(
752 results=results,
753 dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE,
754 dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE,
755 num_iterations=100)
756 asserts.explicit_pass(
757 "test_message_latency_non_interactive_dws finished",
758 extras=results)
Etan Cohen8e9104f2017-06-13 08:33:52 -0700759
Jaineel7e67a3f2019-08-28 15:58:49 -0700760 def test_oob_ndp_setup_latency_default_dws(self):
761 """Measure the NDP setup latency with the default DW configuration. The
Etan Cohen8e9104f2017-06-13 08:33:52 -0700762 NDP is setup with OOB (out-of-band) configuration."""
Jaineel7e67a3f2019-08-28 15:58:49 -0700763 results = {}
764 self.run_ndp_oob_latency(
765 results=results,
766 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
767 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
768 num_iterations=100)
769 asserts.explicit_pass(
770 "test_ndp_setup_latency_default_dws finished", extras=results)
Etan Cohen8e9104f2017-06-13 08:33:52 -0700771
Jaineel7e67a3f2019-08-28 15:58:49 -0700772 def test_oob_ndp_setup_latency_non_interactive_dws(self):
773 """Measure the NDP setup latency with the DW configuration for
Etan Cohen8e9104f2017-06-13 08:33:52 -0700774 non-interactive mode. The NDP is setup with OOB (out-of-band)
775 configuration"""
Jaineel7e67a3f2019-08-28 15:58:49 -0700776 results = {}
777 self.run_ndp_oob_latency(
778 results=results,
779 dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE,
780 dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE,
781 num_iterations=100)
782 asserts.explicit_pass(
783 "test_ndp_setup_latency_non_interactive_dws finished",
784 extras=results)
Etan Cohen3704c262018-05-01 14:38:23 -0700785
Jaineel7e67a3f2019-08-28 15:58:49 -0700786 def test_end_to_end_latency_default_dws(self):
787 """Measure the latency for end-to-end communication link setup:
Etan Cohen3704c262018-05-01 14:38:23 -0700788 - Start Aware
789 - Discovery
790 - Message from Sub -> Pub
791 - Message from Pub -> Sub
792 - NDP setup
793 """
Jaineel7e67a3f2019-08-28 15:58:49 -0700794 results = {}
795 self.run_end_to_end_latency(
796 results,
797 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
798 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
799 num_iterations=10,
800 startup_offset=0,
801 include_setup=True)
802 asserts.explicit_pass(
803 "test_end_to_end_latency_default_dws finished", extras=results)
Etan Cohen3704c262018-05-01 14:38:23 -0700804
Jaineel7e67a3f2019-08-28 15:58:49 -0700805 def test_end_to_end_latency_post_attach_default_dws(self):
806 """Measure the latency for end-to-end communication link setup without
Etan Cohen3704c262018-05-01 14:38:23 -0700807 the initial synchronization:
808 - Start Aware & synchronize initially
809 - Loop:
810 - Discovery
811 - Message from Sub -> Pub
812 - Message from Pub -> Sub
813 - NDP setup
814 """
Jaineel7e67a3f2019-08-28 15:58:49 -0700815 results = {}
816 self.run_end_to_end_latency(
817 results,
818 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
819 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
820 num_iterations=10,
821 startup_offset=0,
822 include_setup=False)
823 asserts.explicit_pass(
824 "test_end_to_end_latency_post_attach_default_dws finished",
825 extras=results)