Roll src/third_party/WebKit f36d5e0:68b67cd (svn 193299:193303)
[chromium-blink-merge.git] / components / proximity_auth / bluetooth_connection_finder_unittest.cc
blobfc0804ee50922e1c9760996141aa27ebba5f99d0
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 kBluetoothAddress[] = "11:22:33:44:55:66";
31 const RemoteDevice kRemoteDevice = {kDeviceName, kBluetoothAddress};
33 const char kUuid[] = "DEADBEEF-CAFE-FEED-FOOD-D15EA5EBEEF";
35 class MockConnection : public Connection {
36 public:
37 MockConnection() : Connection(kRemoteDevice) {}
38 virtual ~MockConnection() {}
40 MOCK_METHOD0(Connect, void());
42 using Connection::SetStatus;
44 private:
45 void Disconnect() {}
46 void SendMessageImpl(scoped_ptr<WireMessage> message) {}
48 DISALLOW_COPY_AND_ASSIGN(MockConnection);
51 class MockBluetoothConnectionFinder : public BluetoothConnectionFinder {
52 public:
53 MockBluetoothConnectionFinder()
54 : BluetoothConnectionFinder(kRemoteDevice,
55 device::BluetoothUUID(kUuid),
56 base::TimeDelta()) {}
57 virtual ~MockBluetoothConnectionFinder() {}
59 MOCK_METHOD0(CreateConnectionProxy, Connection*());
61 // Creates a mock connection and sets an expectation that the mock connection
62 // finder's CreateConnection() method will be called and will return the
63 // created connection. Returns a reference to the created connection.
64 // NOTE: The returned connection's lifetime is managed by the connection
65 // finder.
66 MockConnection* ExpectCreateConnection() {
67 scoped_ptr<MockConnection> connection(new NiceMock<MockConnection>());
68 MockConnection* connection_alias = connection.get();
69 EXPECT_CALL(*this, CreateConnectionProxy())
70 .WillOnce(Return(connection.release()));
71 return connection_alias;
74 using BluetoothConnectionFinder::AdapterPresentChanged;
75 using BluetoothConnectionFinder::AdapterPoweredChanged;
77 protected:
78 virtual scoped_ptr<Connection> CreateConnection() override {
79 return make_scoped_ptr(CreateConnectionProxy());
82 private:
83 DISALLOW_COPY_AND_ASSIGN(MockBluetoothConnectionFinder);
86 } // namespace
88 class ProximityAuthBluetoothConnectionFinderTest : public testing::Test {
89 protected:
90 ProximityAuthBluetoothConnectionFinderTest()
91 : adapter_(new NiceMock<device::MockBluetoothAdapter>),
92 connection_callback_(base::Bind(
93 &ProximityAuthBluetoothConnectionFinderTest::OnConnectionFound,
94 base::Unretained(this))) {
95 device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
97 // By default, configure the environment to allow polling. Individual tests
98 // can override this as needed.
99 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true));
100 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true));
103 MOCK_METHOD1(OnConnectionFoundProxy, void(Connection* connection));
104 void OnConnectionFound(scoped_ptr<Connection> connection) {
105 OnConnectionFoundProxy(connection.get());
106 last_found_connection_ = connection.Pass();
109 scoped_refptr<device::MockBluetoothAdapter> adapter_;
110 ConnectionFinder::ConnectionCallback connection_callback_;
112 private:
113 // Save a pointer to the last found connection, to extend its lifetime.
114 scoped_ptr<Connection> last_found_connection_;
116 base::MessageLoop message_loop_;
119 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
120 ConstructAndDestroyDoesntCrash) {
121 // Destroying a BluetoothConnectionFinder for which Find() has not been called
122 // should not crash.
123 BluetoothConnectionFinder connection_finder(
124 kRemoteDevice,
125 device::BluetoothUUID(kUuid),
126 base::TimeDelta::FromMilliseconds(1));
129 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_NoBluetoothAdapter) {
130 // Some platforms do not support Bluetooth. This test is only meaningful on
131 // those platforms.
132 adapter_ = NULL;
133 if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable())
134 return;
136 // The StrictMock will verify that no connection is created.
137 StrictMock<MockBluetoothConnectionFinder> connection_finder;
138 connection_finder.Find(connection_callback_);
141 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
142 Find_BluetoothAdapterNotPresent) {
143 // The StrictMock will verify that no connection is created.
144 StrictMock<MockBluetoothConnectionFinder> connection_finder;
145 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(false));
146 connection_finder.Find(connection_callback_);
149 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
150 Find_BluetoothAdapterNotPowered) {
151 // The StrictMock will verify that no connection is created.
152 StrictMock<MockBluetoothConnectionFinder> connection_finder;
153 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(false));
154 connection_finder.Find(connection_callback_);
157 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_ConnectionSucceeds) {
158 StrictMock<MockBluetoothConnectionFinder> connection_finder;
160 MockConnection* connection = connection_finder.ExpectCreateConnection();
161 connection_finder.Find(connection_callback_);
163 connection->SetStatus(Connection::IN_PROGRESS);
165 EXPECT_CALL(*this, OnConnectionFoundProxy(_));
166 connection->SetStatus(Connection::CONNECTED);
169 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
170 Find_ConnectionSucceeds_UnregistersAsObserver) {
171 StrictMock<MockBluetoothConnectionFinder> connection_finder;
173 MockConnection* connection = connection_finder.ExpectCreateConnection();
174 connection_finder.Find(connection_callback_);
176 connection->SetStatus(Connection::IN_PROGRESS);
178 EXPECT_CALL(*this, OnConnectionFoundProxy(_));
179 EXPECT_CALL(*adapter_, RemoveObserver(&connection_finder));
180 connection->SetStatus(Connection::CONNECTED);
182 // If for some reason the connection sends more status updates, they should be
183 // ignored.
184 EXPECT_CALL(*this, OnConnectionFoundProxy(_)).Times(0);
185 connection->SetStatus(Connection::IN_PROGRESS);
186 connection->SetStatus(Connection::CONNECTED);
189 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
190 Find_ConnectionFails_PostsTaskToPollAgain) {
191 StrictMock<MockBluetoothConnectionFinder> connection_finder;
193 MockConnection* connection = connection_finder.ExpectCreateConnection();
194 connection_finder.Find(connection_callback_);
196 // Simulate a connection that fails to connect.
197 connection->SetStatus(Connection::IN_PROGRESS);
198 connection->SetStatus(Connection::DISCONNECTED);
200 // A task should have been posted to poll again.
201 base::RunLoop run_loop;
202 connection_finder.ExpectCreateConnection();
203 run_loop.RunUntilIdle();
206 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_PollsOnAdapterPresent) {
207 StrictMock<MockBluetoothConnectionFinder> connection_finder;
209 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(false));
210 EXPECT_CALL(connection_finder, CreateConnectionProxy()).Times(0);
211 connection_finder.Find(connection_callback_);
213 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true));
214 connection_finder.ExpectCreateConnection();
215 connection_finder.AdapterPresentChanged(adapter_.get(), true);
218 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_PollsOnAdapterPowered) {
219 StrictMock<MockBluetoothConnectionFinder> connection_finder;
221 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(false));
222 EXPECT_CALL(connection_finder, CreateConnectionProxy()).Times(0);
223 connection_finder.Find(connection_callback_);
225 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true));
226 connection_finder.ExpectCreateConnection();
227 connection_finder.AdapterPoweredChanged(adapter_.get(), true);
230 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
231 Find_DoesNotPollIfConnectionPending) {
232 StrictMock<MockBluetoothConnectionFinder> connection_finder;
234 MockConnection* connection = connection_finder.ExpectCreateConnection();
235 connection_finder.Find(connection_callback_);
237 connection->SetStatus(Connection::IN_PROGRESS);
239 // At this point, there is a pending connection in progress. Hence, an event
240 // that would normally trigger a new polling iteration should not do so now,
241 // because the delay interval between successive polling attempts has not yet
242 // expired.
243 EXPECT_CALL(connection_finder, CreateConnectionProxy()).Times(0);
244 connection_finder.AdapterPresentChanged(adapter_.get(), true);
247 TEST_F(ProximityAuthBluetoothConnectionFinderTest,
248 Find_ConnectionFails_PostsTaskToPollAgain_PollWaitsForTask) {
249 StrictMock<MockBluetoothConnectionFinder> connection_finder;
251 MockConnection* connection = connection_finder.ExpectCreateConnection();
252 connection_finder.Find(connection_callback_);
254 connection->SetStatus(Connection::IN_PROGRESS);
255 connection->SetStatus(Connection::DISCONNECTED);
257 // At this point, there is a pending poll scheduled. Hence, an event that
258 // would normally trigger a new polling iteration should not do so now,
259 // because the delay interval between successive polling attempts has not yet
260 // expired.
261 EXPECT_CALL(connection_finder, CreateConnectionProxy()).Times(0);
262 connection_finder.AdapterPresentChanged(adapter_.get(), true);
264 // Now, allow the pending task to run, but fail early, so that no new task is
265 // posted.
266 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(false));
267 base::RunLoop run_loop;
268 run_loop.RunUntilIdle();
269 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true));
271 // Now that there is no pending task, events should once again trigger new
272 // polling iterations.
273 connection_finder.ExpectCreateConnection();
274 connection_finder.AdapterPresentChanged(adapter_.get(), true);
277 } // namespace proximity_auth