Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(580)

Side by Side Diff: device/bluetooth/device_unittest.cc

Issue 2448713002: bluetooth: Add Device connection logic and accompanying user interface. (Closed)
Patch Set: More tests, more comments Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium 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 #include "device/bluetooth/device.h"
6
7 #include <memory>
8 #include <string>
9 #include <utility>
10
11 #include "base/logging.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/run_loop.h"
15 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
16 #include "device/bluetooth/test/mock_bluetooth_device.h"
17 #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using ::testing::Return;
21
22 namespace bluetooth {
23
24 typedef testing::NiceMock<device::MockBluetoothAdapter>
25 NiceMockBluetoothAdapter;
26 typedef testing::NiceMock<device::MockBluetoothDevice> NiceMockBluetoothDevice;
27 typedef testing::NiceMock<device::MockBluetoothGattService>
28 NiceMockBluetoothGattService;
29 typedef testing::NiceMock<device::MockBluetoothGattConnection>
30 NiceMockBluetoothGattConnection;
31
32 namespace {
33 const char kTestLeDeviceAddress0[] = "11:22:33:44:55:66";
34 const char kTestLeDeviceName0[] = "Test LE Device 0";
35
36 const char kTestServiceId0[] = "service_id0";
37 const char kTestServiceUuid0[] = "1234";
38
39 const char kTestServiceId1[] = "service_id1";
40 const char kTestServiceUuid1[] = "5678";
41
42 class DeviceTest : public testing::Test {
43 public:
44 enum class Call { EXPECTED, NOT_EXPECTED };
45
46 DeviceTest()
47 : adapter_(new NiceMockBluetoothAdapter),
48 message_loop_(new base::MessageLoop),
49 weak_factory_(this) {
50 device_.reset(
51 new NiceMockBluetoothDevice(adapter_.get(), 0, kTestLeDeviceName0,
52 kTestLeDeviceAddress0, false, true));
53
54 ON_CALL(*adapter_, GetDevice(kTestLeDeviceAddress0))
55 .WillByDefault(Return(device_.get()));
56
57 std::unique_ptr<NiceMockBluetoothGattService> service1(
58 new NiceMockBluetoothGattService(
59 device_.get(), kTestServiceId0,
60 device::BluetoothUUID(kTestServiceUuid0), true /* is_primary */,
61 false /* is_local */));
62 std::unique_ptr<NiceMockBluetoothGattService> service2(
63 new NiceMockBluetoothGattService(
64 device_.get(), kTestServiceId1,
65 device::BluetoothUUID(kTestServiceUuid1), true /* is_primary */,
66 false /* is_local */));
67
68 device_->AddMockService(std::move(service1));
69 device_->AddMockService(std::move(service2));
70
71 EXPECT_CALL(*device_, GetGattServices())
72 .WillRepeatedly(Invoke(device_.get(),
73 &device::MockBluetoothDevice::GetMockServices));
74
75 std::unique_ptr<NiceMockBluetoothGattConnection> connection(
76 new NiceMockBluetoothGattConnection(adapter_, device_->GetAddress()));
77
78 // Owns itself.
79 device_service_ =
80 new Device(adapter_, std::move(connection), mojo::GetProxy(&proxy_));
81 }
82
83 void TearDown() override {
84 EXPECT_EQ(expected_success_callback_calls_, actual_success_callback_calls_);
85
86 if (!expect_device_service_deleted_) {
87 delete device_service_;
88 }
89 }
90
91 protected:
92 void GetServicesCheckForPrecedingCalls(
93 Call expected,
94 size_t expected_length,
95 int num_of_preceding_calls,
96 const base::Closure& continuation,
97 std::vector<mojom::ServiceInfoPtr> services) {
98 EXPECT_EQ(num_of_preceding_calls, callback_count_);
99 ++callback_count_;
100
101 if (expected == Call::EXPECTED)
102 ++actual_success_callback_calls_;
103
104 EXPECT_EQ(expected_length, services.size());
105 continuation.Run();
106 }
107
108 Device::GetServicesCallback GetGetServicesCheckForPrecedingCalls(
109 Call expected,
110 int num_of_preceding_calls,
111 const base::Closure& continuation) {
112 if (expected == Call::EXPECTED)
113 ++expected_success_callback_calls_;
114
115 return base::Bind(&DeviceTest::GetServicesCheckForPrecedingCalls,
116 weak_factory_.GetWeakPtr(), expected, 2,
117 num_of_preceding_calls, continuation);
118 }
119
120 void MakeGetServicesRequests(int num_of_preceding_calls,
121 int expected_calls,
122 Call expected,
123 const base::Closure& continuation) {
124 for (int i = 0; i < expected_calls; i++) {
125 device_service_->GetServices(GetGetServicesCheckForPrecedingCalls(
126 expected, num_of_preceding_calls + i, continuation));
127 }
128 }
129
130 scoped_refptr<NiceMockBluetoothAdapter> adapter_;
131 std::unique_ptr<NiceMockBluetoothDevice> device_;
132 Device* device_service_;
133 std::unique_ptr<base::MessageLoop> message_loop_;
134 mojom::DevicePtr proxy_;
135
136 bool expect_device_service_deleted_ = false;
137 int expected_success_callback_calls_ = 0;
138 int actual_success_callback_calls_ = 0;
139 int callback_count_ = 0;
140
141 base::WeakPtrFactory<DeviceTest> weak_factory_;
142 };
143 } // namespace
144
145 TEST_F(DeviceTest, GetServices) {
146 EXPECT_CALL(*device_, IsGattServicesDiscoveryComplete())
147 .WillRepeatedly(Return(true));
148
149 base::RunLoop loop;
150 MakeGetServicesRequests(0, 1, Call::EXPECTED, loop.QuitClosure());
151 EXPECT_EQ(0, device_service_->GetPendingServiceRequestCountForTesting());
152
153 loop.Run();
154 }
155
156 TEST_F(DeviceTest, GetServicesNotDiscovered) {
157 EXPECT_CALL(*device_, IsGattServicesDiscoveryComplete())
158 .WillOnce(Return(false))
159 .WillOnce(Return(false))
160 .WillRepeatedly(Return(true));
161
162 base::RunLoop loop;
163
164 // Client: Sends multiple requests for services.
165 MakeGetServicesRequests(0, 2, Call::EXPECTED, loop.QuitWhenIdleClosure());
ortuno 2016/11/02 07:56:04 nit: I think scheib was proposing wrapping the Gat
mbrunson 2016/11/02 21:57:08 Hmm ok. I'll just unwrap them then.
166 EXPECT_EQ(2, device_service_->GetPendingServiceRequestCountForTesting());
ortuno 2016/11/02 07:56:04 I'm curious as to why you expose this function. Yo
mbrunson 2016/11/02 21:57:08 Yeah. I probably don't need it here. It was really
167
168 // Simulate: GattServicesDiscovered.
169 device_service_->GattServicesDiscovered(nullptr /* adapter */, device_.get());
170 EXPECT_EQ(0, device_service_->GetPendingServiceRequestCountForTesting());
171
172 // No more GetServices calls will complete.
173 device_service_->GattServicesDiscovered(nullptr /* adapter */, device_.get());
174
175 // Client: Sends more requests which run immediately.
176 MakeGetServicesRequests(2, 2, Call::EXPECTED, loop.QuitWhenIdleClosure());
177 EXPECT_EQ(0, device_service_->GetPendingServiceRequestCountForTesting());
178
179 // No more GetServices calls will complete.
180 device_service_->GattServicesDiscovered(nullptr /* adapter */, device_.get());
181
182 loop.Run();
183 }
184
185 TEST_F(DeviceTest, GetServicesLostConnectionWithPendingRequests) {
ortuno 2016/11/02 07:56:04 In theory the following destructor in Device shoul
mbrunson 2016/11/02 21:57:08 No. It doesn't crash. Let me make sure DCHECK is t
ortuno 2016/11/04 01:50:42 Where you able to get it to crash?
mbrunson 2016/11/04 02:47:06 No. I've tried multiple configurations and orders
186 EXPECT_CALL(*device_, IsGattServicesDiscoveryComplete())
187 .WillRepeatedly(Return(false));
188 // Client: Sends multiple requests for services.
189 base::RunLoop loop;
190 MakeGetServicesRequests(0, 2, Call::NOT_EXPECTED, loop.QuitClosure());
191 EXPECT_EQ(2, device_service_->GetPendingServiceRequestCountForTesting());
192
193 // Simulate connection loss.
194 device_->SetConnected(false);
195 device_service_->DeviceChanged(nullptr /* adapter */, device_.get());
196 expect_device_service_deleted_ = true;
197 }
198
199 TEST_F(DeviceTest, GetServicesForcedDisconnectionWithPendingRequests) {
200 EXPECT_CALL(*device_, IsGattServicesDiscoveryComplete())
201 .WillRepeatedly(Return(false));
202 // Client: Sends multiple requests for services.
203 base::RunLoop loop;
204 MakeGetServicesRequests(0, 2, Call::NOT_EXPECTED, loop.QuitClosure());
205 EXPECT_EQ(2, device_service_->GetPendingServiceRequestCountForTesting());
206
207 // Simulate connection loss.
208 device_service_->Disconnect();
209 expect_device_service_deleted_ = true;
210 }
211
212 TEST_F(DeviceTest, GetServicesPipeClosedWithPendingRequests) {
213 EXPECT_CALL(*device_, IsGattServicesDiscoveryComplete())
214 .WillRepeatedly(Return(false));
215 // Client: Sends multiple requests for services.
216 base::RunLoop loop;
217 MakeGetServicesRequests(0, 2, Call::NOT_EXPECTED, loop.QuitClosure());
218 EXPECT_EQ(2, device_service_->GetPendingServiceRequestCountForTesting());
219
220 // Simulate connection loss.
221 proxy_.reset();
222 expect_device_service_deleted_ = true;
223 }
224
225 } // namespace bluetooth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698