Commit 290ac0ba authored by sacomoto's avatar sacomoto Committed by Commit bot

Adding BLE connection finder unit tests.

Adds unit tests for the proximity_auth::BluetoothLowEnergyConnectionFinder
class.

BUG=485123

Review URL: https://codereview.chromium.org/1129983004

Cr-Commit-Position: refs/heads/master@{#330918}
parent e4cf3208
......@@ -428,6 +428,7 @@
'precache/core/precache_url_table_unittest.cc',
],
'proximity_auth_unittest_sources': [
'proximity_auth/ble/bluetooth_low_energy_connection_finder_unittest.cc',
'proximity_auth/bluetooth_connection_finder_unittest.cc',
'proximity_auth/bluetooth_connection_unittest.cc',
'proximity_auth/bluetooth_throttler_impl_unittest.cc',
......
......@@ -67,6 +67,7 @@ source_set("unit_tests") {
deps = [
":proximity_auth",
"ble:unit_tests",
"cryptauth:unit_tests",
"logging:unit_tests",
"//base/test:test_support",
......
......@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//testing/test.gni")
source_set("ble") {
sources = [
"bluetooth_low_energy_connection.cc",
......@@ -21,3 +23,21 @@ source_set("ble") {
"//net",
]
}
source_set("unit_tests") {
testonly = true
sources = [
"bluetooth_low_energy_connection_finder_unittest.cc",
]
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
":ble",
"//components/proximity_auth",
"//base/test:test_support",
"//device/bluetooth:mocks",
"//testing/gmock",
"//testing/gtest",
]
}
......@@ -48,7 +48,6 @@ class BluetoothLowEnergyConnectionFinder
Connection::Status old_status,
Connection::Status new_status) override;
protected:
// device::BluetoothAdapter::Observer:
void DeviceAdded(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) override;
......@@ -57,6 +56,12 @@ class BluetoothLowEnergyConnectionFinder
void DeviceRemoved(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) override;
protected:
// Creates a proximity_auth::Connection based on |gatt_connection|. Exposed
// for testing.
virtual scoped_ptr<Connection> CreateConnection(
scoped_ptr<device::BluetoothGattConnection> gatt_connection);
private:
// Callback to be called when the Bluetooth adapter is initialized.
void OnAdapterInitialized(scoped_refptr<device::BluetoothAdapter> adapter);
......@@ -100,10 +105,6 @@ class BluetoothLowEnergyConnectionFinder
// be called once the connection is established.
void CreateGattConnection(device::BluetoothDevice* remote_device);
// Creates a connection with |remote_device|.
scoped_ptr<Connection> CreateConnection(
scoped_ptr<device::BluetoothGattConnection> gatt_connection);
// The uuid of the service it looks for to establish a GattConnection.
device::BluetoothUUID remote_service_uuid_;
......
// 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment