1# Lint as: python2, python3 2# Copyright 2019 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""A Batch of Bluetooth Multiple Devices health tests""" 7 8import time 9from autotest_lib.server.cros.bluetooth.bluetooth_adapter_quick_tests import \ 10 BluetoothAdapterQuickTests 11from autotest_lib.server.cros.bluetooth.bluetooth_adapter_hidreports_tests \ 12 import BluetoothAdapterHIDReportTests 13 14class bluetooth_AdapterMDHealth(BluetoothAdapterQuickTests, 15 BluetoothAdapterHIDReportTests): 16 """A Batch of Bluetooth multiple devices health tests. This test is written 17 as a batch of tests in order to reduce test time, since auto-test ramp up 18 time is costy. The batch is using BluetoothAdapterQuickTests wrapper 19 methods to start and end a test and a batch of tests. 20 21 This class can be called to run the entire test batch or to run a 22 specific test only 23 """ 24 25 test_wrapper = BluetoothAdapterQuickTests.quick_test_test_decorator 26 batch_wrapper = BluetoothAdapterQuickTests.quick_test_batch_decorator 27 28 29 def discover_and_pair(self, device): 30 """ Discovers and pairs given device. Automatically connects too. 31 32 @param device: meta object for bt peer device 33 """ 34 self.test_discover_device(device.address) 35 time.sleep(self.TEST_SLEEP_SECS) 36 self.test_pairing(device.address, device.pin, trusted=True) 37 time.sleep(self.TEST_SLEEP_SECS) 38 self.test_connection_by_adapter(device.address) 39 40 41 def pair_and_test_connection(self, devtuples): 42 """ Tests connection and pairing with multiple devices 43 44 @param devtuples: array of tuples consisting of the following: 45 * device: meta object for peer device 46 * device_test: Optional; test function to run w/ 47 device (eg. mouse click) 48 """ 49 try: 50 for device, _ in devtuples: 51 self.discover_and_pair(device) 52 53 # Sleep for a few seconds to give HID controllers time to 54 # initialize, may prevent some flakiness in tests 55 time.sleep(self.TEST_SLEEP_SECS) 56 57 for device, device_test in devtuples: 58 if device_test is not None: 59 device_test(device) 60 61 finally: 62 for device, _ in devtuples: 63 self.test_disconnection_by_adapter(device.address) 64 self.test_remove_pairing(device.address) 65 66 67 @test_wrapper('One classic and one BLE connection', 68 devices={'BLE_MOUSE':1, 'KEYBOARD':1}, supports_floss=True) 69 def md_two_connections_test(self): 70 """test whether DUT can connect to classic keyboard and ble mouse at the 71 same time 72 """ 73 devices = [ 74 (self.devices['BLE_MOUSE'][0], self.test_mouse_left_click), 75 (self.devices['KEYBOARD'][0], self.run_keyboard_tests) 76 ] 77 78 self.pair_and_test_connection(devices) 79 80 81 @test_wrapper('Two BLE connections', 82 devices={ 83 'BLE_MOUSE': 1, 84 'BLE_KEYBOARD': 1 85 }, 86 supports_floss=True) 87 def md_two_ble_hid_connections_test(self): 88 """ test whether DUT can connect to ble keyboard and ble mouse at the 89 same time 90 """ 91 devices = [ 92 (self.devices['BLE_MOUSE'][0], self.test_mouse_left_click), 93 (self.devices['BLE_KEYBOARD'][0], self.run_keyboard_tests) 94 ] 95 96 self.pair_and_test_connection(devices) 97 98 99 @test_wrapper('Two classic connections', 100 devices={ 101 'MOUSE': 1, 102 'KEYBOARD': 1 103 }, 104 supports_floss=True) 105 def md_two_cl_hid_connections_test(self): 106 """ test whether DUT can connect to classic mouse and classic keyboard 107 at the same time 108 """ 109 devices = [ 110 (self.devices['MOUSE'][0], self.test_mouse_left_click), 111 (self.devices['KEYBOARD'][0], self.run_keyboard_tests) 112 ] 113 114 self.pair_and_test_connection(devices) 115 116 117 @batch_wrapper('Multiple Devices Health') 118 def md_health_batch_run(self, num_iterations=1, test_name=None): 119 """Run the multiple devices health test batch or a specific given test. 120 The wrapper of this method is implemented in batch_decorator. 121 Using the decorator a test batch method can implement the only its 122 core tests invocations and let the decorator handle the wrapper, 123 which is taking care for whether to run a specific test or the 124 batch as a whole, and running the batch in iterations 125 126 @param num_iterations: how many interations to run 127 @param test_name: specifc test to run otherwise None to run the 128 whole batch 129 """ 130 self.md_two_connections_test() 131 self.md_two_ble_hid_connections_test() 132 self.md_two_cl_hid_connections_test() 133 134 135 def run_once(self, 136 host, 137 num_iterations=1, 138 args_dict=None, 139 test_name=None, 140 flag='Quick Health', 141 floss=False): 142 """Run the batch of Bluetooth stand health tests 143 144 @param host: the DUT, usually a chromebook 145 @param num_iterations: the number of rounds to execute the test 146 """ 147 # Initialize and run the test batch or the requested specific test 148 self.quick_test_init(host, 149 use_btpeer=True, 150 flag=flag, 151 args_dict=args_dict, 152 floss=floss) 153 self.md_health_batch_run(num_iterations, test_name) 154 self.quick_test_cleanup() 155