Stack sampling profiler: add fire-and-forget interface
[chromium-blink-merge.git] / components / proximity_auth / bluetooth_connection_finder_unittest.cc
blobac6b38c3006a89e07b93b4afa216a70a76fdd812
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/proximity_auth/bluetooth_connection_finder.h"
7 #include "base/bind.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/time/time.h"
13 #include "components/proximity_auth/remote_device.h"
14 #include "components/proximity_auth/wire_message.h"
15 #include "device/bluetooth/bluetooth_adapter_factory.h"
16 #include "device/bluetooth/bluetooth_uuid.h"
17 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 using testing::_;
22 using testing::NiceMock;
23 using testing::Return;
24 using testing::StrictMock;
26 namespace proximity_auth {
27 namespace {
29 const char kDeviceName[] = "Device name";
30 const char kPublicKey[] = "Public key";
31 const char kBluetoothAddress[] = "11:22:33:44:55:66";
32 const char kPersistentSymmetricKey[] = "PSK";
34 const char kUuid[] = "DEADBEEF-CAFE-FEED-FOOD-D15EA5EBEEF";
36 RemoteDevice CreateRemoteDevice() {
37 return RemoteDevice(kDeviceName, kPublicKey, kBluetoothAddress,
38 kPersistentSymmetricKey);
41 class MockConnection : public Connection {
42 public:
43 MockConnection() : Connection(CreateRemoteDevice()) {}
44 ~MockConnection() override {}
46 MOCK_METHOD0(Connect, void());
48 using Connection::SetStatus;
50 private:
51 void Disconnect() override {}
52 void SendMessageImpl(scoped_ptr<WireMessage> message) override {}
54 DISALLOW_COPY_AND_ASSIGN(MockConnection);
57 class MockBluetoothConnectionFinder : public BluetoothConnectionFinder {
58 public:
59 MockBluetoothConnectionFinder()
60 : BluetoothConnectionFinder(CreateRemoteDevice(),
61 device::BluetoothUUID(kUuid),
62 base::TimeDelta()) {}
63 ~MockBluetoothConnectionFinder() override {}
65 MOCK_METHOD0(CreateConnectionProxy, Connection*());
67 // Creates a mock connection and sets an expectation that the mock connection
68 // finder's CreateConnection() method will be called and will return the
69 // created connection. Returns a reference to the created connection.
70 // NOTE: The returned connection's lifetime is managed by the connection
71 // finder.
72 MockConnection* ExpectCreateConnection() {
73 scoped_ptr<MockConnection> connection(new NiceMock<MockConnection>());
74 MockConnection* connection_alias = connection.get();
75 EXPECT_CALL(*this, CreateConnectionProxy())
76 .WillOnce(Return(connection.release()));
77 return connection_alias;
80 using BluetoothConnectionFinder::AdapterPresentChanged;
81 using BluetoothConnectionFinder::AdapterPoweredChanged;
83 protected:
84 scoped_ptr<Connection> CreateConnection() override {
85 return make_scoped_ptr(CreateConnectionProxy());
88 private:
89 DISALLOW_COPY_AND_ASSIGN(MockBluetoothConnectionFinder);
92 } // namespace
94 class ProximityAuthBluetoothConnectionFinderTest : public testing::Test {
95 protected:
96 ProximityAuthBluetoothConnectionFinderTest()
97 : adapter_(new NiceMock<device::MockBluetoothAdapter>),
98 connection_callback_(base::Bind(
99 &ProximityAuthBluetoothConnectionFinderTest::OnConnectionFound,
100 base::Unretained(this))) {
101 device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
103 // By default, configure the environment to allow polling. Individual tests
104 // can override this as needed.
105 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true));
106 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true));
109 MOCK_METHOD1(OnConnectionFoundProxy, void(Connection* connection));
110 void OnConnectionFound(scoped_ptr<Connection> connection) {
111 OnConnectionFoundProxy(connection.get());
112 last_found_connection_ = connection.Pass();
115 scoped_refptr<device::MockBluetoothAdapter> adapter_;
116 ConnectionFinder::ConnectionCallback connection_callback_;
118 private:
119 // Save a pointer to the last found connection, to extend its lifetime.
120 scoped_ptr<Connection> last_found_connection_;
122 base::MessageLoop message_loop_;
125 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
126 ConstructAndDestroyDoesntCrash) {
127 // Destroying a BluetoothConnectionFinder for which Find() has not been called
128 // should not crash.
129 BluetoothConnectionFinder connection_finder(
130 CreateRemoteDevice(), device::BluetoothUUID(kUuid),
131 base::TimeDelta::FromMilliseconds(1));
134 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_NoBluetoothAdapter) {
135 // Some platforms do not support Bluetooth. This test is only meaningful on
136 // those platforms.
137 adapter_ = NULL;
138 if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable())
139 return;
141 // The StrictMock will verify that no connection is created.
142 StrictMock<MockBluetoothConnectionFinder> connection_finder;
143 connection_finder.Find(connection_callback_);
146 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
147 Find_BluetoothAdapterNotPresent) {
148 // The StrictMock will verify that no connection is created.
149 StrictMock<MockBluetoothConnectionFinder> connection_finder;
150 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(false));
151 connection_finder.Find(connection_callback_);
154 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
155 Find_BluetoothAdapterNotPowered) {
156 // The StrictMock will verify that no connection is created.
157 StrictMock<MockBluetoothConnectionFinder> connection_finder;
158 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(false));
159 connection_finder.Find(connection_callback_);
162 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_ConnectionSucceeds) {
163 StrictMock<MockBluetoothConnectionFinder> connection_finder;
165 MockConnection* connection = connection_finder.ExpectCreateConnection();
166 connection_finder.Find(connection_callback_);
168 connection->SetStatus(Connection::IN_PROGRESS);
170 EXPECT_CALL(*this, OnConnectionFoundProxy(_));
171 connection->SetStatus(Connection::CONNECTED);
174 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
175 Find_ConnectionSucceeds_UnregistersAsObserver) {
176 StrictMock<MockBluetoothConnectionFinder> connection_finder;
178 MockConnection* connection = connection_finder.ExpectCreateConnection();
179 connection_finder.Find(connection_callback_);
181 connection->SetStatus(Connection::IN_PROGRESS);
183 EXPECT_CALL(*this, OnConnectionFoundProxy(_));
184 EXPECT_CALL(*adapter_, RemoveObserver(&connection_finder));
185 connection->SetStatus(Connection::CONNECTED);
187 // If for some reason the connection sends more status updates, they should be
188 // ignored.
189 EXPECT_CALL(*this, OnConnectionFoundProxy(_)).Times(0);
190 connection->SetStatus(Connection::IN_PROGRESS);
191 connection->SetStatus(Connection::CONNECTED);
194 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
195 Find_ConnectionFails_PostsTaskToPollAgain) {
196 StrictMock<MockBluetoothConnectionFinder> connection_finder;
198 MockConnection* connection = connection_finder.ExpectCreateConnection();
199 connection_finder.Find(connection_callback_);
201 // Simulate a connection that fails to connect.
202 connection->SetStatus(Connection::IN_PROGRESS);
203 connection->SetStatus(Connection::DISCONNECTED);
205 // A task should have been posted to poll again.
206 base::RunLoop run_loop;
207 connection_finder.ExpectCreateConnection();
208 run_loop.RunUntilIdle();
211 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_PollsOnAdapterPresent) {
212 StrictMock<MockBluetoothConnectionFinder> connection_finder;
214 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(false));
215 EXPECT_CALL(connection_finder, CreateConnectionProxy()).Times(0);
216 connection_finder.Find(connection_callback_);
218 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true));
219 connection_finder.ExpectCreateConnection();
220 connection_finder.AdapterPresentChanged(adapter_.get(), true);
223 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_PollsOnAdapterPowered) {
224 StrictMock<MockBluetoothConnectionFinder> connection_finder;
226 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(false));
227 EXPECT_CALL(connection_finder, CreateConnectionProxy()).Times(0);
228 connection_finder.Find(connection_callback_);
230 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true));
231 connection_finder.ExpectCreateConnection();
232 connection_finder.AdapterPoweredChanged(adapter_.get(), true);
235 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
236 Find_DoesNotPollIfConnectionPending) {
237 StrictMock<MockBluetoothConnectionFinder> connection_finder;
239 MockConnection* connection = connection_finder.ExpectCreateConnection();
240 connection_finder.Find(connection_callback_);
242 connection->SetStatus(Connection::IN_PROGRESS);
244 // At this point, there is a pending connection in progress. Hence, an event
245 // that would normally trigger a new polling iteration should not do so now,
246 // because the delay interval between successive polling attempts has not yet
247 // expired.
248 EXPECT_CALL(connection_finder, CreateConnectionProxy()).Times(0);
249 connection_finder.AdapterPresentChanged(adapter_.get(), true);
252 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
253 Find_ConnectionFails_PostsTaskToPollAgain_PollWaitsForTask) {
254 StrictMock<MockBluetoothConnectionFinder> connection_finder;
256 MockConnection* connection = connection_finder.ExpectCreateConnection();
257 connection_finder.Find(connection_callback_);
259 connection->SetStatus(Connection::IN_PROGRESS);
260 connection->SetStatus(Connection::DISCONNECTED);
262 // At this point, there is a pending poll scheduled. Hence, an event that
263 // would normally trigger a new polling iteration should not do so now,
264 // because the delay interval between successive polling attempts has not yet
265 // expired.
266 EXPECT_CALL(connection_finder, CreateConnectionProxy()).Times(0);
267 connection_finder.AdapterPresentChanged(adapter_.get(), true);
269 // Now, allow the pending task to run, but fail early, so that no new task is
270 // posted.
271 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(false));
272 base::RunLoop run_loop;
273 run_loop.RunUntilIdle();
274 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true));
276 // Now that there is no pending task, events should once again trigger new
277 // polling iterations.
278 connection_finder.ExpectCreateConnection();
279 connection_finder.AdapterPresentChanged(adapter_.get(), true);
282 } // namespace proximity_auth