Index: chromeos/components/tether/ble_connection_manager_unittest.cc |
diff --git a/chromeos/components/tether/ble_connection_manager_unittest.cc b/chromeos/components/tether/ble_connection_manager_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d5491016af47ccb1143cbf53c8be0f04892fe28a |
--- /dev/null |
+++ b/chromeos/components/tether/ble_connection_manager_unittest.cc |
@@ -0,0 +1,1126 @@ |
+// Copyright 2016 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 "chromeos/components/tether/ble_connection_manager.h" |
+ |
+#include "base/logging.h" |
+#include "base/timer/mock_timer.h" |
+#include "chromeos/components/tether/ble_constants.h" |
+#include "chromeos/components/tether/proto/tether.pb.h" |
+#include "components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h" |
+#include "components/cryptauth/bluetooth_throttler.h" |
+#include "components/cryptauth/connection.h" |
+#include "components/cryptauth/fake_connection.h" |
+#include "components/cryptauth/fake_secure_channel.h" |
+#include "components/cryptauth/fake_secure_message_delegate.h" |
+#include "components/cryptauth/remote_device_test_util.h" |
+#include "device/bluetooth/test/mock_bluetooth_adapter.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using testing::_; |
+using testing::NiceMock; |
+using testing::Return; |
+ |
+namespace chromeos { |
+ |
+namespace tether { |
+ |
+namespace { |
+ |
+const char kTetherFeature[] = "magic_tether"; |
+ |
+const int64_t kAdvertisingTimeoutMillis = 12000; |
+const int64_t kShortErrorTimeoutMillis = 100; |
Ryan Hansberry
2017/02/16 19:29:36
I think we should just reuse the constants from Bl
Kyle Horimoto
2017/02/17 01:06:53
Done.
|
+ |
+const char kUserId[] = "userId"; |
+ |
+const char kBluetoothAddress1[] = "11:22:33:44:55:66"; |
+const char kBluetoothAddress2[] = "22:33:44:55:66:77"; |
+const char kBluetoothAddress3[] = "33:44:55:66:77:88"; |
+// const char kBluetoothAddress4[] = "44:55:66:77:88:99"; |
Ryan Hansberry
2017/02/16 19:29:36
remove this
Kyle Horimoto
2017/02/17 01:06:52
Done.
|
+ |
+class FakeSecureChannelDelegate : public cryptauth::SecureChannel::Delegate { |
+ public: |
+ FakeSecureChannelDelegate() {} |
+ ~FakeSecureChannelDelegate() override {} |
+ |
+ std::unique_ptr<cryptauth::SecureMessageDelegate> |
+ CreateSecureMessageDelegate() override { |
+ return base::MakeUnique<cryptauth::FakeSecureMessageDelegate>(); |
+ } |
+}; |
+ |
+class TestDelegate : public BleConnectionManager::Delegate { |
+ public: |
+ TestDelegate() {} |
+ ~TestDelegate() {} |
+ |
+ std::unique_ptr<cryptauth::SecureChannel::Delegate> |
+ CreateSecureChannelDelegate() override { |
+ return base::WrapUnique(new FakeSecureChannelDelegate()); |
+ } |
+}; |
+ |
+struct SecureChannelStatusChange { |
+ SecureChannelStatusChange(const cryptauth::RemoteDevice& remote_device, |
+ const cryptauth::SecureChannel::Status& old_status, |
+ const cryptauth::SecureChannel::Status& new_status) |
+ : remote_device(remote_device), |
+ old_status(old_status), |
+ new_status(new_status) {} |
+ |
+ cryptauth::RemoteDevice remote_device; |
+ cryptauth::SecureChannel::Status old_status; |
+ cryptauth::SecureChannel::Status new_status; |
+}; |
+ |
+struct ReceivedMessage { |
+ ReceivedMessage(const cryptauth::RemoteDevice& remote_device, |
+ const std::string& payload) |
+ : remote_device(remote_device), payload(payload) {} |
+ |
+ cryptauth::RemoteDevice remote_device; |
+ std::string payload; |
+}; |
+ |
+class TestObserver : public BleConnectionManager::Observer { |
+ public: |
+ TestObserver() {} |
+ |
+ // BleConnectionManager::Observer: |
+ void OnSecureChannelStatusChanged( |
+ const cryptauth::RemoteDevice& remote_device, |
+ const cryptauth::SecureChannel::Status& old_status, |
+ const cryptauth::SecureChannel::Status& new_status) override { |
+ connection_status_changes_.push_back( |
+ SecureChannelStatusChange(remote_device, old_status, new_status)); |
+ } |
+ |
+ void OnMessageReceived(const cryptauth::RemoteDevice& remote_device, |
+ const std::string& payload) override { |
+ received_messages_.push_back(ReceivedMessage(remote_device, payload)); |
+ } |
+ |
+ std::vector<SecureChannelStatusChange>& connection_status_changes() { |
+ return connection_status_changes_; |
+ } |
+ |
+ std::vector<ReceivedMessage>& received_messages() { |
+ return received_messages_; |
+ } |
+ |
+ private: |
+ std::vector<SecureChannelStatusChange> connection_status_changes_; |
+ std::vector<ReceivedMessage> received_messages_; |
+}; |
+ |
+class MockBleScanner : public BleScanner { |
+ public: |
+ MockBleScanner() : BleScanner(nullptr) {} |
+ ~MockBleScanner() override {} |
+ |
+ MOCK_METHOD1(RegisterScanFilterForDevice, |
+ bool(const cryptauth::RemoteDevice&)); |
+ MOCK_METHOD1(UnregisterScanFilterForDevice, |
+ bool(const cryptauth::RemoteDevice&)); |
+ |
+ void SimulateScanResults(const std::string& device_address, |
+ const cryptauth::RemoteDevice& remote_device) { |
+ for (auto& observer : observer_list_) { |
+ observer.OnReceivedAdvertisementFromDevice(device_address, remote_device); |
+ } |
+ } |
+}; |
+ |
+class MockBleAdvertiser : public BleAdvertiser { |
+ public: |
+ MockBleAdvertiser() : BleAdvertiser(nullptr, nullptr, nullptr) {} |
+ ~MockBleAdvertiser() override {} |
+ |
+ MOCK_METHOD1(StartAdvertisingToDevice, bool(const cryptauth::RemoteDevice&)); |
+ MOCK_METHOD1(StopAdvertisingToDevice, bool(const cryptauth::RemoteDevice&)); |
+}; |
+ |
+class MockBluetoothThrottler : public cryptauth::BluetoothThrottler { |
+ public: |
+ MockBluetoothThrottler() {} |
+ virtual ~MockBluetoothThrottler() {} |
+ |
+ MOCK_CONST_METHOD0(GetDelay, base::TimeDelta()); |
+ MOCK_METHOD1(OnConnection, void(cryptauth::Connection*)); |
+}; |
+ |
+class FakeConnectionWithAddress : public cryptauth::FakeConnection { |
+ public: |
+ FakeConnectionWithAddress(const cryptauth::RemoteDevice& remote_device, |
+ const std::string& device_address) |
+ : FakeConnection(remote_device, /* should_auto_connect */ false), |
Ryan Hansberry
2017/02/16 19:29:36
param comment should come after param
https://cs.
Kyle Horimoto
2017/02/17 01:06:53
Done.
|
+ device_address_(device_address) {} |
+ |
+ std::string device_address() { return device_address_; } |
Ryan Hansberry
2017/02/16 19:29:36
please use GetDeviceAddress
Kyle Horimoto
2017/02/17 01:06:53
Done.
|
+ |
+ private: |
+ const std::string device_address_; |
+}; |
+ |
+class FakeConnectionFactory |
+ : public cryptauth::weave::BluetoothLowEnergyWeaveClientConnection:: |
+ Factory { |
+ public: |
+ FakeConnectionFactory( |
+ scoped_refptr<device::BluetoothAdapter> expected_adapter, |
+ const device::BluetoothUUID expected_remote_service_uuid, |
+ cryptauth::BluetoothThrottler* expected_bluetooth_throttler) |
+ : expected_adapter_(expected_adapter), |
+ expected_remote_service_uuid_(expected_remote_service_uuid), |
+ expected_bluetooth_throttler_(expected_bluetooth_throttler) {} |
+ |
+ std::unique_ptr<cryptauth::Connection> BuildInstance( |
+ const cryptauth::RemoteDevice& remote_device, |
+ const std::string& device_address, |
+ scoped_refptr<device::BluetoothAdapter> adapter, |
+ const device::BluetoothUUID remote_service_uuid, |
+ cryptauth::BluetoothThrottler* bluetooth_throttler) override { |
+ EXPECT_EQ(expected_adapter_, adapter); |
+ EXPECT_EQ(expected_remote_service_uuid_, remote_service_uuid); |
+ EXPECT_EQ(expected_bluetooth_throttler_, bluetooth_throttler); |
+ |
+ return base::WrapUnique<FakeConnectionWithAddress>( |
+ new FakeConnectionWithAddress(remote_device, device_address)); |
+ } |
+ |
+ private: |
+ scoped_refptr<device::BluetoothAdapter> expected_adapter_; |
+ const device::BluetoothUUID expected_remote_service_uuid_; |
+ cryptauth::BluetoothThrottler* expected_bluetooth_throttler_; |
+}; |
+ |
+std::vector<cryptauth::RemoteDevice> CreateTestDevices(size_t num_to_create) { |
+ std::vector<cryptauth::RemoteDevice> test_devices = |
+ cryptauth::GenerateTestRemoteDevices(num_to_create); |
+ for (auto& device : test_devices) { |
+ device.user_id = std::string(kUserId); |
+ } |
+ return test_devices; |
+} |
+ |
+} // namespace |
+ |
+class BleConnectionManagerTest : public testing::Test { |
+ protected: |
+ class FakeSecureChannel : public cryptauth::FakeSecureChannel { |
+ public: |
+ FakeSecureChannel( |
+ std::unique_ptr<cryptauth::Connection> connection, |
+ std::unique_ptr<cryptauth::SecureChannel::Delegate> delegate) |
+ : cryptauth::FakeSecureChannel(std::move(connection), |
+ std::move(delegate)) {} |
+ |
+ void AddObserver(Observer* observer) override { |
+ cryptauth::FakeSecureChannel::AddObserver(observer); |
+ |
+ EXPECT_EQ(static_cast<size_t>(1), observers().size()); |
+ } |
+ |
+ void RemoveObserver(Observer* observer) override { |
+ cryptauth::FakeSecureChannel::RemoveObserver(observer); |
+ EXPECT_EQ(static_cast<size_t>(0), observers().size()); |
+ } |
+ }; |
+ |
+ class FakeSecureChannelFactory : public cryptauth::SecureChannel::Factory { |
+ public: |
+ FakeSecureChannelFactory() {} |
+ |
+ void SetExpectedDeviceAddress(const std::string& expected_device_address) { |
+ expected_device_address_ = expected_device_address; |
+ } |
+ |
+ std::unique_ptr<cryptauth::SecureChannel> BuildInstance( |
+ std::unique_ptr<cryptauth::Connection> connection, |
+ std::unique_ptr<cryptauth::SecureChannel::Delegate> delegate) override { |
+ FakeConnectionWithAddress* fake_connection = |
+ static_cast<FakeConnectionWithAddress*>(connection.get()); |
+ EXPECT_EQ(expected_device_address_, fake_connection->device_address()); |
+ return base::WrapUnique( |
+ new FakeSecureChannel(std::move(connection), std::move(delegate))); |
+ } |
+ |
+ private: |
+ std::string expected_device_address_; |
+ }; |
+ |
+ class MockTimerFactory : public BleConnectionManager::TimerFactory { |
+ public: |
+ std::unique_ptr<base::Timer> CreateTimer() override { |
+ return base::MakeUnique<base::MockTimer>( |
+ /* retains_user_task */ false, /* is_repeating */ false); |
Ryan Hansberry
2017/02/16 19:29:36
param comment should come after param
Kyle Horimoto
2017/02/17 01:06:52
Done.
|
+ } |
+ }; |
+ |
+ BleConnectionManagerTest() : test_devices_(CreateTestDevices(4)) { |
+ // These tests assume a maximum of two concurrent advertisers. Some of the |
+ // multi-device tests would need to be re-written if this constant changes. |
+ EXPECT_EQ(2, kMaxConcurrentAdvertisements); |
+ } |
+ |
+ void SetUp() override { |
+ verified_status_changes_.clear(); |
+ verified_received_messages_.clear(); |
+ |
+ delegate_ = new TestDelegate(); |
+ mock_adapter_ = |
+ make_scoped_refptr(new NiceMock<device::MockBluetoothAdapter>()); |
+ |
+ mock_ble_scanner_ = new MockBleScanner(); |
+ ON_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(_)) |
+ .WillByDefault(Return(true)); |
+ ON_CALL(*mock_ble_scanner_, UnregisterScanFilterForDevice(_)) |
+ .WillByDefault(Return(true)); |
+ |
+ mock_ble_advertiser_ = new MockBleAdvertiser(); |
+ ON_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(_)) |
+ .WillByDefault(Return(true)); |
+ ON_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(_)) |
+ .WillByDefault(Return(true)); |
+ |
+ device_queue_ = new BleAdvertisementDeviceQueue(); |
+ mock_timer_factory_ = new MockTimerFactory(); |
+ mock_bluetooth_throttler_ = base::WrapUnique(new MockBluetoothThrottler()); |
+ |
+ fake_connection_factory_ = base::WrapUnique(new FakeConnectionFactory( |
+ mock_adapter_, device::BluetoothUUID(std::string(kGattServerUuid)), |
+ mock_bluetooth_throttler_.get())); |
+ cryptauth::weave::BluetoothLowEnergyWeaveClientConnection::Factory:: |
+ SetInstanceForTesting(std::move(fake_connection_factory_)); |
+ |
+ fake_secure_channel_factory_ = |
+ base::WrapUnique(new FakeSecureChannelFactory()); |
+ cryptauth::SecureChannel::Factory::SetInstanceForTesting( |
+ fake_secure_channel_factory_.get()); |
+ |
+ manager_ = base::WrapUnique(new BleConnectionManager( |
+ base::WrapUnique(delegate_), mock_adapter_, |
+ base::WrapUnique(mock_ble_scanner_), |
+ base::WrapUnique(mock_ble_advertiser_), base::WrapUnique(device_queue_), |
+ base::WrapUnique(mock_timer_factory_), |
+ mock_bluetooth_throttler_.get())); |
+ test_observer_ = base::WrapUnique(new TestObserver()); |
+ manager_->AddObserver(test_observer_.get()); |
+ } |
+ |
+ void TearDown() override { |
+ // All state changes should have already been verified. This ensures that |
+ // no test has missed one. |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>()); |
+ |
+ // Same with received messages. |
+ VerifyReceivedMessages(std::vector<ReceivedMessage>()); |
+ } |
+ |
+ void VerifyConnectionStateChanges( |
+ const std::vector<SecureChannelStatusChange>& expected_changes) { |
+ verified_status_changes_.insert(verified_status_changes_.end(), |
+ expected_changes.begin(), |
+ expected_changes.end()); |
+ |
+ ASSERT_EQ(verified_status_changes_.size(), |
+ test_observer_->connection_status_changes().size()); |
+ |
+ for (size_t i = 0; i < verified_status_changes_.size(); i++) { |
+ EXPECT_EQ(verified_status_changes_[i].remote_device, |
+ test_observer_->connection_status_changes()[i].remote_device); |
+ EXPECT_EQ(verified_status_changes_[i].old_status, |
+ test_observer_->connection_status_changes()[i].old_status); |
+ EXPECT_EQ(verified_status_changes_[i].new_status, |
+ test_observer_->connection_status_changes()[i].new_status); |
+ } |
+ } |
+ |
+ void VerifyReceivedMessages( |
+ const std::vector<ReceivedMessage>& expected_messages) { |
+ verified_received_messages_.insert(verified_received_messages_.end(), |
+ expected_messages.begin(), |
+ expected_messages.end()); |
+ |
+ ASSERT_EQ(verified_received_messages_.size(), |
+ test_observer_->received_messages().size()); |
+ |
+ for (size_t i = 0; i < verified_received_messages_.size(); i++) { |
+ EXPECT_EQ(verified_received_messages_[i].remote_device, |
+ test_observer_->received_messages()[i].remote_device); |
+ EXPECT_EQ(verified_received_messages_[i].payload, |
+ test_observer_->received_messages()[i].payload); |
+ } |
+ } |
+ |
+ void VerifyNoTimeoutSet(const cryptauth::RemoteDevice& remote_device) { |
+ std::shared_ptr<BleConnectionManager::ConnectionMetadata> data = |
+ manager_->GetConnectionMetadata(remote_device); |
+ EXPECT_TRUE(data); |
Ryan Hansberry
2017/02/16 19:29:36
Throughout this entire cl, please use the variable
Kyle Horimoto
2017/02/17 01:06:53
Done.
|
+ EXPECT_FALSE(data->connection_attempt_timeout_timer_->IsRunning()); |
+ } |
+ |
+ void VerifyShortErrorTimeoutSet( |
+ const cryptauth::RemoteDevice& remote_device) { |
+ VerifyTimeoutSet(remote_device, kShortErrorTimeoutMillis); |
Ryan Hansberry
2017/02/16 19:29:36
This test will break if the value of this is chang
Kyle Horimoto
2017/02/17 01:06:53
Done.
|
+ } |
+ |
+ void VerifyAdvertisingTimeoutSet( |
+ const cryptauth::RemoteDevice& remote_device) { |
+ VerifyTimeoutSet(remote_device, kAdvertisingTimeoutMillis); |
+ } |
+ |
+ void VerifyTimeoutSet(const cryptauth::RemoteDevice& remote_device, |
+ int64_t expected_num_millis) { |
+ std::shared_ptr<BleConnectionManager::ConnectionMetadata> data = |
+ manager_->GetConnectionMetadata(remote_device); |
+ EXPECT_TRUE(data); |
+ EXPECT_TRUE(data->connection_attempt_timeout_timer_->IsRunning()); |
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(expected_num_millis), |
+ data->connection_attempt_timeout_timer_->GetCurrentDelay()); |
+ } |
+ |
+ void FireTimerForDevice(const cryptauth::RemoteDevice& remote_device) { |
+ std::shared_ptr<BleConnectionManager::ConnectionMetadata> data = |
+ manager_->GetConnectionMetadata(remote_device); |
+ EXPECT_TRUE(data); |
+ EXPECT_TRUE(data->connection_attempt_timeout_timer_->IsRunning()); |
+ static_cast<base::MockTimer*>(data->connection_attempt_timeout_timer_.get()) |
+ ->Fire(); |
+ } |
+ |
+ FakeSecureChannel* GetChannelForDevice( |
+ const cryptauth::RemoteDevice& remote_device) { |
+ std::shared_ptr<BleConnectionManager::ConnectionMetadata> data = |
+ manager_->GetConnectionMetadata(remote_device); |
+ EXPECT_TRUE(data); |
+ EXPECT_TRUE(data->secure_channel_); |
+ return static_cast<FakeSecureChannel*>(data->secure_channel_.get()); |
+ } |
+ |
+ void VerifyDeviceRegistered(const cryptauth::RemoteDevice& remote_device) { |
+ std::shared_ptr<BleConnectionManager::ConnectionMetadata> data = |
+ manager_->GetConnectionMetadata(remote_device); |
+ EXPECT_TRUE(data); |
+ } |
+ |
+ void VerifyDeviceNotRegistered(const cryptauth::RemoteDevice& remote_device) { |
+ std::shared_ptr<BleConnectionManager::ConnectionMetadata> data = |
+ manager_->GetConnectionMetadata(remote_device); |
+ EXPECT_FALSE(data); |
+ } |
+ |
+ FakeSecureChannel* ConnectSuccessfully( |
Ryan Hansberry
2017/02/16 19:29:36
It seems to me that this method is essentially a h
Kyle Horimoto
2017/02/17 01:06:53
Done.
|
+ const cryptauth::RemoteDevice& remote_device, |
+ const std::string& bluetooth_address, |
+ const MessageType connection_reason) { |
+ manager_->RegisterRemoteDevice(remote_device, connection_reason); |
+ VerifyAdvertisingTimeoutSet(remote_device); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {remote_device, cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ FakeSecureChannel* channel = |
+ ConnectChannel(remote_device, bluetooth_address); |
+ AuthenticateChannel(remote_device); |
+ return channel; |
+ } |
+ |
+ FakeSecureChannel* ConnectChannel( |
+ const cryptauth::RemoteDevice& remote_device, |
+ const std::string& bluetooth_address) { |
+ VerifyDeviceRegistered(remote_device); |
+ |
+ fake_secure_channel_factory_->SetExpectedDeviceAddress(bluetooth_address); |
+ mock_ble_scanner_->SimulateScanResults(bluetooth_address, remote_device); |
+ return GetChannelForDevice(remote_device); |
+ } |
+ |
+ void AuthenticateChannel(const cryptauth::RemoteDevice& remote_device) { |
+ VerifyDeviceRegistered(remote_device); |
+ |
+ FakeSecureChannel* channel = GetChannelForDevice(remote_device); |
+ DCHECK(channel); |
+ |
+ channel->ChangeStatus(cryptauth::SecureChannel::Status::CONNECTING); |
+ channel->ChangeStatus(cryptauth::SecureChannel::Status::CONNECTED); |
+ channel->ChangeStatus(cryptauth::SecureChannel::Status::AUTHENTICATING); |
+ channel->ChangeStatus(cryptauth::SecureChannel::Status::AUTHENTICATED); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {remote_device, cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::CONNECTED}, |
+ {remote_device, cryptauth::SecureChannel::Status::CONNECTED, |
+ cryptauth::SecureChannel::Status::AUTHENTICATING}, |
+ {remote_device, cryptauth::SecureChannel::Status::AUTHENTICATING, |
+ cryptauth::SecureChannel::Status::AUTHENTICATED}}); |
+ } |
+ |
+ void VerifyLastMessageSent(FakeSecureChannel* channel, |
+ const std::string& payload, |
+ size_t expected_size) { |
+ ASSERT_EQ(expected_size, channel->sent_messages().size()); |
+ cryptauth::FakeSecureChannel::SentMessage sent_message = |
+ channel->sent_messages()[expected_size - 1]; |
+ EXPECT_EQ(std::string(kTetherFeature), sent_message.feature); |
+ EXPECT_EQ(payload, sent_message.payload); |
+ } |
+ |
+ const std::vector<cryptauth::RemoteDevice> test_devices_; |
+ |
+ BleConnectionManager::Delegate* delegate_; |
+ scoped_refptr<NiceMock<device::MockBluetoothAdapter>> mock_adapter_; |
+ MockBleScanner* mock_ble_scanner_; |
+ MockBleAdvertiser* mock_ble_advertiser_; |
+ BleAdvertisementDeviceQueue* device_queue_; |
+ MockTimerFactory* mock_timer_factory_; |
+ std::unique_ptr<MockBluetoothThrottler> mock_bluetooth_throttler_; |
+ std::unique_ptr<FakeConnectionFactory> fake_connection_factory_; |
+ std::unique_ptr<FakeSecureChannelFactory> fake_secure_channel_factory_; |
+ std::unique_ptr<TestObserver> test_observer_; |
+ |
+ std::vector<SecureChannelStatusChange> verified_status_changes_; |
+ std::vector<ReceivedMessage> verified_received_messages_; |
+ |
+ std::unique_ptr<BleConnectionManager> manager_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(BleConnectionManagerTest); |
+}; |
+ |
+TEST_F(BleConnectionManagerTest, TestCannotAdvertise) { |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[0])) |
+ .WillOnce(Return(false)); |
+ |
+ manager_->RegisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyShortErrorTimeoutSet(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, TestCannotScan) { |
Ryan Hansberry
2017/02/16 19:29:37
super nit: since scanning is attempted first, plac
Kyle Horimoto
2017/02/17 01:06:53
Done.
|
+ EXPECT_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(test_devices_[0])) |
+ .WillOnce(Return(false)); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[0])) |
+ .Times(0); |
+ |
+ manager_->RegisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyShortErrorTimeoutSet(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, TestRegistersButNoResult) { |
+ // Expected to start a connection attempt, then stop once the timer fires, |
Ryan Hansberry
2017/02/16 19:29:36
I can't tell how this test stops and starts again?
Kyle Horimoto
2017/02/17 01:06:52
Oops - that was an incorrect comment. Removed.
|
+ // then start again; 2 starts and 1 stop. |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, |
+ StartAdvertisingToDevice(test_devices_[0])); |
+ |
+ manager_->RegisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyAdvertisingTimeoutSet(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, TestRegistersAndUnregister_NoConnection) { |
+ // Expected to start a connection attempt after the device is registered and |
+ // to stop the attempt once the device is unregistered. |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, |
+ StartAdvertisingToDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[0])); |
+ |
+ manager_->RegisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyAdvertisingTimeoutSet(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ manager_->UnregisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, TestRegisterWithNoConnection_TimerFires) { |
Ryan Hansberry
2017/02/16 19:29:37
Suggestion: instead of saying "timer fires" you co
Kyle Horimoto
2017/02/17 01:06:53
Done.
|
+ // Expected to start a connection attempt, then stop once the timer fires, |
+ // then start again, then stop when the device is unregistered; in total, 2 |
+ // starts and 2 stops. |
+ EXPECT_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(test_devices_[0])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[0])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[0])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[0])) |
+ .Times(2); |
+ |
+ manager_->RegisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyAdvertisingTimeoutSet(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ FireTimerForDevice(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}, |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ manager_->UnregisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, TestSuccessfulConnection_FailsAuthentication) { |
+ EXPECT_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(test_devices_[0])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[0])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[0])); |
+ |
+ manager_->RegisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyAdvertisingTimeoutSet(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ fake_secure_channel_factory_->SetExpectedDeviceAddress( |
+ std::string(kBluetoothAddress1)); |
+ mock_ble_scanner_->SimulateScanResults(std::string(kBluetoothAddress1), |
+ test_devices_[0]); |
+ FakeSecureChannel* channel = GetChannelForDevice(test_devices_[0]); |
+ |
+ // Should not result in an additional "disconnected => connecting" broadcast. |
+ channel->ChangeStatus(cryptauth::SecureChannel::Status::CONNECTING); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>()); |
+ |
+ channel->ChangeStatus(cryptauth::SecureChannel::Status::CONNECTED); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::CONNECTED}}); |
+ |
+ channel->ChangeStatus(cryptauth::SecureChannel::Status::AUTHENTICATING); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::CONNECTED, |
+ cryptauth::SecureChannel::Status::AUTHENTICATING}}); |
+ |
+ // Fail authentication, which should automatically start a retry. |
+ channel->ChangeStatus(cryptauth::SecureChannel::Status::DISCONNECTED); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::AUTHENTICATING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}, |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, TestSuccessfulConnection_SendAndReceive) { |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, |
+ StartAdvertisingToDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[0])); |
+ |
+ FakeSecureChannel* channel = |
+ ConnectSuccessfully(test_devices_[0], std::string(kBluetoothAddress1), |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ |
+ manager_->SendMessage(test_devices_[0], "request1"); |
+ VerifyLastMessageSent(channel, "request1", 1); |
+ |
+ channel->ReceiveMessage(std::string(kTetherFeature), "response1"); |
+ VerifyReceivedMessages( |
+ std::vector<ReceivedMessage>{{test_devices_[0], "response1"}}); |
+ |
+ manager_->SendMessage(test_devices_[0], "request2"); |
+ VerifyLastMessageSent(channel, "request2", 2); |
+ |
+ channel->ReceiveMessage(std::string(kTetherFeature), "response2"); |
+ VerifyReceivedMessages( |
+ std::vector<ReceivedMessage>{{test_devices_[0], "response2"}}); |
+ |
+ manager_->UnregisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::AUTHENTICATED, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+ VerifyDeviceNotRegistered(test_devices_[0]); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, |
+ TestSuccessfulConnection_MultipleConnectionReasons) { |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, |
+ StartAdvertisingToDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[0])); |
+ |
+ ConnectSuccessfully(test_devices_[0], std::string(kBluetoothAddress1), |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ |
+ // Now, register a different connection reason. |
+ manager_->RegisterRemoteDevice(test_devices_[0], |
+ MessageType::CONNECT_TETHERING_REQUEST); |
+ |
+ // Unregister the |TETHER_AVAILABILITY_REQUEST| reason, but leave the |
+ // |CONNECT_TETHERING_REQUEST| registered. |
+ manager_->UnregisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyDeviceRegistered(test_devices_[0]); |
+ |
+ // Now, unregister the other reason; this should cause the device to be |
+ // fully unregistered. |
+ manager_->UnregisterRemoteDevice(test_devices_[0], |
+ MessageType::CONNECT_TETHERING_REQUEST); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::AUTHENTICATED, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+ VerifyDeviceNotRegistered(test_devices_[0]); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, |
+ TestSuccessfulConnection_DisconnectsAfterConnection) { |
Ryan Hansberry
2017/02/16 19:29:36
Is this test really testing anything that other te
Kyle Horimoto
2017/02/17 01:06:53
Yes. This is the only test which tests what should
|
+ // A reconnection attempt is expected once the disconnection occurs, meaning |
+ // two separate connection attempts. |
+ EXPECT_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(test_devices_[0])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[0])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[0])); |
+ |
+ FakeSecureChannel* channel = |
+ ConnectSuccessfully(test_devices_[0], std::string(kBluetoothAddress1), |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ |
+ channel->ChangeStatus(cryptauth::SecureChannel::Status::DISCONNECTED); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::AUTHENTICATED, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}, |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, TwoDevices_NeitherCanScan) { |
Ryan Hansberry
2017/02/16 19:29:36
Is this test really necessary?
Kyle Horimoto
2017/02/17 01:06:53
It expands the test coverage for this class, so it
|
+ EXPECT_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(test_devices_[0])) |
+ .WillOnce(Return(false)); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[0])) |
+ .Times(0); |
+ EXPECT_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(test_devices_[1])) |
+ .WillOnce(Return(false)); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[1])) |
+ .Times(0); |
+ |
+ manager_->RegisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyShortErrorTimeoutSet(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ manager_->RegisterRemoteDevice(test_devices_[1], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyShortErrorTimeoutSet(test_devices_[1]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[1], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, TwoDevices_NeitherCanAdvertise) { |
Ryan Hansberry
2017/02/16 19:29:36
Same here
Kyle Horimoto
2017/02/17 01:06:53
Same here.
|
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[0])) |
+ .WillOnce(Return(false)); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[1])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[1])) |
+ .WillOnce(Return(false)); |
+ |
+ manager_->RegisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyShortErrorTimeoutSet(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ manager_->RegisterRemoteDevice(test_devices_[1], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyShortErrorTimeoutSet(test_devices_[1]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[1], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, |
+ TwoDevices_RegisterWithNoConnection_TimerFires) { |
+ // Expected to start a connection attempt, then stop once the timer fires, |
+ // then start again, then stop when the device is unregistered; in total, 2 |
+ // starts and 2 stops. |
+ EXPECT_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(test_devices_[0])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[0])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[0])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[0])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(test_devices_[1])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[1])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[1])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[1])) |
+ .Times(2); |
+ |
+ // Register device 0. |
+ manager_->RegisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyAdvertisingTimeoutSet(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ // Register device 1. |
+ manager_->RegisterRemoteDevice(test_devices_[1], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyAdvertisingTimeoutSet(test_devices_[1]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[1], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ // Simulate timeout for device 0 by firing timeout. |
+ FireTimerForDevice(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}, |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ // Simulate timeout for device 1 by firing timeout. |
+ FireTimerForDevice(test_devices_[1]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[1], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}, |
+ {test_devices_[1], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ // Unregister device 0. |
+ manager_->UnregisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+ |
+ // Unregister device 1. |
+ manager_->UnregisterRemoteDevice(test_devices_[1], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[1], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, TwoDevices_OneConnects) { |
+ // Device 0 is expected to start the attempt and stop once a connection has |
+ // been achieved. Device 1 is expected to start, then stop once the tiemr |
Ryan Hansberry
2017/02/16 19:29:36
timer*
Kyle Horimoto
2017/02/17 01:06:53
Done.
|
+ // fires, then start again. |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, |
+ StartAdvertisingToDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(test_devices_[1])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[1])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[1])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[1])) |
+ .Times(2); |
+ |
+ // Successfully connect to device 0. |
+ ConnectSuccessfully(test_devices_[0], std::string(kBluetoothAddress1), |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ |
+ // Register device 1. |
+ manager_->RegisterRemoteDevice(test_devices_[1], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyAdvertisingTimeoutSet(test_devices_[1]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[1], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ // Simulate timeout for device 1 by firing timeout. |
+ FireTimerForDevice(test_devices_[1]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[1], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}, |
+ {test_devices_[1], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ // Unregister device 0. |
+ manager_->UnregisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::AUTHENTICATED, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+ |
+ // Unregister device 1. |
+ manager_->UnregisterRemoteDevice(test_devices_[1], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[1], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, TwoDevices_BothConnectSendAndReceive) { |
+ // Device 0 is expected to start the attempt and stop once a connection has |
+ // been achieved. Device 1 is expected to start, then stop once the tiemr |
+ // fires, then start again. |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, |
+ StartAdvertisingToDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[1])); |
+ EXPECT_CALL(*mock_ble_advertiser_, |
+ StartAdvertisingToDevice(test_devices_[1])); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[1])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[1])); |
+ |
+ FakeSecureChannel* channel0 = |
+ ConnectSuccessfully(test_devices_[0], std::string(kBluetoothAddress1), |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ |
+ FakeSecureChannel* channel1 = |
+ ConnectSuccessfully(test_devices_[1], std::string(kBluetoothAddress2), |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ |
+ manager_->SendMessage(test_devices_[0], "request1_device0"); |
+ VerifyLastMessageSent(channel0, "request1_device0", 1); |
+ |
+ manager_->SendMessage(test_devices_[1], "request1_device1"); |
+ VerifyLastMessageSent(channel1, "request1_device1", 1); |
+ |
+ channel0->ReceiveMessage(std::string(kTetherFeature), "response1_device0"); |
+ VerifyReceivedMessages( |
+ std::vector<ReceivedMessage>{{test_devices_[0], "response1_device0"}}); |
+ |
+ channel1->ReceiveMessage(std::string(kTetherFeature), "response1_device1"); |
+ VerifyReceivedMessages( |
+ std::vector<ReceivedMessage>{{test_devices_[1], "response1_device1"}}); |
+ |
+ manager_->SendMessage(test_devices_[0], "request2_device0"); |
+ VerifyLastMessageSent(channel0, "request2_device0", 2); |
+ |
+ manager_->SendMessage(test_devices_[1], "request2_device1"); |
+ VerifyLastMessageSent(channel1, "request2_device1", 2); |
+ |
+ channel0->ReceiveMessage(std::string(kTetherFeature), "response2_device0"); |
+ VerifyReceivedMessages( |
+ std::vector<ReceivedMessage>{{test_devices_[0], "response2_device0"}}); |
+ |
+ channel1->ReceiveMessage(std::string(kTetherFeature), "response2_device1"); |
+ VerifyReceivedMessages( |
+ std::vector<ReceivedMessage>{{test_devices_[1], "response2_device1"}}); |
+ |
+ manager_->UnregisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::AUTHENTICATED, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+ VerifyDeviceNotRegistered(test_devices_[0]); |
+ |
+ manager_->UnregisterRemoteDevice(test_devices_[1], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[1], cryptauth::SecureChannel::Status::AUTHENTICATED, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+ VerifyDeviceNotRegistered(test_devices_[1]); |
+} |
+ |
+TEST_F(BleConnectionManagerTest, FourDevices_ComprehensiveTest) { |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, |
+ StartAdvertisingToDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[0])); |
+ EXPECT_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(test_devices_[1])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[1])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[1])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[1])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(test_devices_[2])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StartAdvertisingToDevice(test_devices_[2])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[2])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[2])) |
+ .Times(2); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ RegisterScanFilterForDevice(test_devices_[3])); |
+ EXPECT_CALL(*mock_ble_advertiser_, |
+ StartAdvertisingToDevice(test_devices_[3])); |
+ EXPECT_CALL(*mock_ble_scanner_, |
+ UnregisterScanFilterForDevice(test_devices_[3])); |
+ EXPECT_CALL(*mock_ble_advertiser_, StopAdvertisingToDevice(test_devices_[3])); |
+ |
+ // Register all devices. Since the maximum number of simultaneous connection |
+ // attempts is 2, only devices 0 and 1 should actually start connecting. |
+ manager_->RegisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ manager_->RegisterRemoteDevice(test_devices_[1], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ manager_->RegisterRemoteDevice(test_devices_[2], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ manager_->RegisterRemoteDevice(test_devices_[3], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ |
+ // Devices 0 and 1 should be advertising; devices 2 and 3 should not be. |
+ VerifyAdvertisingTimeoutSet(test_devices_[0]); |
+ VerifyAdvertisingTimeoutSet(test_devices_[1]); |
+ VerifyNoTimeoutSet(test_devices_[2]); |
+ VerifyNoTimeoutSet(test_devices_[3]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}, |
+ {test_devices_[1], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ // Device 0 connects successfully. |
+ FakeSecureChannel* channel0 = |
+ ConnectChannel(test_devices_[0], std::string(kBluetoothAddress1)); |
+ |
+ // Since device 0 has connected, advertising to that device is no longer |
+ // necessary. Device 2 should have filled up that advertising slot. |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[2], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ // Meanwhile, device 1 fails to connect, so the timeout fires. The advertising |
+ // slot left by device 1 creates space for device 3 to start connecting. |
+ FireTimerForDevice(test_devices_[1]); |
+ VerifyAdvertisingTimeoutSet(test_devices_[3]); |
+ VerifyNoTimeoutSet(test_devices_[1]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[1], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}, |
+ {test_devices_[3], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ // Now, device 0 authenticates and sends and receives a message. |
+ AuthenticateChannel(test_devices_[0]); |
+ manager_->SendMessage(test_devices_[0], "request1"); |
+ VerifyLastMessageSent(channel0, "request1", 1); |
+ |
+ channel0->ReceiveMessage(std::string(kTetherFeature), "response1"); |
+ VerifyReceivedMessages( |
+ std::vector<ReceivedMessage>{{test_devices_[0], "response1"}}); |
+ |
+ // Now, device 0 is unregistered. |
+ manager_->UnregisterRemoteDevice(test_devices_[0], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyDeviceNotRegistered(test_devices_[0]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[0], cryptauth::SecureChannel::Status::AUTHENTICATED, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+ |
+ // Device 2 fails to connect, so the timeout fires. Device 1 takes its spot. |
+ FireTimerForDevice(test_devices_[2]); |
+ VerifyAdvertisingTimeoutSet(test_devices_[1]); |
+ VerifyNoTimeoutSet(test_devices_[2]); |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[2], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}, |
+ {test_devices_[1], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ // Device 3 connects successfully. |
+ FakeSecureChannel* channel3 = |
+ ConnectChannel(test_devices_[3], std::string(kBluetoothAddress3)); |
+ |
+ // Since device 3 has connected, device 2 starts connecting again. |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[2], cryptauth::SecureChannel::Status::DISCONNECTED, |
+ cryptauth::SecureChannel::Status::CONNECTING}}); |
+ |
+ // Now, device 3 authenticates and sends and receives a message. |
+ AuthenticateChannel(test_devices_[3]); |
+ manager_->SendMessage(test_devices_[3], "request3"); |
+ VerifyLastMessageSent(channel3, "request3", 1); |
+ |
+ channel3->ReceiveMessage(std::string(kTetherFeature), "response3"); |
+ VerifyReceivedMessages( |
+ std::vector<ReceivedMessage>{{test_devices_[3], "response3"}}); |
+ |
+ // Assume that none of the other devices can connect, and unregister the |
+ // remaining 3 devices. |
+ manager_->UnregisterRemoteDevice(test_devices_[3], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyDeviceNotRegistered(test_devices_[3]); |
+ manager_->UnregisterRemoteDevice(test_devices_[1], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyDeviceNotRegistered(test_devices_[1]); |
+ manager_->UnregisterRemoteDevice(test_devices_[2], |
+ MessageType::TETHER_AVAILABILITY_REQUEST); |
+ VerifyDeviceNotRegistered(test_devices_[2]); |
+ |
+ VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>{ |
+ {test_devices_[3], cryptauth::SecureChannel::Status::AUTHENTICATED, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}, |
+ {test_devices_[1], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}, |
+ {test_devices_[2], cryptauth::SecureChannel::Status::CONNECTING, |
+ cryptauth::SecureChannel::Status::DISCONNECTED}}); |
+} |
+ |
+} // namespace tether |
+ |
+} // namespace cryptauth |