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