Chromium Code Reviews| Index: device/bluetooth/device_unittest.cc |
| diff --git a/device/bluetooth/device_unittest.cc b/device/bluetooth/device_unittest.cc |
| index b1e9ae1a36b847c9e60d1f3fb12cbbceeacebf1d..c252fcd0296a37a9344a9be0dcec06e7e4280a66 100644 |
| --- a/device/bluetooth/device_unittest.cc |
| +++ b/device/bluetooth/device_unittest.cc |
| @@ -14,7 +14,9 @@ |
| #include "base/run_loop.h" |
| #include "device/bluetooth/test/mock_bluetooth_adapter.h" |
| #include "device/bluetooth/test/mock_bluetooth_device.h" |
| +#include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h" |
| #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h" |
| +#include "device/bluetooth/test/mock_bluetooth_gatt_service.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| using ::testing::Return; |
| @@ -26,9 +28,14 @@ using NiceMockBluetoothAdapter = |
| using NiceMockBluetoothDevice = testing::NiceMock<device::MockBluetoothDevice>; |
| using NiceMockBluetoothGattService = |
| testing::NiceMock<device::MockBluetoothGattService>; |
| +using NiceMockBluetoothGattCharacteristic = |
| + testing::NiceMock<device::MockBluetoothGattCharacteristic>; |
| using NiceMockBluetoothGattConnection = |
| testing::NiceMock<device::MockBluetoothGattConnection>; |
| +using Properties = device::BluetoothGattCharacteristic::Properties; |
| +using Property = device::BluetoothGattCharacteristic::Property; |
| + |
| namespace { |
| const char kTestLeDeviceAddress0[] = "11:22:33:44:55:66"; |
| const char kTestLeDeviceName0[] = "Test LE Device 0"; |
| @@ -39,6 +46,19 @@ const char kTestServiceUuid0[] = "1234"; |
| const char kTestServiceId1[] = "service_id1"; |
| const char kTestServiceUuid1[] = "5678"; |
| +const char kTestCharacteristicId0[] = "characteristic_id0"; |
| +const char kTestCharacteristicUuid0[] = "1234"; |
| + |
| +const char kTestCharacteristicId1[] = "characteristic_id1"; |
| +const char kTestCharacteristicUuid1[] = "5678"; |
| + |
| +const char kTestCharacteristicId2[] = "characteristic_id2"; |
| +const char kTestCharacteristicUuid2[] = "9012"; |
| + |
| +const Properties kReadWriteProperties = |
| + Property::PROPERTY_READ | Property::PROPERTY_WRITE; |
| +const Properties kAllProperties = Property::NUM_PROPERTY - 1; |
| + |
| class BluetoothInterfaceDeviceTest : public testing::Test { |
| public: |
| enum class Call { EXPECTED, NOT_EXPECTED }; |
| @@ -58,10 +78,44 @@ class BluetoothInterfaceDeviceTest : public testing::Test { |
| auto service1 = base::MakeUnique<NiceMockBluetoothGattService>( |
| &device_, kTestServiceId0, device::BluetoothUUID(kTestServiceUuid0), |
| true /* is_primary */, false /* is_local */); |
| + |
| + auto characteristic1 = |
| + base::MakeUnique<NiceMockBluetoothGattCharacteristic>( |
| + service1.get(), kTestCharacteristicId0, |
| + device::BluetoothUUID(kTestCharacteristicUuid0), |
| + false /* is_local */, kReadWriteProperties, 0 /* permissions */); |
| + |
| + auto characteristic2 = |
| + base::MakeUnique<NiceMockBluetoothGattCharacteristic>( |
| + service1.get(), kTestCharacteristicId1, |
| + device::BluetoothUUID(kTestCharacteristicUuid1), |
| + false /* is_local */, kReadWriteProperties, 0 /* permissions */); |
| + |
| + service1->AddMockCharacteristic(std::move(characteristic1)); |
| + service1->AddMockCharacteristic(std::move(characteristic2)); |
| + |
| auto service2 = base::MakeUnique<NiceMockBluetoothGattService>( |
| &device_, kTestServiceId1, device::BluetoothUUID(kTestServiceUuid1), |
| true /* is_primary */, false /* is_local */); |
| + auto characteristic3 = |
| + base::MakeUnique<NiceMockBluetoothGattCharacteristic>( |
| + service2.get(), kTestCharacteristicId2, |
| + device::BluetoothUUID(kTestCharacteristicUuid2), |
| + false /* is_local */, kAllProperties, 0 /* permissions */); |
| + |
| + service2->AddMockCharacteristic(std::move(characteristic3)); |
| + |
| + EXPECT_CALL(*service1, GetCharacteristics()) |
| + .WillRepeatedly( |
| + Invoke(service1.get(), |
| + &device::MockBluetoothGattService::GetMockCharacteristics)); |
| + |
| + EXPECT_CALL(*service2, GetCharacteristics()) |
| + .WillRepeatedly( |
| + Invoke(service2.get(), |
| + &device::MockBluetoothGattService::GetMockCharacteristics)); |
| + |
| device_.AddMockService(std::move(service1)); |
| device_.AddMockService(std::move(service2)); |
| @@ -69,6 +123,10 @@ class BluetoothInterfaceDeviceTest : public testing::Test { |
| .WillRepeatedly( |
| Invoke(&device_, &device::MockBluetoothDevice::GetMockServices)); |
| + EXPECT_CALL(device_, GetGattService(testing::_)) |
| + .WillRepeatedly( |
| + Invoke(&device_, &device::MockBluetoothDevice::GetMockService)); |
| + |
| auto connection = base::MakeUnique<NiceMockBluetoothGattConnection>( |
| adapter_, device_.GetAddress()); |
| @@ -124,6 +182,58 @@ class BluetoothInterfaceDeviceTest : public testing::Test { |
| num_of_preceding_calls); |
| } |
| + void GetCharacteristicsCheckForPrecedingCalls( |
|
scheib
2017/01/13 05:24:40
Maybe names such as:
CheckGetCharacteristicsCount
mbrunson
2017/01/13 21:21:13
Done.
|
| + Call expected, |
| + size_t expected_count, |
| + int num_of_preceding_calls, |
| + std::vector<mojom::CharacteristicInfoPtr> characteristics) { |
| + EXPECT_EQ(num_of_preceding_calls, callback_count_); |
| + ++callback_count_; |
| + |
| + if (expected == Call::EXPECTED) |
| + ++actual_success_callback_calls_; |
| + |
| + EXPECT_EQ(expected_count, characteristics.size()); |
| + } |
| + |
| + Device::GetCharacteristicsCallback |
| + GetGetCharacteristicsCheckForPrecedingCalls(Call expected, |
| + int num_of_preceding_calls, |
|
scheib
2017/01/13 05:24:40
Can't num_of_preceding be incremented as a test fi
mbrunson
2017/01/13 21:21:13
Done.
|
| + int expected_count) { |
| + if (expected == Call::EXPECTED) |
| + ++expected_success_callback_calls_; |
| + |
| + return base::Bind( |
| + &BluetoothInterfaceDeviceTest::GetCharacteristicsCheckForPrecedingCalls, |
| + weak_factory_.GetWeakPtr(), expected, expected_count, |
| + num_of_preceding_calls); |
| + } |
| + |
| + void GetCharacteristicsCheckProperties( |
| + Call expected, |
| + std::vector<Properties> expected_properties, |
| + std::vector<mojom::CharacteristicInfoPtr> characteristics) { |
| + if (expected == Call::EXPECTED) |
| + ++actual_success_callback_calls_; |
| + |
| + ASSERT_EQ(expected_properties.size(), characteristics.size()); |
| + |
| + for (size_t i = 0; i < characteristics.size(); i++) { |
| + EXPECT_EQ(expected_properties[i], characteristics[i]->properties); |
| + } |
| + } |
| + |
| + Device::GetCharacteristicsCallback GetGetCharacteristicsCheckProperties( |
| + Call expected, |
| + std::vector<Properties> expected_properties) { |
| + if (expected == Call::EXPECTED) |
| + ++expected_success_callback_calls_; |
| + |
| + return base::Bind( |
| + &BluetoothInterfaceDeviceTest::GetCharacteristicsCheckProperties, |
| + weak_factory_.GetWeakPtr(), expected, std::move(expected_properties)); |
| + } |
| + |
| scoped_refptr<NiceMockBluetoothAdapter> adapter_; |
| NiceMockBluetoothDevice device_; |
| base::MessageLoop message_loop_; |
| @@ -226,4 +336,152 @@ TEST_F(BluetoothInterfaceDeviceTest, |
| base::RunLoop().RunUntilIdle(); |
| } |
| +TEST_F(BluetoothInterfaceDeviceTest, GetCharacteristics) { |
| + EXPECT_CALL(device_, IsGattServicesDiscoveryComplete()) |
| + .WillRepeatedly(Return(true)); |
| + |
| + proxy_->GetCharacteristics(kTestServiceId0, |
| + GetGetCharacteristicsCheckForPrecedingCalls( |
| + Call::EXPECTED, 0 /* num_of_preceding_calls |
|
scheib
2017/01/13 05:24:40
Use "//" comment style to force auto-wrapping to n
mbrunson
2017/01/13 21:21:13
I've removed these comments. Done.
|
| + */, |
| + 2 /* expected_count */)); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BluetoothInterfaceDeviceTest, |
| + GetCharacteristicsCheckPropertiesService0) { |
| + EXPECT_CALL(device_, IsGattServicesDiscoveryComplete()) |
| + .WillRepeatedly(Return(true)); |
| + |
| + std::vector<Properties> properties; |
| + properties.push_back(kReadWriteProperties); |
| + properties.push_back(kReadWriteProperties); |
| + |
| + proxy_->GetCharacteristics(kTestServiceId0, |
| + GetGetCharacteristicsCheckProperties( |
| + Call::EXPECTED, std::move(properties))); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BluetoothInterfaceDeviceTest, |
| + GetCharacteristicsCheckPropertiesService1) { |
| + EXPECT_CALL(device_, IsGattServicesDiscoveryComplete()) |
| + .WillRepeatedly(Return(true)); |
| + |
| + std::vector<Properties> properties; |
| + properties.push_back(kAllProperties); |
| + |
| + proxy_->GetCharacteristics(kTestServiceId1, |
| + GetGetCharacteristicsCheckProperties( |
| + Call::EXPECTED, std::move(properties))); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BluetoothInterfaceDeviceTest, GetCharacteristicsNotDiscovered) { |
| + EXPECT_CALL(device_, IsGattServicesDiscoveryComplete()) |
| + .WillOnce(Return(false)) |
| + .WillOnce(Return(false)) |
| + .WillRepeatedly(Return(true)); |
| + |
| + // Client: Sends multiple requests for services. |
| + proxy_->GetCharacteristics(kTestServiceId0, |
| + GetGetCharacteristicsCheckForPrecedingCalls( |
| + Call::EXPECTED, 0 /* num_of_preceding_calls |
| + */, |
| + 2 /* expected_count */)); |
| + proxy_->GetCharacteristics(kTestServiceId1, |
| + GetGetCharacteristicsCheckForPrecedingCalls( |
| + Call::EXPECTED, 1 /* num_of_preceding_calls |
| + */, |
| + 1 /* expected_count */)); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + SimulateGattServicesDiscovered(); |
| + |
| + // No more GetServices calls will complete. |
| + SimulateGattServicesDiscovered(); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // Client: Sends more requests which run immediately. |
| + proxy_->GetCharacteristics(kTestServiceId0, |
| + GetGetCharacteristicsCheckForPrecedingCalls( |
| + Call::EXPECTED, 2 /* num_of_preceding_calls |
| + */, |
| + 2 /* expected_count */)); |
| + proxy_->GetCharacteristics(kTestServiceId1, |
| + GetGetCharacteristicsCheckForPrecedingCalls( |
| + Call::EXPECTED, 3 /* num_of_preceding_calls |
| + */, |
| + 1 /* expected_count */)); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // No more GetCharacteristics calls will complete. |
| + SimulateGattServicesDiscovered(); |
| + |
| + // Wait for message pipe to process error. |
| + base::RunLoop().RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BluetoothInterfaceDeviceTest, |
| + GetCharacteristicsLostConnectionWithPendingRequests) { |
| + EXPECT_CALL(device_, IsGattServicesDiscoveryComplete()) |
| + .WillRepeatedly(Return(false)); |
| + // Client: Sends multiple requests for characteristics. |
| + proxy_->GetCharacteristics( |
| + kTestServiceId0, |
| + GetGetCharacteristicsCheckForPrecedingCalls(Call::NOT_EXPECTED, 0 /* |
| + num_of_preceding_calls |
| + */, |
| + 2 /* expected_count */)); |
| + proxy_->GetCharacteristics( |
| + kTestServiceId1, |
| + GetGetCharacteristicsCheckForPrecedingCalls(Call::NOT_EXPECTED, 1 /* |
| + num_of_preceding_calls |
| + */, |
| + 1 /* expected_count */)); |
| + EXPECT_EQ(0, callback_count_); |
| + |
| + // Simulate connection loss. |
| + device_.SetConnected(false); |
| + SimulateDeviceChanged(); |
| + expect_device_service_deleted_ = true; |
| + |
| + // Wait for message pipe to process error. |
| + base::RunLoop().RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BluetoothInterfaceDeviceTest, |
| + GetCharacteristicsForcedDisconnectionWithPendingRequests) { |
| + EXPECT_CALL(device_, IsGattServicesDiscoveryComplete()) |
| + .WillRepeatedly(Return(false)); |
| + |
| + // Client: Sends multiple requests for services. |
| + proxy_->GetCharacteristics( |
| + kTestServiceId0, |
| + GetGetCharacteristicsCheckForPrecedingCalls(Call::NOT_EXPECTED, 0 /* |
| + num_of_preceding_calls |
| + */, |
| + 2 /* expected_count */)); |
| + proxy_->GetCharacteristics( |
| + kTestServiceId1, |
| + GetGetCharacteristicsCheckForPrecedingCalls(Call::NOT_EXPECTED, 1 /* |
| + num_of_preceding_calls |
| + */, |
| + 1 /* expected_count */)); |
| + EXPECT_EQ(0, callback_count_); |
| + |
| + // Simulate connection loss. |
| + proxy_->Disconnect(); |
| + expect_device_service_deleted_ = true; |
| + |
| + // Wait for message pipe to process error. |
| + base::RunLoop().RunUntilIdle(); |
| +} |
| + |
| } // namespace bluetooth |