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

Side by Side Diff: components/proximity_auth/bluetooth_connection_unittest.cc

Issue 585743004: [Easy Unlock] Port the BluetoothConnection class to native code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Save references to OnReceive() callbacks Created 6 years, 2 months 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 2014 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 "components/proximity_auth/bluetooth_connection.h"
6
7 #include "base/message_loop/message_loop.h"
8 #include "base/numerics/safe_conversions.h"
9 #include "base/run_loop.h"
10 #include "components/proximity_auth/remote_device.h"
11 #include "components/proximity_auth/wire_message.h"
12 #include "device/bluetooth/bluetooth_adapter_factory.h"
13 #include "device/bluetooth/bluetooth_uuid.h"
14 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
15 #include "device/bluetooth/test/mock_bluetooth_device.h"
16 #include "device/bluetooth/test/mock_bluetooth_socket.h"
17 #include "net/base/io_buffer.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 using testing::_;
22 using testing::AnyNumber;
23 using testing::NiceMock;
24 using testing::Ref;
25 using testing::Return;
26 using testing::SaveArg;
27 using testing::StrictMock;
28
29 namespace proximity_auth {
30 namespace {
31
32 const char kDeviceName[] = "Device name";
33 const char kOtherDeviceName[] = "Other device name";
34
35 const char kBluetoothAddress[] = "11:22:33:44:55:66";
36 const char kOtherBluetoothAddress[] = "AA:BB:CC:DD:EE:FF";
37
38 const char kSerializedMessage[] = "Yarrr, this be a serialized message. Yarr!";
39 const int kSerializedMessageLength = strlen(kSerializedMessage);
40
41 const char kUuid[] = "DEADBEEF-CAFE-FEED-FOOD-D15EA5EBEEF";
42
43 const RemoteDevice kRemoteDevice = {kDeviceName, kBluetoothAddress};
44
45 const int kReceiveBufferSize = 6;
46 const char kReceiveBufferContents[] = "bytes";
47
48 // Create a buffer for testing received data.
49 scoped_refptr<net::IOBuffer> CreateReceiveBuffer() {
50 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kReceiveBufferSize);
51 memcpy(buffer->data(), kReceiveBufferContents, kReceiveBufferSize);
52 return buffer;
53 }
54
55 class MockBluetoothConnection : public BluetoothConnection {
56 public:
57 MockBluetoothConnection()
58 : BluetoothConnection(kRemoteDevice, device::BluetoothUUID(kUuid)) {}
59
60 // Bluetooth dependencies.
61 typedef device::BluetoothDevice::ConnectToServiceCallback
62 ConnectToServiceCallback;
63 typedef device::BluetoothDevice::ConnectToServiceErrorCallback
64 ConnectToServiceErrorCallback;
65 MOCK_METHOD4(ConnectToService,
66 void(device::BluetoothDevice* device,
67 const device::BluetoothUUID& uuid,
68 const ConnectToServiceCallback& callback,
69 const ConnectToServiceErrorCallback& error_callback));
70
71 // Calls back into the parent Connection class.
72 MOCK_METHOD1(SetStatusProxy, void(Status status));
73 MOCK_METHOD1(OnBytesReceived, void(const std::string& bytes));
74 MOCK_METHOD2(OnDidSendMessage,
75 void(const WireMessage& message, bool success));
76
77 virtual void SetStatus(Status status) OVERRIDE {
78 SetStatusProxy(status);
79 BluetoothConnection::SetStatus(status);
80 }
81
82 using BluetoothConnection::status;
83 using BluetoothConnection::Connect;
84 using BluetoothConnection::DeviceRemoved;
85 using BluetoothConnection::Disconnect;
86
87 private:
88 DISALLOW_COPY_AND_ASSIGN(MockBluetoothConnection);
89 };
90
91 class TestWireMessage : public WireMessage {
92 public:
93 TestWireMessage() : WireMessage("permit id", "payload") {}
94 virtual ~TestWireMessage() {}
95
96 virtual std::string Serialize() const OVERRIDE { return kSerializedMessage; }
97
98 private:
99 DISALLOW_COPY_AND_ASSIGN(TestWireMessage);
100 };
101
102 } // namespace
103
104 class ProximityAuthBluetoothConnectionTest : public testing::Test {
105 public:
106 ProximityAuthBluetoothConnectionTest()
107 : adapter_(new device::MockBluetoothAdapter),
108 device_(adapter_.get(), 0, kDeviceName, kBluetoothAddress, true, true),
109 socket_(new StrictMock<device::MockBluetoothSocket>),
110 uuid_(kUuid) {
111 device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
112
113 // Suppress uninteresting Gmock call warnings.
114 EXPECT_CALL(*adapter_, GetDevice(_)).Times(AnyNumber());
115 }
116
117 // Transition the connection into an in-progress state.
118 void BeginConnecting(MockBluetoothConnection* connection) {
119 EXPECT_EQ(Connection::DISCONNECTED, connection->status());
120
121 ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
122 EXPECT_CALL(*connection, SetStatusProxy(Connection::IN_PROGRESS));
123 EXPECT_CALL(*adapter_, AddObserver(connection));
124 EXPECT_CALL(*connection, ConnectToService(&device_, uuid_, _, _));
125 connection->Connect();
126
127 EXPECT_EQ(Connection::IN_PROGRESS, connection->status());
128 }
129
130 // Transition the connection into a connected state.
131 // Saves the success and error callbacks passed into OnReceive(), which can be
132 // accessed via receive_callback() and receive_success_callback().
133 void Connect(MockBluetoothConnection* connection) {
134 EXPECT_EQ(Connection::DISCONNECTED, connection->status());
135
136 device::BluetoothDevice::ConnectToServiceCallback callback;
137 ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
138 EXPECT_CALL(*connection, SetStatusProxy(Connection::IN_PROGRESS));
139 EXPECT_CALL(*adapter_, AddObserver(connection));
140 EXPECT_CALL(*connection, ConnectToService(_, _, _, _))
141 .WillOnce(SaveArg<2>(&callback));
142 connection->Connect();
143 ASSERT_FALSE(callback.is_null());
144
145 EXPECT_CALL(*connection, SetStatusProxy(Connection::CONNECTED));
146 EXPECT_CALL(*socket_, Receive(_, _, _))
147 .WillOnce(DoAll(SaveArg<1>(&receive_callback_),
148 SaveArg<2>(&receive_error_callback_)));
149 callback.Run(socket_);
150
151 EXPECT_EQ(Connection::CONNECTED, connection->status());
152 }
153
154 device::BluetoothSocket::ReceiveCompletionCallback* receive_callback() {
155 return &receive_callback_;
156 }
157 device::BluetoothSocket::ReceiveErrorCompletionCallback*
158 receive_error_callback() {
159 return &receive_error_callback_;
160 }
161
162 protected:
163 // Mocks used for verifying interactions with the Bluetooth subsystem.
164 scoped_refptr<device::MockBluetoothAdapter> adapter_;
165 NiceMock<device::MockBluetoothDevice> device_;
166 scoped_refptr<StrictMock<device::MockBluetoothSocket>> socket_;
167
168 device::BluetoothUUID uuid_;
169
170 private:
171 base::MessageLoop message_loop_;
172
173 device::BluetoothSocket::ReceiveCompletionCallback receive_callback_;
174 device::BluetoothSocket::ReceiveErrorCompletionCallback
175 receive_error_callback_;
176 };
177
178 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionWasInProgress) {
179 // Create an in-progress connection.
180 StrictMock<MockBluetoothConnection> connection;
181 BeginConnecting(&connection);
182
183 // A second call to Connect() should be ignored.
184 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
185 connection.Connect();
186
187 // The connection cleans up after itself upon destruction.
188 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
189 }
190
191 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionWasConnected) {
192 // Create a connected connection.
193 StrictMock<MockBluetoothConnection> connection;
194 Connect(&connection);
195
196 // A second call to Connect() should be ignored.
197 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
198 connection.Connect();
199
200 // The connection disconnects and unregisters as an observer upon destruction.
201 EXPECT_CALL(*socket_, Disconnect(_));
202 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
203 }
204
205 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_NoBluetoothAdapter) {
206 // Some platforms do not support Bluetooth. This test is only meaningful on
207 // those platforms.
208 adapter_ = NULL;
209 if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable())
210 return;
211
212 StrictMock<MockBluetoothConnection> connection;
213 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
214 connection.Connect();
215 }
216
217 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_DeviceMissing) {
218 StrictMock<MockBluetoothConnection> connection;
219
220 ON_CALL(*adapter_, GetDevice(_))
221 .WillByDefault(Return(static_cast<device::BluetoothDevice*>(NULL)));
222 EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
223 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
224 connection.Connect();
225 }
226
227 TEST_F(ProximityAuthBluetoothConnectionTest,
228 Connect_DeviceRemovedWhileConnecting) {
229 // Create an in-progress connection.
230 StrictMock<MockBluetoothConnection> connection;
231 BeginConnecting(&connection);
232
233 // Remove the device while the connection is in-progress. This should cause
234 // the connection to disconnect.
235 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
236 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
237 connection.DeviceRemoved(adapter_.get(), &device_);
238 }
239
240 TEST_F(ProximityAuthBluetoothConnectionTest,
241 Connect_OtherDeviceRemovedWhileConnecting) {
242 // Create an in-progress connection.
243 StrictMock<MockBluetoothConnection> connection;
244 BeginConnecting(&connection);
245
246 // Remove a device other than the one that is being connected to. This should
247 // not have any effect on the connection.
248 NiceMock<device::MockBluetoothDevice> other_device(
249 adapter_.get(), 0, kOtherDeviceName, kOtherBluetoothAddress, true, true);
250 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
251 connection.DeviceRemoved(adapter_.get(), &other_device);
252
253 // The connection removes itself as an observer when it is destroyed.
254 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
255 }
256
257 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionFails) {
258 StrictMock<MockBluetoothConnection> connection;
259
260 device::BluetoothDevice::ConnectToServiceErrorCallback error_callback;
261 ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
262 EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
263 EXPECT_CALL(*adapter_, AddObserver(&connection));
264 EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _))
265 .WillOnce(SaveArg<3>(&error_callback));
266 connection.Connect();
267 ASSERT_FALSE(error_callback.is_null());
268
269 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
270 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
271 error_callback.Run("super descriptive error message");
272 }
273
274 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionSucceeds) {
275 StrictMock<MockBluetoothConnection> connection;
276 Connect(&connection);
277
278 // The connection disconnects and unregisters as an observer upon destruction.
279 EXPECT_CALL(*socket_, Disconnect(_));
280 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
281 }
282
283 TEST_F(ProximityAuthBluetoothConnectionTest,
284 Connect_ConnectionSucceeds_ThenDeviceRemoved) {
285 StrictMock<MockBluetoothConnection> connection;
286 Connect(&connection);
287
288 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
289 EXPECT_CALL(*socket_, Disconnect(_));
290 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
291 connection.DeviceRemoved(adapter_.get(), &device_);
292 }
293
294 TEST_F(ProximityAuthBluetoothConnectionTest,
295 Connect_ConnectionSucceeds_ReceiveData) {
296 StrictMock<MockBluetoothConnection> connection;
297 Connect(&connection);
298 ASSERT_TRUE(receive_callback() && !receive_callback()->is_null());
299
300 // Receive some data. Once complete, the connection should re-register to be
301 // ready receive more data.
302 scoped_refptr<net::IOBuffer> buffer = CreateReceiveBuffer();
303 EXPECT_CALL(
304 connection,
305 OnBytesReceived(std::string(kReceiveBufferContents, kReceiveBufferSize)));
306 EXPECT_CALL(*socket_, Receive(_, _, _));
307 receive_callback()->Run(kReceiveBufferSize, buffer);
308 base::RunLoop run_loop;
309 run_loop.RunUntilIdle();
310
311 // The connection disconnects and unregisters as an observer upon destruction.
312 EXPECT_CALL(*socket_, Disconnect(_));
313 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
314 }
315
316 TEST_F(ProximityAuthBluetoothConnectionTest,
317 Connect_ConnectionSucceeds_ReceiveDataAfterReceiveError) {
318 StrictMock<MockBluetoothConnection> connection;
319 Connect(&connection);
320 ASSERT_TRUE(receive_error_callback() && !receive_error_callback()->is_null());
321
322 // Simulate an error while receiving data. The connection should re-register
323 // to be ready receive more data despite the error.
324 device::BluetoothSocket::ReceiveCompletionCallback receive_callback;
325 EXPECT_CALL(*socket_, Receive(_, _, _))
326 .WillOnce(SaveArg<1>(&receive_callback));
327 receive_error_callback()->Run(device::BluetoothSocket::kSystemError,
328 "The system is down. They're taking over!");
329 base::RunLoop run_loop;
330 run_loop.RunUntilIdle();
331 ASSERT_FALSE(receive_callback.is_null());
332
333 // Receive some data.
334 scoped_refptr<net::IOBuffer> buffer = CreateReceiveBuffer();
335 EXPECT_CALL(
336 connection,
337 OnBytesReceived(std::string(kReceiveBufferContents, kReceiveBufferSize)));
338 EXPECT_CALL(*socket_, Receive(_, _, _));
339 receive_callback.Run(kReceiveBufferSize, buffer);
340 base::RunLoop run_loop2;
341 run_loop2.RunUntilIdle();
342
343 // The connection disconnects and unregisters as an observer upon destruction.
344 EXPECT_CALL(*socket_, Disconnect(_));
345 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
346 }
347
348 TEST_F(ProximityAuthBluetoothConnectionTest,
349 Disconnect_ConnectionWasAlreadyDisconnected) {
350 StrictMock<MockBluetoothConnection> connection;
351 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
352 connection.Disconnect();
353 }
354
355 TEST_F(ProximityAuthBluetoothConnectionTest,
356 Disconnect_ConnectionWasInProgress) {
357 // Create an in-progress connection.
358 StrictMock<MockBluetoothConnection> connection;
359 BeginConnecting(&connection);
360
361 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
362 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
363 connection.Disconnect();
364 }
365
366 TEST_F(ProximityAuthBluetoothConnectionTest,
367 Disconnect_ConnectionWasConnected) {
368 // Create a connected connection.
369 StrictMock<MockBluetoothConnection> connection;
370 Connect(&connection);
371
372 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
373 EXPECT_CALL(*socket_, Disconnect(_));
374 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
375 connection.Disconnect();
376 }
377
378 TEST_F(ProximityAuthBluetoothConnectionTest,
379 Connect_ThenDisconnectWhileInProgress_ThenBackingConnectionSucceeds) {
380 StrictMock<MockBluetoothConnection> connection;
381 device::BluetoothDevice::ConnectToServiceCallback callback;
382 ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
383 EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
384 EXPECT_CALL(*adapter_, AddObserver(&connection));
385 EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _))
386 .WillOnce(SaveArg<2>(&callback));
387 connection.Connect();
388 ASSERT_FALSE(callback.is_null());
389
390 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
391 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
392 connection.Disconnect();
393
394 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
395 EXPECT_CALL(*socket_, Receive(_, _, _)).Times(0);
396 callback.Run(socket_);
397 }
398
399 TEST_F(ProximityAuthBluetoothConnectionTest,
400 SendMessage_SendsExpectedDataOverTheWire) {
401 // Create a connected connection.
402 StrictMock<MockBluetoothConnection> connection;
403 Connect(&connection);
404
405 scoped_refptr<net::IOBuffer> buffer;
406 scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
407 EXPECT_CALL(*socket_, Send(_, kSerializedMessageLength, _, _))
408 .WillOnce(SaveArg<0>(&buffer));
409 connection.SendMessage(wire_message.PassAs<WireMessage>());
410 ASSERT_TRUE(buffer.get());
411 EXPECT_EQ(kSerializedMessage,
412 std::string(buffer->data(), kSerializedMessageLength));
413
414 // The connection disconnects and unregisters as an observer upon destruction.
415 EXPECT_CALL(*socket_, Disconnect(_));
416 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
417 }
418
419 TEST_F(ProximityAuthBluetoothConnectionTest, SendMessage_Success) {
420 // Create a connected connection.
421 StrictMock<MockBluetoothConnection> connection;
422 Connect(&connection);
423
424 scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
425 // Ownership will be transfered below, so grab a reference here.
426 TestWireMessage* expected_wire_message = wire_message.get();
427
428 device::BluetoothSocket::SendCompletionCallback callback;
429 EXPECT_CALL(*socket_, Send(_, _, _, _)).WillOnce(SaveArg<2>(&callback));
430 connection.SendMessage(wire_message.PassAs<WireMessage>());
431 ASSERT_FALSE(callback.is_null());
432
433 EXPECT_CALL(connection, OnDidSendMessage(Ref(*expected_wire_message), true));
434 callback.Run(kSerializedMessageLength);
435
436 // The connection disconnects and unregisters as an observer upon destruction.
437 EXPECT_CALL(*socket_, Disconnect(_));
438 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
439 }
440
441 TEST_F(ProximityAuthBluetoothConnectionTest, SendMessage_Failure) {
442 // Create a connected connection.
443 StrictMock<MockBluetoothConnection> connection;
444 Connect(&connection);
445
446 scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
447 // Ownership will be transfered below, so grab a reference here.
448 TestWireMessage* expected_wire_message = wire_message.get();
449
450 device::BluetoothSocket::ErrorCompletionCallback error_callback;
451 EXPECT_CALL(*socket_, Send(_, _, _, _)).WillOnce(SaveArg<3>(&error_callback));
452 connection.SendMessage(wire_message.PassAs<WireMessage>());
453
454 ASSERT_FALSE(error_callback.is_null());
455 EXPECT_CALL(connection, OnDidSendMessage(Ref(*expected_wire_message), false));
456 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
457 EXPECT_CALL(*socket_, Disconnect(_));
458 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
459 error_callback.Run("The most helpful of error messages");
460 }
461
462 } // namespace proximity_auth
OLDNEW
« no previous file with comments | « components/proximity_auth/bluetooth_connection.cc ('k') | components/proximity_auth/connection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698