blob: bfadebcefb915b5da98fea9fa15275c1b0642b97 [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
Etan Cohen8e9104f2017-06-13 08:33:52 -070021from acts.test_utils.net import connectivity_const as cconsts
Etan Cohen2b1b03b2017-06-08 11:27:50 -070022from acts.test_utils.wifi.aware import aware_const as aconsts
23from acts.test_utils.wifi.aware import aware_test_utils as autils
24from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest
25
26
27class LatencyTest(AwareBaseTest):
28 """Set of tests for Wi-Fi Aware to measure latency of Aware operations."""
Etan Cohen7185c482017-06-12 14:30:59 -070029 SERVICE_NAME = "GoogleTestServiceXY"
Etan Cohen2b1b03b2017-06-08 11:27:50 -070030
Etan Cohen2b1b03b2017-06-08 11:27:50 -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
35
36 def __init__(self, controllers):
37 AwareBaseTest.__init__(self, controllers)
38
39 def start_discovery_session(self, dut, session_id, is_publish, dtype):
40 """Start a discovery session
41
42 Args:
43 dut: Device under test
44 session_id: ID of the Aware session in which to start discovery
45 is_publish: True for a publish session, False for subscribe session
46 dtype: Type of the discovery session
47
48 Returns:
49 Discovery session started event.
50 """
51 config = {}
52 config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype
53 config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceXY"
54
55 if is_publish:
56 disc_id = dut.droid.wifiAwarePublish(session_id, config)
57 event_name = aconsts.SESSION_CB_ON_PUBLISH_STARTED
58 else:
59 disc_id = dut.droid.wifiAwareSubscribe(session_id, config)
60 event_name = aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED
61
62 event = autils.wait_for_event(dut, event_name)
63 return disc_id, event
64
Etan Cohen04b89522017-06-19 17:07:47 -070065 def run_synchronization_latency(self, results, do_unsolicited_passive,
66 dw_24ghz, dw_5ghz, num_iterations,
67 startup_offset, timeout_period):
68 """Run the synchronization latency test with the specified DW intervals.
69 There is no direct measure of synchronization. Instead starts a discovery
70 session as soon as possible and measures both probability of discovery
71 within a timeout period and the actual discovery time (not necessarily
72 accurate).
73
74 Args:
75 results: Result array to be populated - will add results (not erase it)
76 do_unsolicited_passive: True for unsolicited/passive, False for
77 solicited/active.
78 dw_24ghz: DW interval in the 2.4GHz band.
79 dw_5ghz: DW interval in the 5GHz band.
80 startup_offset: The start-up gap (in seconds) between the two devices
81 timeout_period: Time period over which to measure synchronization
82 """
83 key = "%s_dw24_%d_dw5_%d_offset_%d" % (
84 "unsolicited_passive" if do_unsolicited_passive else "solicited_active",
85 dw_24ghz, dw_5ghz, startup_offset)
86 results[key] = {}
87 results[key]["num_iterations"] = num_iterations
88
89 p_dut = self.android_devices[0]
90 p_dut.pretty_name = "Publisher"
91 s_dut = self.android_devices[1]
92 s_dut.pretty_name = "Subscriber"
93
94 # override the default DW configuration
Etan Cohena9fdb402017-12-28 15:13:08 -080095 autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz)
96 autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz)
Etan Cohen04b89522017-06-19 17:07:47 -070097
98 latencies = []
99 failed_discoveries = 0
100 for i in range(num_iterations):
101 # Publisher+Subscriber: attach and wait for confirmation
102 p_id = p_dut.droid.wifiAwareAttach(False)
103 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED)
104 time.sleep(startup_offset)
105 s_id = s_dut.droid.wifiAwareAttach(False)
106 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED)
107
108 # start publish
109 p_disc_id, p_disc_event = self.start_discovery_session(
110 p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED
111 if do_unsolicited_passive else aconsts.PUBLISH_TYPE_SOLICITED)
112
113 # start subscribe
114 s_disc_id, s_session_event = self.start_discovery_session(
115 s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE
116 if do_unsolicited_passive else aconsts.SUBSCRIBE_TYPE_ACTIVE)
117
118 # wait for discovery (allow for failures here since running lots of
119 # samples and would like to get the partial data even in the presence of
120 # errors)
121 try:
122 discovery_event = s_dut.ed.pop_event(
123 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, timeout_period)
124 s_dut.log.info("[Subscriber] SESSION_CB_ON_SERVICE_DISCOVERED: %s",
125 discovery_event["data"])
126 except queue.Empty:
127 s_dut.log.info("[Subscriber] Timed out while waiting for "
128 "SESSION_CB_ON_SERVICE_DISCOVERED")
129 failed_discoveries = failed_discoveries + 1
130 continue
131 finally:
132 # destroy sessions
133 p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id)
134 s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id)
135 p_dut.droid.wifiAwareDestroy(p_id)
136 s_dut.droid.wifiAwareDestroy(s_id)
137
138 # collect latency information
139 latencies.append(
140 discovery_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS] -
141 s_session_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS])
142 self.log.info("Latency #%d = %d" % (i, latencies[-1]))
143
144 autils.extract_stats(
145 s_dut,
146 data=latencies,
147 results=results[key],
148 key_prefix="",
149 log_prefix="Subscribe Session Sync/Discovery (%s, dw24=%d, dw5=%d)" %
150 ("Unsolicited/Passive"
151 if do_unsolicited_passive else "Solicited/Active", dw_24ghz, dw_5ghz))
152 results[key]["num_failed_discovery"] = failed_discoveries
153
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700154 def run_discovery_latency(self, results, do_unsolicited_passive, dw_24ghz,
Etan Cohen9b11b182017-06-12 09:51:12 -0700155 dw_5ghz, num_iterations):
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700156 """Run the service discovery latency test with the specified DW intervals.
157
158 Args:
159 results: Result array to be populated - will add results (not erase it)
160 do_unsolicited_passive: True for unsolicited/passive, False for
161 solicited/active.
162 dw_24ghz: DW interval in the 2.4GHz band.
163 dw_5ghz: DW interval in the 5GHz band.
164 """
165 key = "%s_dw24_%d_dw5_%d" % (
166 "unsolicited_passive"
167 if do_unsolicited_passive else "solicited_active", dw_24ghz, dw_5ghz)
168 results[key] = {}
Etan Cohen9b11b182017-06-12 09:51:12 -0700169 results[key]["num_iterations"] = num_iterations
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700170
171 p_dut = self.android_devices[0]
172 p_dut.pretty_name = "Publisher"
173 s_dut = self.android_devices[1]
174 s_dut.pretty_name = "Subscriber"
175
Etan Cohen9b11b182017-06-12 09:51:12 -0700176 # override the default DW configuration
Etan Cohena9fdb402017-12-28 15:13:08 -0800177 autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz)
178 autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz)
Etan Cohen9b11b182017-06-12 09:51:12 -0700179
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700180 # Publisher+Subscriber: attach and wait for confirmation
181 p_id = p_dut.droid.wifiAwareAttach(False)
182 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED)
Etan Cohen76ff8012017-06-16 13:13:44 -0700183 time.sleep(self.device_startup_offset)
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700184 s_id = s_dut.droid.wifiAwareAttach(False)
185 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED)
186
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700187 # start publish
188 p_disc_event = self.start_discovery_session(
189 p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED
190 if do_unsolicited_passive else aconsts.PUBLISH_TYPE_SOLICITED)
191
192 # wait for for devices to synchronize with each other - used so that first
193 # discovery isn't biased by synchronization.
194 time.sleep(self.WAIT_FOR_CLUSTER)
195
196 # loop, perform discovery, and collect latency information
197 latencies = []
198 failed_discoveries = 0
Etan Cohen9b11b182017-06-12 09:51:12 -0700199 for i in range(num_iterations):
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700200 # start subscribe
201 s_disc_id, s_session_event = self.start_discovery_session(
202 s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE
203 if do_unsolicited_passive else aconsts.SUBSCRIBE_TYPE_ACTIVE)
204
205 # wait for discovery (allow for failures here since running lots of
206 # samples and would like to get the partial data even in the presence of
207 # errors)
208 try:
209 discovery_event = s_dut.ed.pop_event(
210 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, 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)
219
220 # 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]))
225
226 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"
233 if do_unsolicited_passive else "Solicited/Active", dw_24ghz, dw_5ghz))
234 results[key]["num_failed_discovery"] = failed_discoveries
235
Etan Cohen9b11b182017-06-12 09:51:12 -0700236 # clean up
237 p_dut.droid.wifiAwareDestroyAll()
238 s_dut.droid.wifiAwareDestroyAll()
239
Etan Cohen7185c482017-06-12 14:30:59 -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.
242
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 """
248 key = "dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz)
249 results[key] = {}
250 results[key]["num_iterations"] = num_iterations
251
252 p_dut = self.android_devices[0]
253 s_dut = self.android_devices[1]
254
255 # override the default DW configuration
Etan Cohena9fdb402017-12-28 15:13:08 -0800256 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
259 # 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(
Etan Cohen76ff8012017-06-16 13:13:44 -0700267 self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE),
268 device_startup_offset=self.device_startup_offset)
Etan Cohen7185c482017-06-12 14:30:59 -0700269
270 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, next_msg_id,
280 msg_s2p, 0)
281
282 # wait for Tx confirmation
283 try:
284 sub_tx_msg_event = s_dut.ed.pop_event(
285 aconsts.SESSION_CB_ON_MESSAGE_SENT, 2 * autils.EVENT_TIMEOUT)
286 latencies.append(
287 sub_tx_msg_event["data"][aconsts.SESSION_CB_KEY_LATENCY_MS])
288 except queue.Empty:
289 s_dut.log.info("[Subscriber] Timed out while waiting for "
290 "SESSION_CB_ON_MESSAGE_SENT")
291 failed_tx = failed_tx + 1
292 continue
293
294 # wait for Rx confirmation (and validate contents)
295 try:
296 pub_rx_msg_event = p_dut.ed.pop_event(
297 aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, 2 * autils.EVENT_TIMEOUT)
298 messages_rx = messages_rx + 1
299 if (pub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING]
300 != msg_s2p):
301 corrupted_rx = corrupted_rx + 1
302 except queue.Empty:
303 s_dut.log.info("[Publisher] Timed out while waiting for "
304 "SESSION_CB_ON_MESSAGE_RECEIVED")
305 missing_rx = missing_rx + 1
306 continue
307
308 autils.extract_stats(
309 s_dut,
310 data=latencies,
311 results=results[key],
312 key_prefix="",
313 log_prefix="Subscribe Session Discovery (dw24=%d, dw5=%d)" %
314 (dw_24ghz, dw_5ghz))
315 results[key]["failed_tx"] = failed_tx
316 results[key]["messages_rx"] = messages_rx
317 results[key]["missing_rx"] = missing_rx
318 results[key]["corrupted_rx"] = corrupted_rx
319
320 # clean up
321 p_dut.droid.wifiAwareDestroyAll()
322 s_dut.droid.wifiAwareDestroyAll()
323
Etan Cohen8e9104f2017-06-13 08:33:52 -0700324 def run_ndp_oob_latency(self, results, dw_24ghz, dw_5ghz, num_iterations):
325 """Runs the NDP setup with OOB (out-of-band) discovery latency test.
326
327 Args:
328 results: Result array to be populated - will add results (not erase it)
329 dw_24ghz: DW interval in the 2.4GHz band.
330 dw_5ghz: DW interval in the 5GHz band.
331 """
332 key_avail = "on_avail_dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz)
333 key_link_props = "link_props_dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz)
334 results[key_avail] = {}
335 results[key_link_props] = {}
336 results[key_avail]["num_iterations"] = num_iterations
337
338 init_dut = self.android_devices[0]
339 init_dut.pretty_name = 'Initiator'
340 resp_dut = self.android_devices[1]
341 resp_dut.pretty_name = 'Responder'
342
343 # override the default DW configuration
Etan Cohena9fdb402017-12-28 15:13:08 -0800344 autils.config_power_settings(init_dut, dw_24ghz, dw_5ghz)
345 autils.config_power_settings(resp_dut, dw_24ghz, dw_5ghz)
Etan Cohen8e9104f2017-06-13 08:33:52 -0700346
347 # Initiator+Responder: attach and wait for confirmation & identity
348 init_id = init_dut.droid.wifiAwareAttach(True)
349 autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED)
350 init_ident_event = autils.wait_for_event(init_dut,
351 aconsts.EVENT_CB_ON_IDENTITY_CHANGED)
352 init_mac = init_ident_event['data']['mac']
Etan Cohen76ff8012017-06-16 13:13:44 -0700353 time.sleep(self.device_startup_offset)
Etan Cohen8e9104f2017-06-13 08:33:52 -0700354 resp_id = resp_dut.droid.wifiAwareAttach(True)
355 autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED)
356 resp_ident_event = autils.wait_for_event(resp_dut,
357 aconsts.EVENT_CB_ON_IDENTITY_CHANGED)
358 resp_mac = resp_ident_event['data']['mac']
359
360 # wait for for devices to synchronize with each other - there are no other
361 # mechanisms to make sure this happens for OOB discovery (except retrying
362 # to execute the data-path request)
363 time.sleep(autils.WAIT_FOR_CLUSTER)
364
365 on_available_latencies = []
366 link_props_latencies = []
367 ndp_setup_failures = 0
368 for i in range(num_iterations):
369 # Responder: request network
370 resp_req_key = autils.request_network(
371 resp_dut,
372 resp_dut.droid.wifiAwareCreateNetworkSpecifierOob(
373 resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, None))
374
375 # Initiator: request network
376 init_req_key = autils.request_network(
377 init_dut,
378 init_dut.droid.wifiAwareCreateNetworkSpecifierOob(
379 init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, None))
380
381 # Initiator & Responder: wait for network formation
382 got_on_available = False
383 got_on_link_props = False
384 while not got_on_available or not got_on_link_props:
385 try:
386 nc_event = init_dut.ed.pop_event(cconsts.EVENT_NETWORK_CALLBACK,
Etan Cohene47ec432017-06-21 10:42:16 -0700387 autils.EVENT_NDP_TIMEOUT)
Etan Cohen8e9104f2017-06-13 08:33:52 -0700388 if nc_event["data"][
389 cconsts.NETWORK_CB_KEY_EVENT] == cconsts.NETWORK_CB_AVAILABLE:
390 got_on_available = True
391 on_available_latencies.append(
392 nc_event["data"][cconsts.NETWORK_CB_KEY_CURRENT_TS] -
393 nc_event["data"][cconsts.NETWORK_CB_KEY_CREATE_TS])
394 elif (nc_event["data"][cconsts.NETWORK_CB_KEY_EVENT] ==
395 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED):
396 got_on_link_props = True
397 link_props_latencies.append(
398 nc_event["data"][cconsts.NETWORK_CB_KEY_CURRENT_TS] -
399 nc_event["data"][cconsts.NETWORK_CB_KEY_CREATE_TS])
400 except queue.Empty:
401 ndp_setup_failures = ndp_setup_failures + 1
402 init_dut.log.info("[Initiator] Timed out while waiting for "
403 "EVENT_NETWORK_CALLBACK")
404 break
405
Etan Cohen8e9104f2017-06-13 08:33:52 -0700406 # clean-up
407 init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key)
408 resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key)
409
Etan Cohen2e821802017-08-10 17:47:42 -0700410 # wait to make sure previous NDP terminated, otherwise its termination
411 # time will be counted in the setup latency!
412 time.sleep(2)
Etan Cohen1ff5c8e2017-07-10 18:04:38 -0700413
Etan Cohen8e9104f2017-06-13 08:33:52 -0700414 autils.extract_stats(
415 init_dut,
416 data=on_available_latencies,
417 results=results[key_avail],
418 key_prefix="",
419 log_prefix="NDP setup OnAvailable(dw24=%d, dw5=%d)" % (dw_24ghz,
420 dw_5ghz))
421 autils.extract_stats(
422 init_dut,
423 data=link_props_latencies,
424 results=results[key_link_props],
425 key_prefix="",
426 log_prefix="NDP setup OnLinkProperties (dw24=%d, dw5=%d)" % (dw_24ghz,
427 dw_5ghz))
428 results[key_avail]["ndp_setup_failures"] = ndp_setup_failures
429
Etan Cohen3704c262018-05-01 14:38:23 -0700430 def run_end_to_end_latency(self, results, dw_24ghz, dw_5ghz, num_iterations,
431 startup_offset, include_setup):
432 """Measure the latency for end-to-end communication link setup:
433 - Start Aware
434 - Discovery
435 - Message from Sub -> Pub
436 - Message from Pub -> Sub
437 - NDP setup
438
439 Args:
440 results: Result array to be populated - will add results (not erase it)
441 dw_24ghz: DW interval in the 2.4GHz band.
442 dw_5ghz: DW interval in the 5GHz band.
443 startup_offset: The start-up gap (in seconds) between the two devices
444 include_setup: True to include the cluster setup in the latency
445 measurements.
446 """
447 key = "dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz)
448 results[key] = {}
449 results[key]["num_iterations"] = num_iterations
450
451 p_dut = self.android_devices[0]
452 p_dut.pretty_name = "Publisher"
453 s_dut = self.android_devices[1]
454 s_dut.pretty_name = "Subscriber"
455
456 # override the default DW configuration
457 autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz)
458 autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz)
459
460 latencies = []
461
462 # allow for failures here since running lots of samples and would like to
463 # get the partial data even in the presence of errors
464 failures = 0
465
466 if not include_setup:
467 # Publisher+Subscriber: attach and wait for confirmation
468 p_id = p_dut.droid.wifiAwareAttach(False)
469 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED)
470 time.sleep(startup_offset)
471 s_id = s_dut.droid.wifiAwareAttach(False)
472 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED)
473
474 for i in range(num_iterations):
475 while (True): # for pseudo-goto/finalize
476 timestamp_start = time.perf_counter()
477
478 if include_setup:
479 # Publisher+Subscriber: attach and wait for confirmation
480 p_id = p_dut.droid.wifiAwareAttach(False)
481 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED)
482 time.sleep(startup_offset)
483 s_id = s_dut.droid.wifiAwareAttach(False)
484 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED)
485
486 # start publish
487 p_disc_id, p_disc_event = self.start_discovery_session(
488 p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED)
489
490 # start subscribe
491 s_disc_id, s_session_event = self.start_discovery_session(
492 s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE)
493
494 # wait for discovery (allow for failures here since running lots of
495 # samples and would like to get the partial data even in the presence of
496 # errors)
497 try:
498 event = s_dut.ed.pop_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED,
499 autils.EVENT_TIMEOUT)
500 s_dut.log.info("[Subscriber] SESSION_CB_ON_SERVICE_DISCOVERED: %s",
501 event["data"])
502 peer_id_on_sub = event['data'][aconsts.SESSION_CB_KEY_PEER_ID]
503 except queue.Empty:
504 s_dut.log.info("[Subscriber] Timed out while waiting for "
505 "SESSION_CB_ON_SERVICE_DISCOVERED")
506 failures = failures + 1
507 break
508
509 # message from Sub -> Pub
510 msg_s2p = "Message Subscriber -> Publisher #%d" % i
511 next_msg_id = self.get_next_msg_id()
512 s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, next_msg_id,
513 msg_s2p, 0)
514
515 # wait for Tx confirmation
516 try:
517 s_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_SENT,
518 autils.EVENT_TIMEOUT)
519 except queue.Empty:
520 s_dut.log.info("[Subscriber] Timed out while waiting for "
521 "SESSION_CB_ON_MESSAGE_SENT")
522 failures = failures + 1
523 break
524
525 # wait for Rx confirmation (and validate contents)
526 try:
527 event = p_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_RECEIVED,
528 autils.EVENT_TIMEOUT)
529 peer_id_on_pub = event['data'][aconsts.SESSION_CB_KEY_PEER_ID]
530 if (event["data"][
531 aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] != msg_s2p):
532 p_dut.log.info("[Publisher] Corrupted input message - %s", event)
533 failures = failures + 1
534 break
535 except queue.Empty:
536 p_dut.log.info("[Publisher] Timed out while waiting for "
537 "SESSION_CB_ON_MESSAGE_RECEIVED")
538 failures = failures + 1
539 break
540
541 # message from Pub -> Sub
542 msg_p2s = "Message Publisher -> Subscriber #%d" % i
543 next_msg_id = self.get_next_msg_id()
544 p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, next_msg_id,
545 msg_p2s, 0)
546
547 # wait for Tx confirmation
548 try:
549 p_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_SENT,
550 autils.EVENT_TIMEOUT)
551 except queue.Empty:
552 p_dut.log.info("[Publisher] Timed out while waiting for "
553 "SESSION_CB_ON_MESSAGE_SENT")
554 failures = failures + 1
555 break
556
557 # wait for Rx confirmation (and validate contents)
558 try:
559 event = s_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_RECEIVED,
560 autils.EVENT_TIMEOUT)
561 if (event["data"][
562 aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] != msg_p2s):
563 s_dut.log.info("[Subscriber] Corrupted input message - %s", event)
564 failures = failures + 1
565 break
566 except queue.Empty:
567 s_dut.log.info("[Subscriber] Timed out while waiting for "
568 "SESSION_CB_ON_MESSAGE_RECEIVED")
569 failures = failures + 1
570 break
571
572 # create NDP
573
574 # Publisher: request network
575 p_req_key = autils.request_network(
576 p_dut,
577 p_dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id,
578 peer_id_on_pub, None))
579
580 # Subscriber: request network
581 s_req_key = autils.request_network(
582 s_dut,
583 s_dut.droid.wifiAwareCreateNetworkSpecifier(s_disc_id,
584 peer_id_on_sub, None))
585
586 # Publisher & Subscriber: wait for network formation
587 try:
588 p_net_event = autils.wait_for_event_with_keys(
589 p_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_TIMEOUT, (
590 cconsts.NETWORK_CB_KEY_EVENT,
591 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
592 (cconsts.NETWORK_CB_KEY_ID, p_req_key))
593 s_net_event = autils.wait_for_event_with_keys(
594 s_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_TIMEOUT, (
595 cconsts.NETWORK_CB_KEY_EVENT,
596 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
597 (cconsts.NETWORK_CB_KEY_ID, s_req_key))
598 except:
599 failures = failures + 1
600 break
601
602 p_aware_if = p_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
603 s_aware_if = s_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
604
605 p_ipv6 = \
606 p_dut.droid.connectivityGetLinkLocalIpv6Address(p_aware_if).split("%")[
607 0]
608 s_ipv6 = \
609 s_dut.droid.connectivityGetLinkLocalIpv6Address(s_aware_if).split("%")[
610 0]
611
612 p_dut.log.info("[Publisher] IF=%s, IPv6=%s", p_aware_if, p_ipv6)
613 s_dut.log.info("[Subscriber] IF=%s, IPv6=%s", s_aware_if, s_ipv6)
614
615 latencies.append(time.perf_counter() - timestamp_start)
616 break
617
618 # destroy sessions
619 p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id)
620 s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id)
621 if include_setup:
622 p_dut.droid.wifiAwareDestroy(p_id)
623 s_dut.droid.wifiAwareDestroy(s_id)
624
625 autils.extract_stats(
626 p_dut,
627 data=latencies,
628 results=results[key],
629 key_prefix="",
630 log_prefix="End-to-End(dw24=%d, dw5=%d)" % (dw_24ghz, dw_5ghz))
631 results[key]["failures"] = failures
632
Etan Cohen7185c482017-06-12 14:30:59 -0700633
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700634 ########################################################################
635
Etan Cohen04b89522017-06-19 17:07:47 -0700636 def test_synchronization_default_dws(self):
637 """Measure the device synchronization for default dws. Loop over values
638 from 0 to 4 seconds."""
639 results = {}
640 for startup_offset in range(5):
641 self.run_synchronization_latency(
642 results=results,
643 do_unsolicited_passive=True,
Etan Cohena9fdb402017-12-28 15:13:08 -0800644 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
645 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
Etan Cohen04b89522017-06-19 17:07:47 -0700646 num_iterations=10,
647 startup_offset=startup_offset,
648 timeout_period=20)
649 asserts.explicit_pass(
650 "test_synchronization_default_dws finished", extras=results)
651
652 def test_synchronization_non_interactive_dws(self):
653 """Measure the device synchronization for non-interactive dws. Loop over
654 values from 0 to 4 seconds."""
655 results = {}
656 for startup_offset in range(5):
657 self.run_synchronization_latency(
658 results=results,
659 do_unsolicited_passive=True,
Etan Cohena9fdb402017-12-28 15:13:08 -0800660 dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE,
661 dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE,
Etan Cohen04b89522017-06-19 17:07:47 -0700662 num_iterations=10,
663 startup_offset=startup_offset,
664 timeout_period=20)
665 asserts.explicit_pass(
666 "test_synchronization_non_interactive_dws finished", extras=results)
667
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700668 def test_discovery_latency_default_dws(self):
669 """Measure the service discovery latency with the default DW configuration.
670 """
671 results = {}
672 self.run_discovery_latency(
Etan Cohen35764fa2017-06-27 17:20:12 -0700673 results=results,
674 do_unsolicited_passive=True,
Etan Cohena9fdb402017-12-28 15:13:08 -0800675 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
676 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
Etan Cohen9b11b182017-06-12 09:51:12 -0700677 num_iterations=100)
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700678 asserts.explicit_pass(
679 "test_discovery_latency_default_parameters finished", extras=results)
680
681 def test_discovery_latency_non_interactive_dws(self):
682 """Measure the service discovery latency with the DW configuration for non
683 -interactive mode (lower power)."""
684 results = {}
685 self.run_discovery_latency(
Etan Cohen35764fa2017-06-27 17:20:12 -0700686 results=results,
687 do_unsolicited_passive=True,
Etan Cohena9fdb402017-12-28 15:13:08 -0800688 dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE,
689 dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE,
Etan Cohen9b11b182017-06-12 09:51:12 -0700690 num_iterations=100)
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700691 asserts.explicit_pass(
692 "test_discovery_latency_non_interactive_dws finished", extras=results)
Etan Cohen9b11b182017-06-12 09:51:12 -0700693
694 def test_discovery_latency_all_dws(self):
695 """Measure the service discovery latency with all DW combinations (low
696 iteration count)"""
697 results = {}
698 for dw24 in range(1, 6): # permitted values: 1-5
699 for dw5 in range(0, 6): # permitted values: 0, 1-5
700 self.run_discovery_latency(
701 results=results,
702 do_unsolicited_passive=True,
703 dw_24ghz=dw24,
704 dw_5ghz=dw5,
705 num_iterations=10)
706 asserts.explicit_pass(
707 "test_discovery_latency_all_dws finished", extras=results)
Etan Cohen7185c482017-06-12 14:30:59 -0700708
709 def test_message_latency_default_dws(self):
710 """Measure the send message latency with the default DW configuration. Test
711 performed on non-queued message transmission - i.e. waiting for confirmation
712 of reception (ACK) before sending the next message."""
713 results = {}
714 self.run_message_latency(
Etan Cohen35764fa2017-06-27 17:20:12 -0700715 results=results,
Etan Cohena9fdb402017-12-28 15:13:08 -0800716 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
717 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
Etan Cohen35764fa2017-06-27 17:20:12 -0700718 num_iterations=100)
Etan Cohen7185c482017-06-12 14:30:59 -0700719 asserts.explicit_pass(
720 "test_message_latency_default_dws finished", extras=results)
721
722 def test_message_latency_non_interactive_dws(self):
723 """Measure the send message latency with the DW configuration for
724 non-interactive mode. Test performed on non-queued message transmission -
725 i.e. waiting for confirmation of reception (ACK) before sending the next
726 message."""
727 results = {}
728 self.run_message_latency(
Etan Cohen35764fa2017-06-27 17:20:12 -0700729 results=results,
Etan Cohena9fdb402017-12-28 15:13:08 -0800730 dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE,
731 dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE,
Etan Cohen35764fa2017-06-27 17:20:12 -0700732 num_iterations=100)
Etan Cohen7185c482017-06-12 14:30:59 -0700733 asserts.explicit_pass(
734 "test_message_latency_non_interactive_dws finished", extras=results)
Etan Cohen8e9104f2017-06-13 08:33:52 -0700735
736 def test_oob_ndp_setup_latency_default_dws(self):
737 """Measure the NDP setup latency with the default DW configuration. The
738 NDP is setup with OOB (out-of-band) configuration."""
739 results = {}
740 self.run_ndp_oob_latency(
Etan Cohen35764fa2017-06-27 17:20:12 -0700741 results=results,
Etan Cohena9fdb402017-12-28 15:13:08 -0800742 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
743 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
Etan Cohen2e821802017-08-10 17:47:42 -0700744 num_iterations=100)
Etan Cohen8e9104f2017-06-13 08:33:52 -0700745 asserts.explicit_pass(
746 "test_ndp_setup_latency_default_dws finished", extras=results)
747
748 def test_oob_ndp_setup_latency_non_interactive_dws(self):
749 """Measure the NDP setup latency with the DW configuration for
750 non-interactive mode. The NDP is setup with OOB (out-of-band)
751 configuration"""
752 results = {}
753 self.run_ndp_oob_latency(
Etan Cohen35764fa2017-06-27 17:20:12 -0700754 results=results,
Etan Cohena9fdb402017-12-28 15:13:08 -0800755 dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE,
756 dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE,
Etan Cohen2e821802017-08-10 17:47:42 -0700757 num_iterations=100)
Etan Cohen8e9104f2017-06-13 08:33:52 -0700758 asserts.explicit_pass(
759 "test_ndp_setup_latency_non_interactive_dws finished", extras=results)
Etan Cohen3704c262018-05-01 14:38:23 -0700760
761 def test_end_to_end_latency_default_dws(self):
762 """Measure the latency for end-to-end communication link setup:
763 - Start Aware
764 - Discovery
765 - Message from Sub -> Pub
766 - Message from Pub -> Sub
767 - NDP setup
768 """
769 results = {}
770 self.run_end_to_end_latency(
771 results,
772 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
773 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
774 num_iterations=10,
775 startup_offset=0,
776 include_setup=True)
777 asserts.explicit_pass(
778 "test_end_to_end_latency_default_dws finished", extras=results)
779
780 def test_end_to_end_latency_post_attach_default_dws(self):
781 """Measure the latency for end-to-end communication link setup without
782 the initial synchronization:
783 - Start Aware & synchronize initially
784 - Loop:
785 - Discovery
786 - Message from Sub -> Pub
787 - Message from Pub -> Sub
788 - NDP setup
789 """
790 results = {}
791 self.run_end_to_end_latency(
792 results,
793 dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE,
794 dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE,
795 num_iterations=10,
796 startup_offset=0,
797 include_setup=False)
798 asserts.explicit_pass(
799 "test_end_to_end_latency_post_attach_default_dws finished",
800 extras=results)