blob: dc952695a59fff83943914c47ecbc3d8701f8ffb [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
25from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
26from acts.test_utils.bt.BleEnum import AdvertiseSettingsAdvertiseMode
27from acts.test_utils.bt.BleEnum import ScanSettingsCallbackType
28from acts.test_utils.bt.BleEnum import ScanSettingsScanMode
29from acts.test_utils.bt.bt_test_utils import adv_succ
30from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
31from acts.test_utils.bt.bt_test_utils import get_advanced_droid_list
32from acts.test_utils.bt.bt_test_utils import reset_bluetooth
33from acts.test_utils.bt.bt_test_utils import scan_failed
34from acts.test_utils.bt.bt_test_utils import scan_result
35from acts.test_utils.bt.bt_test_utils import take_btsnoop_logs
36
37
38class ConcurrentBleScanningTest(BluetoothBaseTest):
39 default_timeout = 20
40 max_concurrent_scans = 28
41
42 def __init__(self, controllers):
43 BluetoothBaseTest.__init__(self, controllers)
tturney1ce8dc62016-02-18 09:55:53 -080044 self.droid_list = get_advanced_droid_list(self.android_devices)
45 self.scn_ad = self.android_devices[0]
46 self.adv_ad = self.android_devices[1]
Ang Li73697b32015-12-03 00:41:53 +000047 if self.droid_list[1]['max_advertisements'] == 0:
tturney0c334432016-05-18 11:23:38 -070048 self.tests = ("test_max_concurrent_ble_scans_plus_one", )
Ang Li73697b32015-12-03 00:41:53 +000049 return
Ang Li73697b32015-12-03 00:41:53 +000050
51 def on_fail(self, test_name, begin_time):
tturney0c334432016-05-18 11:23:38 -070052 self.log.debug("Test {} failed. Gathering bugreport and btsnoop logs."
53 .format(test_name))
tturney1ce8dc62016-02-18 09:55:53 -080054 take_btsnoop_logs(self.android_devices, self, test_name)
55 reset_bluetooth(self.android_devices)
Ang Li73697b32015-12-03 00:41:53 +000056
57 def setup_test(self):
tturney1ce8dc62016-02-18 09:55:53 -080058 return reset_bluetooth(self.android_devices)
Ang Li73697b32015-12-03 00:41:53 +000059
60 @BluetoothBaseTest.bt_test_wrap
61 def test_max_concurrent_ble_scans(self):
62 """Test max LE scans.
63
64 Test that a single device can have max scans concurrently scanning.
65
66 Steps:
67 1. Initialize scanner
68 2. Initialize advertiser
69 3. Start advertising on the device from step 2
70 4. Create max ble scan callbacks
71 5. Start ble scan on each callback
72 6. Verify that each callback triggers
73 7. Stop all scans and advertisements
74
75 Expected Result:
76 All scanning instances should start without errors and the advertisement
77 should be found on each scan instance.
78
79 Returns:
80 Pass if True
81 Fail if False
82
83 TAGS: LE, Scanning, Concurrency
84 Priority: 0
85 """
86 test_result = True
tturney1ce8dc62016-02-18 09:55:53 -080087 self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
88 self.scn_ad.droid.bleSetScanSettingsCallbackType(
Ang Li73697b32015-12-03 00:41:53 +000089 ScanSettingsCallbackType.CALLBACK_TYPE_ALL_MATCHES.value)
tturney1ce8dc62016-02-18 09:55:53 -080090 self.scn_ad.droid.bleSetScanSettingsScanMode(
Ang Li73697b32015-12-03 00:41:53 +000091 ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value)
tturney1ce8dc62016-02-18 09:55:53 -080092 self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
Ang Li73697b32015-12-03 00:41:53 +000093 AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value)
94 advertise_callback, advertise_data, advertise_settings = (
tturney1ce8dc62016-02-18 09:55:53 -080095 generate_ble_advertise_objects(self.adv_ad.droid))
96 self.adv_ad.droid.bleSetAdvertiseSettingsIsConnectable(False)
97 self.adv_ad.droid.bleStartBleAdvertising(
Ang Li73697b32015-12-03 00:41:53 +000098 advertise_callback, advertise_data, advertise_settings)
99 try:
tturney1ce8dc62016-02-18 09:55:53 -0800100 self.adv_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000101 adv_succ.format(advertise_callback), self.default_timeout)
102 except Empty as error:
tturney0c334432016-05-18 11:23:38 -0700103 self.log.exception("Test failed with Empty error: {}".format(
104 error))
Ang Li73697b32015-12-03 00:41:53 +0000105 test_result = False
106 except concurrent.futures._base.TimeoutError as error:
tturney0c334432016-05-18 11:23:38 -0700107 self.log.exception(
108 "Test failed callback onSuccess never occurred: "
109 "{}".format(error))
Ang Li73697b32015-12-03 00:41:53 +0000110 test_result = False
111 if not test_result:
112 return test_result
tturney1ce8dc62016-02-18 09:55:53 -0800113 filter_list = self.scn_ad.droid.bleGenFilterList()
114 self.scn_ad.droid.bleSetScanFilterDeviceName(
115 self.adv_ad.droid.bluetoothGetLocalName())
116 self.scn_ad.droid.bleBuildScanFilter(filter_list)
117 scan_settings = self.scn_ad.droid.bleBuildScanSetting()
Ang Li73697b32015-12-03 00:41:53 +0000118 scan_callback_list = []
119 for i in range(self.max_concurrent_scans):
120 self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
tturney1ce8dc62016-02-18 09:55:53 -0800121 scan_callback = self.scn_ad.droid.bleGenScanCallback()
Ang Li73697b32015-12-03 00:41:53 +0000122 scan_callback_list.append(scan_callback)
tturney0c334432016-05-18 11:23:38 -0700123 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
124 scan_callback)
Ang Li73697b32015-12-03 00:41:53 +0000125 try:
tturney1ce8dc62016-02-18 09:55:53 -0800126 self.scn_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000127 scan_result.format(scan_callback), self.default_timeout)
tturney0c334432016-05-18 11:23:38 -0700128 self.log.info("Found scan event successfully. Iteration {} "
129 "successful.".format(i))
Ang Li73697b32015-12-03 00:41:53 +0000130 except Exception:
tturney0c334432016-05-18 11:23:38 -0700131 self.log.info("Failed to find a scan result for callback {}"
132 .format(scan_callback))
Ang Li73697b32015-12-03 00:41:53 +0000133 test_result = False
134 break
135 for callback in scan_callback_list:
tturney1ce8dc62016-02-18 09:55:53 -0800136 self.scn_ad.droid.bleStopBleScan(callback)
137 self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
Ang Li73697b32015-12-03 00:41:53 +0000138 if not test_result:
139 return test_result
140 self.log.info("Waiting for scan callbacks to stop completely.")
141 # Wait for all scan callbacks to stop. There is no confirmation
142 # otherwise.
143 time.sleep(10)
144 return test_result
145
146 @BluetoothBaseTest.bt_test_wrap
147 def test_max_concurrent_ble_scans_then_discover_advertisement(self):
148 """Test max LE scans variant.
149
150 Test that a single device can have max scans concurrently scanning.
151
152 Steps:
153 1. Initialize scanner
154 2. Initialize advertiser
155 3. Create max ble scan callbacks
156 4. Start ble scan on each callback
157 5. Start advertising on the device from step 2
158 6. Verify that each callback triggers
159 7. Stop all scans and advertisements
160
161 Expected Result:
162 All scanning instances should start without errors and the advertisement
163 should be found on each scan instance.
164
165 Returns:
166 Pass if True
167 Fail if False
168
169 TAGS: LE, Scanning, Concurrency
170 Priority: 1
171 """
tturney1ce8dc62016-02-18 09:55:53 -0800172 self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
173 self.scn_ad.droid.bleSetScanSettingsCallbackType(
Ang Li73697b32015-12-03 00:41:53 +0000174 ScanSettingsCallbackType.CALLBACK_TYPE_ALL_MATCHES.value)
tturney1ce8dc62016-02-18 09:55:53 -0800175 self.scn_ad.droid.bleSetScanSettingsScanMode(
Ang Li73697b32015-12-03 00:41:53 +0000176 ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value)
tturney1ce8dc62016-02-18 09:55:53 -0800177 self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
Ang Li73697b32015-12-03 00:41:53 +0000178 AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value)
179 advertise_callback, advertise_data, advertise_settings = (
tturney1ce8dc62016-02-18 09:55:53 -0800180 generate_ble_advertise_objects(self.adv_ad.droid))
181 filter_list = self.scn_ad.droid.bleGenFilterList()
182 self.scn_ad.droid.bleSetScanFilterDeviceName(
183 self.adv_ad.droid.bluetoothGetLocalName())
184 self.scn_ad.droid.bleBuildScanFilter(filter_list)
185 scan_settings = self.scn_ad.droid.bleBuildScanSetting()
Ang Li73697b32015-12-03 00:41:53 +0000186 scan_callback_list = []
187 for i in range(self.max_concurrent_scans):
188 self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
tturney1ce8dc62016-02-18 09:55:53 -0800189 scan_callback = self.scn_ad.droid.bleGenScanCallback()
Ang Li73697b32015-12-03 00:41:53 +0000190 scan_callback_list.append(scan_callback)
tturney0c334432016-05-18 11:23:38 -0700191 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
192 scan_callback)
tturney1ce8dc62016-02-18 09:55:53 -0800193 self.adv_ad.droid.bleStartBleAdvertising(
Ang Li73697b32015-12-03 00:41:53 +0000194 advertise_callback, advertise_data, advertise_settings)
195 try:
tturney1ce8dc62016-02-18 09:55:53 -0800196 self.adv_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000197 adv_succ.format(advertise_callback), self.default_timeout)
198 except Empty as error:
tturney0c334432016-05-18 11:23:38 -0700199 self.log.exception("Test failed with Empty error: {}".format(
200 error))
Ang Li73697b32015-12-03 00:41:53 +0000201 return False
202 except concurrent.futures._base.TimeoutError as error:
203 self.log.exception("Test failed, filtering callback onSuccess "
204 "never occurred: {}".format(error))
205 return False
206 i = 0
207 for callback in scan_callback_list:
208 try:
tturney0c334432016-05-18 11:23:38 -0700209 self.scn_ad.ed.pop_event(
210 scan_result.format(scan_callback), self.default_timeout)
Ang Li73697b32015-12-03 00:41:53 +0000211 self.log.info(
212 "Found scan event successfully. Iteration {} successful."
213 .format(i))
214 except Exception:
tturney0c334432016-05-18 11:23:38 -0700215 self.log.info("Failed to find a scan result for callback {}"
216 .format(scan_callback))
Ang Li73697b32015-12-03 00:41:53 +0000217 return False
218 i += 1
219 for callback in scan_callback_list:
tturney1ce8dc62016-02-18 09:55:53 -0800220 self.scn_ad.droid.bleStopBleScan(callback)
221 self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
Ang Li73697b32015-12-03 00:41:53 +0000222 return True
223
224 @BluetoothBaseTest.bt_test_wrap
225 def test_max_concurrent_ble_scans_plus_one(self):
226 """Test mac LE scans variant.
227
228 Test that a single device can have max scans concurrently scanning.
229
230 Steps:
231 1. Initialize scanner
232 3. Create max ble scan callbacks plus one
233 5. Start ble scan on each callback
234 6. Verify that the n+1th scan fails.
235 7. Stop all scans
236
237 Expected Result:
238 The n+1th scan should fail to start.
239
240 Returns:
241 Pass if True
242 Fail if False
243
244 TAGS: LE, Scanning, Concurrency
245 Priority: 1
246 """
247 test_result = True
tturney1ce8dc62016-02-18 09:55:53 -0800248 self.scn_ad.droid.bleSetScanSettingsCallbackType(
Ang Li73697b32015-12-03 00:41:53 +0000249 ScanSettingsCallbackType.CALLBACK_TYPE_ALL_MATCHES.value)
tturney1ce8dc62016-02-18 09:55:53 -0800250 self.scn_ad.droid.bleSetScanSettingsScanMode(
Ang Li73697b32015-12-03 00:41:53 +0000251 ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value)
tturney1ce8dc62016-02-18 09:55:53 -0800252 filter_list = self.scn_ad.droid.bleGenFilterList()
253 self.scn_ad.droid.bleBuildScanFilter(filter_list)
254 scan_settings = self.scn_ad.droid.bleBuildScanSetting()
Ang Li73697b32015-12-03 00:41:53 +0000255 scan_callback_list = []
256 for i in range(self.max_concurrent_scans):
257 self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
tturney1ce8dc62016-02-18 09:55:53 -0800258 scan_callback = self.scn_ad.droid.bleGenScanCallback()
tturney0c334432016-05-18 11:23:38 -0700259 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
260 scan_callback)
Ang Li73697b32015-12-03 00:41:53 +0000261 scan_callback_list.append(scan_callback)
tturney1ce8dc62016-02-18 09:55:53 -0800262 scan_callback = self.scn_ad.droid.bleGenScanCallback()
tturney0c334432016-05-18 11:23:38 -0700263 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
264 scan_callback)
Ang Li73697b32015-12-03 00:41:53 +0000265 try:
tturney1ce8dc62016-02-18 09:55:53 -0800266 self.scn_ad.ed.pop_event(
Ang Li73697b32015-12-03 00:41:53 +0000267 scan_failed.format(scan_callback), self.default_timeout)
268 self.log.info(
269 "Found scan event successfully. Iteration {} successful."
270 .format(i))
271 except Exception:
272 self.log.info("Failed to find a onScanFailed event for callback {}"
273 .format(scan_callback))
274 test_result = False
275 for callback in scan_callback_list:
tturney1ce8dc62016-02-18 09:55:53 -0800276 self.scn_ad.droid.bleStopBleScan(callback)
Ang Li73697b32015-12-03 00:41:53 +0000277 return test_result
278
279 @BluetoothBaseTest.bt_test_wrap
280 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(
Ang Li73697b32015-12-03 00:41:53 +0000308 ScanSettingsCallbackType.CALLBACK_TYPE_ALL_MATCHES.value)
tturney1ce8dc62016-02-18 09:55:53 -0800309 self.scn_ad.droid.bleSetScanSettingsScanMode(
Ang Li73697b32015-12-03 00:41:53 +0000310 ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value)
tturney1ce8dc62016-02-18 09:55:53 -0800311 self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
Ang Li73697b32015-12-03 00:41:53 +0000312 AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value)
313 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(
tturney0c334432016-05-18 11:23:38 -0700348 "Found scan event successfully. Iteration {} successful.".format(
349 i))
Ang Li73697b32015-12-03 00:41:53 +0000350 i += 1
351 except Exception:
352 self.log.info(
tturney0c334432016-05-18 11:23:38 -0700353 "Failed to find a scan result for callback {}".format(
354 scan_callback))
Ang Li73697b32015-12-03 00:41:53 +0000355 return False
tturney1ce8dc62016-02-18 09:55:53 -0800356 self.scn_ad.droid.bleStopBleScan(callback)
357 self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
Ang Li73697b32015-12-03 00:41:53 +0000358 return True