blob: 1972806c80841f8a4ddfd0d9dc89aed4abd5fdf9 [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.
Ang Li73697b32015-12-03 00:41:53 +000016"""
17Test script to exercises Ble Scans can run in concurrency.
18This test was designed to be run in a shield box.
19"""
20
21import concurrent
22import time
23
24from queue import Empty
tturney4aaad3e2017-01-11 12:09:34 -080025from acts.test_decorators import test_tracker_info
Ang Li73697b32015-12-03 00:41:53 +000026from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
tturney5cb24882017-07-24 10:52:17 -070027from acts.test_utils.bt.bt_constants import ble_advertise_settings_modes
28from acts.test_utils.bt.bt_constants import ble_scan_settings_callback_types
29from acts.test_utils.bt.bt_constants import ble_scan_settings_modes
30from acts.test_utils.bt.bt_constants import adv_succ
Ang Li73697b32015-12-03 00:41:53 +000031from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
Ang Li73697b32015-12-03 00:41:53 +000032from acts.test_utils.bt.bt_test_utils import reset_bluetooth
33from acts.test_utils.bt.bt_test_utils import scan_failed
tturney5cb24882017-07-24 10:52:17 -070034from acts.test_utils.bt.bt_constants import scan_result
Ang Li73697b32015-12-03 00:41:53 +000035from acts.test_utils.bt.bt_test_utils import take_btsnoop_logs
36
37
38class ConcurrentBleScanningTest(BluetoothBaseTest):
39 default_timeout = 20
Jakub Pawłowskiba99e8c2018-05-04 17:19:22 +020040 max_concurrent_scans = 27
Ang Li73697b32015-12-03 00:41:53 +000041
42 def __init__(self, controllers):
43 BluetoothBaseTest.__init__(self, controllers)
tturney1ce8dc62016-02-18 09:55:53 -080044 self.scn_ad = self.android_devices[0]
45 self.adv_ad = self.android_devices[1]
Ang Li73697b32015-12-03 00:41:53 +000046
47 def on_fail(self, test_name, begin_time):
tturney0c334432016-05-18 11:23:38 -070048 self.log.debug("Test {} failed. Gathering bugreport and btsnoop logs."
49 .format(test_name))
tturney1ce8dc62016-02-18 09:55:53 -080050 take_btsnoop_logs(self.android_devices, self, test_name)
51 reset_bluetooth(self.android_devices)
Ang Li73697b32015-12-03 00:41:53 +000052
53 def setup_test(self):
tturney1ce8dc62016-02-18 09:55:53 -080054 return reset_bluetooth(self.android_devices)
Ang Li73697b32015-12-03 00:41:53 +000055
56 @BluetoothBaseTest.bt_test_wrap
tturney4aaad3e2017-01-11 12:09:34 -080057 @test_tracker_info(uuid='e7f68b9b-fb3f-48e9-a272-e41c2a32b4bd')
Ang Li73697b32015-12-03 00:41:53 +000058 def test_max_concurrent_ble_scans(self):
59 """Test max LE scans.
60
61 Test that a single device can have max scans concurrently scanning.
62
63 Steps:
64 1. Initialize scanner
65 2. Initialize advertiser
66 3. Start advertising on the device from step 2
67 4. Create max ble scan callbacks
68 5. Start ble scan on each callback
69 6. Verify that each callback triggers
70 7. Stop all scans and advertisements
71
72 Expected Result:
73 All scanning instances should start without errors and the advertisement
74 should be found on each scan instance.
75
76 Returns:
77 Pass if True
78 Fail if False
79
80 TAGS: LE, Scanning, Concurrency
81 Priority: 0
82 """
83 test_result = True
tturney1ce8dc62016-02-18 09:55:53 -080084 self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
85 self.scn_ad.droid.bleSetScanSettingsCallbackType(
tturney5cb24882017-07-24 10:52:17 -070086 ble_scan_settings_callback_types['all_matches'])
87 self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
88 'low_latency'])
tturney1ce8dc62016-02-18 09:55:53 -080089 self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
tturney5cb24882017-07-24 10:52:17 -070090 ble_advertise_settings_modes['low_latency'])
Ang Li73697b32015-12-03 00:41:53 +000091 advertise_callback, advertise_data, advertise_settings = (
tturney1ce8dc62016-02-18 09:55:53 -080092 generate_ble_advertise_objects(self.adv_ad.droid))
93 self.adv_ad.droid.bleSetAdvertiseSettingsIsConnectable(False)
94 self.adv_ad.droid.bleStartBleAdvertising(
Ang Li73697b32015-12-03 00:41:53 +000095 advertise_callback, advertise_data, advertise_settings)
96 try:
tturney1ce8dc62016-02-18 09:55:53 -080097 self.adv_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +000098 adv_succ.format(advertise_callback), self.default_timeout)
99 except Empty as error:
tturney0c334432016-05-18 11:23:38 -0700100 self.log.exception("Test failed with Empty error: {}".format(
101 error))
Ang Li73697b32015-12-03 00:41:53 +0000102 test_result = False
103 except concurrent.futures._base.TimeoutError as error:
tturney0c334432016-05-18 11:23:38 -0700104 self.log.exception(
105 "Test failed callback onSuccess never occurred: "
106 "{}".format(error))
Ang Li73697b32015-12-03 00:41:53 +0000107 test_result = False
108 if not test_result:
109 return test_result
tturney1ce8dc62016-02-18 09:55:53 -0800110 filter_list = self.scn_ad.droid.bleGenFilterList()
111 self.scn_ad.droid.bleSetScanFilterDeviceName(
112 self.adv_ad.droid.bluetoothGetLocalName())
113 self.scn_ad.droid.bleBuildScanFilter(filter_list)
114 scan_settings = self.scn_ad.droid.bleBuildScanSetting()
Ang Li73697b32015-12-03 00:41:53 +0000115 scan_callback_list = []
116 for i in range(self.max_concurrent_scans):
117 self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
tturney1ce8dc62016-02-18 09:55:53 -0800118 scan_callback = self.scn_ad.droid.bleGenScanCallback()
Ang Li73697b32015-12-03 00:41:53 +0000119 scan_callback_list.append(scan_callback)
tturney0c334432016-05-18 11:23:38 -0700120 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
121 scan_callback)
Ang Li73697b32015-12-03 00:41:53 +0000122 try:
tturney1ce8dc62016-02-18 09:55:53 -0800123 self.scn_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000124 scan_result.format(scan_callback), self.default_timeout)
tturney0c334432016-05-18 11:23:38 -0700125 self.log.info("Found scan event successfully. Iteration {} "
126 "successful.".format(i))
Ang Li73697b32015-12-03 00:41:53 +0000127 except Exception:
tturney0c334432016-05-18 11:23:38 -0700128 self.log.info("Failed to find a scan result for callback {}"
129 .format(scan_callback))
Ang Li73697b32015-12-03 00:41:53 +0000130 test_result = False
131 break
132 for callback in scan_callback_list:
tturney1ce8dc62016-02-18 09:55:53 -0800133 self.scn_ad.droid.bleStopBleScan(callback)
134 self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
Ang Li73697b32015-12-03 00:41:53 +0000135 if not test_result:
136 return test_result
137 self.log.info("Waiting for scan callbacks to stop completely.")
138 # Wait for all scan callbacks to stop. There is no confirmation
139 # otherwise.
140 time.sleep(10)
141 return test_result
142
143 @BluetoothBaseTest.bt_test_wrap
tturney4aaad3e2017-01-11 12:09:34 -0800144 @test_tracker_info(uuid='58b0c45e-1cbc-420a-9e89-901518ffe3d1')
Ang Li73697b32015-12-03 00:41:53 +0000145 def test_max_concurrent_ble_scans_then_discover_advertisement(self):
146 """Test max LE scans variant.
147
148 Test that a single device can have max scans concurrently scanning.
149
150 Steps:
151 1. Initialize scanner
152 2. Initialize advertiser
153 3. Create max ble scan callbacks
154 4. Start ble scan on each callback
155 5. Start advertising on the device from step 2
156 6. Verify that each callback triggers
157 7. Stop all scans and advertisements
158
159 Expected Result:
160 All scanning instances should start without errors and the advertisement
161 should be found on each scan instance.
162
163 Returns:
164 Pass if True
165 Fail if False
166
167 TAGS: LE, Scanning, Concurrency
168 Priority: 1
169 """
tturney1ce8dc62016-02-18 09:55:53 -0800170 self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
171 self.scn_ad.droid.bleSetScanSettingsCallbackType(
tturney5cb24882017-07-24 10:52:17 -0700172 ble_scan_settings_callback_types['all_matches'])
173 self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
174 'low_latency'])
tturney1ce8dc62016-02-18 09:55:53 -0800175 self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
tturney5cb24882017-07-24 10:52:17 -0700176 ble_advertise_settings_modes['low_latency'])
Ang Li73697b32015-12-03 00:41:53 +0000177 advertise_callback, advertise_data, advertise_settings = (
tturney1ce8dc62016-02-18 09:55:53 -0800178 generate_ble_advertise_objects(self.adv_ad.droid))
179 filter_list = self.scn_ad.droid.bleGenFilterList()
180 self.scn_ad.droid.bleSetScanFilterDeviceName(
181 self.adv_ad.droid.bluetoothGetLocalName())
182 self.scn_ad.droid.bleBuildScanFilter(filter_list)
183 scan_settings = self.scn_ad.droid.bleBuildScanSetting()
Ang Li73697b32015-12-03 00:41:53 +0000184 scan_callback_list = []
185 for i in range(self.max_concurrent_scans):
186 self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
tturney1ce8dc62016-02-18 09:55:53 -0800187 scan_callback = self.scn_ad.droid.bleGenScanCallback()
Ang Li73697b32015-12-03 00:41:53 +0000188 scan_callback_list.append(scan_callback)
tturney0c334432016-05-18 11:23:38 -0700189 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
190 scan_callback)
tturney1ce8dc62016-02-18 09:55:53 -0800191 self.adv_ad.droid.bleStartBleAdvertising(
Ang Li73697b32015-12-03 00:41:53 +0000192 advertise_callback, advertise_data, advertise_settings)
193 try:
tturney1ce8dc62016-02-18 09:55:53 -0800194 self.adv_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000195 adv_succ.format(advertise_callback), self.default_timeout)
196 except Empty as error:
tturney0c334432016-05-18 11:23:38 -0700197 self.log.exception("Test failed with Empty error: {}".format(
198 error))
Ang Li73697b32015-12-03 00:41:53 +0000199 return False
200 except concurrent.futures._base.TimeoutError as error:
201 self.log.exception("Test failed, filtering callback onSuccess "
202 "never occurred: {}".format(error))
203 return False
204 i = 0
205 for callback in scan_callback_list:
206 try:
tturney0c334432016-05-18 11:23:38 -0700207 self.scn_ad.ed.pop_event(
208 scan_result.format(scan_callback), self.default_timeout)
Ang Li73697b32015-12-03 00:41:53 +0000209 self.log.info(
210 "Found scan event successfully. Iteration {} successful."
211 .format(i))
212 except Exception:
tturney0c334432016-05-18 11:23:38 -0700213 self.log.info("Failed to find a scan result for callback {}"
214 .format(scan_callback))
Ang Li73697b32015-12-03 00:41:53 +0000215 return False
216 i += 1
217 for callback in scan_callback_list:
tturney1ce8dc62016-02-18 09:55:53 -0800218 self.scn_ad.droid.bleStopBleScan(callback)
219 self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
Ang Li73697b32015-12-03 00:41:53 +0000220 return True
221
222 @BluetoothBaseTest.bt_test_wrap
tturney4aaad3e2017-01-11 12:09:34 -0800223 @test_tracker_info(uuid='7a45e45c-faf3-4e89-abb7-a52f63e53208')
Ang Li73697b32015-12-03 00:41:53 +0000224 def test_max_concurrent_ble_scans_plus_one(self):
225 """Test mac LE scans variant.
226
227 Test that a single device can have max scans concurrently scanning.
228
229 Steps:
230 1. Initialize scanner
231 3. Create max ble scan callbacks plus one
232 5. Start ble scan on each callback
233 6. Verify that the n+1th scan fails.
234 7. Stop all scans
235
236 Expected Result:
237 The n+1th scan should fail to start.
238
239 Returns:
240 Pass if True
241 Fail if False
242
243 TAGS: LE, Scanning, Concurrency
244 Priority: 1
245 """
246 test_result = True
tturney1ce8dc62016-02-18 09:55:53 -0800247 self.scn_ad.droid.bleSetScanSettingsCallbackType(
tturney5cb24882017-07-24 10:52:17 -0700248 ble_scan_settings_callback_types['all_matches'])
249 self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
250 'low_latency'])
tturney1ce8dc62016-02-18 09:55:53 -0800251 filter_list = self.scn_ad.droid.bleGenFilterList()
252 self.scn_ad.droid.bleBuildScanFilter(filter_list)
253 scan_settings = self.scn_ad.droid.bleBuildScanSetting()
Ang Li73697b32015-12-03 00:41:53 +0000254 scan_callback_list = []
255 for i in range(self.max_concurrent_scans):
256 self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
tturney1ce8dc62016-02-18 09:55:53 -0800257 scan_callback = self.scn_ad.droid.bleGenScanCallback()
tturney0c334432016-05-18 11:23:38 -0700258 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
259 scan_callback)
Ang Li73697b32015-12-03 00:41:53 +0000260 scan_callback_list.append(scan_callback)
tturney1ce8dc62016-02-18 09:55:53 -0800261 scan_callback = self.scn_ad.droid.bleGenScanCallback()
tturney0c334432016-05-18 11:23:38 -0700262 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
263 scan_callback)
Ang Li73697b32015-12-03 00:41:53 +0000264 try:
tturney1ce8dc62016-02-18 09:55:53 -0800265 self.scn_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000266 scan_failed.format(scan_callback), self.default_timeout)
267 self.log.info(
268 "Found scan event successfully. Iteration {} successful."
269 .format(i))
270 except Exception:
271 self.log.info("Failed to find a onScanFailed event for callback {}"
272 .format(scan_callback))
273 test_result = False
274 for callback in scan_callback_list:
tturney1ce8dc62016-02-18 09:55:53 -0800275 self.scn_ad.droid.bleStopBleScan(callback)
Ang Li73697b32015-12-03 00:41:53 +0000276 return test_result
277
278 @BluetoothBaseTest.bt_test_wrap
tturney4aaad3e2017-01-11 12:09:34 -0800279 @test_tracker_info(uuid='5a91f612-69e5-490f-b9d0-50d58a3db736')
Ang Li73697b32015-12-03 00:41:53 +0000280 def test_max_concurrent_ble_scans_verify_scans_stop_independently(self):
281 """Test max LE scans variant.
282
283 Test that a single device can have max scans concurrently scanning.
284
285 Steps:
286 1. Initialize scanner
287 2. Initialize advertiser
288 3. Create max ble scan callbacks
289 4. Start ble scan on each callback
290 5. Start advertising on the device from step 2
291 6. Verify that the first callback triggers
292 7. Stop the scan and repeat steps 6 and 7 until all scans stopped
293
294 Expected Result:
295 All scanning instances should start without errors and the advertisement
296 should be found on each scan instance. All scanning instances should
297 stop successfully.
298
299 Returns:
300 Pass if True
301 Fail if False
302
303 TAGS: LE, Scanning, Concurrency
304 Priority: 1
305 """
tturney1ce8dc62016-02-18 09:55:53 -0800306 self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
307 self.scn_ad.droid.bleSetScanSettingsCallbackType(
tturney5cb24882017-07-24 10:52:17 -0700308 ble_scan_settings_callback_types['all_matches'])
309 self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
310 'low_latency'])
tturney1ce8dc62016-02-18 09:55:53 -0800311 self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
tturney5cb24882017-07-24 10:52:17 -0700312 ble_advertise_settings_modes['low_latency'])
Ang Li73697b32015-12-03 00:41:53 +0000313 advertise_callback, advertise_data, advertise_settings = (
tturney1ce8dc62016-02-18 09:55:53 -0800314 generate_ble_advertise_objects(self.adv_ad.droid))
315 filter_list = self.scn_ad.droid.bleGenFilterList()
316 self.scn_ad.droid.bleSetScanFilterDeviceName(
317 self.adv_ad.droid.bluetoothGetLocalName())
318 self.scn_ad.droid.bleBuildScanFilter(filter_list)
319 scan_settings = self.scn_ad.droid.bleBuildScanSetting()
Ang Li73697b32015-12-03 00:41:53 +0000320 scan_callback_list = []
321 for i in range(self.max_concurrent_scans):
322 self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
tturney1ce8dc62016-02-18 09:55:53 -0800323 scan_callback = self.scn_ad.droid.bleGenScanCallback()
Ang Li73697b32015-12-03 00:41:53 +0000324 scan_callback_list.append(scan_callback)
tturney0c334432016-05-18 11:23:38 -0700325 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
326 scan_callback)
tturney1ce8dc62016-02-18 09:55:53 -0800327 self.adv_ad.droid.bleStartBleAdvertising(
Ang Li73697b32015-12-03 00:41:53 +0000328 advertise_callback, advertise_data, advertise_settings)
329 try:
tturney1ce8dc62016-02-18 09:55:53 -0800330 self.adv_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000331 adv_succ.format(advertise_callback), self.default_timeout)
332 except Empty as error:
tturney0c334432016-05-18 11:23:38 -0700333 self.log.exception("Test failed with Empty error: {}".format(
334 error))
Ang Li73697b32015-12-03 00:41:53 +0000335 return False
336 except concurrent.futures._base.TimeoutError as error:
tturney0c334432016-05-18 11:23:38 -0700337 self.log.exception(
338 "Test failed, filtering callback onSuccess never"
339 " occurred: {}".format(error))
Ang Li73697b32015-12-03 00:41:53 +0000340 return False
341 i = 0
342 for callback in scan_callback_list:
343 expected_scan_event_name = scan_result.format(scan_callback)
344 try:
tturney0c334432016-05-18 11:23:38 -0700345 self.scn_ad.ed.pop_event(expected_scan_event_name,
346 self.default_timeout)
Ang Li73697b32015-12-03 00:41:53 +0000347 self.log.info(
tturney4aaad3e2017-01-11 12:09:34 -0800348 "Found scan event successfully. Iteration {} successful.".
349 format(i))
Ang Li73697b32015-12-03 00:41:53 +0000350 i += 1
351 except Exception:
tturney4aaad3e2017-01-11 12:09:34 -0800352 self.log.info("Failed to find a scan result for callback {}".
353 format(scan_callback))
Ang Li73697b32015-12-03 00:41:53 +0000354 return False
tturney1ce8dc62016-02-18 09:55:53 -0800355 self.scn_ad.droid.bleStopBleScan(callback)
356 self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
Ang Li73697b32015-12-03 00:41:53 +0000357 return True