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

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: Use the Connect() utility function in more places Created 6 years, 3 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 // If |receive_callback| or |receive_error_callback| is non-NULL, it is filled
132 // with the appropriate callback from the socket's |Receive()| call.
133 void ConnectAndCaptureReceiveCallbacks(
Tim Song 2014/09/24 01:15:40 It might be more readable to just save these callb
Ilya Sherman 2014/09/26 02:22:47 Done.
134 MockBluetoothConnection* connection,
135 device::BluetoothSocket::ReceiveCompletionCallback* receive_callback,
136 device::BluetoothSocket::ReceiveErrorCompletionCallback*
137 receive_error_callback) {
138 EXPECT_EQ(Connection::DISCONNECTED, connection->status());
139
140 device::BluetoothDevice::ConnectToServiceCallback callback;
141 ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
142 EXPECT_CALL(*connection, SetStatusProxy(Connection::IN_PROGRESS));
143 EXPECT_CALL(*adapter_, AddObserver(connection));
144 EXPECT_CALL(*connection, ConnectToService(_, _, _, _))
145 .WillOnce(SaveArg<2>(&callback));
146 connection->Connect();
147 ASSERT_FALSE(callback.is_null());
148
149 device::BluetoothSocket::ReceiveCompletionCallback local_receive_callback;
150 device::BluetoothSocket::ReceiveErrorCompletionCallback
151 local_receive_error_callback;
152 EXPECT_CALL(*connection, SetStatusProxy(Connection::CONNECTED));
153 EXPECT_CALL(*socket_, Receive(_, _, _))
154 .WillOnce(DoAll(SaveArg<1>(&local_receive_callback),
155 SaveArg<2>(&local_receive_error_callback)));
156 callback.Run(socket_);
157
158 EXPECT_EQ(Connection::CONNECTED, connection->status());
159
160 if (receive_callback)
161 *receive_callback = local_receive_callback;
162 if (receive_error_callback)
163 *receive_error_callback = local_receive_error_callback;
164 }
165
166 // Transition the connection into a connected state.
167 void Connect(MockBluetoothConnection* connection) {
168 ConnectAndCaptureReceiveCallbacks(connection, NULL, NULL);
169 }
170
171 protected:
172 // Mocks used for verifying interactions with the Bluetooth subsystem.
173 scoped_refptr<device::MockBluetoothAdapter> adapter_;
174 NiceMock<device::MockBluetoothDevice> device_;
175 scoped_refptr<StrictMock<device::MockBluetoothSocket> > socket_;
176
177 device::BluetoothUUID uuid_;
178
179 private:
180 base::MessageLoop message_loop_;
181 };
182
183 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionWasInProgress) {
184 // Create an in-progress connection.
185 StrictMock<MockBluetoothConnection> connection;
186 BeginConnecting(&connection);
187
188 // A second call to Connect() should be ignored.
189 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
190 connection.Connect();
191
192 // The connection cleans up after itself upon destruction.
193 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
194 }
195
196 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionWasConnected) {
197 // Create a connected connection.
198 StrictMock<MockBluetoothConnection> connection;
199 Connect(&connection);
200
201 // A second call to Connect() should be ignored.
202 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
203 connection.Connect();
204
205 // The connection disconnects and unregisters as an observer upon destruction.
206 EXPECT_CALL(*socket_, Disconnect(_));
207 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
208 }
209
210 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_NoBluetoothAdapter) {
211 // Some platforms do not support Bluetooth. This test is only meaningful on
212 // those platforms.
213 adapter_ = NULL;
214 if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable())
215 return;
216
217 StrictMock<MockBluetoothConnection> connection;
218 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
219 connection.Connect();
220 }
221
222 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_DeviceMissing) {
223 StrictMock<MockBluetoothConnection> connection;
224
225 ON_CALL(*adapter_, GetDevice(_))
226 .WillByDefault(Return(static_cast<device::BluetoothDevice*>(NULL)));
227 EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
228 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
229 connection.Connect();
230 }
231
232 TEST_F(ProximityAuthBluetoothConnectionTest,
233 Connect_DeviceRemovedWhileConnecting) {
234 // Create an in-progress connection.
235 StrictMock<MockBluetoothConnection> connection;
236 BeginConnecting(&connection);
237
238 // Remove the device while the connection is in-progress. This should cause
239 // the connection to disconnect.
240 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
241 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
242 connection.DeviceRemoved(adapter_.get(), &device_);
243 }
244
245 TEST_F(ProximityAuthBluetoothConnectionTest,
246 Connect_OtherDeviceRemovedWhileConnecting) {
247 // Create an in-progress connection.
248 StrictMock<MockBluetoothConnection> connection;
249 BeginConnecting(&connection);
250
251 // Remove a device other than the one that is being connected to. This should
252 // not have any effect on the connection.
253 NiceMock<device::MockBluetoothDevice> other_device(
254 adapter_.get(), 0, kOtherDeviceName, kOtherBluetoothAddress, true, true);
255 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
256 connection.DeviceRemoved(adapter_.get(), &other_device);
257
258 // The connection removes itself as an observer when it is destroyed.
259 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
260 }
261
262 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionFails) {
263 StrictMock<MockBluetoothConnection> connection;
264
265 device::BluetoothDevice::ConnectToServiceErrorCallback error_callback;
266 ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
267 EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
268 EXPECT_CALL(*adapter_, AddObserver(&connection));
269 EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _))
270 .WillOnce(SaveArg<3>(&error_callback));
271 connection.Connect();
272 ASSERT_FALSE(error_callback.is_null());
273
274 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
275 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
276 error_callback.Run("super descriptive error message");
277 }
278
279 TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionSucceeds) {
280 StrictMock<MockBluetoothConnection> connection;
281 Connect(&connection);
282
283 // The connection disconnects and unregisters as an observer upon destruction.
284 EXPECT_CALL(*socket_, Disconnect(_));
285 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
286 }
287
288 TEST_F(ProximityAuthBluetoothConnectionTest,
289 Connect_ConnectionSucceeds_ThenDeviceRemoved) {
290 StrictMock<MockBluetoothConnection> connection;
291 Connect(&connection);
292
293 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
294 EXPECT_CALL(*socket_, Disconnect(_));
295 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
296 connection.DeviceRemoved(adapter_.get(), &device_);
297 }
298
299 TEST_F(ProximityAuthBluetoothConnectionTest,
300 Connect_ConnectionSucceeds_ReceiveData) {
301 StrictMock<MockBluetoothConnection> connection;
302 device::BluetoothSocket::ReceiveCompletionCallback receive_callback;
303 ConnectAndCaptureReceiveCallbacks(&connection, &receive_callback, NULL);
304 ASSERT_FALSE(receive_callback.is_null());
305
306 // Receive some data. Once complete, the connection should re-register to be
307 // ready receive more data.
308 scoped_refptr<net::IOBuffer> buffer = CreateReceiveBuffer();
309 EXPECT_CALL(
310 connection,
311 OnBytesReceived(std::string(kReceiveBufferContents, kReceiveBufferSize)));
312 EXPECT_CALL(*socket_, Receive(_, _, _));
313 receive_callback.Run(kReceiveBufferSize, buffer);
314 base::RunLoop run_loop;
315 run_loop.RunUntilIdle();
316
317 // The connection disconnects and unregisters as an observer upon destruction.
318 EXPECT_CALL(*socket_, Disconnect(_));
319 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
320 }
321
322 TEST_F(ProximityAuthBluetoothConnectionTest,
323 Connect_ConnectionSucceeds_ReceiveDataAfterReceiveError) {
324 StrictMock<MockBluetoothConnection> connection;
325 device::BluetoothSocket::ReceiveErrorCompletionCallback
326 receive_error_callback;
327 ConnectAndCaptureReceiveCallbacks(&connection, NULL, &receive_error_callback);
328 ASSERT_FALSE(receive_error_callback.is_null());
329
330 // Simulate an error while receiving data. The connection should re-register
331 // to be ready receive more data despite the error.
332 device::BluetoothSocket::ReceiveCompletionCallback receive_callback;
333 EXPECT_CALL(*socket_, Receive(_, _, _))
334 .WillOnce(SaveArg<1>(&receive_callback));
335 receive_error_callback.Run(device::BluetoothSocket::kSystemError,
336 "The system is down. They're taking over!");
337 base::RunLoop run_loop;
338 run_loop.RunUntilIdle();
339
340 // Receive some data.
341 scoped_refptr<net::IOBuffer> buffer = CreateReceiveBuffer();
342 EXPECT_CALL(
343 connection,
344 OnBytesReceived(std::string(kReceiveBufferContents, kReceiveBufferSize)));
345 EXPECT_CALL(*socket_, Receive(_, _, _));
346 receive_callback.Run(kReceiveBufferSize, buffer);
347 base::RunLoop run_loop2;
348 run_loop2.RunUntilIdle();
349
350 // The connection disconnects and unregisters as an observer upon destruction.
351 EXPECT_CALL(*socket_, Disconnect(_));
352 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
353 }
354
355 TEST_F(ProximityAuthBluetoothConnectionTest,
356 Disconnect_ConnectionWasAlreadyDisconnected) {
357 StrictMock<MockBluetoothConnection> connection;
358 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
359 connection.Disconnect();
360 }
361
362 TEST_F(ProximityAuthBluetoothConnectionTest,
363 Disconnect_ConnectionWasInProgress) {
364 // Create an in-progress connection.
365 StrictMock<MockBluetoothConnection> connection;
366 BeginConnecting(&connection);
367
368 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
369 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
370 connection.Disconnect();
371 }
372
373 TEST_F(ProximityAuthBluetoothConnectionTest,
374 Disconnect_ConnectionWasConnected) {
375 // Create a connected connection.
376 StrictMock<MockBluetoothConnection> connection;
377 Connect(&connection);
378
379 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
380 EXPECT_CALL(*socket_, Disconnect(_));
381 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
382 connection.Disconnect();
383 }
384
385 TEST_F(ProximityAuthBluetoothConnectionTest,
386 Connect_ThenDisconnectWhileInProgress_ThenBackingConnectionSucceeds) {
387 StrictMock<MockBluetoothConnection> connection;
388 device::BluetoothDevice::ConnectToServiceCallback callback;
389 ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
390 EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
391 EXPECT_CALL(*adapter_, AddObserver(&connection));
392 EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _))
393 .WillOnce(SaveArg<2>(&callback));
394 connection.Connect();
395 ASSERT_FALSE(callback.is_null());
396
397 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
398 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
399 connection.Disconnect();
400
401 EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
402 EXPECT_CALL(*socket_, Receive(_, _, _)).Times(0);
403 callback.Run(socket_);
404 }
405
406 TEST_F(ProximityAuthBluetoothConnectionTest,
407 SendMessage_SendsExpectedDataOverTheWire) {
408 // Create a connected connection.
409 StrictMock<MockBluetoothConnection> connection;
410 Connect(&connection);
411
412 scoped_refptr<net::IOBuffer> buffer;
413 scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
414 EXPECT_CALL(*socket_, Send(_, kSerializedMessageLength, _, _))
415 .WillOnce(SaveArg<0>(&buffer));
416 connection.SendMessage(wire_message.PassAs<WireMessage>());
417 ASSERT_TRUE(buffer.get());
418 EXPECT_EQ(kSerializedMessage,
419 std::string(buffer->data(), kSerializedMessageLength));
420
421 // The connection disconnects and unregisters as an observer upon destruction.
422 EXPECT_CALL(*socket_, Disconnect(_));
423 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
424 }
425
426 TEST_F(ProximityAuthBluetoothConnectionTest, SendMessage_Success) {
427 // Create a connected connection.
428 StrictMock<MockBluetoothConnection> connection;
429 Connect(&connection);
430
431 scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
432 // Ownership will be transfered below, so grab a reference here.
433 TestWireMessage* expected_wire_message = wire_message.get();
434
435 device::BluetoothSocket::SendCompletionCallback callback;
436 EXPECT_CALL(*socket_, Send(_, _, _, _)).WillOnce(SaveArg<2>(&callback));
437 connection.SendMessage(wire_message.PassAs<WireMessage>());
438 ASSERT_FALSE(callback.is_null());
439
440 EXPECT_CALL(connection, OnDidSendMessage(Ref(*expected_wire_message), true));
441 callback.Run(kSerializedMessageLength);
442
443 // The connection disconnects and unregisters as an observer upon destruction.
444 EXPECT_CALL(*socket_, Disconnect(_));
445 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
446 }
447
448 TEST_F(ProximityAuthBluetoothConnectionTest, SendMessage_Failure) {
449 // Create a connected connection.
450 StrictMock<MockBluetoothConnection> connection;
451 Connect(&connection);
452
453 scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
454 // Ownership will be transfered below, so grab a reference here.
455 TestWireMessage* expected_wire_message = wire_message.get();
456
457 device::BluetoothSocket::ErrorCompletionCallback error_callback;
458 EXPECT_CALL(*socket_, Send(_, _, _, _)).WillOnce(SaveArg<3>(&error_callback));
459 connection.SendMessage(wire_message.PassAs<WireMessage>());
460
461 ASSERT_FALSE(error_callback.is_null());
462 EXPECT_CALL(connection, OnDidSendMessage(Ref(*expected_wire_message), false));
463 EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
464 EXPECT_CALL(*socket_, Disconnect(_));
465 EXPECT_CALL(*adapter_, RemoveObserver(&connection));
466 error_callback.Run("The most helpful of error messages");
467 }
468
469 } // 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