blob: 3deca591168e7a056e0ce1172b3338ab0b8c81a9 [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
21from acts.test_utils.wifi.aware import aware_const as aconsts
22from acts.test_utils.wifi.aware import aware_test_utils as autils
23from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest
24
25
26class LatencyTest(AwareBaseTest):
27 """Set of tests for Wi-Fi Aware to measure latency of Aware operations."""
Etan Cohen7185c482017-06-12 14:30:59 -070028 SERVICE_NAME = "GoogleTestServiceXY"
Etan Cohen2b1b03b2017-06-08 11:27:50 -070029
Etan Cohen2b1b03b2017-06-08 11:27:50 -070030 # number of second to 'reasonably' wait to make sure that devices synchronize
31 # with each other - useful for OOB test cases, where the OOB discovery would
32 # take some time
33 WAIT_FOR_CLUSTER = 5
34
35 def __init__(self, controllers):
36 AwareBaseTest.__init__(self, controllers)
37
38 def start_discovery_session(self, dut, session_id, is_publish, dtype):
39 """Start a discovery session
40
41 Args:
42 dut: Device under test
43 session_id: ID of the Aware session in which to start discovery
44 is_publish: True for a publish session, False for subscribe session
45 dtype: Type of the discovery session
46
47 Returns:
48 Discovery session started event.
49 """
50 config = {}
51 config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype
52 config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceXY"
53
54 if is_publish:
55 disc_id = dut.droid.wifiAwarePublish(session_id, config)
56 event_name = aconsts.SESSION_CB_ON_PUBLISH_STARTED
57 else:
58 disc_id = dut.droid.wifiAwareSubscribe(session_id, config)
59 event_name = aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED
60
61 event = autils.wait_for_event(dut, event_name)
62 return disc_id, event
63
64 def run_discovery_latency(self, results, do_unsolicited_passive, dw_24ghz,
Etan Cohen9b11b182017-06-12 09:51:12 -070065 dw_5ghz, num_iterations):
Etan Cohen2b1b03b2017-06-08 11:27:50 -070066 """Run the service discovery latency test with the specified DW intervals.
67
68 Args:
69 results: Result array to be populated - will add results (not erase it)
70 do_unsolicited_passive: True for unsolicited/passive, False for
71 solicited/active.
72 dw_24ghz: DW interval in the 2.4GHz band.
73 dw_5ghz: DW interval in the 5GHz band.
74 """
75 key = "%s_dw24_%d_dw5_%d" % (
76 "unsolicited_passive"
77 if do_unsolicited_passive else "solicited_active", dw_24ghz, dw_5ghz)
78 results[key] = {}
Etan Cohen9b11b182017-06-12 09:51:12 -070079 results[key]["num_iterations"] = num_iterations
Etan Cohen2b1b03b2017-06-08 11:27:50 -070080
81 p_dut = self.android_devices[0]
82 p_dut.pretty_name = "Publisher"
83 s_dut = self.android_devices[1]
84 s_dut.pretty_name = "Subscriber"
85
Etan Cohen9b11b182017-06-12 09:51:12 -070086 # override the default DW configuration
87 autils.configure_dw(p_dut, is_default=True, is_24_band=True, value=dw_24ghz)
88 autils.configure_dw(
89 p_dut, is_default=False, is_24_band=True, value=dw_24ghz)
90 autils.configure_dw(p_dut, is_default=True, is_24_band=False, value=dw_5ghz)
91 autils.configure_dw(
92 p_dut, is_default=False, is_24_band=False, value=dw_5ghz)
93 autils.configure_dw(s_dut, is_default=True, is_24_band=True, value=dw_24ghz)
94 autils.configure_dw(
95 s_dut, is_default=False, is_24_band=True, value=dw_24ghz)
96 autils.configure_dw(s_dut, is_default=True, is_24_band=False, value=dw_5ghz)
97 autils.configure_dw(
98 s_dut, is_default=False, is_24_band=False, value=dw_5ghz)
99
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700100 # Publisher+Subscriber: attach and wait for confirmation
101 p_id = p_dut.droid.wifiAwareAttach(False)
102 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED)
103 s_id = s_dut.droid.wifiAwareAttach(False)
104 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED)
105
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700106 # start publish
107 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)
110
111 # wait for for devices to synchronize with each other - used so that first
112 # discovery isn't biased by synchronization.
113 time.sleep(self.WAIT_FOR_CLUSTER)
114
115 # loop, perform discovery, and collect latency information
116 latencies = []
117 failed_discoveries = 0
Etan Cohen9b11b182017-06-12 09:51:12 -0700118 for i in range(num_iterations):
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700119 # start subscribe
120 s_disc_id, s_session_event = self.start_discovery_session(
121 s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE
122 if do_unsolicited_passive else aconsts.SUBSCRIBE_TYPE_ACTIVE)
123
124 # wait for discovery (allow for failures here since running lots of
125 # samples and would like to get the partial data even in the presence of
126 # errors)
127 try:
128 discovery_event = s_dut.ed.pop_event(
129 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, autils.EVENT_TIMEOUT)
130 except queue.Empty:
131 s_dut.log.info("[Subscriber] Timed out while waiting for "
132 "SESSION_CB_ON_SERVICE_DISCOVERED")
133 failed_discoveries = failed_discoveries + 1
134 continue
135 finally:
136 # destroy subscribe
137 s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id)
138
139 # collect latency information
140 latencies.append(
141 discovery_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS] -
142 s_session_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS])
143 self.log.info("Latency #%d = %d" % (i, latencies[-1]))
144
145 autils.extract_stats(
146 s_dut,
147 data=latencies,
148 results=results[key],
149 key_prefix="",
150 log_prefix="Subscribe Session Discovery (%s, dw24=%d, dw5=%d)" %
151 ("Unsolicited/Passive"
152 if do_unsolicited_passive else "Solicited/Active", dw_24ghz, dw_5ghz))
153 results[key]["num_failed_discovery"] = failed_discoveries
154
Etan Cohen9b11b182017-06-12 09:51:12 -0700155 # clean up
156 p_dut.droid.wifiAwareDestroyAll()
157 s_dut.droid.wifiAwareDestroyAll()
158
Etan Cohen7185c482017-06-12 14:30:59 -0700159 def run_message_latency(self, results, dw_24ghz, dw_5ghz, num_iterations):
160 """Run the message tx latency test with the specified DW intervals.
161
162 Args:
163 results: Result array to be populated - will add results (not erase it)
164 dw_24ghz: DW interval in the 2.4GHz band.
165 dw_5ghz: DW interval in the 5GHz band.
166 """
167 key = "dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz)
168 results[key] = {}
169 results[key]["num_iterations"] = num_iterations
170
171 p_dut = self.android_devices[0]
172 s_dut = self.android_devices[1]
173
174 # override the default DW configuration
175 autils.configure_dw(p_dut, is_default=True, is_24_band=True, value=dw_24ghz)
176 autils.configure_dw(
177 p_dut, is_default=False, is_24_band=True, value=dw_24ghz)
178 autils.configure_dw(p_dut, is_default=True, is_24_band=False, value=dw_5ghz)
179 autils.configure_dw(
180 p_dut, is_default=False, is_24_band=False, value=dw_5ghz)
181 autils.configure_dw(s_dut, is_default=True, is_24_band=True, value=dw_24ghz)
182 autils.configure_dw(
183 s_dut, is_default=False, is_24_band=True, value=dw_24ghz)
184 autils.configure_dw(s_dut, is_default=True, is_24_band=False, value=dw_5ghz)
185 autils.configure_dw(
186 s_dut, is_default=False, is_24_band=False, value=dw_5ghz)
187
188 # Start up a discovery session
189 (p_id, s_id, p_disc_id, s_disc_id,
190 peer_id_on_sub) = autils.create_discovery_pair(
191 p_dut,
192 s_dut,
193 p_config=autils.create_discovery_config(
194 self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED),
195 s_config=autils.create_discovery_config(
196 self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE))
197
198 latencies = []
199 failed_tx = 0
200 messages_rx = 0
201 missing_rx = 0
202 corrupted_rx = 0
203 for i in range(num_iterations):
204 # send message
205 msg_s2p = "Message Subscriber -> Publisher #%d" % i
206 next_msg_id = self.get_next_msg_id()
207 s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, next_msg_id,
208 msg_s2p, 0)
209
210 # wait for Tx confirmation
211 try:
212 sub_tx_msg_event = s_dut.ed.pop_event(
213 aconsts.SESSION_CB_ON_MESSAGE_SENT, 2 * autils.EVENT_TIMEOUT)
214 latencies.append(
215 sub_tx_msg_event["data"][aconsts.SESSION_CB_KEY_LATENCY_MS])
216 except queue.Empty:
217 s_dut.log.info("[Subscriber] Timed out while waiting for "
218 "SESSION_CB_ON_MESSAGE_SENT")
219 failed_tx = failed_tx + 1
220 continue
221
222 # wait for Rx confirmation (and validate contents)
223 try:
224 pub_rx_msg_event = p_dut.ed.pop_event(
225 aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, 2 * autils.EVENT_TIMEOUT)
226 messages_rx = messages_rx + 1
227 if (pub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING]
228 != msg_s2p):
229 corrupted_rx = corrupted_rx + 1
230 except queue.Empty:
231 s_dut.log.info("[Publisher] Timed out while waiting for "
232 "SESSION_CB_ON_MESSAGE_RECEIVED")
233 missing_rx = missing_rx + 1
234 continue
235
236 autils.extract_stats(
237 s_dut,
238 data=latencies,
239 results=results[key],
240 key_prefix="",
241 log_prefix="Subscribe Session Discovery (dw24=%d, dw5=%d)" %
242 (dw_24ghz, dw_5ghz))
243 results[key]["failed_tx"] = failed_tx
244 results[key]["messages_rx"] = messages_rx
245 results[key]["missing_rx"] = missing_rx
246 results[key]["corrupted_rx"] = corrupted_rx
247
248 # clean up
249 p_dut.droid.wifiAwareDestroyAll()
250 s_dut.droid.wifiAwareDestroyAll()
251
252
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700253 ########################################################################
254
255 def test_discovery_latency_default_dws(self):
256 """Measure the service discovery latency with the default DW configuration.
257 """
258 results = {}
259 self.run_discovery_latency(
Etan Cohen9b11b182017-06-12 09:51:12 -0700260 results=results, do_unsolicited_passive=True, dw_24ghz=1, dw_5ghz=1,
261 num_iterations=100)
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700262 asserts.explicit_pass(
263 "test_discovery_latency_default_parameters finished", extras=results)
264
265 def test_discovery_latency_non_interactive_dws(self):
266 """Measure the service discovery latency with the DW configuration for non
267 -interactive mode (lower power)."""
268 results = {}
269 self.run_discovery_latency(
Etan Cohen9b11b182017-06-12 09:51:12 -0700270 results=results, do_unsolicited_passive=True, dw_24ghz=4, dw_5ghz=0,
271 num_iterations=100)
Etan Cohen2b1b03b2017-06-08 11:27:50 -0700272 asserts.explicit_pass(
273 "test_discovery_latency_non_interactive_dws finished", extras=results)
Etan Cohen9b11b182017-06-12 09:51:12 -0700274
275 def test_discovery_latency_all_dws(self):
276 """Measure the service discovery latency with all DW combinations (low
277 iteration count)"""
278 results = {}
279 for dw24 in range(1, 6): # permitted values: 1-5
280 for dw5 in range(0, 6): # permitted values: 0, 1-5
281 self.run_discovery_latency(
282 results=results,
283 do_unsolicited_passive=True,
284 dw_24ghz=dw24,
285 dw_5ghz=dw5,
286 num_iterations=10)
287 asserts.explicit_pass(
288 "test_discovery_latency_all_dws finished", extras=results)
Etan Cohen7185c482017-06-12 14:30:59 -0700289
290 def test_message_latency_default_dws(self):
291 """Measure the send message latency with the default DW configuration. Test
292 performed on non-queued message transmission - i.e. waiting for confirmation
293 of reception (ACK) before sending the next message."""
294 results = {}
295 self.run_message_latency(
296 results=results, dw_24ghz=1, dw_5ghz=1, num_iterations=100)
297 asserts.explicit_pass(
298 "test_message_latency_default_dws finished", extras=results)
299
300 def test_message_latency_non_interactive_dws(self):
301 """Measure the send message latency with the DW configuration for
302 non-interactive mode. Test performed on non-queued message transmission -
303 i.e. waiting for confirmation of reception (ACK) before sending the next
304 message."""
305 results = {}
306 self.run_message_latency(
307 results=results, dw_24ghz=4, dw_5ghz=0, num_iterations=100)
308 asserts.explicit_pass(
309 "test_message_latency_non_interactive_dws finished", extras=results)