def test_write_handle_ok(self, time_mock, popen_mock): """Test writing to a handle successfully.""" _configure_popenmock(popen_mock, 'Characteristic value was written successfully') backend = GatttoolBackend() backend.connect(TEST_MAC) self.assertTrue(backend.write_handle(0xFF, b'\x00\x10\xFF'))
def test_bytes_to_string(self): """Test conversion of byte arrays.""" self.assertEqual('0A0B', GatttoolBackend.bytes_to_string(bytes([0x0A, 0x0B]))) self.assertEqual( '0x0C0D', GatttoolBackend.bytes_to_string(bytes([0x0C, 0x0D]), True))
def test_read_handle_ok(self, popen_mock): """Test reading handle successfully.""" gattoutput = bytes([0x00, 0x11, 0xAA, 0xFF]) _configure_popenmock(popen_mock, "Characteristic value/descriptor: 00 11 AA FF") backend = GatttoolBackend() backend.connect(TEST_MAC) result = backend.read_handle(0xFF) self.assertEqual(gattoutput, result)
def test_notification_timeout(self, time_mock, popen_mock, os_mock): """Test notification when timeout""" _configure_popenmock_timeout(popen_mock, ( "Characteristic value was written successfully\n" "Notification handle = 0x000e value: 54 3d 32 37 2e 33 20 48 3d 32 37 2e 30 00\n" "Notification handle = 0x000e value: 54 3d 32 37 2e 32 20 48 3d 32 37 2e 32 00\n" "Notification handle = 0x000e value: 54 3d 32 37 2e 31 20 48 3d 32 37 2e 34 00" )) backend = GatttoolBackend() backend.connect(TEST_MAC) self.handle_notification_called = False self.assertTrue(backend.wait_for_notification(0xFF, self, 10)) self.assertTrue(self.handle_notification_called)
def test_read_handle_timeout(self, time_mock, popen_mock, os_mock): """Test notification when timeout""" _configure_popenmock_timeout(popen_mock, "Characteristic") backend = GatttoolBackend() backend.connect(TEST_MAC) with self.assertRaises(BluetoothBackendException): backend.read_handle(0xFF)
def test_read_handle_empty_output(self, _, popen_mock): """Test reading handle where no result is returned.""" _configure_popenmock(popen_mock, "") backend = GatttoolBackend() backend.connect(TEST_MAC) with self.assertRaises(BluetoothBackendException): backend.read_handle(0xFF)
def test_notification_no_answer(self, time_mock, popen_mock): """Test notification when no result is returned.""" _configure_popenmock(popen_mock, "") backend = GatttoolBackend() backend.connect(TEST_MAC) with self.assertRaises(BluetoothBackendException): backend.wait_for_notification(0xFF, self, 10)
def test_write_handle_no_answer(self, time_mock, popen_mock): """Test writing to a handle when no result is returned.""" _configure_popenmock(popen_mock, "") backend = GatttoolBackend() backend.connect(TEST_MAC) with self.assertRaises(BluetoothBackendException): backend.write_handle(0xFF, b"\x00\x10\xFF")
def test_run_connect_disconnect(self): """Just run connect and disconnect""" backend = GatttoolBackend() backend.connect(TEST_MAC) self.assertEqual(TEST_MAC, backend._mac) backend.disconnect() self.assertEqual(None, backend._mac)
def test_notification_payload_ok(self): """testing data processing""" notification_response = ( "Characteristic value was written successfully\n" "Notification handle = 0x000e value: 54 3d 32 37 2e 33 20 48 3d 32 37 2e 30 00\n" "Notification handle = 0x000e value: 54 3d 32 37 2e 32 20 48 3d 32 37 2e 32 00\n" "Notification handle = 0x000e value: 54 3d 32 37 2e 31 20 48 3d 32 37 2e 34 00" ) data = GatttoolBackend().extract_notification_payload(notification_response) self.assertTrue(len(data) == 3) self.assertTrue(data[0] == "54 3d 32 37 2e 33 20 48 3d 32 37 2e 30 00") self.assertTrue(data[2] == "54 3d 32 37 2e 31 20 48 3d 32 37 2e 34 00")
def test_read_handle_wrong_handle(self, popen_mock): """Test reading invalid handle.""" _configure_popenmock( popen_mock, "Characteristic value/descriptor read failed: Invalid handle" ) backend = GatttoolBackend() backend.connect(TEST_MAC) with self.assertRaises(BluetoothBackendException): backend.read_handle(0xFF)
def test_write_handle_wrong_handle(self, time_mock, popen_mock): """Test writing to a non-writable handle.""" _configure_popenmock( popen_mock, "Characteristic Write Request failed: Attribute can't be written") backend = GatttoolBackend() backend.connect(TEST_MAC) with self.assertRaises(BluetoothBackendException): backend.write_handle(0xFF, b'\x00\x10\xFF')
def test_notification_wrong_handle(self, time_mock, popen_mock): """Test notification when wrong handle""" _configure_popenmock( popen_mock, "Characteristic Write Request failed: Attribute can't be written") backend = GatttoolBackend() backend.connect(TEST_MAC) with self.assertRaises(BluetoothBackendException): backend.wait_for_notification(0xFF, self, 10)
class TestGatttool(unittest.TestCase, CommonTests): """Test btlewrap by connecting to a real device.""" # pylint does not understand pytest fixtures, so we have to disable the warning # pylint: disable=no-member def setUp(self): """Set up the test environment.""" self.backend = GatttoolBackend() def test_scan_with_adapter(self): """Scan for devices with specific adapter.""" devices = self.backend.scan_for_devices(timeout=7, adapter='hci0') self.assertGreater(len(devices), 0)
def test_parse_scan_output_update_names(self): """Check if "unknown" names are updated later on.""" test_data = ''' LE Scan ... 78:24:AC:37:21:3D (SomeDevice) 78:24:AC:37:21:3D (unknown) 63:82:9D:D1:B3:A2 (unknown) 63:82:9D:D1:B3:A2 (OtherDevice) ''' expected = [ ('78:24:AC:37:21:3D', 'SomeDevice'), ('63:82:9D:D1:B3:A2', 'OtherDevice'), ] self.assertCountEqual(expected, GatttoolBackend._parse_scan_output(test_data))
def test_parse_scan_output_update_names(self): """Check if "unknown" names are updated later on.""" test_data = """ LE Scan ... 78:24:AC:37:21:3D (SomeDevice) 78:24:AC:37:21:3D (unknown) 63:82:9D:D1:B3:A2 (unknown) 63:82:9D:D1:B3:A2 (OtherDevice) """ expected = [ ("78:24:AC:37:21:3D", "SomeDevice"), ("63:82:9D:D1:B3:A2", "OtherDevice"), ] self.assertCountEqual(expected, GatttoolBackend._parse_scan_output(test_data))
def test_parse_scan_output_partial_data(self): """Check if the parser can handle partial data""" test_data = ''' LE Scan ... 78:24:AC:37:21:3D (SomeDevice) 65:B8:8C:38:D5:77 (unknown) 78:24:AC:37:21:3D (unknown) 63:82:9D:D1:B3:A2 (unknown) 63:82:9D:D1:B3:A2 (OtherDevice) 65:B8:8C:38:D5:77 (unknown) 65:B8:8C:38:D5:77 (MyDevice) 65:B8:8C:38:D5:77 (unknown) ''' for length in range(0, len(test_data)): result = GatttoolBackend._parse_scan_output(test_data[0:length]) self.assertEqual(len(result) > 0, length > 66)
def test_parse_scan_output_deduplicate(self): """Check if parsed lists are de-duplicated.""" test_data = """ LE Scan ... 65:B8:8C:38:D5:77 (MyDevice) 78:24:AC:37:21:3D (unknown) 78:24:AC:37:21:3D (unknown) 78:24:AC:37:21:3D (unknown) 63:82:9D:D1:B3:A2 (unknown) 63:82:9D:D1:B3:A2 (unknown) """ expected = [ ("65:B8:8C:38:D5:77", "MyDevice"), ("78:24:AC:37:21:3D", "unknown"), ("63:82:9D:D1:B3:A2", "unknown"), ] self.assertCountEqual(expected, GatttoolBackend._parse_scan_output(test_data))
def test_parse_scan_output_deduplicate(self): """Check if parsed lists are de-duplicated.""" test_data = ''' LE Scan ... 65:B8:8C:38:D5:77 (MyDevice) 78:24:AC:37:21:3D (unknown) 78:24:AC:37:21:3D (unknown) 78:24:AC:37:21:3D (unknown) 63:82:9D:D1:B3:A2 (unknown) 63:82:9D:D1:B3:A2 (unknown) ''' expected = [ ('65:B8:8C:38:D5:77', 'MyDevice'), ('78:24:AC:37:21:3D', 'unknown'), ('63:82:9D:D1:B3:A2', 'unknown'), ] self.assertCountEqual(expected, GatttoolBackend._parse_scan_output(test_data))
def test_check_backend_ok(self, call_mock): """Test check_backend successfully.""" self.assertTrue(GatttoolBackend().check_backend())
def test_byte_to_handle(self): """Test conversion of handles.""" self.assertEqual('0x0B', GatttoolBackend.byte_to_handle(0x0B)) self.assertEqual('0xAF', GatttoolBackend.byte_to_handle(0xAF)) self.assertEqual('0xAABB', GatttoolBackend.byte_to_handle(0xAABB))
def setUp(self): """Setup of the test case.""" self.backend = GatttoolBackend(retries=0, timeout=20)
def test_write_not_connected(self): """Test writing data when not connected.""" backend = GatttoolBackend() with self.assertRaises(BluetoothBackendException): backend.write_handle(0xFF, [0x00])
class TestGatttoolBackend(unittest.TestCase): """Test GatttoolBackend with real sensor.""" # pylint does not understand pytest fixtures, so we have to disable the warning # pylint: disable=no-member def setUp(self): """Setup of the test case.""" self.backend = GatttoolBackend(retries=0, timeout=20) @pytest.mark.usefixtures("mac") def test_read(self): """Test reading a handle from the sensor.""" self.backend.connect(self.mac) result = self.backend.read_handle(HANDLE_READ_NAME) self.assertIsNotNone(result) self.backend.disconnect() def test_read_not_connected(self): """Test error handling if not connected.""" with self.assertRaises(BluetoothBackendException): self.backend.read_handle(HANDLE_READ_NAME) def test_check_backend(self): """Test check_backend function.""" self.assertTrue(self.backend.check_backend()) def test_invalid_mac_exception(self): """Test writing data to handle of the sensor.""" with self.assertRaises(BluetoothBackendException): self.backend.connect(TEST_MAC) self.backend.read_handle(HANDLE_READ_NAME)
def test_read_not_connected(self): """Test reading data when not connected.""" backend = GatttoolBackend() with self.assertRaises(BluetoothBackendException): backend.read_handle(0xFF)
def test_notification_not_connected(self): """Test writing data when not connected.""" backend = GatttoolBackend() with self.assertRaises(BluetoothBackendException): backend.wait_for_notification(0xFF, self, 10)
def test_supports_scanning(self): """Check if scanning is set correctly.""" backend = GatttoolBackend() self.assertTrue(backend.supports_scanning())
def test_check_backend_fail(self, call_mock): """Test check_backend with IOError being risen.""" self.assertFalse(GatttoolBackend().check_backend())
def setUp(self): """Set up the test environment.""" self.backend = GatttoolBackend()