• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 of Bluetooth LE sanity tests"""
6
7import time
8
9from autotest_lib.server.cros.bluetooth.bluetooth_adapter_quick_tests import \
10     BluetoothAdapterQuickTests
11from autotest_lib.server.cros.bluetooth.bluetooth_adapter_pairing_tests import \
12     BluetoothAdapterPairingTests
13from autotest_lib.server.cros.bluetooth.bluetooth_adapter_hidreports_tests \
14     import BluetoothAdapterHIDReportTests
15
16
17class bluetooth_AdapterLESanity(BluetoothAdapterQuickTests,
18        BluetoothAdapterPairingTests,
19        BluetoothAdapterHIDReportTests):
20    """A Batch of Bluetooth LE sanity tests. This test is written as a batch
21       of tests in order to reduce test time, since auto-test ramp up time is
22       costly. The batch is using BluetoothAdapterQuickTests wrapper methods to
23       start and end a test and a batch of tests.
24
25       This class can be called to run the entire test batch or to run a
26       specific test only
27    """
28
29    test_wrapper = BluetoothAdapterQuickTests.quick_test_test_decorator
30    batch_wrapper = BluetoothAdapterQuickTests.quick_test_batch_decorator
31
32    @test_wrapper('Discovery Test', devices={"BLE_MOUSE":1})
33    def le_discovery_test(self):
34        """Performs discovery test with mouse peripheral"""
35        device = self.devices['BLE_MOUSE'][0]
36
37        self.test_discover_device(device.address)
38
39        # Removed due to b:149093897 - the raspi peer can't instantly update
40        # the advertised name, causing this test to fail
41        # self.test_device_name(device.address, device.name)
42
43
44    @test_wrapper('Connect Disconnect Loop', devices={'BLE_MOUSE':1})
45    def le_connect_disconnect_loop(self):
46        """Run connect/disconnect loop initiated by DUT.
47           The test also checks that there are no undesired
48           reconnections.
49           TODO(ysahvit) - add connection creation attempts
50                           initiated by HID device
51        """
52
53        device = self.devices['BLE_MOUSE'][0]
54        self.connect_disconnect_loop(device=device, loops=3)
55
56
57    @test_wrapper('Mouse Reports', devices={'BLE_MOUSE':1})
58    def le_mouse_reports(self):
59        """Run all bluetooth mouse reports tests"""
60
61        device = self.devices['BLE_MOUSE'][0]
62        # Let the adapter pair, and connect to the target device.
63        self.test_discover_device(device.address)
64        # self.bluetooth_facade.is_discovering() doesn't work as expected:
65        # crbug:905374
66        # self.test_stop_discovery()
67        self.bluetooth_facade.stop_discovery()
68        time.sleep(self.TEST_SLEEP_SECS)
69        self.test_pairing(device.address, device.pin, trusted=True)
70        time.sleep(self.TEST_SLEEP_SECS)
71        self.test_connection_by_adapter(device.address)
72
73        # With raspberry pi peer, it takes a moment before the device is
74        # registered as an input device. Without delay, the input recorder
75        # doesn't find the device
76        time.sleep(1)
77        self.run_mouse_tests(device=device)
78
79
80    @test_wrapper('Keyboard Reports', devices={'BLE_KEYBOARD':1})
81    def le_keyboard_reports(self):
82        """Run all bluetooth keyboard reports tests"""
83
84        device = self.devices['BLE_KEYBOARD'][0]
85        # Let the adapter pair, and connect to the target device.
86        self.test_discover_device(device.address)
87        # self.bluetooth_facade.is_discovering() doesn't work as expected:
88        # crbug:905374
89        # self.test_stop_discovery()
90        self.bluetooth_facade.stop_discovery()
91        time.sleep(self.TEST_SLEEP_SECS)
92        self.test_pairing(device.address, device.pin, trusted=True)
93        time.sleep(self.TEST_SLEEP_SECS)
94        self.test_connection_by_adapter(device.address)
95
96        # With raspberry pi peer, it takes a moment before the device is
97        # registered as an input device. Without delay, the input recorder
98        # doesn't find the device
99        time.sleep(1)
100        self.run_keyboard_tests(device=device)
101
102
103    @test_wrapper('Auto Reconnect', devices={'BLE_MOUSE':1})
104    def le_auto_reconnect(self):
105        """LE reconnection loop by reseting HID and check reconnection"""
106
107        device = self.devices['BLE_MOUSE'][0]
108        self.auto_reconnect_loop(device=device,
109                                 loops=3,
110                                 check_connected_method=\
111                                 self.test_mouse_left_click)
112
113
114    @test_wrapper('GATT Client', devices={'BLE_KEYBOARD':1})
115    def le_gatt_client_attribute_browse_test(self):
116        """Browse the whole tree-structured GATT attributes"""
117
118        device = self.devices['BLE_KEYBOARD'][0]
119        self.test_discover_device(device.address)
120        self.bluetooth_facade.stop_discovery()
121        time.sleep(self.TEST_SLEEP_SECS)
122        self.test_pairing(device.address, device.pin, trusted=True)
123        time.sleep(self.TEST_SLEEP_SECS)
124        self.test_connection_by_adapter(device.address)
125        self.test_service_resolved(device.address)
126        self.test_gatt_browse(device.address)
127
128
129    @batch_wrapper('LE Sanity')
130    def le_sanity_batch_run(self, num_iterations=1, test_name=None):
131        """Run the LE sanity test batch or a specific given test.
132           The wrapper of this method is implemented in batch_decorator.
133           Using the decorator a test batch method can implement the only its
134           core tests invocations and let the decorator handle the wrapper,
135           which is taking care for whether to run a specific test or the
136           batch as a whole, and running the batch in iterations
137
138           @param num_iterations: how many interations to run
139           @param test_name: specifc test to run otherwise None to run the
140                             whole batch
141        """
142        self.le_connect_disconnect_loop()
143        self.le_mouse_reports()
144        self.le_keyboard_reports()
145        self.le_auto_reconnect()
146        self.le_discovery_test()
147
148
149    def run_once(self, host, num_iterations=1, test_name=None,
150                 flag='Quick Sanity'):
151        """Run the batch of Bluetooth LE sanity tests
152
153        @param host: the DUT, usually a chromebook
154        @param num_iterations: the number of rounds to execute the test
155        @test_name: the test to run, or None for all tests
156        """
157
158        # Initialize and run the test batch or the requested specific test
159        self.quick_test_init(host, use_chameleon=True, flag=flag)
160        self.le_sanity_batch_run(num_iterations, test_name)
161        self.quick_test_cleanup()
162