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

Unified 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, 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/proximity_auth/bluetooth_connection.cc ('k') | components/proximity_auth/connection.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/proximity_auth/bluetooth_connection_unittest.cc
diff --git a/components/proximity_auth/bluetooth_connection_unittest.cc b/components/proximity_auth/bluetooth_connection_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bfa99e35eba2d035a28db781cb143845478f2d9d
--- /dev/null
+++ b/components/proximity_auth/bluetooth_connection_unittest.cc
@@ -0,0 +1,462 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/proximity_auth/bluetooth_connection.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/run_loop.h"
+#include "components/proximity_auth/remote_device.h"
+#include "components/proximity_auth/wire_message.h"
+#include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/test/mock_bluetooth_adapter.h"
+#include "device/bluetooth/test/mock_bluetooth_device.h"
+#include "device/bluetooth/test/mock_bluetooth_socket.h"
+#include "net/base/io_buffer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::NiceMock;
+using testing::Ref;
+using testing::Return;
+using testing::SaveArg;
+using testing::StrictMock;
+
+namespace proximity_auth {
+namespace {
+
+const char kDeviceName[] = "Device name";
+const char kOtherDeviceName[] = "Other device name";
+
+const char kBluetoothAddress[] = "11:22:33:44:55:66";
+const char kOtherBluetoothAddress[] = "AA:BB:CC:DD:EE:FF";
+
+const char kSerializedMessage[] = "Yarrr, this be a serialized message. Yarr!";
+const int kSerializedMessageLength = strlen(kSerializedMessage);
+
+const char kUuid[] = "DEADBEEF-CAFE-FEED-FOOD-D15EA5EBEEF";
+
+const RemoteDevice kRemoteDevice = {kDeviceName, kBluetoothAddress};
+
+const int kReceiveBufferSize = 6;
+const char kReceiveBufferContents[] = "bytes";
+
+// Create a buffer for testing received data.
+scoped_refptr<net::IOBuffer> CreateReceiveBuffer() {
+ scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kReceiveBufferSize);
+ memcpy(buffer->data(), kReceiveBufferContents, kReceiveBufferSize);
+ return buffer;
+}
+
+class MockBluetoothConnection : public BluetoothConnection {
+ public:
+ MockBluetoothConnection()
+ : BluetoothConnection(kRemoteDevice, device::BluetoothUUID(kUuid)) {}
+
+ // Bluetooth dependencies.
+ typedef device::BluetoothDevice::ConnectToServiceCallback
+ ConnectToServiceCallback;
+ typedef device::BluetoothDevice::ConnectToServiceErrorCallback
+ ConnectToServiceErrorCallback;
+ MOCK_METHOD4(ConnectToService,
+ void(device::BluetoothDevice* device,
+ const device::BluetoothUUID& uuid,
+ const ConnectToServiceCallback& callback,
+ const ConnectToServiceErrorCallback& error_callback));
+
+ // Calls back into the parent Connection class.
+ MOCK_METHOD1(SetStatusProxy, void(Status status));
+ MOCK_METHOD1(OnBytesReceived, void(const std::string& bytes));
+ MOCK_METHOD2(OnDidSendMessage,
+ void(const WireMessage& message, bool success));
+
+ virtual void SetStatus(Status status) OVERRIDE {
+ SetStatusProxy(status);
+ BluetoothConnection::SetStatus(status);
+ }
+
+ using BluetoothConnection::status;
+ using BluetoothConnection::Connect;
+ using BluetoothConnection::DeviceRemoved;
+ using BluetoothConnection::Disconnect;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockBluetoothConnection);
+};
+
+class TestWireMessage : public WireMessage {
+ public:
+ TestWireMessage() : WireMessage("permit id", "payload") {}
+ virtual ~TestWireMessage() {}
+
+ virtual std::string Serialize() const OVERRIDE { return kSerializedMessage; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestWireMessage);
+};
+
+} // namespace
+
+class ProximityAuthBluetoothConnectionTest : public testing::Test {
+ public:
+ ProximityAuthBluetoothConnectionTest()
+ : adapter_(new device::MockBluetoothAdapter),
+ device_(adapter_.get(), 0, kDeviceName, kBluetoothAddress, true, true),
+ socket_(new StrictMock<device::MockBluetoothSocket>),
+ uuid_(kUuid) {
+ device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
+
+ // Suppress uninteresting Gmock call warnings.
+ EXPECT_CALL(*adapter_, GetDevice(_)).Times(AnyNumber());
+ }
+
+ // Transition the connection into an in-progress state.
+ void BeginConnecting(MockBluetoothConnection* connection) {
+ EXPECT_EQ(Connection::DISCONNECTED, connection->status());
+
+ ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
+ EXPECT_CALL(*connection, SetStatusProxy(Connection::IN_PROGRESS));
+ EXPECT_CALL(*adapter_, AddObserver(connection));
+ EXPECT_CALL(*connection, ConnectToService(&device_, uuid_, _, _));
+ connection->Connect();
+
+ EXPECT_EQ(Connection::IN_PROGRESS, connection->status());
+ }
+
+ // Transition the connection into a connected state.
+ // Saves the success and error callbacks passed into OnReceive(), which can be
+ // accessed via receive_callback() and receive_success_callback().
+ void Connect(MockBluetoothConnection* connection) {
+ EXPECT_EQ(Connection::DISCONNECTED, connection->status());
+
+ device::BluetoothDevice::ConnectToServiceCallback callback;
+ ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
+ EXPECT_CALL(*connection, SetStatusProxy(Connection::IN_PROGRESS));
+ EXPECT_CALL(*adapter_, AddObserver(connection));
+ EXPECT_CALL(*connection, ConnectToService(_, _, _, _))
+ .WillOnce(SaveArg<2>(&callback));
+ connection->Connect();
+ ASSERT_FALSE(callback.is_null());
+
+ EXPECT_CALL(*connection, SetStatusProxy(Connection::CONNECTED));
+ EXPECT_CALL(*socket_, Receive(_, _, _))
+ .WillOnce(DoAll(SaveArg<1>(&receive_callback_),
+ SaveArg<2>(&receive_error_callback_)));
+ callback.Run(socket_);
+
+ EXPECT_EQ(Connection::CONNECTED, connection->status());
+ }
+
+ device::BluetoothSocket::ReceiveCompletionCallback* receive_callback() {
+ return &receive_callback_;
+ }
+ device::BluetoothSocket::ReceiveErrorCompletionCallback*
+ receive_error_callback() {
+ return &receive_error_callback_;
+ }
+
+ protected:
+ // Mocks used for verifying interactions with the Bluetooth subsystem.
+ scoped_refptr<device::MockBluetoothAdapter> adapter_;
+ NiceMock<device::MockBluetoothDevice> device_;
+ scoped_refptr<StrictMock<device::MockBluetoothSocket>> socket_;
+
+ device::BluetoothUUID uuid_;
+
+ private:
+ base::MessageLoop message_loop_;
+
+ device::BluetoothSocket::ReceiveCompletionCallback receive_callback_;
+ device::BluetoothSocket::ReceiveErrorCompletionCallback
+ receive_error_callback_;
+};
+
+TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionWasInProgress) {
+ // Create an in-progress connection.
+ StrictMock<MockBluetoothConnection> connection;
+ BeginConnecting(&connection);
+
+ // A second call to Connect() should be ignored.
+ EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
+ connection.Connect();
+
+ // The connection cleans up after itself upon destruction.
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionWasConnected) {
+ // Create a connected connection.
+ StrictMock<MockBluetoothConnection> connection;
+ Connect(&connection);
+
+ // A second call to Connect() should be ignored.
+ EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
+ connection.Connect();
+
+ // The connection disconnects and unregisters as an observer upon destruction.
+ EXPECT_CALL(*socket_, Disconnect(_));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest, Connect_NoBluetoothAdapter) {
+ // Some platforms do not support Bluetooth. This test is only meaningful on
+ // those platforms.
+ adapter_ = NULL;
+ if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable())
+ return;
+
+ StrictMock<MockBluetoothConnection> connection;
+ EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
+ connection.Connect();
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest, Connect_DeviceMissing) {
+ StrictMock<MockBluetoothConnection> connection;
+
+ ON_CALL(*adapter_, GetDevice(_))
+ .WillByDefault(Return(static_cast<device::BluetoothDevice*>(NULL)));
+ EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
+ EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
+ connection.Connect();
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest,
+ Connect_DeviceRemovedWhileConnecting) {
+ // Create an in-progress connection.
+ StrictMock<MockBluetoothConnection> connection;
+ BeginConnecting(&connection);
+
+ // Remove the device while the connection is in-progress. This should cause
+ // the connection to disconnect.
+ EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+ connection.DeviceRemoved(adapter_.get(), &device_);
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest,
+ Connect_OtherDeviceRemovedWhileConnecting) {
+ // Create an in-progress connection.
+ StrictMock<MockBluetoothConnection> connection;
+ BeginConnecting(&connection);
+
+ // Remove a device other than the one that is being connected to. This should
+ // not have any effect on the connection.
+ NiceMock<device::MockBluetoothDevice> other_device(
+ adapter_.get(), 0, kOtherDeviceName, kOtherBluetoothAddress, true, true);
+ EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
+ connection.DeviceRemoved(adapter_.get(), &other_device);
+
+ // The connection removes itself as an observer when it is destroyed.
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionFails) {
+ StrictMock<MockBluetoothConnection> connection;
+
+ device::BluetoothDevice::ConnectToServiceErrorCallback error_callback;
+ ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
+ EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
+ EXPECT_CALL(*adapter_, AddObserver(&connection));
+ EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _))
+ .WillOnce(SaveArg<3>(&error_callback));
+ connection.Connect();
+ ASSERT_FALSE(error_callback.is_null());
+
+ EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+ error_callback.Run("super descriptive error message");
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionSucceeds) {
+ StrictMock<MockBluetoothConnection> connection;
+ Connect(&connection);
+
+ // The connection disconnects and unregisters as an observer upon destruction.
+ EXPECT_CALL(*socket_, Disconnect(_));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest,
+ Connect_ConnectionSucceeds_ThenDeviceRemoved) {
+ StrictMock<MockBluetoothConnection> connection;
+ Connect(&connection);
+
+ EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
+ EXPECT_CALL(*socket_, Disconnect(_));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+ connection.DeviceRemoved(adapter_.get(), &device_);
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest,
+ Connect_ConnectionSucceeds_ReceiveData) {
+ StrictMock<MockBluetoothConnection> connection;
+ Connect(&connection);
+ ASSERT_TRUE(receive_callback() && !receive_callback()->is_null());
+
+ // Receive some data. Once complete, the connection should re-register to be
+ // ready receive more data.
+ scoped_refptr<net::IOBuffer> buffer = CreateReceiveBuffer();
+ EXPECT_CALL(
+ connection,
+ OnBytesReceived(std::string(kReceiveBufferContents, kReceiveBufferSize)));
+ EXPECT_CALL(*socket_, Receive(_, _, _));
+ receive_callback()->Run(kReceiveBufferSize, buffer);
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+
+ // The connection disconnects and unregisters as an observer upon destruction.
+ EXPECT_CALL(*socket_, Disconnect(_));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest,
+ Connect_ConnectionSucceeds_ReceiveDataAfterReceiveError) {
+ StrictMock<MockBluetoothConnection> connection;
+ Connect(&connection);
+ ASSERT_TRUE(receive_error_callback() && !receive_error_callback()->is_null());
+
+ // Simulate an error while receiving data. The connection should re-register
+ // to be ready receive more data despite the error.
+ device::BluetoothSocket::ReceiveCompletionCallback receive_callback;
+ EXPECT_CALL(*socket_, Receive(_, _, _))
+ .WillOnce(SaveArg<1>(&receive_callback));
+ receive_error_callback()->Run(device::BluetoothSocket::kSystemError,
+ "The system is down. They're taking over!");
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+ ASSERT_FALSE(receive_callback.is_null());
+
+ // Receive some data.
+ scoped_refptr<net::IOBuffer> buffer = CreateReceiveBuffer();
+ EXPECT_CALL(
+ connection,
+ OnBytesReceived(std::string(kReceiveBufferContents, kReceiveBufferSize)));
+ EXPECT_CALL(*socket_, Receive(_, _, _));
+ receive_callback.Run(kReceiveBufferSize, buffer);
+ base::RunLoop run_loop2;
+ run_loop2.RunUntilIdle();
+
+ // The connection disconnects and unregisters as an observer upon destruction.
+ EXPECT_CALL(*socket_, Disconnect(_));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest,
+ Disconnect_ConnectionWasAlreadyDisconnected) {
+ StrictMock<MockBluetoothConnection> connection;
+ EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
+ connection.Disconnect();
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest,
+ Disconnect_ConnectionWasInProgress) {
+ // Create an in-progress connection.
+ StrictMock<MockBluetoothConnection> connection;
+ BeginConnecting(&connection);
+
+ EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+ connection.Disconnect();
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest,
+ Disconnect_ConnectionWasConnected) {
+ // Create a connected connection.
+ StrictMock<MockBluetoothConnection> connection;
+ Connect(&connection);
+
+ EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
+ EXPECT_CALL(*socket_, Disconnect(_));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+ connection.Disconnect();
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest,
+ Connect_ThenDisconnectWhileInProgress_ThenBackingConnectionSucceeds) {
+ StrictMock<MockBluetoothConnection> connection;
+ device::BluetoothDevice::ConnectToServiceCallback callback;
+ ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
+ EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
+ EXPECT_CALL(*adapter_, AddObserver(&connection));
+ EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _))
+ .WillOnce(SaveArg<2>(&callback));
+ connection.Connect();
+ ASSERT_FALSE(callback.is_null());
+
+ EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+ connection.Disconnect();
+
+ EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
+ EXPECT_CALL(*socket_, Receive(_, _, _)).Times(0);
+ callback.Run(socket_);
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest,
+ SendMessage_SendsExpectedDataOverTheWire) {
+ // Create a connected connection.
+ StrictMock<MockBluetoothConnection> connection;
+ Connect(&connection);
+
+ scoped_refptr<net::IOBuffer> buffer;
+ scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
+ EXPECT_CALL(*socket_, Send(_, kSerializedMessageLength, _, _))
+ .WillOnce(SaveArg<0>(&buffer));
+ connection.SendMessage(wire_message.PassAs<WireMessage>());
+ ASSERT_TRUE(buffer.get());
+ EXPECT_EQ(kSerializedMessage,
+ std::string(buffer->data(), kSerializedMessageLength));
+
+ // The connection disconnects and unregisters as an observer upon destruction.
+ EXPECT_CALL(*socket_, Disconnect(_));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest, SendMessage_Success) {
+ // Create a connected connection.
+ StrictMock<MockBluetoothConnection> connection;
+ Connect(&connection);
+
+ scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
+ // Ownership will be transfered below, so grab a reference here.
+ TestWireMessage* expected_wire_message = wire_message.get();
+
+ device::BluetoothSocket::SendCompletionCallback callback;
+ EXPECT_CALL(*socket_, Send(_, _, _, _)).WillOnce(SaveArg<2>(&callback));
+ connection.SendMessage(wire_message.PassAs<WireMessage>());
+ ASSERT_FALSE(callback.is_null());
+
+ EXPECT_CALL(connection, OnDidSendMessage(Ref(*expected_wire_message), true));
+ callback.Run(kSerializedMessageLength);
+
+ // The connection disconnects and unregisters as an observer upon destruction.
+ EXPECT_CALL(*socket_, Disconnect(_));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+}
+
+TEST_F(ProximityAuthBluetoothConnectionTest, SendMessage_Failure) {
+ // Create a connected connection.
+ StrictMock<MockBluetoothConnection> connection;
+ Connect(&connection);
+
+ scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
+ // Ownership will be transfered below, so grab a reference here.
+ TestWireMessage* expected_wire_message = wire_message.get();
+
+ device::BluetoothSocket::ErrorCompletionCallback error_callback;
+ EXPECT_CALL(*socket_, Send(_, _, _, _)).WillOnce(SaveArg<3>(&error_callback));
+ connection.SendMessage(wire_message.PassAs<WireMessage>());
+
+ ASSERT_FALSE(error_callback.is_null());
+ EXPECT_CALL(connection, OnDidSendMessage(Ref(*expected_wire_message), false));
+ EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
+ EXPECT_CALL(*socket_, Disconnect(_));
+ EXPECT_CALL(*adapter_, RemoveObserver(&connection));
+ error_callback.Run("The most helpful of error messages");
+}
+
+} // namespace proximity_auth
« 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