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..75724d687cacfae3537cc0e8c29ac76e6b70d42d 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()); |
| @@ -98,30 +156,78 @@ class BluetoothInterfaceDeviceTest : public testing::Test { |
| observer.DeviceChanged(adapter_.get(), &device_); |
| } |
| - void GetServicesCheckForPrecedingCalls( |
| + void CheckGetServicesCountImpl(Call expected, |
| + size_t expected_service_count, |
| + int num_of_preceding_calls, |
| + std::vector<mojom::ServiceInfoPtr> services) { |
| + EXPECT_EQ(num_of_preceding_calls, actual_callback_count_); |
| + ++actual_callback_count_; |
| + |
| + if (expected == Call::EXPECTED) |
| + ++actual_success_callback_calls_; |
| + |
| + EXPECT_EQ(expected_service_count, services.size()); |
| + } |
| + |
| + Device::GetServicesCallback CheckGetServicesCount(Call expected) { |
| + if (expected == Call::EXPECTED) |
| + ++expected_success_callback_calls_; |
| + |
| + return base::Bind(&BluetoothInterfaceDeviceTest::CheckGetServicesCountImpl, |
| + weak_factory_.GetWeakPtr(), expected, |
| + 2 /* expected_service_count */, |
| + expected_callback_count_++); |
| + } |
| + |
| + void CheckGetCharacteristicsCountImpl( |
| Call expected, |
| - size_t expected_service_count, |
| + size_t expected_count, |
| int num_of_preceding_calls, |
| - std::vector<mojom::ServiceInfoPtr> services) { |
| - EXPECT_EQ(num_of_preceding_calls, callback_count_); |
| - ++callback_count_; |
| + std::vector<mojom::CharacteristicInfoPtr> characteristics) { |
| + EXPECT_EQ(num_of_preceding_calls, actual_callback_count_); |
| + ++actual_callback_count_; |
| if (expected == Call::EXPECTED) |
| ++actual_success_callback_calls_; |
| - EXPECT_EQ(expected_service_count, services.size()); |
| + EXPECT_EQ(expected_count, characteristics.size()); |
| } |
| - Device::GetServicesCallback GetGetServicesCheckForPrecedingCalls( |
| + Device::GetCharacteristicsCallback CheckGetCharacteristicsCount( |
| Call expected, |
| - int num_of_preceding_calls) { |
| + int expected_count) { |
| if (expected == Call::EXPECTED) |
| ++expected_success_callback_calls_; |
| return base::Bind( |
| - &BluetoothInterfaceDeviceTest::GetServicesCheckForPrecedingCalls, |
| - weak_factory_.GetWeakPtr(), expected, 2 /* expected_service_count */, |
| - num_of_preceding_calls); |
| + &BluetoothInterfaceDeviceTest::CheckGetCharacteristicsCountImpl, |
| + weak_factory_.GetWeakPtr(), expected, expected_count, |
| + expected_callback_count_++); |
| + } |
| + |
| + void CheckGetCharacteristicsPropertiesImpl( |
| + 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 CheckGetCharacteristicsProperties( |
| + Call expected, |
| + std::vector<Properties> expected_properties) { |
| + if (expected == Call::EXPECTED) |
| + ++expected_success_callback_calls_; |
| + |
| + return base::Bind( |
| + &BluetoothInterfaceDeviceTest::CheckGetCharacteristicsPropertiesImpl, |
| + weak_factory_.GetWeakPtr(), expected, std::move(expected_properties)); |
| } |
| scoped_refptr<NiceMockBluetoothAdapter> adapter_; |
| @@ -134,7 +240,8 @@ class BluetoothInterfaceDeviceTest : public testing::Test { |
| bool expect_device_service_deleted_ = false; |
| int expected_success_callback_calls_ = 0; |
| int actual_success_callback_calls_ = 0; |
| - int callback_count_ = 0; |
| + int actual_callback_count_ = 0; |
| + int expected_callback_count_ = 0; |
| base::WeakPtrFactory<BluetoothInterfaceDeviceTest> weak_factory_; |
| }; |
| @@ -144,8 +251,7 @@ TEST_F(BluetoothInterfaceDeviceTest, GetServices) { |
| EXPECT_CALL(device_, IsGattServicesDiscoveryComplete()) |
| .WillRepeatedly(Return(true)); |
| - proxy_->GetServices(GetGetServicesCheckForPrecedingCalls( |
| - Call::EXPECTED, 0 /* num_of_preceding_calls */)); |
| + proxy_->GetServices(CheckGetServicesCount(Call::EXPECTED)); |
| base::RunLoop().RunUntilIdle(); |
| } |
| @@ -157,10 +263,8 @@ TEST_F(BluetoothInterfaceDeviceTest, GetServicesNotDiscovered) { |
| .WillRepeatedly(Return(true)); |
| // Client: Sends multiple requests for services. |
| - proxy_->GetServices(GetGetServicesCheckForPrecedingCalls( |
| - Call::EXPECTED, 0 /* num_of_preceding_calls */)); |
| - proxy_->GetServices(GetGetServicesCheckForPrecedingCalls( |
| - Call::EXPECTED, 1 /* num_of_preceding_calls */)); |
| + proxy_->GetServices(CheckGetServicesCount(Call::EXPECTED)); |
| + proxy_->GetServices(CheckGetServicesCount(Call::EXPECTED)); |
| base::RunLoop().RunUntilIdle(); |
| @@ -172,10 +276,8 @@ TEST_F(BluetoothInterfaceDeviceTest, GetServicesNotDiscovered) { |
| base::RunLoop().RunUntilIdle(); |
| // Client: Sends more requests which run immediately. |
| - proxy_->GetServices(GetGetServicesCheckForPrecedingCalls( |
| - Call::EXPECTED, 2 /* num_of_preceding_calls */)); |
| - proxy_->GetServices(GetGetServicesCheckForPrecedingCalls( |
| - Call::EXPECTED, 3 /* num_of_preceding_calls */)); |
| + proxy_->GetServices(CheckGetServicesCount(Call::EXPECTED)); |
| + proxy_->GetServices(CheckGetServicesCount(Call::EXPECTED)); |
| base::RunLoop().RunUntilIdle(); |
| @@ -191,11 +293,9 @@ TEST_F(BluetoothInterfaceDeviceTest, |
| EXPECT_CALL(device_, IsGattServicesDiscoveryComplete()) |
| .WillRepeatedly(Return(false)); |
| // Client: Sends multiple requests for services. |
| - proxy_->GetServices(GetGetServicesCheckForPrecedingCalls( |
| - Call::NOT_EXPECTED, 0 /* num_of_preceding_calls */)); |
| - proxy_->GetServices(GetGetServicesCheckForPrecedingCalls( |
| - Call::NOT_EXPECTED, 1 /* num_of_preceding_calls */)); |
| - EXPECT_EQ(0, callback_count_); |
| + proxy_->GetServices(CheckGetServicesCount(Call::NOT_EXPECTED)); |
| + proxy_->GetServices(CheckGetServicesCount(Call::NOT_EXPECTED)); |
| + EXPECT_EQ(0, actual_callback_count_); |
| // Simulate connection loss. |
| device_.SetConnected(false); |
| @@ -212,11 +312,126 @@ TEST_F(BluetoothInterfaceDeviceTest, |
| .WillRepeatedly(Return(false)); |
| // Client: Sends multiple requests for services. |
| - proxy_->GetServices(GetGetServicesCheckForPrecedingCalls( |
| - Call::NOT_EXPECTED, 0 /* num_of_preceding_calls */)); |
| - proxy_->GetServices(GetGetServicesCheckForPrecedingCalls( |
| - Call::NOT_EXPECTED, 1 /* num_of_preceding_calls */)); |
| - EXPECT_EQ(0, callback_count_); |
| + proxy_->GetServices(CheckGetServicesCount(Call::NOT_EXPECTED)); |
| + proxy_->GetServices(CheckGetServicesCount(Call::NOT_EXPECTED)); |
| + EXPECT_EQ(0, actual_callback_count_); |
| + |
| + // Simulate connection loss. |
| + proxy_->Disconnect(); |
| + expect_device_service_deleted_ = true; |
| + |
| + // Wait for message pipe to process error. |
| + base::RunLoop().RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BluetoothInterfaceDeviceTest, GetCharacteristics) { |
| + EXPECT_CALL(device_, IsGattServicesDiscoveryComplete()) |
| + .WillRepeatedly(Return(true)); |
| + |
| + proxy_->GetCharacteristics(kTestServiceId0, |
| + CheckGetCharacteristicsCount(Call::EXPECTED, 2)); |
| + |
| + 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, |
| + CheckGetCharacteristicsProperties(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, |
| + CheckGetCharacteristicsProperties(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. |
|
scheib
2017/01/14 00:07:14
for characteristics
mbrunson
2017/01/14 01:49:32
Done.
|
| + proxy_->GetCharacteristics(kTestServiceId0, |
| + CheckGetCharacteristicsCount(Call::EXPECTED, 2)); |
| + proxy_->GetCharacteristics(kTestServiceId1, |
| + CheckGetCharacteristicsCount(Call::EXPECTED, 1)); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + SimulateGattServicesDiscovered(); |
| + |
| + // No more GetServices calls will complete. |
| + SimulateGattServicesDiscovered(); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // Client: Sends more requests which run immediately. |
| + proxy_->GetCharacteristics(kTestServiceId0, |
| + CheckGetCharacteristicsCount(Call::EXPECTED, 2)); |
| + proxy_->GetCharacteristics(kTestServiceId1, |
| + CheckGetCharacteristicsCount(Call::EXPECTED, 1)); |
| + |
| + 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, CheckGetCharacteristicsCount(Call::NOT_EXPECTED, 2)); |
| + proxy_->GetCharacteristics( |
| + kTestServiceId1, CheckGetCharacteristicsCount(Call::NOT_EXPECTED, 1)); |
| + EXPECT_EQ(0, actual_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, CheckGetCharacteristicsCount(Call::NOT_EXPECTED, 2)); |
| + proxy_->GetCharacteristics( |
| + kTestServiceId1, CheckGetCharacteristicsCount(Call::NOT_EXPECTED, 1)); |
| + EXPECT_EQ(0, actual_callback_count_); |
| // Simulate connection loss. |
| proxy_->Disconnect(); |