Home | History | Annotate | Download | only in system_tests
      1 #/usr/bin/env python3.4
      2 #
      3 # Copyright (C) 2016 The Android Open Source Project
      4 #
      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 Basic LE Stress tests.
     18 """
     19 
     20 import concurrent
     21 import pprint
     22 import time
     23 
     24 from queue import Empty
     25 from acts.test_decorators import test_tracker_info
     26 from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
     27 from acts.test_utils.bt.bt_test_utils import BtTestUtilsError
     28 from acts.test_utils.bt.bt_test_utils import clear_bonded_devices
     29 from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
     30 from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects
     31 from acts.test_utils.bt.bt_test_utils import get_advanced_droid_list
     32 from acts.test_utils.bt.bt_test_utils import get_mac_address_of_generic_advertisement
     33 from acts.test_utils.bt.bt_test_utils import reset_bluetooth
     34 from acts.test_utils.bt.bt_test_utils import scan_result
     35 
     36 
     37 class BleStressTest(BluetoothBaseTest):
     38     default_timeout = 10
     39     PAIRING_TIMEOUT = 20
     40 
     41     def __init__(self, controllers):
     42         BluetoothBaseTest.__init__(self, controllers)
     43         self.droid_list = get_advanced_droid_list(self.android_devices)
     44         self.scn_ad = self.android_devices[0]
     45         self.adv_ad = self.android_devices[1]
     46 
     47     def teardown_test(self):
     48         super(BluetoothBaseTest, self).teardown_test()
     49         self.log_stats()
     50 
     51     def bleadvertise_verify_onsuccess_handler(self, event):
     52         test_result = True
     53         self.log.debug("Verifying onSuccess event")
     54         self.log.debug(pprint.pformat(event))
     55         return test_result
     56 
     57     def _verify_successful_bond(self, target_address):
     58         end_time = time.time() + self.PAIRING_TIMEOUT
     59         self.log.info("Verifying devices are bonded")
     60         while time.time() < end_time:
     61             bonded_devices = self.scn_ad.droid.bluetoothGetBondedDevices()
     62             if target_address in {d['address'] for d in bonded_devices}:
     63                 self.log.info("Successfully bonded to device")
     64                 return True
     65         return False
     66 
     67     @BluetoothBaseTest.bt_test_wrap
     68     @test_tracker_info(uuid='22f98085-6ed8-4ad8-b62d-b8d1eae20b89')
     69     def test_loop_scanning_1000(self):
     70         """Stress start/stop scan instances.
     71 
     72         This test will start and stop scan instances as fast as possible. This
     73         will guarantee that the scan instances are properly being cleaned up
     74         when the scan is stopped.
     75 
     76         Steps:
     77         1. Start a scan instance.
     78         2. Stop the scan instance.
     79         3. Repeat steps 1-2 1000 times.
     80 
     81         Expected Result:
     82         Neither starting or stopping scan instances causes any failures.
     83 
     84         Returns:
     85           Pass if True
     86           Fail if False
     87 
     88         TAGS: LE, Scanning, Stress
     89         Priority: 1
     90         """
     91         test_result = True
     92         for _ in range(1000):
     93             filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
     94                 self.scn_ad.droid)
     95             self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
     96                                               scan_callback)
     97             self.scn_ad.droid.bleStopBleScan(scan_callback)
     98         return test_result
     99 
    100     @BluetoothBaseTest.bt_test_wrap
    101     @test_tracker_info(uuid='6caa84c2-50ac-46f2-a5e5-f942fd2cd6f6')
    102     def test_loop_scanning_100_verify_no_hci_timeout(self):
    103         """Stress start/stop scan instances variant.
    104 
    105         This test will start and stop scan instances with a one second timeout
    106         in between each iteration. This testcase was added because the specific
    107         timing combination caused hci timeouts.
    108 
    109         Steps:
    110         1. Start a scan instance.
    111         2. Stop the scan instance.
    112         3. Sleep for 1 second.
    113         4. Repeat steps 1-3 100 times.
    114 
    115         Expected Result:
    116         Neither starting or stopping scan instances causes any failures.
    117 
    118         Returns:
    119           Pass if True
    120           Fail if False
    121 
    122         TAGS: LE, Scanning, Stress
    123         Priority: 1
    124         """
    125         for _ in range(self.droid_list[1]['max_advertisements']):
    126             adv_callback, adv_data, adv_settings = generate_ble_advertise_objects(
    127                 self.adv_ad.droid)
    128             self.adv_ad.droid.bleStartBleAdvertising(adv_callback, adv_data,
    129                                                      adv_settings)
    130         for _ in range(100):
    131             filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
    132                 self.scn_ad.droid)
    133             self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    134                                               scan_callback)
    135             self.log.info(
    136                 self.scn_ad.ed.pop_event(scan_result.format(scan_callback)))
    137             self.scn_ad.droid.bleStopBleScan(scan_callback)
    138             time.sleep(1)
    139         return True
    140 
    141     @BluetoothBaseTest.bt_test_wrap
    142     @test_tracker_info(uuid='5e9e4c8d-b72e-4767-81e5-f907c1834430')
    143     def test_loop_advertising_100(self):
    144         """Stress start/stop advertising instances.
    145 
    146         This test will start and stop advertising instances as fast as possible.
    147 
    148         Steps:
    149         1. Start a advertising instance.
    150         2. Find that an onSuccess callback is triggered.
    151         3. Stop the advertising instance.
    152         4. Repeat steps 1-3 100 times.
    153 
    154         Expected Result:
    155         Neither starting or stopping advertising instances causes any failures.
    156 
    157         Returns:
    158           Pass if True
    159           Fail if False
    160 
    161         TAGS: LE, Advertising, Stress
    162         Priority: 1
    163         """
    164         test_result = True
    165         for _ in range(100):
    166             advertise_callback, advertise_data, advertise_settings = generate_ble_advertise_objects(
    167                 self.adv_ad.droid)
    168             self.adv_ad.droid.bleStartBleAdvertising(
    169                 advertise_callback, advertise_data, advertise_settings)
    170             expected_advertise_event_name = "".join(
    171                 ["BleAdvertise", str(advertise_callback), "onSuccess"])
    172             worker = self.adv_ad.ed.handle_event(
    173                 self.bleadvertise_verify_onsuccess_handler,
    174                 expected_advertise_event_name, ([]), self.default_timeout)
    175             try:
    176                 self.log.debug(worker.result(self.default_timeout))
    177             except Empty as error:
    178                 self.log.debug(" ".join(
    179                     ["Test failed with Empty error:", str(error)]))
    180                 test_result = False
    181             except concurrent.futures._base.TimeoutError as error:
    182                 self.log.debug(" ".join([
    183                     "Test failed, filtering callback onSuccess never occurred:",
    184                     str(error)
    185                 ]))
    186                 test_result = False
    187             self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
    188         return test_result
    189 
    190     @BluetoothBaseTest.bt_test_wrap
    191     @test_tracker_info(uuid='11a2f51b-7178-4c32-bb5c-7eddd100a50f')
    192     def test_restart_advertise_callback_after_bt_toggle(self):
    193         """Test to reuse an advertise callback.
    194 
    195         This will verify if advertising objects can be reused after a bluetooth
    196         toggle.
    197 
    198         Steps:
    199         1. Start a advertising instance.
    200         2. Find that an onSuccess callback is triggered.
    201         3. Stop the advertising instance.
    202         4. Toggle bluetooth off and on.
    203         5. Start an advertising instance on the same objects used in step 1.
    204         6. Find that an onSuccess callback is triggered.
    205 
    206         Expected Result:
    207         Advertisement should start successfully.
    208 
    209         Returns:
    210           Pass if True
    211           Fail if False
    212 
    213         TAGS: LE, Advertising, Stress
    214         Priority: 1
    215         """
    216         test_result = True
    217         advertise_callback, advertise_data, advertise_settings = generate_ble_advertise_objects(
    218             self.adv_ad.droid)
    219         self.adv_ad.droid.bleStartBleAdvertising(
    220             advertise_callback, advertise_data, advertise_settings)
    221         expected_advertise_event_name = "".join(
    222             ["BleAdvertise", str(advertise_callback), "onSuccess"])
    223         worker = self.adv_ad.ed.handle_event(
    224             self.bleadvertise_verify_onsuccess_handler,
    225             expected_advertise_event_name, ([]), self.default_timeout)
    226         try:
    227             self.log.debug(worker.result(self.default_timeout))
    228         except Empty as error:
    229             self.log.debug(" ".join(
    230                 ["Test failed with Empty error:", str(error)]))
    231             test_result = False
    232         except concurrent.futures._base.TimeoutError as error:
    233             self.log.debug(" ".join([
    234                 "Test failed, filtering callback onSuccess never occurred:",
    235                 str(error)
    236             ]))
    237         test_result = reset_bluetooth([self.scn_ad])
    238         if not test_result:
    239             return test_result
    240         time.sleep(5)
    241         self.adv_ad.droid.bleStartBleAdvertising(
    242             advertise_callback, advertise_data, advertise_settings)
    243         worker = self.adv_ad.ed.handle_event(
    244             self.bleadvertise_verify_onsuccess_handler,
    245             expected_advertise_event_name, ([]), self.default_timeout)
    246         try:
    247             self.log.debug(worker.result(self.default_timeout))
    248         except Empty as error:
    249             self.log.debug(" ".join(
    250                 ["Test failed with Empty error:", str(error)]))
    251             test_result = False
    252         except concurrent.futures._base.TimeoutError as error:
    253             self.log.debug(" ".join([
    254                 "Test failed, filtering callback onSuccess never occurred:",
    255                 str(error)
    256             ]))
    257         return test_result
    258 
    259     @BluetoothBaseTest.bt_test_wrap
    260     @test_tracker_info(uuid='88f3c068-41be-41df-920c-c0ecaae1a619')
    261     def test_restart_scan_callback_after_bt_toggle(self):
    262         """Test to reuse an scan callback.
    263 
    264         This will verify if scan objects can be reused after a bluetooth
    265         toggle.
    266 
    267         Steps:
    268         1. Start a scanning instance.
    269         3. Stop the scanning instance.
    270         4. Toggle bluetooth off and on.
    271         5. Start an scanning instance on the same objects used in step 1.
    272 
    273         Expected Result:
    274         Scanner should start successfully.
    275 
    276         Returns:
    277           Pass if True
    278           Fail if False
    279 
    280         TAGS: LE, Scanning, Stress
    281         Priority: 1
    282         """
    283         test_result = True
    284         filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
    285             self.scn_ad.droid)
    286         self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    287                                           scan_callback)
    288         reset_bluetooth([self.scn_ad])
    289         self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    290                                           scan_callback)
    291 
    292         return test_result
    293 
    294     @BluetoothBaseTest.bt_test_wrap
    295     @test_tracker_info(uuid='ce8adfc0-384f-4751-9438-13a76cada8da')
    296     def test_le_pairing(self):
    297         """Test LE pairing transport stress
    298 
    299         This will test LE pairing between two android devices.
    300 
    301         Steps:
    302         1. Start an LE advertisement on secondary device.
    303         2. Find address from primary device.
    304         3. Discover and bond to LE address.
    305         4. Stop LE advertisement on secondary device.
    306         5. Repeat steps 1-4 100 times
    307 
    308         Expected Result:
    309         LE pairing should pass 100 times.
    310 
    311         Returns:
    312           Pass if True
    313           Fail if False
    314 
    315         TAGS: LE, Scanning, Stress, Pairing
    316         Priority: 1
    317         """
    318         iterations = 100
    319         for i in range(iterations):
    320             try:
    321                 target_address, adv_callback = get_mac_address_of_generic_advertisement(
    322                     self.scn_ad, self.adv_ad)
    323             except BtTestUtilsError as err:
    324                 self.log.error(err)
    325                 return False
    326             self.log.info("Begin interation {}/{}".format(i + 1, iterations))
    327             self.scn_ad.droid.bluetoothStartPairingHelper()
    328             self.adv_ad.droid.bluetoothStartPairingHelper()
    329             start_time = self.start_timer()
    330             self.scn_ad.droid.bluetoothDiscoverAndBond(target_address)
    331             if not self._verify_successful_bond(target_address):
    332                 self.log.error("Failed to bond devices.")
    333                 return False
    334             self.log.info("Total time (ms): {}".format(self.end_timer()))
    335             if not clear_bonded_devices(self.scn_ad):
    336                 self.log.error("Failed to unbond device from scanner.")
    337                 return False
    338             if not clear_bonded_devices(self.adv_ad):
    339                 self.log.error("Failed to unbond device from advertiser.")
    340                 return False
    341             self.adv_ad.droid.bleStopBleAdvertising(adv_callback)
    342             # Magic sleep to let unbonding finish
    343             time.sleep(2)
    344         return True
    345