blob: 94ee0f771ec5ba937dfcc4f9b68f5b0133016a9d [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright (C) 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""
Test script to exercises different ways Ble Advertisements can run in
concurrency. This test was designed to be run in a shield box.
"""
import concurrent
import os
import time
from queue import Empty
from acts.test_decorators import test_tracker_info
from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
from acts.test_utils.bt.bt_test_utils import BtTestUtilsError
from acts.test_utils.bt.bt_constants import ble_advertise_settings_modes
from acts.test_utils.bt.bt_constants import ble_scan_settings_callback_types
from acts.test_utils.bt.bt_constants import ble_scan_settings_modes
from acts.test_utils.bt.bt_constants import adv_succ
from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects
from acts.test_utils.bt.bt_test_utils import get_advanced_droid_list
from acts.test_utils.bt.bt_test_utils import reset_bluetooth
from acts.test_utils.bt.bt_test_utils import scan_and_verify_n_advertisements
from acts.test_utils.bt.bt_constants import scan_result
from acts.test_utils.bt.bt_test_utils import setup_n_advertisements
from acts.test_utils.bt.bt_test_utils import take_btsnoop_logs
from acts.test_utils.bt.bt_test_utils import teardown_n_advertisements
class ConcurrentBleAdvertisingTest(BluetoothBaseTest):
default_timeout = 10
max_advertisements = -1
def setup_class(self):
super().setup_class()
self.droid_list = get_advanced_droid_list(self.android_devices)
self.scn_ad = self.android_devices[0]
self.adv_ad = self.android_devices[1]
self.max_advertisements = self.droid_list[1]['max_advertisements']
def setup_test(self):
super(BluetoothBaseTest, self).setup_test()
return reset_bluetooth(self.android_devices)
def _verify_n_advertisements(self, num_advertisements):
try:
advertise_callback_list = setup_n_advertisements(
self.adv_ad, num_advertisements)
except BtTestUtilsError:
return False
try:
scan_and_verify_n_advertisements(self.scn_ad, num_advertisements)
except BtTestUtilsError:
return False
teardown_n_advertisements(self.adv_ad,
len(advertise_callback_list),
advertise_callback_list)
return True
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='abc03874-6d7a-4b5d-9f29-18731a102793')
def test_max_advertisements_defaults(self):
"""Testing max advertisements.
Test that a single device can have the max advertisements
concurrently advertising.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Start scanning on the max_advertisements as defined in the script.
4. Verify that all advertisements are found.
Expected Result:
All advertisements should start without errors.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 0
"""
return self._verify_n_advertisements(self.max_advertisements)
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='50ee137e-eb71-40ef-b72f-a5fd646190d2')
def test_max_advertisements_include_device_name_and_filter_device_name(
self):
"""Testing max advertisement variant.
Test that a single device can have the max advertisements
concurrently advertising. Include the device name as a part of the filter
and advertisement data.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Include device name in each advertisement.
4. Include device name filter in the scanner.
5. Start scanning on the max_advertisements as defined in the script.
6. Verify that all advertisements are found.
Expected Result:
All advertisements should start without errors.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 2
"""
self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
self.scn_ad.droid.bleSetScanFilterDeviceName(
self.adv_ad.droid.bluetoothGetLocalName())
return self._verify_n_advertisements(self.max_advertisements)
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='f7e9ba2b-6286-4510-a8a0-f1df831056c0')
def test_max_advertisements_exclude_device_name_and_filter_device_name(
self):
"""Test max advertisement variant.
Test that a single device can have the max advertisements concurrently
advertising. Include the device name as a part of the filter but not the
advertisement data.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Include device name filter in the scanner.
4. Start scanning on the max_advertisements as defined in the script.
5. Verify that no advertisements are found.
Expected Result:
All advertisements should start without errors.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 2
"""
self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(False)
self.scn_ad.droid.bleSetScanFilterDeviceName(
self.adv_ad.droid.bluetoothGetLocalName())
return not self._verify_n_advertisements(self.max_advertisements)
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='6ce102d7-61e1-4ca0-bcfb-767437b86c2b')
def test_max_advertisements_with_manufacturer_data(self):
"""Test max advertisement variant.
Test that a single device can have the max advertisements concurrently
advertising. Include the manufacturer data as a part of the filter and
advertisement data.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Include manufacturer data in each advertisement.
4. Include manufacturer data filter in the scanner.
5. Start scanning on the max_advertisements as defined in the script.
6. Verify that all advertisements are found.
Expected Result:
All advertisements should start without errors.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 2
"""
self.scn_ad.droid.bleSetScanFilterManufacturerData(1, [1])
self.adv_ad.droid.bleAddAdvertiseDataManufacturerId(1, [1])
return self._verify_n_advertisements(self.max_advertisements)
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='2fc7d5e8-1539-42a8-8681-ce0b8bfc0924')
def test_max_advertisements_with_manufacturer_data_mask(self):
"""Test max advertisements variant.
Test that a single device can have the max advertisements concurrently
advertising. Include the manufacturer data mask as a part of the filter
and advertisement data.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Include manufacturer data in each advertisement.
4. Include manufacturer data mask filter in the scanner.
5. Start scanning on the max_advertisements as defined in the script.
6. Verify that all advertisements are found.
Expected Result:
All advertisements should start without errors.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 2
"""
self.scn_ad.droid.bleSetScanFilterManufacturerData(1, [1], [1])
self.adv_ad.droid.bleAddAdvertiseDataManufacturerId(1, [1])
return self._verify_n_advertisements(self.max_advertisements)
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='9ef615ed-1705-44ae-ab5b-f7e8fb4bb770')
def test_max_advertisements_with_service_data(self):
"""Test max advertisement variant.
Test that a single device can have the max advertisements concurrently
advertising. Include the service data as a part of the filter and
advertisement data.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Include service data in each advertisement.
4. Include service data filter in the scanner.
5. Start scanning on the max_advertisements as defined in the script.
6. Verify that all advertisements are found.
Expected Result:
All advertisements should start without errors.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 2
"""
test_result = True
filter_list = self.scn_ad.droid.bleGenFilterList()
self.scn_ad.droid.bleSetScanFilterServiceData(
"0000110A-0000-1000-8000-00805F9B34FB", [11, 17, 80])
self.adv_ad.droid.bleAddAdvertiseDataServiceData(
"0000110A-0000-1000-8000-00805F9B34FB", [11, 17, 80])
return self._verify_n_advertisements(self.max_advertisements)
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='9ef615ed-1705-44ae-ab5b-f7e8fb4bb770')
def test_max_advertisements_with_manufacturer_data_mask_and_include_device_name(
self):
"""Test max advertisement variant.
Test that a single device can have the max advertisements concurrently
advertising. Include the device name and manufacturer data as a part of
the filter and advertisement data.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Include device name and manufacturer data in each advertisement.
4. Include device name and manufacturer data filter in the scanner.
5. Start scanning on the max_advertisements as defined in the script.
6. Verify that all advertisements are found.
Expected Result:
All advertisements should start without errors.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 2
"""
self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
self.scn_ad.droid.bleSetScanFilterDeviceName(
self.adv_ad.droid.bluetoothGetLocalName())
self.scn_ad.droid.bleSetScanFilterManufacturerData(1, [1], [1])
self.adv_ad.droid.bleAddAdvertiseDataManufacturerId(1, [1])
return self._verify_n_advertisements(self.max_advertisements)
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='c2ca85fb-6663-431d-aa30-5286a85dbbe0')
def test_max_advertisements_with_service_uuids(self):
"""Test max advertisement variant.
Test that a single device can have the max advertisements concurrently
advertising. Include the service uuid as a part of the filter and
advertisement data.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Include service uuid in each advertisement.
4. Include service uuid filter in the scanner.
5. Start scanning on the max_advertisements as defined in the script.
6. Verify that all advertisements are found.
Expected Result:
All advertisements should start without errors.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 1
"""
self.scn_ad.droid.bleSetScanFilterServiceUuid(
"00000000-0000-1000-8000-00805f9b34fb")
self.adv_ad.droid.bleSetAdvertiseDataSetServiceUuids(
["00000000-0000-1000-8000-00805f9b34fb"])
return self._verify_n_advertisements(self.max_advertisements)
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='756e026f-64d7-4a2f-935a-3790c0ac4503')
def test_max_advertisements_with_service_uuid_and_service_mask(self):
"""Test max advertisements variant.
Test that a single device can have the max advertisements concurrently
advertising. Include the service mask as a part of the filter and
advertisement data.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Include service uuid in each advertisement.
4. Include service mask filter in the scanner.
5. Start scanning on the max_advertisements as defined in the script.
6. Verify that all advertisements are found.
Expected Result:
All advertisements should start without errors.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 2
"""
self.scn_ad.droid.bleSetScanFilterServiceUuid(
"00000000-0000-1000-8000-00805f9b34fb",
"00000000-0000-1000-8000-00805f9b34fb")
self.adv_ad.droid.bleSetAdvertiseDataSetServiceUuids(
["00000000-0000-1000-8000-00805f9b34fb"])
return self._verify_n_advertisements(self.max_advertisements)
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='79c4b6cd-9f07-49a9-829f-69b29ea8d322')
def test_max_advertisements_plus_one(self):
"""Test max advertisements plus one.
Test that a single device can have the max advertisements concurrently
advertising but fail on starting the max advertisements plus one.
filter and advertisement data.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Start max_advertisements + 1.
Expected Result:
The last advertisement should fail.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 0
"""
return not self._verify_n_advertisements(self.max_advertisements + 1)
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='0bd6e490-a501-4fe1-88e5-9b77970c0b95')
def test_start_two_advertisements_on_same_callback(self):
"""Test invalid advertisement scenario.
Test that a single device cannot have two advertisements start on the
same callback.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Call start ble advertising on the same callback.
Expected Result:
The second call of start advertising on the same callback should fail.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 1
"""
test_result = True
advertise_callback, advertise_data, advertise_settings = (
generate_ble_advertise_objects(self.adv_ad.droid))
self.adv_ad.droid.bleStartBleAdvertising(
advertise_callback, advertise_data, advertise_settings)
try:
self.adv_ad.ed.pop_event(
adv_succ.format(advertise_callback), self.default_timeout)
except Empty as error:
self.log.error("Test failed with Empty error: {}".format(error))
return False
except concurrent.futures._base.TimeoutError as error:
self.log.debug(
"Test failed, filtering callback onSuccess never occurred: {}"
.format(error))
try:
self.adv_ad.droid.bleStartBleAdvertising(
advertise_callback, advertise_data, advertise_settings)
self.adv_ad.ed.pop_event(
adv_succ.format(advertise_callback), self.default_timeout)
test_result = False
except Empty as error:
self.log.debug("Test passed with Empty error: {}".format(error))
except concurrent.futures._base.TimeoutError as error:
self.log.debug(
"Test passed, filtering callback onSuccess never occurred: {}"
.format(error))
return test_result
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='12632b31-22b9-4121-80b6-1263b9d90909')
def test_toggle_advertiser_bt_state(self):
"""Test forcing stopping advertisements.
Test that a single device resets its callbacks when the bluetooth state is
reset. There should be no advertisements.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Call start ble advertising.
4. Toggle bluetooth on and off.
5. Scan for any advertisements.
Expected Result:
No advertisements should be found after toggling Bluetooth on the
advertising device.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 2
"""
test_result = True
self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
advertise_callback, advertise_data, advertise_settings = (
generate_ble_advertise_objects(self.adv_ad.droid))
self.adv_ad.droid.bleStartBleAdvertising(
advertise_callback, advertise_data, advertise_settings)
try:
self.adv_ad.ed.pop_event(
adv_succ.format(advertise_callback), self.default_timeout)
except Empty as error:
self.log.error("Test failed with Empty error: {}".format(error))
return False
except concurrent.futures._base.TimeoutError as error:
self.log.error(
"Test failed, filtering callback onSuccess never occurred: {}".
format(error))
self.scn_ad.droid.bleSetScanSettingsScanMode(
ble_scan_settings_modes['low_latency'])
self.scn_ad.droid.bleSetScanFilterDeviceName(
self.adv_ad.droid.bluetoothGetLocalName())
filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
self.scn_ad.droid)
self.scn_ad.droid.bleBuildScanFilter(filter_list)
self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
scan_callback)
try:
self.scn_ad.ed.pop_event(
scan_result.format(scan_callback), self.default_timeout)
except Empty as error:
self.log.error("Test failed with: {}".format(error))
return False
self.scn_ad.droid.bleStopBleScan(scan_callback)
test_result = reset_bluetooth([self.android_devices[1]])
self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
scan_callback)
if not test_result:
return False
try:
expected_event = scan_result.format(scan_callback)
event = self.scn_ad.ed.pop_event(expected_event,
self.default_timeout)
self.log.error("Event {} not expected. Found: {}".format(
expected_event, event))
return False
except Empty as error:
self.log.debug("Test passed with: {}".format(error))
self.scn_ad.droid.bleStopBleScan(scan_callback)
self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
return True
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='785c5c77-d5d4-4d0f-8b7b-3eb1f1646d2c')
def test_restart_advertise_callback_after_bt_toggle(self):
"""Test starting an advertisement on a cleared out callback.
Test that a single device resets its callbacks when the bluetooth state
is reset.
Steps:
1. Setup the scanning android device.
2. Setup the advertiser android device.
3. Call start ble advertising.
4. Toggle bluetooth on and off.
5. Call start ble advertising on the same callback.
Expected Result:
Starting an advertisement on a callback id after toggling bluetooth
should fail.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 1
"""
test_result = True
advertise_callback, advertise_data, advertise_settings = (
generate_ble_advertise_objects(self.adv_ad.droid))
self.adv_ad.droid.bleStartBleAdvertising(
advertise_callback, advertise_data, advertise_settings)
try:
self.adv_ad.ed.pop_event(
adv_succ.format(advertise_callback), self.default_timeout)
except Empty as error:
self.log.error("Test failed with Empty error: {}".format(error))
test_result = False
except concurrent.futures._base.TimeoutError as error:
self.log.debug(
"Test failed, filtering callback onSuccess never occurred: {}".
format(error))
test_result = reset_bluetooth([self.android_devices[1]])
if not test_result:
return test_result
self.adv_ad.droid.bleStartBleAdvertising(
advertise_callback, advertise_data, advertise_settings)
try:
self.adv_ad.ed.pop_event(
adv_succ.format(advertise_callback), self.default_timeout)
except Empty as error:
self.log.error("Test failed with Empty error: {}".format(error))
test_result = False
except concurrent.futures._base.TimeoutError as error:
self.log.debug(
"Test failed, filtering callback onSuccess never occurred: {}".
format(error))
return test_result
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='dd5529b7-6774-4580-8b29-d84568c15442')
def test_timeout(self):
"""Test starting advertiser with timeout.
Test that when a timeout is used, the advertiser is cleaned properly,
and next one can be started.
Steps:
1. Setup the advertiser android device with 4 second timeout.
2. Call start ble advertising.
3. Wait 5 seconds, to make sure advertiser times out.
4. Repeat steps 1-4 four times.
Expected Result:
Starting the advertising should succeed each time.
Returns:
Pass if True
Fail if False
TAGS: LE, Advertising, Concurrency
Priority: 1
"""
advertise_timeout_s = 4
num_iterations = 4
test_result = True
for i in range(0, num_iterations):
advertise_callback, advertise_data, advertise_settings = (
generate_ble_advertise_objects(self.adv_ad.droid))
self.adv_ad.droid.bleSetAdvertiseSettingsTimeout(
advertise_timeout_s * 1000)
self.adv_ad.droid.bleStartBleAdvertising(
advertise_callback, advertise_data, advertise_settings)
try:
self.adv_ad.ed.pop_event(
adv_succ.format(advertise_callback), self.default_timeout)
except Empty as error:
self.log.error("Test failed with Empty error: {}".format(
error))
test_result = False
except concurrent.futures._base.TimeoutError as error:
self.log.debug(
"Test failed, filtering callback onSuccess never occurred: {}".
format(error))
if not test_result:
return test_result
time.sleep(advertise_timeout_s + 1)
return test_result