Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / components / proximity_auth / remote_device_life_cycle_impl_unittest.cc
blobafe6a36f39b645fc79d11d80769b7dce51f18ac2
1 // Copyright 2015 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/remote_device_life_cycle_impl.h"
7 #include "base/callback.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/test/test_simple_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "components/proximity_auth/authenticator.h"
12 #include "components/proximity_auth/client.h"
13 #include "components/proximity_auth/connection.h"
14 #include "components/proximity_auth/connection_finder.h"
15 #include "components/proximity_auth/secure_context.h"
16 #include "components/proximity_auth/wire_message.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using testing::_;
21 using testing::Mock;
22 using testing::NiceMock;
23 using testing::Return;
24 using testing::StrictMock;
26 namespace proximity_auth {
28 namespace {
30 // Attributes of the remote device under test.
31 const char kRemoteDeviceName[] = "remote device";
32 const char kRemoteDevicePublicKey[] = "public key";
33 const char kRemoteDeviceBluetoothAddress[] = "AA:BB:CC:DD:EE:FF";
34 const char kRemoteDevicePSK[] = "remote device psk";
36 class StubConnection : public Connection {
37 public:
38 StubConnection() : Connection(RemoteDevice()) {
39 SetStatus(Connection::Status::CONNECTED);
42 ~StubConnection() override {}
44 // Connection:
45 void Connect() override { NOTREACHED(); }
47 void Disconnect() override { SetStatus(Connection::Status::DISCONNECTED); }
49 void SendMessageImpl(scoped_ptr<WireMessage> message) override {
50 NOTREACHED();
53 private:
54 DISALLOW_COPY_AND_ASSIGN(StubConnection);
57 class StubSecureContext : public SecureContext {
58 public:
59 StubSecureContext() {}
60 ~StubSecureContext() override {}
62 void Decode(const std::string& encoded_message,
63 const MessageCallback& callback) override {
64 NOTREACHED();
67 void Encode(const std::string& message,
68 const MessageCallback& callback) override {
69 NOTREACHED();
72 ProtocolVersion GetProtocolVersion() const override {
73 NOTREACHED();
74 return SecureContext::PROTOCOL_VERSION_THREE_ONE;
77 private:
78 DISALLOW_COPY_AND_ASSIGN(StubSecureContext);
81 class FakeConnectionFinder : public ConnectionFinder {
82 public:
83 FakeConnectionFinder() : connection_(nullptr) {}
84 ~FakeConnectionFinder() override {}
86 void OnConnectionFound() {
87 ASSERT_FALSE(connection_callback_.is_null());
88 scoped_ptr<StubConnection> scoped_connection_(new StubConnection());
89 connection_ = scoped_connection_.get();
90 connection_callback_.Run(scoped_connection_.Pass());
93 StubConnection* connection() { return connection_; }
95 private:
96 // ConnectionFinder:
97 void Find(const ConnectionCallback& connection_callback) override {
98 ASSERT_TRUE(connection_callback_.is_null());
99 connection_callback_ = connection_callback;
102 StubConnection* connection_;
104 ConnectionCallback connection_callback_;
106 DISALLOW_COPY_AND_ASSIGN(FakeConnectionFinder);
109 class FakeAuthenticator : public Authenticator {
110 public:
111 FakeAuthenticator() {}
112 ~FakeAuthenticator() override {}
114 void OnAuthenticationResult(Authenticator::Result result) {
115 ASSERT_FALSE(callback_.is_null());
116 scoped_ptr<SecureContext> secure_context;
117 if (result == Authenticator::Result::SUCCESS)
118 secure_context.reset(new StubSecureContext());
119 callback_.Run(result, secure_context.Pass());
122 private:
123 // Authenticator:
124 void Authenticate(const AuthenticationCallback& callback) override {
125 ASSERT_TRUE(callback_.is_null());
126 callback_ = callback;
129 AuthenticationCallback callback_;
131 DISALLOW_COPY_AND_ASSIGN(FakeAuthenticator);
134 // Subclass of RemoteDeviceLifeCycleImpl to make it testable.
135 class TestableRemoteDeviceLifeCycleImpl : public RemoteDeviceLifeCycleImpl {
136 public:
137 TestableRemoteDeviceLifeCycleImpl()
138 : RemoteDeviceLifeCycleImpl(RemoteDevice(kRemoteDeviceName,
139 kRemoteDevicePublicKey,
140 kRemoteDeviceBluetoothAddress,
141 kRemoteDevicePSK),
142 nullptr) {}
144 ~TestableRemoteDeviceLifeCycleImpl() override {}
146 FakeConnectionFinder* connection_finder() { return connection_finder_; }
147 FakeAuthenticator* authenticator() { return authenticator_; }
149 private:
150 scoped_ptr<ConnectionFinder> CreateConnectionFinder() override {
151 scoped_ptr<FakeConnectionFinder> scoped_connection_finder(
152 new FakeConnectionFinder());
153 connection_finder_ = scoped_connection_finder.get();
154 return scoped_connection_finder.Pass();
157 scoped_ptr<Authenticator> CreateAuthenticator() override {
158 scoped_ptr<FakeAuthenticator> scoped_authenticator(new FakeAuthenticator());
159 authenticator_ = scoped_authenticator.get();
160 return scoped_authenticator.Pass();
163 FakeConnectionFinder* connection_finder_;
164 FakeAuthenticator* authenticator_;
166 DISALLOW_COPY_AND_ASSIGN(TestableRemoteDeviceLifeCycleImpl);
169 } // namespace
171 class ProximityAuthRemoteDeviceLifeCycleImplTest
172 : public testing::Test,
173 public RemoteDeviceLifeCycle::Observer {
174 protected:
175 ProximityAuthRemoteDeviceLifeCycleImplTest()
176 : task_runner_(new base::TestSimpleTaskRunner()),
177 thread_task_runner_handle_(task_runner_) {}
179 ~ProximityAuthRemoteDeviceLifeCycleImplTest() override {
180 life_cycle_.RemoveObserver(this);
183 void StartLifeCycle() {
184 EXPECT_EQ(RemoteDeviceLifeCycle::State::STOPPED, life_cycle_.GetState());
185 life_cycle_.AddObserver(this);
187 EXPECT_CALL(*this, OnLifeCycleStateChanged(
188 RemoteDeviceLifeCycle::State::STOPPED,
189 RemoteDeviceLifeCycle::State::FINDING_CONNECTION));
190 life_cycle_.Start();
191 task_runner_->RunUntilIdle();
192 Mock::VerifyAndClearExpectations(this);
194 EXPECT_EQ(RemoteDeviceLifeCycle::State::FINDING_CONNECTION,
195 life_cycle_.GetState());
198 StubConnection* OnConnectionFound() {
199 EXPECT_EQ(RemoteDeviceLifeCycle::State::FINDING_CONNECTION,
200 life_cycle_.GetState());
202 EXPECT_CALL(*this, OnLifeCycleStateChanged(
203 RemoteDeviceLifeCycle::State::FINDING_CONNECTION,
204 RemoteDeviceLifeCycle::State::AUTHENTICATING));
205 life_cycle_.connection_finder()->OnConnectionFound();
206 task_runner_->RunUntilIdle();
207 Mock::VerifyAndClearExpectations(this);
209 EXPECT_EQ(RemoteDeviceLifeCycle::State::AUTHENTICATING,
210 life_cycle_.GetState());
211 return life_cycle_.connection_finder()->connection();
214 void Authenticate(Authenticator::Result result) {
215 EXPECT_EQ(RemoteDeviceLifeCycle::State::AUTHENTICATING,
216 life_cycle_.GetState());
218 RemoteDeviceLifeCycle::State expected_state =
219 (result == Authenticator::Result::SUCCESS)
220 ? RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED
221 : RemoteDeviceLifeCycle::State::AUTHENTICATION_FAILED;
223 EXPECT_CALL(*this, OnLifeCycleStateChanged(
224 RemoteDeviceLifeCycle::State::AUTHENTICATING,
225 expected_state));
226 life_cycle_.authenticator()->OnAuthenticationResult(result);
228 if (result == Authenticator::Result::SUCCESS)
229 task_runner_->RunUntilIdle();
231 EXPECT_EQ(expected_state, life_cycle_.GetState());
232 Mock::VerifyAndClearExpectations(this);
235 MOCK_METHOD2(OnLifeCycleStateChanged,
236 void(RemoteDeviceLifeCycle::State old_state,
237 RemoteDeviceLifeCycle::State new_state));
239 TestableRemoteDeviceLifeCycleImpl life_cycle_;
240 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
241 base::ThreadTaskRunnerHandle thread_task_runner_handle_;
243 private:
244 DISALLOW_COPY_AND_ASSIGN(ProximityAuthRemoteDeviceLifeCycleImplTest);
247 TEST_F(ProximityAuthRemoteDeviceLifeCycleImplTest, AuthenticateAndDisconnect) {
248 StartLifeCycle();
249 for (size_t i = 0; i < 3; ++i) {
250 Connection* connection = OnConnectionFound();
251 Authenticate(Authenticator::Result::SUCCESS);
252 EXPECT_TRUE(life_cycle_.GetClient());
254 EXPECT_CALL(*this,
255 OnLifeCycleStateChanged(
256 RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED,
257 RemoteDeviceLifeCycle::State::FINDING_CONNECTION));
258 connection->Disconnect();
259 Mock::VerifyAndClearExpectations(this);
263 TEST_F(ProximityAuthRemoteDeviceLifeCycleImplTest, AuthenticationFails) {
264 // Simulate an authentication failure after connecting to the device.
265 StartLifeCycle();
266 OnConnectionFound();
267 Authenticate(Authenticator::Result::FAILURE);
268 EXPECT_FALSE(life_cycle_.GetClient());
270 // After a delay, the life cycle should return to FINDING_CONNECTION.
271 EXPECT_CALL(*this, OnLifeCycleStateChanged(
272 RemoteDeviceLifeCycle::State::AUTHENTICATION_FAILED,
273 RemoteDeviceLifeCycle::State::FINDING_CONNECTION));
274 task_runner_->RunUntilIdle();
275 EXPECT_EQ(RemoteDeviceLifeCycle::State::FINDING_CONNECTION,
276 life_cycle_.GetState());
278 // Try failing with the DISCONNECTED state instead.
279 OnConnectionFound();
280 Authenticate(Authenticator::Result::DISCONNECTED);
281 EXPECT_FALSE(life_cycle_.GetClient());
283 // Check we're back in FINDING_CONNECTION state again.
284 EXPECT_CALL(*this, OnLifeCycleStateChanged(
285 RemoteDeviceLifeCycle::State::AUTHENTICATION_FAILED,
286 RemoteDeviceLifeCycle::State::FINDING_CONNECTION));
287 task_runner_->RunUntilIdle();
288 EXPECT_EQ(RemoteDeviceLifeCycle::State::FINDING_CONNECTION,
289 life_cycle_.GetState());
292 TEST_F(ProximityAuthRemoteDeviceLifeCycleImplTest,
293 AuthenticationFailsThenSucceeds) {
294 // Authentication fails on first pass.
295 StartLifeCycle();
296 OnConnectionFound();
297 Authenticate(Authenticator::Result::FAILURE);
298 EXPECT_FALSE(life_cycle_.GetClient());
299 EXPECT_CALL(*this, OnLifeCycleStateChanged(_, _));
300 task_runner_->RunUntilIdle();
302 // Authentication succeeds on second pass.
303 Connection* connection = OnConnectionFound();
304 Authenticate(Authenticator::Result::SUCCESS);
305 EXPECT_TRUE(life_cycle_.GetClient());
306 EXPECT_CALL(*this, OnLifeCycleStateChanged(_, _));
307 connection->Disconnect();
310 } // namespace proximity_auth