| Index: components/proximity_auth/ble/bluetooth_low_energy_connection_finder_unittest.cc
|
| diff --git a/components/proximity_auth/ble/bluetooth_low_energy_connection_finder_unittest.cc b/components/proximity_auth/ble/bluetooth_low_energy_connection_finder_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8cf50186afa438f57a063d1ac9e3be969250b10a
|
| --- /dev/null
|
| +++ b/components/proximity_auth/ble/bluetooth_low_energy_connection_finder_unittest.cc
|
| @@ -0,0 +1,325 @@
|
| +// Copyright 2015 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/ble/bluetooth_low_energy_connection_finder.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/time/time.h"
|
| +#include "components/proximity_auth/connection.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_discovery_session.h"
|
| +#include "device/bluetooth/test/mock_bluetooth_gatt_connection.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using testing::_;
|
| +using testing::AtLeast;
|
| +using testing::NiceMock;
|
| +using testing::Return;
|
| +using testing::StrictMock;
|
| +using testing::SaveArg;
|
| +
|
| +namespace proximity_auth {
|
| +namespace {
|
| +
|
| +const char kDeviceName[] = "Device name";
|
| +const char kBluetoothAddress[] = "11:22:33:44:55:66";
|
| +const RemoteDevice kRemoteDevice = {kDeviceName, kBluetoothAddress};
|
| +
|
| +const char kServiceUUID[] = "1EADBEEF-CAFE-FEED-FOOD-D15EA5EBEEEF";
|
| +const char kToPeripheralCharUUID[] = "2EADBEEF-CAFE-FEED-FOOD-D15EA5EBEEEF";
|
| +const char kFromPeripheralCharUUID[] = "3EADBEEF-CAFE-FEED-FOOD-D15EA5EBEEEF";
|
| +
|
| +const char kOtherUUID[] = "AAAAAAAA-AAAA-AAAA-AAAA-D15EA5EBEEEF";
|
| +const char kOtherBluetoothAddress[] = "00:00:00:00:00:00";
|
| +
|
| +class MockConnection : public Connection {
|
| + public:
|
| + MockConnection() : Connection(kRemoteDevice) {}
|
| + ~MockConnection() override {}
|
| +
|
| + MOCK_METHOD0(Connect, void());
|
| +
|
| + using Connection::SetStatus;
|
| +
|
| + private:
|
| + void Disconnect() override {}
|
| + void SendMessageImpl(scoped_ptr<WireMessage> message) override {}
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MockConnection);
|
| +};
|
| +
|
| +class MockBluetoothLowEnergyConnectionFinder
|
| + : public BluetoothLowEnergyConnectionFinder {
|
| + public:
|
| + MockBluetoothLowEnergyConnectionFinder()
|
| + : BluetoothLowEnergyConnectionFinder(kServiceUUID,
|
| + kToPeripheralCharUUID,
|
| + kFromPeripheralCharUUID) {}
|
| + ~MockBluetoothLowEnergyConnectionFinder() override {}
|
| +
|
| + // Mock methods don't support return type scoped_ptr<>. This is a possible
|
| + // workaround: mock a proxy method to be called by the target overrided method
|
| + // (CreateConnection).
|
| + MOCK_METHOD0(CreateConnectionProxy, Connection*());
|
| +
|
| + // Creates a mock connection and sets an expectation that the mock connection
|
| + // finder's CreateConnection() method will be called and will return the
|
| + // created connection. Returns a reference to the created connection.
|
| + // NOTE: The returned connection's lifetime is managed by the connection
|
| + // finder.
|
| + MockConnection* ExpectCreateConnection() {
|
| + scoped_ptr<MockConnection> connection(new NiceMock<MockConnection>());
|
| + MockConnection* connection_alias = connection.get();
|
| + EXPECT_CALL(*this, CreateConnectionProxy())
|
| + .WillOnce(Return(connection.release()));
|
| + return connection_alias;
|
| + }
|
| +
|
| + protected:
|
| + scoped_ptr<Connection> CreateConnection(
|
| + scoped_ptr<device::BluetoothGattConnection> gatt_connection) override {
|
| + return make_scoped_ptr(CreateConnectionProxy());
|
| + }
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(MockBluetoothLowEnergyConnectionFinder);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class ProximityAuthBluetoothLowEnergyConnectionFinderTest
|
| + : public testing::Test {
|
| + protected:
|
| + ProximityAuthBluetoothLowEnergyConnectionFinderTest()
|
| + : adapter_(new NiceMock<device::MockBluetoothAdapter>),
|
| + connection_callback_(
|
| + base::Bind(&ProximityAuthBluetoothLowEnergyConnectionFinderTest::
|
| + OnConnectionFound,
|
| + base::Unretained(this))),
|
| + device_(new NiceMock<device::MockBluetoothDevice>(adapter_.get(),
|
| + 0,
|
| + kDeviceName,
|
| + kBluetoothAddress,
|
| + false,
|
| + false)) {
|
| + device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
|
| +
|
| + ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true));
|
| + ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true));
|
| + }
|
| +
|
| + void OnConnectionFound(scoped_ptr<Connection> connection) {
|
| + last_found_connection_ = connection.Pass();
|
| + }
|
| +
|
| + void FindAndExpectStartDiscovery(
|
| + BluetoothLowEnergyConnectionFinder& connection_finder) {
|
| + device::BluetoothAdapter::DiscoverySessionCallback discovery_callback;
|
| + scoped_ptr<device::MockBluetoothDiscoverySession> discovery_session(
|
| + new NiceMock<device::MockBluetoothDiscoverySession>());
|
| + device::MockBluetoothDiscoverySession* discovery_session_alias =
|
| + discovery_session.get();
|
| +
|
| + // Starting a discovery session
|
| + EXPECT_CALL(*adapter_, StartDiscoverySession(_, _))
|
| + .WillOnce(SaveArg<0>(&discovery_callback));
|
| + EXPECT_CALL(*adapter_, AddObserver(_));
|
| + ON_CALL(*discovery_session_alias, IsActive()).WillByDefault(Return(true));
|
| + connection_finder.Find(connection_callback_);
|
| + ASSERT_FALSE(discovery_callback.is_null());
|
| + discovery_callback.Run(discovery_session.Pass());
|
| +
|
| + // Cleaning up
|
| + EXPECT_CALL(*discovery_session_alias, Stop(_, _)).Times(AtLeast(1));
|
| + EXPECT_CALL(*adapter_, RemoveObserver(_));
|
| + }
|
| +
|
| + // Prepare |device_| with |uuid|.
|
| + void PrepareDevice(const std::string& uuid) {
|
| + std::vector<device::BluetoothUUID> uuids;
|
| + uuids.push_back(device::BluetoothUUID(uuid));
|
| + ON_CALL(*device_, GetUUIDs()).WillByDefault(Return(uuids));
|
| + }
|
| +
|
| + // Prepare expectations to add/change a right device.
|
| + void PrepareForNewRightDevice(
|
| + const std::string& uuid,
|
| + device::BluetoothDevice::GattConnectionCallback& callback) {
|
| + PrepareDevice(uuid);
|
| + EXPECT_CALL(*device_, CreateGattConnection(_, _))
|
| + .WillOnce(SaveArg<0>(&callback));
|
| + }
|
| +
|
| + // Prepare expectations to add/change a wrong device.
|
| + void PrepareForNewWrongDevice(const std::string& uuid) {
|
| + PrepareDevice(uuid);
|
| + EXPECT_CALL(*device_, CreateGattConnection(_, _)).Times(0);
|
| + }
|
| +
|
| + scoped_refptr<device::MockBluetoothAdapter> adapter_;
|
| + ConnectionFinder::ConnectionCallback connection_callback_;
|
| +
|
| + protected:
|
| + scoped_ptr<device::MockBluetoothDevice> device_;
|
| + scoped_ptr<Connection> last_found_connection_;
|
| +};
|
| +
|
| +TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
|
| + ConstructAndDestroyDoesntCrash) {
|
| + // Destroying a BluetoothConnectionFinder for which Find() has not been called
|
| + // should not crash.
|
| + BluetoothLowEnergyConnectionFinder connection_finder(
|
| + kServiceUUID, kToPeripheralCharUUID, kFromPeripheralCharUUID);
|
| +}
|
| +
|
| +TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
|
| + Find_StartsDiscoverySession) {
|
| + BluetoothLowEnergyConnectionFinder connection_finder(
|
| + kServiceUUID, kToPeripheralCharUUID, kFromPeripheralCharUUID);
|
| +
|
| + EXPECT_CALL(*adapter_, StartDiscoverySession(_, _));
|
| + EXPECT_CALL(*adapter_, AddObserver(_));
|
| + connection_finder.Find(connection_callback_);
|
| +}
|
| +
|
| +TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
|
| + Find_StopsDiscoverySessionBeforeDestroying) {
|
| + BluetoothLowEnergyConnectionFinder connection_finder(
|
| + kServiceUUID, kToPeripheralCharUUID, kFromPeripheralCharUUID);
|
| +
|
| + device::BluetoothAdapter::DiscoverySessionCallback discovery_callback;
|
| + scoped_ptr<device::MockBluetoothDiscoverySession> discovery_session(
|
| + new NiceMock<device::MockBluetoothDiscoverySession>());
|
| + device::MockBluetoothDiscoverySession* discovery_session_alias =
|
| + discovery_session.get();
|
| +
|
| + EXPECT_CALL(*adapter_, StartDiscoverySession(_, _))
|
| + .WillOnce(SaveArg<0>(&discovery_callback));
|
| + ON_CALL(*discovery_session_alias, IsActive()).WillByDefault(Return(true));
|
| + EXPECT_CALL(*adapter_, AddObserver(_));
|
| + connection_finder.Find(connection_callback_);
|
| +
|
| + EXPECT_CALL(*discovery_session_alias, Stop(_, _));
|
| + ASSERT_FALSE(discovery_callback.is_null());
|
| + discovery_callback.Run(discovery_session.Pass());
|
| +
|
| + EXPECT_CALL(*adapter_, RemoveObserver(_));
|
| +}
|
| +
|
| +TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
|
| + Find_CreatesGattConnectionWhenRightDeviceIsAdded) {
|
| + BluetoothLowEnergyConnectionFinder connection_finder(
|
| + kServiceUUID, kToPeripheralCharUUID, kFromPeripheralCharUUID);
|
| + device::BluetoothDevice::GattConnectionCallback gatt_connection_callback;
|
| + FindAndExpectStartDiscovery(connection_finder);
|
| +
|
| + PrepareForNewRightDevice(kServiceUUID, gatt_connection_callback);
|
| + connection_finder.DeviceAdded(adapter_.get(), device_.get());
|
| + ASSERT_FALSE(gatt_connection_callback.is_null());
|
| +}
|
| +
|
| +TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
|
| + Find_DoesntCreateGattConnectionWhenWrongDeviceIsAdded) {
|
| + BluetoothLowEnergyConnectionFinder connection_finder(
|
| + kServiceUUID, kToPeripheralCharUUID, kFromPeripheralCharUUID);
|
| + FindAndExpectStartDiscovery(connection_finder);
|
| +
|
| + PrepareForNewWrongDevice(kOtherUUID);
|
| + connection_finder.DeviceAdded(adapter_.get(), device_.get());
|
| +}
|
| +
|
| +TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
|
| + Find_CreatesGattConnectionWhenRightDeviceIsChanged) {
|
| + BluetoothLowEnergyConnectionFinder connection_finder(
|
| + kServiceUUID, kToPeripheralCharUUID, kFromPeripheralCharUUID);
|
| + device::BluetoothDevice::GattConnectionCallback gatt_connection_callback;
|
| + FindAndExpectStartDiscovery(connection_finder);
|
| +
|
| + PrepareForNewRightDevice(kServiceUUID, gatt_connection_callback);
|
| + connection_finder.DeviceChanged(adapter_.get(), device_.get());
|
| + ASSERT_FALSE(gatt_connection_callback.is_null());
|
| +}
|
| +
|
| +TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
|
| + Find_DoesntCreateGattConnectionWhenWrongDeviceIsChanged) {
|
| + BluetoothLowEnergyConnectionFinder connection_finder(
|
| + kServiceUUID, kToPeripheralCharUUID, kFromPeripheralCharUUID);
|
| + FindAndExpectStartDiscovery(connection_finder);
|
| +
|
| + PrepareForNewWrongDevice(kOtherUUID);
|
| + connection_finder.DeviceChanged(adapter_.get(), device_.get());
|
| +}
|
| +
|
| +TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
|
| + Find_CreatesTwoGattConnections) {
|
| + StrictMock<MockBluetoothLowEnergyConnectionFinder> connection_finder;
|
| + FindAndExpectStartDiscovery(connection_finder);
|
| + connection_finder.ExpectCreateConnection();
|
| +
|
| + // Prepare to add |device_|.
|
| + device::BluetoothDevice::GattConnectionCallback gatt_connection_callback;
|
| + PrepareForNewRightDevice(kServiceUUID, gatt_connection_callback);
|
| +
|
| + // Prepare to add |other_device|.
|
| + device::BluetoothDevice::GattConnectionCallback
|
| + other_gatt_connection_callback;
|
| + NiceMock<device::MockBluetoothDevice> other_device(
|
| + adapter_.get(), 0, kDeviceName, kOtherBluetoothAddress, false, false);
|
| + std::vector<device::BluetoothUUID> uuids;
|
| + uuids.push_back(device::BluetoothUUID(kServiceUUID));
|
| + ON_CALL(other_device, GetUUIDs()).WillByDefault((Return(uuids)));
|
| + EXPECT_CALL(other_device, CreateGattConnection(_, _))
|
| + .WillOnce(SaveArg<0>(&other_gatt_connection_callback));
|
| +
|
| + // Add the devices.
|
| + connection_finder.DeviceAdded(adapter_.get(), device_.get());
|
| + connection_finder.DeviceAdded(adapter_.get(), &other_device);
|
| +
|
| + ASSERT_FALSE(gatt_connection_callback.is_null());
|
| + ASSERT_FALSE(other_gatt_connection_callback.is_null());
|
| +
|
| + gatt_connection_callback.Run(make_scoped_ptr(
|
| + new NiceMock<device::MockBluetoothGattConnection>(kBluetoothAddress)));
|
| +
|
| + // The second device should be forgetten
|
| + EXPECT_CALL(*adapter_, GetDevice(std::string(kOtherBluetoothAddress)))
|
| + .WillOnce(Return(&other_device));
|
| + EXPECT_CALL(other_device, Forget(_));
|
| + other_gatt_connection_callback.Run(
|
| + make_scoped_ptr(new NiceMock<device::MockBluetoothGattConnection>(
|
| + kOtherBluetoothAddress)));
|
| +}
|
| +
|
| +TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
|
| + Find_ConnectionSucceeds) {
|
| + StrictMock<MockBluetoothLowEnergyConnectionFinder> connection_finder;
|
| +
|
| + // Starting discovery
|
| + FindAndExpectStartDiscovery(connection_finder);
|
| +
|
| + // Finding and creating a GATT connection to the right device
|
| + device::BluetoothDevice::GattConnectionCallback gatt_connection_callback;
|
| + PrepareForNewRightDevice(kServiceUUID, gatt_connection_callback);
|
| + connection_finder.DeviceAdded(adapter_.get(), device_.get());
|
| +
|
| + // Creating a connection
|
| + MockConnection* connection = connection_finder.ExpectCreateConnection();
|
| + ASSERT_FALSE(gatt_connection_callback.is_null());
|
| + gatt_connection_callback.Run(make_scoped_ptr(
|
| + new NiceMock<device::MockBluetoothGattConnection>(kBluetoothAddress)));
|
| + ASSERT_FALSE(last_found_connection_);
|
| + connection->SetStatus(Connection::IN_PROGRESS);
|
| + connection->SetStatus(Connection::CONNECTED);
|
| + ASSERT_FALSE(!last_found_connection_);
|
| +}
|
| +
|
| +} // namespace proximity_auth
|
|
|