blob: 3b1a1334201f1a79f6027531d6ca8c98e34055b1 [file] [log] [blame]
tturney1bdf77d2015-12-28 17:46:13 -08001#/usr/bin/env python3.4
2#
3# Copyright (C) 2016 The Android Open Source Project
Ang Li73697b32015-12-03 00:41:53 +00004#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6# use this file except in compliance with the License. You may obtain a copy of
7# 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, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations under
15# the License.
16
17"""
18Test script to exercises Ble Scans can run in concurrency.
19This test was designed to be run in a shield box.
20"""
21
22import concurrent
23import time
24
25from queue import Empty
26from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
27from acts.test_utils.bt.BleEnum import AdvertiseSettingsAdvertiseMode
28from acts.test_utils.bt.BleEnum import ScanSettingsCallbackType
29from acts.test_utils.bt.BleEnum import ScanSettingsScanMode
30from acts.test_utils.bt.bt_test_utils import adv_succ
31from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
32from acts.test_utils.bt.bt_test_utils import get_advanced_droid_list
33from acts.test_utils.bt.bt_test_utils import reset_bluetooth
34from acts.test_utils.bt.bt_test_utils import scan_failed
35from acts.test_utils.bt.bt_test_utils import scan_result
36from acts.test_utils.bt.bt_test_utils import take_btsnoop_logs
37
38
39class ConcurrentBleScanningTest(BluetoothBaseTest):
40 default_timeout = 20
41 max_concurrent_scans = 28
42
43 def __init__(self, controllers):
44 BluetoothBaseTest.__init__(self, controllers)
tturney1ce8dc62016-02-18 09:55:53 -080045 self.droid_list = get_advanced_droid_list(self.android_devices)
46 self.scn_ad = self.android_devices[0]
47 self.adv_ad = self.android_devices[1]
Ang Li73697b32015-12-03 00:41:53 +000048 if self.droid_list[1]['max_advertisements'] == 0:
49 self.tests = (
50 "test_max_concurrent_ble_scans_plus_one",
51 )
52 return
53 self.tests = (
54 "test_max_concurrent_ble_scans",
55 "test_max_concurrent_ble_scans_then_discover_advertisement",
56 "test_max_concurrent_ble_scans_plus_one",
57 "test_max_concurrent_ble_scans_verify_scans_stop_independently",
58 )
59
60 def on_fail(self, test_name, begin_time):
61 self.log.debug(
62 "Test {} failed. Gathering bugreport and btsnoop logs."
63 .format(test_name))
tturney1ce8dc62016-02-18 09:55:53 -080064 take_btsnoop_logs(self.android_devices, self, test_name)
65 reset_bluetooth(self.android_devices)
Ang Li73697b32015-12-03 00:41:53 +000066
67 def setup_test(self):
tturney1ce8dc62016-02-18 09:55:53 -080068 return reset_bluetooth(self.android_devices)
Ang Li73697b32015-12-03 00:41:53 +000069
70 @BluetoothBaseTest.bt_test_wrap
71 def test_max_concurrent_ble_scans(self):
72 """Test max LE scans.
73
74 Test that a single device can have max scans concurrently scanning.
75
76 Steps:
77 1. Initialize scanner
78 2. Initialize advertiser
79 3. Start advertising on the device from step 2
80 4. Create max ble scan callbacks
81 5. Start ble scan on each callback
82 6. Verify that each callback triggers
83 7. Stop all scans and advertisements
84
85 Expected Result:
86 All scanning instances should start without errors and the advertisement
87 should be found on each scan instance.
88
89 Returns:
90 Pass if True
91 Fail if False
92
93 TAGS: LE, Scanning, Concurrency
94 Priority: 0
95 """
96 test_result = True
tturney1ce8dc62016-02-18 09:55:53 -080097 self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
98 self.scn_ad.droid.bleSetScanSettingsCallbackType(
Ang Li73697b32015-12-03 00:41:53 +000099 ScanSettingsCallbackType.CALLBACK_TYPE_ALL_MATCHES.value)
tturney1ce8dc62016-02-18 09:55:53 -0800100 self.scn_ad.droid.bleSetScanSettingsScanMode(
Ang Li73697b32015-12-03 00:41:53 +0000101 ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value)
tturney1ce8dc62016-02-18 09:55:53 -0800102 self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
Ang Li73697b32015-12-03 00:41:53 +0000103 AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value)
104 advertise_callback, advertise_data, advertise_settings = (
tturney1ce8dc62016-02-18 09:55:53 -0800105 generate_ble_advertise_objects(self.adv_ad.droid))
106 self.adv_ad.droid.bleSetAdvertiseSettingsIsConnectable(False)
107 self.adv_ad.droid.bleStartBleAdvertising(
Ang Li73697b32015-12-03 00:41:53 +0000108 advertise_callback, advertise_data, advertise_settings)
109 try:
tturney1ce8dc62016-02-18 09:55:53 -0800110 self.adv_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000111 adv_succ.format(advertise_callback), self.default_timeout)
112 except Empty as error:
113 self.log.exception(
114 "Test failed with Empty error: {}".format(error))
115 test_result = False
116 except concurrent.futures._base.TimeoutError as error:
117 self.log.exception("Test failed callback onSuccess never occurred: "
118 "{}".format(error))
119 test_result = False
120 if not test_result:
121 return test_result
tturney1ce8dc62016-02-18 09:55:53 -0800122 filter_list = self.scn_ad.droid.bleGenFilterList()
123 self.scn_ad.droid.bleSetScanFilterDeviceName(
124 self.adv_ad.droid.bluetoothGetLocalName())
125 self.scn_ad.droid.bleBuildScanFilter(filter_list)
126 scan_settings = self.scn_ad.droid.bleBuildScanSetting()
Ang Li73697b32015-12-03 00:41:53 +0000127 scan_callback_list = []
128 for i in range(self.max_concurrent_scans):
129 self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
tturney1ce8dc62016-02-18 09:55:53 -0800130 scan_callback = self.scn_ad.droid.bleGenScanCallback()
Ang Li73697b32015-12-03 00:41:53 +0000131 scan_callback_list.append(scan_callback)
tturney1ce8dc62016-02-18 09:55:53 -0800132 self.scn_ad.droid.bleStartBleScan(
Ang Li73697b32015-12-03 00:41:53 +0000133 filter_list, scan_settings, scan_callback)
134 try:
tturney1ce8dc62016-02-18 09:55:53 -0800135 self.scn_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000136 scan_result.format(scan_callback), self.default_timeout)
137 self.log.info(
138 "Found scan event successfully. Iteration {} "
139 "successful.".format(i))
140 except Exception:
141 self.log.info(
142 "Failed to find a scan result for callback {}"
143 .format(scan_callback))
144 test_result = False
145 break
146 for callback in scan_callback_list:
tturney1ce8dc62016-02-18 09:55:53 -0800147 self.scn_ad.droid.bleStopBleScan(callback)
148 self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
Ang Li73697b32015-12-03 00:41:53 +0000149 if not test_result:
150 return test_result
151 self.log.info("Waiting for scan callbacks to stop completely.")
152 # Wait for all scan callbacks to stop. There is no confirmation
153 # otherwise.
154 time.sleep(10)
155 return test_result
156
157 @BluetoothBaseTest.bt_test_wrap
158 def test_max_concurrent_ble_scans_then_discover_advertisement(self):
159 """Test max LE scans variant.
160
161 Test that a single device can have max scans concurrently scanning.
162
163 Steps:
164 1. Initialize scanner
165 2. Initialize advertiser
166 3. Create max ble scan callbacks
167 4. Start ble scan on each callback
168 5. Start advertising on the device from step 2
169 6. Verify that each callback triggers
170 7. Stop all scans and advertisements
171
172 Expected Result:
173 All scanning instances should start without errors and the advertisement
174 should be found on each scan instance.
175
176 Returns:
177 Pass if True
178 Fail if False
179
180 TAGS: LE, Scanning, Concurrency
181 Priority: 1
182 """
tturney1ce8dc62016-02-18 09:55:53 -0800183 self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
184 self.scn_ad.droid.bleSetScanSettingsCallbackType(
Ang Li73697b32015-12-03 00:41:53 +0000185 ScanSettingsCallbackType.CALLBACK_TYPE_ALL_MATCHES.value)
tturney1ce8dc62016-02-18 09:55:53 -0800186 self.scn_ad.droid.bleSetScanSettingsScanMode(
Ang Li73697b32015-12-03 00:41:53 +0000187 ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value)
tturney1ce8dc62016-02-18 09:55:53 -0800188 self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
Ang Li73697b32015-12-03 00:41:53 +0000189 AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value)
190 advertise_callback, advertise_data, advertise_settings = (
tturney1ce8dc62016-02-18 09:55:53 -0800191 generate_ble_advertise_objects(self.adv_ad.droid))
192 filter_list = self.scn_ad.droid.bleGenFilterList()
193 self.scn_ad.droid.bleSetScanFilterDeviceName(
194 self.adv_ad.droid.bluetoothGetLocalName())
195 self.scn_ad.droid.bleBuildScanFilter(filter_list)
196 scan_settings = self.scn_ad.droid.bleBuildScanSetting()
Ang Li73697b32015-12-03 00:41:53 +0000197 scan_callback_list = []
198 for i in range(self.max_concurrent_scans):
199 self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
tturney1ce8dc62016-02-18 09:55:53 -0800200 scan_callback = self.scn_ad.droid.bleGenScanCallback()
Ang Li73697b32015-12-03 00:41:53 +0000201 scan_callback_list.append(scan_callback)
tturney1ce8dc62016-02-18 09:55:53 -0800202 self.scn_ad.droid.bleStartBleScan(
Ang Li73697b32015-12-03 00:41:53 +0000203 filter_list, scan_settings, scan_callback)
tturney1ce8dc62016-02-18 09:55:53 -0800204 self.adv_ad.droid.bleStartBleAdvertising(
Ang Li73697b32015-12-03 00:41:53 +0000205 advertise_callback, advertise_data, advertise_settings)
206 try:
tturney1ce8dc62016-02-18 09:55:53 -0800207 self.adv_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000208 adv_succ.format(advertise_callback), self.default_timeout)
209 except Empty as error:
210 self.log.exception("Test failed with Empty error: {}".format(error))
211 return False
212 except concurrent.futures._base.TimeoutError as error:
213 self.log.exception("Test failed, filtering callback onSuccess "
214 "never occurred: {}".format(error))
215 return False
216 i = 0
217 for callback in scan_callback_list:
218 try:
tturney1ce8dc62016-02-18 09:55:53 -0800219 self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
Ang Li73697b32015-12-03 00:41:53 +0000220 self.default_timeout)
221 self.log.info(
222 "Found scan event successfully. Iteration {} successful."
223 .format(i))
224 except Exception:
225 self.log.info(
226 "Failed to find a scan result for callback {}"
227 .format(scan_callback))
228 return False
229 i += 1
230 for callback in scan_callback_list:
tturney1ce8dc62016-02-18 09:55:53 -0800231 self.scn_ad.droid.bleStopBleScan(callback)
232 self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
Ang Li73697b32015-12-03 00:41:53 +0000233 return True
234
235 @BluetoothBaseTest.bt_test_wrap
236 def test_max_concurrent_ble_scans_plus_one(self):
237 """Test mac LE scans variant.
238
239 Test that a single device can have max scans concurrently scanning.
240
241 Steps:
242 1. Initialize scanner
243 3. Create max ble scan callbacks plus one
244 5. Start ble scan on each callback
245 6. Verify that the n+1th scan fails.
246 7. Stop all scans
247
248 Expected Result:
249 The n+1th scan should fail to start.
250
251 Returns:
252 Pass if True
253 Fail if False
254
255 TAGS: LE, Scanning, Concurrency
256 Priority: 1
257 """
258 test_result = True
tturney1ce8dc62016-02-18 09:55:53 -0800259 self.scn_ad.droid.bleSetScanSettingsCallbackType(
Ang Li73697b32015-12-03 00:41:53 +0000260 ScanSettingsCallbackType.CALLBACK_TYPE_ALL_MATCHES.value)
tturney1ce8dc62016-02-18 09:55:53 -0800261 self.scn_ad.droid.bleSetScanSettingsScanMode(
Ang Li73697b32015-12-03 00:41:53 +0000262 ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value)
tturney1ce8dc62016-02-18 09:55:53 -0800263 filter_list = self.scn_ad.droid.bleGenFilterList()
264 self.scn_ad.droid.bleBuildScanFilter(filter_list)
265 scan_settings = self.scn_ad.droid.bleBuildScanSetting()
Ang Li73697b32015-12-03 00:41:53 +0000266 scan_callback_list = []
267 for i in range(self.max_concurrent_scans):
268 self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
tturney1ce8dc62016-02-18 09:55:53 -0800269 scan_callback = self.scn_ad.droid.bleGenScanCallback()
270 self.scn_ad.droid.bleStartBleScan(
Ang Li73697b32015-12-03 00:41:53 +0000271 filter_list, scan_settings, scan_callback)
272 scan_callback_list.append(scan_callback)
tturney1ce8dc62016-02-18 09:55:53 -0800273 scan_callback = self.scn_ad.droid.bleGenScanCallback()
274 self.scn_ad.droid.bleStartBleScan(
Ang Li73697b32015-12-03 00:41:53 +0000275 filter_list, scan_settings, scan_callback)
276 try:
tturney1ce8dc62016-02-18 09:55:53 -0800277 self.scn_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000278 scan_failed.format(scan_callback), self.default_timeout)
279 self.log.info(
280 "Found scan event successfully. Iteration {} successful."
281 .format(i))
282 except Exception:
283 self.log.info("Failed to find a onScanFailed event for callback {}"
284 .format(scan_callback))
285 test_result = False
286 for callback in scan_callback_list:
tturney1ce8dc62016-02-18 09:55:53 -0800287 self.scn_ad.droid.bleStopBleScan(callback)
Ang Li73697b32015-12-03 00:41:53 +0000288 return test_result
289
290 @BluetoothBaseTest.bt_test_wrap
291 def test_max_concurrent_ble_scans_verify_scans_stop_independently(self):
292 """Test max LE scans variant.
293
294 Test that a single device can have max scans concurrently scanning.
295
296 Steps:
297 1. Initialize scanner
298 2. Initialize advertiser
299 3. Create max ble scan callbacks
300 4. Start ble scan on each callback
301 5. Start advertising on the device from step 2
302 6. Verify that the first callback triggers
303 7. Stop the scan and repeat steps 6 and 7 until all scans stopped
304
305 Expected Result:
306 All scanning instances should start without errors and the advertisement
307 should be found on each scan instance. All scanning instances should
308 stop successfully.
309
310 Returns:
311 Pass if True
312 Fail if False
313
314 TAGS: LE, Scanning, Concurrency
315 Priority: 1
316 """
tturney1ce8dc62016-02-18 09:55:53 -0800317 self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
318 self.scn_ad.droid.bleSetScanSettingsCallbackType(
Ang Li73697b32015-12-03 00:41:53 +0000319 ScanSettingsCallbackType.CALLBACK_TYPE_ALL_MATCHES.value)
tturney1ce8dc62016-02-18 09:55:53 -0800320 self.scn_ad.droid.bleSetScanSettingsScanMode(
Ang Li73697b32015-12-03 00:41:53 +0000321 ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value)
tturney1ce8dc62016-02-18 09:55:53 -0800322 self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
Ang Li73697b32015-12-03 00:41:53 +0000323 AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value)
324 advertise_callback, advertise_data, advertise_settings = (
tturney1ce8dc62016-02-18 09:55:53 -0800325 generate_ble_advertise_objects(self.adv_ad.droid))
326 filter_list = self.scn_ad.droid.bleGenFilterList()
327 self.scn_ad.droid.bleSetScanFilterDeviceName(
328 self.adv_ad.droid.bluetoothGetLocalName())
329 self.scn_ad.droid.bleBuildScanFilter(filter_list)
330 scan_settings = self.scn_ad.droid.bleBuildScanSetting()
Ang Li73697b32015-12-03 00:41:53 +0000331 scan_callback_list = []
332 for i in range(self.max_concurrent_scans):
333 self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
tturney1ce8dc62016-02-18 09:55:53 -0800334 scan_callback = self.scn_ad.droid.bleGenScanCallback()
Ang Li73697b32015-12-03 00:41:53 +0000335 scan_callback_list.append(scan_callback)
tturney1ce8dc62016-02-18 09:55:53 -0800336 self.scn_ad.droid.bleStartBleScan(
Ang Li73697b32015-12-03 00:41:53 +0000337 filter_list, scan_settings, scan_callback)
tturney1ce8dc62016-02-18 09:55:53 -0800338 self.adv_ad.droid.bleStartBleAdvertising(
Ang Li73697b32015-12-03 00:41:53 +0000339 advertise_callback, advertise_data, advertise_settings)
340 try:
tturney1ce8dc62016-02-18 09:55:53 -0800341 self.adv_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000342 adv_succ.format(advertise_callback), self.default_timeout)
343 except Empty as error:
344 self.log.exception(
345 "Test failed with Empty error: {}".format(error))
346 return False
347 except concurrent.futures._base.TimeoutError as error:
348 self.log.exception("Test failed, filtering callback onSuccess never"
349 " occurred: {}".format(error))
350 return False
351 i = 0
352 for callback in scan_callback_list:
353 expected_scan_event_name = scan_result.format(scan_callback)
354 try:
tturney1ce8dc62016-02-18 09:55:53 -0800355 self.scn_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000356 expected_scan_event_name, self.default_timeout)
357 self.log.info(
358 "Found scan event successfully. Iteration {} successful.".
359 format(i))
360 i += 1
361 except Exception:
362 self.log.info(
363 "Failed to find a scan result for callback {}".
364 format(scan_callback))
365 return False
tturney1ce8dc62016-02-18 09:55:53 -0800366 self.scn_ad.droid.bleStopBleScan(callback)
367 self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
Ang Li73697b32015-12-03 00:41:53 +0000368 return True