1# Lint as: python2, python3 2# Copyright 2022 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"""A Batch of Bluetooth Quality Report tests""" 6 7import collections 8import time 9 10from autotest_lib.client.common_lib import error 11from autotest_lib.client.cros.bluetooth.bluetooth_audio_test_data import ( 12 A2DP_MEDIUM, HFP_WBS, HFP_NBS, HFP_WBS_MEDIUM, HFP_NBS_MEDIUM) 13from autotest_lib.server.cros.bluetooth.bluetooth_adapter_qr_tests import ( 14 BluetoothAdapterQRTests, QR_UNSUPPORTED_CHIPSETS) 15from autotest_lib.server.cros.bluetooth.bluetooth_adapter_quick_tests import ( 16 BluetoothAdapterQuickTests) 17 18 19class bluetooth_AdapterQRHealth(BluetoothAdapterQuickTests, 20 BluetoothAdapterQRTests): 21 """A Batch of Bluetooth audio health tests""" 22 23 test_wrapper = BluetoothAdapterQuickTests.quick_test_test_decorator 24 batch_wrapper = BluetoothAdapterQuickTests.quick_test_batch_decorator 25 26 def run_test_method(self, 27 devices, 28 test_method, 29 test_profile, 30 logging_and_check=True): 31 """Common procedure to run a specific test method. 32 33 @param devices: a list of devices. 34 @param test_method: the test method to run. 35 @param test_profile: audio test profile to use. 36 @param logging_and_check: set this to True to opend the quality 37 report log checking. 38 """ 39 40 if not isinstance(devices, collections.Iterable): 41 devices = (devices, ) 42 43 num_devices = len(devices) 44 45 # Make sure WBS profile works fine. 46 if test_profile in (HFP_WBS, HFP_WBS_MEDIUM): 47 if self.check_wbs_capability(): 48 if not self.bluetooth_facade.enable_wbs(True): 49 raise error.TestError('failed to enble wbs') 50 else: 51 raise error.TestNAError( 52 'The DUT does not support WBS. Skip the test.') 53 elif test_profile in (HFP_NBS, HFP_NBS_MEDIUM): 54 if not self.bluetooth_facade.enable_wbs(False): 55 raise error.TestError('failed to disable wbs') 56 57 time.sleep(3) 58 59 self.test_reset_on_adapter() 60 self.test_bluetoothd_running() 61 62 for device in devices: 63 if device.device_type == 'BLUETOOTH_AUDIO': 64 self.initialize_bluetooth_audio(device, test_profile) 65 66 self.test_discover_device(device.address) 67 self.test_pairing(device.address, device.pin, trusted=True) 68 self.test_connection_by_adapter(device.address) 69 70 time.sleep(2) 71 72 if logging_and_check: 73 self.dut_btmon_log_path = self.start_new_btmon() 74 self.enable_disable_debug_log(enable=True) 75 self.enable_disable_quality_debug_log(enable=True) 76 77 test_method() 78 79 if logging_and_check: 80 self.test_send_log() 81 self.check_qr_event_log(num_devices=num_devices) 82 self.enable_disable_quality_debug_log(enable=False) 83 self.enable_disable_debug_log(enable=False) 84 85 for device in devices: 86 self.test_disconnection_by_adapter(device.address) 87 88 if device.device_type == 'BLUETOOTH_AUDIO': 89 self.cleanup_bluetooth_audio(device, test_profile) 90 91 # Remove flags=['Quick Health'] when this test is migrated to stable suite. 92 @test_wrapper('Quality Report A2DP test', 93 devices={'BLUETOOTH_AUDIO': 1}, 94 flags=['Quick Health'], 95 skip_chipsets=QR_UNSUPPORTED_CHIPSETS) 96 def qr_a2dp_test(self): 97 """Quality Report A2DP test""" 98 device = self.devices['BLUETOOTH_AUDIO'][0] 99 test_profile = A2DP_MEDIUM 100 test_method = lambda: self.qr_a2dp(device, test_profile) 101 102 self.run_test_method(device, test_method, test_profile) 103 104 # Remove flags=['Quick Health'] when this test is migrated to stable suite. 105 @test_wrapper('Quality Report power cycle and A2DP test', 106 devices={'BLUETOOTH_AUDIO': 1}, 107 flags=['Quick Health'], 108 skip_chipsets=QR_UNSUPPORTED_CHIPSETS) 109 def qr_power_cycle_a2dp_test(self): 110 """Quality Report power cycle and A2DP test""" 111 device = self.devices['BLUETOOTH_AUDIO'][0] 112 test_profile = A2DP_MEDIUM 113 test_method = lambda: self.qr_power_cycle_a2dp(device, test_profile) 114 115 self.run_test_method(device, test_method, test_profile) 116 117 # Remove flags=['Quick Health'] when this test is migrated to stable suite. 118 @test_wrapper('Quality Report HFP NBS dut as source test', 119 devices={'BLUETOOTH_AUDIO': 1}, 120 flags=['Quick Health'], 121 skip_chipsets=QR_UNSUPPORTED_CHIPSETS) 122 def qr_hfp_nbs_dut_as_src_test(self): 123 """Quality Report HFP NBS dut as source test""" 124 device = self.devices['BLUETOOTH_AUDIO'][0] 125 test_profile = HFP_NBS_MEDIUM 126 test_method = lambda: self.qr_hfp_dut_as_src(device, test_profile) 127 128 self.run_test_method(device, test_method, test_profile) 129 130 # Remove flags=['Quick Health'] when this test is migrated to stable suite. 131 @test_wrapper('Quality Report HFP WBS dut as source test', 132 devices={'BLUETOOTH_AUDIO': 1}, 133 flags=['Quick Health'], 134 skip_chipsets=QR_UNSUPPORTED_CHIPSETS) 135 def qr_hfp_wbs_dut_as_src_test(self): 136 """Quality Report HFP WBS dut as source test""" 137 device = self.devices['BLUETOOTH_AUDIO'][0] 138 test_profile = HFP_WBS_MEDIUM 139 test_method = lambda: self.qr_hfp_dut_as_src(device, test_profile) 140 141 self.run_test_method(device, test_method, test_profile) 142 143 # Remove flags=['Quick Health'] when this test is migrated to stable suite. 144 @test_wrapper('Quality Report disabled A2DP test', 145 devices={'BLUETOOTH_AUDIO': 1}, 146 flags=['Quick Health'], 147 skip_chipsets=QR_UNSUPPORTED_CHIPSETS) 148 def qr_disabled_a2dp_test(self): 149 """Quality Report disabled A2DP test""" 150 device = self.devices['BLUETOOTH_AUDIO'][0] 151 test_profile = A2DP_MEDIUM 152 test_method = lambda: self.qr_disabled_a2dp(device, test_profile) 153 154 self.run_test_method(device, 155 test_method, 156 test_profile, 157 logging_and_check=False) 158 159 # Remove flags=['Quick Health'] when this test is migrated to stable suite. 160 @test_wrapper('Quality Report A2DP and classic keyboard test', 161 devices={ 162 'BLUETOOTH_AUDIO': 1, 163 "KEYBOARD": 1 164 }, 165 flags=['Quick Health'], 166 skip_chipsets=QR_UNSUPPORTED_CHIPSETS) 167 def qr_a2dp_cl_keyboard_test(self): 168 """Quality Report A2DP and classic keyboard test""" 169 audio_device = self.devices['BLUETOOTH_AUDIO'][0] 170 keyboard_device = self.devices['KEYBOARD'][0] 171 test_profile = A2DP_MEDIUM 172 test_method = lambda: self.qr_a2dp_cl_keyboard( 173 audio_device, keyboard_device, test_profile) 174 175 self.run_test_method((audio_device, keyboard_device), 176 test_method, 177 test_profile) 178 179 # Remove flags=['Quick Health'] when this test is migrated to stable suite. 180 @test_wrapper( 181 'Quality Report HFP WBS dut as sink and classic keyboard test', 182 devices={ 183 'BLUETOOTH_AUDIO': 1, 184 'KEYBOARD': 1 185 }, 186 flags=['Quick Health'], 187 skip_chipsets=QR_UNSUPPORTED_CHIPSETS) 188 def qr_hfp_wbs_dut_as_sink_cl_keyboard_test(self): 189 """Quality Report HFP WBS dut as sink and classic keyboard test""" 190 audio_device = self.devices['BLUETOOTH_AUDIO'][0] 191 keyboard_device = self.devices['KEYBOARD'][0] 192 test_profile = HFP_WBS_MEDIUM 193 test_method = lambda: self.qr_hfp_dut_as_sink_cl_keyboard( 194 audio_device, keyboard_device, test_profile) 195 196 self.run_test_method((audio_device, keyboard_device), 197 test_method, 198 test_profile) 199 200 # Remove flags=['Quick Health'] when this test is migrated to stable suite. 201 @test_wrapper( 202 'Quality Report HFP NBS dut as sink and classic keyboard test', 203 devices={ 204 'BLUETOOTH_AUDIO': 1, 205 'KEYBOARD': 1 206 }, 207 flags=['Quick Health'], 208 skip_chipsets=QR_UNSUPPORTED_CHIPSETS) 209 def qr_hfp_nbs_dut_as_sink_cl_keyboard_test(self): 210 """Quality Report HFP NBS dut as sink and classic keyboard test""" 211 audio_device = self.devices['BLUETOOTH_AUDIO'][0] 212 keyboard_device = self.devices['KEYBOARD'][0] 213 test_profile = HFP_NBS_MEDIUM 214 test_method = lambda: self.qr_hfp_dut_as_sink_cl_keyboard( 215 audio_device, keyboard_device, test_profile) 216 217 self.run_test_method((audio_device, keyboard_device), 218 test_method, 219 test_profile) 220 221 @batch_wrapper('Bluetooth BQR Batch Health Tests') 222 def qr_health_batch_run(self, num_iterations=1, test_name=None): 223 """Run the bluetooth audio health test batch or a specific given test. 224 225 @param num_iterations: how many iterations to run 226 @param test_name: specific test to run otherwise None to run the 227 whole batch 228 """ 229 self.qr_a2dp_test() 230 self.qr_power_cycle_a2dp_test() 231 self.qr_hfp_nbs_dut_as_src_test() 232 self.qr_hfp_wbs_dut_as_src_test() 233 self.qr_disabled_a2dp_test() 234 self.qr_a2dp_cl_keyboard_test() 235 self.qr_hfp_wbs_dut_as_sink_cl_keyboard_test() 236 self.qr_hfp_nbs_dut_as_sink_cl_keyboard_test() 237 238 def run_once(self, 239 host, 240 num_iterations=1, 241 args_dict=None, 242 test_name=None, 243 flag='Quick Health'): 244 """Run the batch of Bluetooth stand health tests 245 246 @param host: the DUT, usually a chromebook 247 @param num_iterations: the number of rounds to execute the test 248 @param test_name: the test to run, or None for all tests 249 """ 250 self.host = host 251 252 self.quick_test_init(host, 253 use_btpeer=True, 254 flag=flag, 255 args_dict=args_dict) 256 self.qr_health_batch_run(num_iterations, test_name) 257 self.quick_test_cleanup() 258