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 |