1#!/usr/bin/env python3
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"""
17Basic Bluetooth Classic stress tests.
18"""
19
20import time
21from acts.base_test import BaseTestClass
22from acts.test_decorators import test_tracker_info
23from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
24from acts.test_utils.bt.bt_constants import bluetooth_off
25from acts.test_utils.bt.bt_constants import bluetooth_on
26from acts.test_utils.bt.bt_test_utils import clear_bonded_devices
27from acts.test_utils.bt.bt_test_utils import pair_pri_to_sec
28from acts.test_utils.bt.bt_test_utils import reset_bluetooth
29from acts.test_utils.bt.bt_test_utils import setup_multiple_devices_for_bt_test
30
31
32class BtStressTest(BluetoothBaseTest):
33    default_timeout = 20
34    iterations = 100
35
36    def setup_class(self):
37        super().setup_class()
38
39    def teardown_test(self):
40        super(BluetoothBaseTest, self).teardown_test()
41        self.log_stats()
42        return True
43
44    @test_tracker_info(uuid='bbe050f8-7970-42b3-9104-a2cd8f09579c')
45    def test_toggle_bluetooth(self):
46        """Stress test toggling bluetooth on and off.
47
48        Test the integrity of toggling bluetooth on and off.
49
50        Steps:
51        1. Toggle bluetooth off.
52        2. Toggle bluetooth on.
53        3. Repeat steps 1 and 2 one-hundred times.
54
55        Expected Result:
56        Each iteration of toggling bluetooth on and off should not cause an
57        exception.
58
59        Returns:
60          Pass if True
61          Fail if False
62
63        TAGS: Classic, Stress
64        Priority: 1
65        """
66        dut = self.android_devices[0]
67        for n in range(self.iterations):
68            self.log.info("Toggling bluetooth iteration {}.".format(n + 1))
69            dut.ed.clear_all_events()
70            try:
71                dut.droid.bluetoothToggleState(False)
72                dut.ed.pop_event(bluetooth_off, self.default_timeout)
73            except Exception as err:
74                dut.log.error(
75                    "Failed to toggle off Bluetooth with error: {}".format(
76                        err))
77                return False
78            try:
79                dut.droid.bluetoothToggleState(True)
80                dut.ed.pop_event(bluetooth_on, self.default_timeout)
81            except Exception as err:
82                dut.log.error(
83                    "Failed to toggle on Bluetooth with error: {}".format(err))
84                return False
85        return True
86
87    @test_tracker_info(uuid='a6fac426-d068-4a86-9d55-00dbe51b2ff0')
88    def test_pair_bluetooth_stress(self):
89        """Stress test for pairing BT devices.
90
91        Test the integrity of Bluetooth pairing.
92
93        1. Primary device discover the secondary device
94        2. Primary device tries to pair to secondary device
95        3. Pair two devices after verifying pin number on both devices are equal
96        4. Verify both devices are paired
97        5. Unpair devices.
98        6. Verify devices unpaired.
99        7. Repeat steps 1-6 100 times.
100
101
102        Expected Result:
103        Each iteration of toggling Bluetooth pairing and unpairing
104        should succeed.
105
106        Returns:
107          Pass if True
108          Fail if False
109
110        TAGS: Classic, Stress
111        Priority: 1
112        """
113        for n in range(self.iterations):
114            self.log.info("Pair bluetooth iteration {}.".format(n + 1))
115            self.start_timer()
116            if (not pair_pri_to_sec(
117                    self.android_devices[0],
118                    self.android_devices[1],
119                    attempts=1,
120                    auto_confirm=False)):
121                self.log.error("Failed to bond devices.")
122                return False
123            self.log.info("Total time (ms): {}".format(self.end_timer()))
124            # A device bond will trigger a number of system routines that need
125            # to settle before unbond
126            time.sleep(2)
127            for ad in self.android_devices:
128                if not clear_bonded_devices(ad):
129                    return False
130                # Necessary sleep time for entries to update unbonded state
131                time.sleep(2)
132                bonded_devices = ad.droid.bluetoothGetBondedDevices()
133                if len(bonded_devices) > 0:
134                    self.log.error(
135                        "Failed to unbond devices: {}".format(bonded_devices))
136                    return False
137        return True
138