blob: 39d9b34885d9f47474a252d360cc3476f4092fd6 [file] [log] [blame]
[email protected]b5a6afe2012-01-07 05:48:201// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]1bc9c7c2011-12-14 00:13:392// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "remoting/protocol/pepper_session.h"
6
7#include "base/bind.h"
8#include "base/message_loop.h"
9#include "base/time.h"
10#include "base/test/test_timeouts.h"
11#include "remoting/base/constants.h"
12#include "remoting/protocol/authenticator.h"
13#include "remoting/protocol/channel_authenticator.h"
14#include "remoting/protocol/connection_tester.h"
15#include "remoting/protocol/fake_authenticator.h"
16#include "remoting/protocol/jingle_session.h"
17#include "remoting/protocol/jingle_session_manager.h"
18#include "remoting/protocol/pepper_session_manager.h"
19#include "remoting/jingle_glue/jingle_thread.h"
20#include "remoting/jingle_glue/fake_signal_strategy.h"
21#include "testing/gmock/include/gmock/gmock.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24using testing::_;
25using testing::AtMost;
26using testing::DeleteArg;
27using testing::DoAll;
28using testing::InSequence;
29using testing::Invoke;
30using testing::InvokeWithoutArgs;
31using testing::Return;
32using testing::SaveArg;
33using testing::SetArgumentPointee;
34using testing::WithArg;
35
36namespace remoting {
37namespace protocol {
38
39namespace {
40
41const char kHostJid[] = "[email protected]/123";
42const char kClientJid[] = "[email protected]/321";
43
44class MockSessionManagerListener : public SessionManager::Listener {
45 public:
[email protected]08128a312012-01-03 21:02:3946 MOCK_METHOD0(OnSessionManagerReady, void());
[email protected]1bc9c7c2011-12-14 00:13:3947 MOCK_METHOD2(OnIncomingSession,
48 void(Session*,
49 SessionManager::IncomingSessionResponse*));
50};
51
52class MockSessionCallback {
53 public:
54 MOCK_METHOD1(OnStateChange, void(Session::State));
55};
56
57} // namespace
58
59class PepperSessionTest : public testing::Test {
60 public:
61 PepperSessionTest()
62 : message_loop_(talk_base::Thread::Current()) {
63 }
64
65 // Helper method that handles OnIncomingSession().
66 void SetHostSession(Session* session) {
67 DCHECK(session);
68 host_session_.reset(session);
69 host_session_->SetStateChangeCallback(
70 base::Bind(&MockSessionCallback::OnStateChange,
71 base::Unretained(&host_connection_callback_)));
72
73 session->set_config(SessionConfig::GetDefault());
74 }
75
76 protected:
77 virtual void SetUp() {
78 }
79
80 virtual void TearDown() {
81 CloseSessions();
82 CloseSessionManager();
83 }
84
85 void CloseSessions() {
86 host_session_.reset();
87 client_session_.reset();
88 }
89
90 void CreateSessionManagers(int auth_round_trips,
91 FakeAuthenticator::Action auth_action) {
92 host_signal_strategy_.reset(new FakeSignalStrategy(kHostJid));
93 client_signal_strategy_.reset(new FakeSignalStrategy(kClientJid));
94 FakeSignalStrategy::Connect(host_signal_strategy_.get(),
95 client_signal_strategy_.get());
96
[email protected]08128a312012-01-03 21:02:3997 EXPECT_CALL(host_server_listener_, OnSessionManagerReady())
[email protected]1bc9c7c2011-12-14 00:13:3998 .Times(1);
99 host_server_.reset(new JingleSessionManager(
100 base::MessageLoopProxy::current()));
101 host_server_->Init(
[email protected]08128a312012-01-03 21:02:39102 host_signal_strategy_.get(), &host_server_listener_, false);
[email protected]1bc9c7c2011-12-14 00:13:39103
[email protected]b5a6afe2012-01-07 05:48:20104 scoped_ptr<AuthenticatorFactory> factory(
[email protected]1bc9c7c2011-12-14 00:13:39105 new FakeHostAuthenticatorFactory(auth_round_trips, auth_action, true));
[email protected]b5a6afe2012-01-07 05:48:20106 host_server_->set_authenticator_factory(factory.Pass());
[email protected]1bc9c7c2011-12-14 00:13:39107
[email protected]08128a312012-01-03 21:02:39108 EXPECT_CALL(client_server_listener_, OnSessionManagerReady())
[email protected]1bc9c7c2011-12-14 00:13:39109 .Times(1);
110 client_server_.reset(new PepperSessionManager(NULL));
111 client_server_->Init(
[email protected]08128a312012-01-03 21:02:39112 client_signal_strategy_.get(), &client_server_listener_, false);
[email protected]1bc9c7c2011-12-14 00:13:39113 }
114
115 void CloseSessionManager() {
116 if (host_server_.get()) {
117 host_server_->Close();
118 host_server_.reset();
119 }
120 if (client_server_.get()) {
121 client_server_->Close();
122 client_server_.reset();
123 }
124 host_signal_strategy_.reset();
125 client_signal_strategy_.reset();
126 }
127
128 void InitiateConnection(int auth_round_trips,
129 FakeAuthenticator::Action auth_action,
130 bool expect_fail) {
131 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
132 .WillOnce(DoAll(
133 WithArg<0>(Invoke(this, &PepperSessionTest::SetHostSession)),
134 SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
135
136 {
137 InSequence dummy;
138
139 EXPECT_CALL(host_connection_callback_,
140 OnStateChange(Session::CONNECTED))
141 .Times(AtMost(1));
142 if (expect_fail) {
143 EXPECT_CALL(host_connection_callback_,
144 OnStateChange(Session::FAILED))
145 .Times(1);
146 } else {
147 EXPECT_CALL(host_connection_callback_,
148 OnStateChange(Session::AUTHENTICATED))
149 .Times(1);
150 // Expect that the connection will be closed eventually.
151 EXPECT_CALL(host_connection_callback_,
152 OnStateChange(Session::CLOSED))
153 .Times(AtMost(1));
154 }
155 }
156
157 {
158 InSequence dummy;
159
160 EXPECT_CALL(client_connection_callback_,
161 OnStateChange(Session::CONNECTING))
162 .Times(1);
163 EXPECT_CALL(client_connection_callback_,
164 OnStateChange(Session::CONNECTED))
165 .Times(AtMost(1));
166 if (expect_fail) {
167 EXPECT_CALL(client_connection_callback_,
168 OnStateChange(Session::FAILED))
169 .Times(1);
170 } else {
171 EXPECT_CALL(client_connection_callback_,
172 OnStateChange(Session::AUTHENTICATED))
173 .Times(1);
174 // Expect that the connection will be closed eventually.
175 EXPECT_CALL(client_connection_callback_,
176 OnStateChange(Session::CLOSED))
177 .Times(AtMost(1));
178 }
179 }
180
181 Authenticator* authenticator = new FakeAuthenticator(
182 FakeAuthenticator::CLIENT, auth_round_trips, auth_action, true);
183
184 client_session_.reset(client_server_->Connect(
185 kHostJid, authenticator,
186 CandidateSessionConfig::CreateDefault(),
187 base::Bind(&MockSessionCallback::OnStateChange,
188 base::Unretained(&client_connection_callback_))));
189
190 message_loop_.RunAllPending();
191 }
192
193 JingleThreadMessageLoop message_loop_;
194
195 scoped_ptr<FakeSignalStrategy> host_signal_strategy_;
196 scoped_ptr<FakeSignalStrategy> client_signal_strategy_;
197
198 scoped_ptr<JingleSessionManager> host_server_;
199 MockSessionManagerListener host_server_listener_;
200 scoped_ptr<PepperSessionManager> client_server_;
201 MockSessionManagerListener client_server_listener_;
202
203 scoped_ptr<Session> host_session_;
204 MockSessionCallback host_connection_callback_;
205 scoped_ptr<Session> client_session_;
206 MockSessionCallback client_connection_callback_;
207};
208
209
210// Verify that we can create and destroy session managers without a
211// connection.
212TEST_F(PepperSessionTest, CreateAndDestoy) {
213 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
214}
215
216// Verify that an incoming session can be rejected, and that the
217// status of the connection is set to FAILED in this case.
218TEST_F(PepperSessionTest, RejectConnection) {
219 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
220
221 // Reject incoming session.
222 EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
223 .WillOnce(SetArgumentPointee<1>(protocol::SessionManager::DECLINE));
224
225 {
226 InSequence dummy;
227
228 EXPECT_CALL(client_connection_callback_,
229 OnStateChange(Session::CONNECTING))
230 .Times(1);
231 EXPECT_CALL(client_connection_callback_,
232 OnStateChange(Session::FAILED))
233 .Times(1);
234 }
235
236 Authenticator* authenticator = new FakeAuthenticator(
237 FakeAuthenticator::CLIENT, 1, FakeAuthenticator::ACCEPT, true);
238 client_session_.reset(client_server_->Connect(
239 kHostJid, authenticator,
240 CandidateSessionConfig::CreateDefault(),
241 base::Bind(&MockSessionCallback::OnStateChange,
242 base::Unretained(&client_connection_callback_))));
243
244 message_loop_.RunAllPending();
245}
246
247// Verify that we can connect two endpoints with single-step authentication.
248TEST_F(PepperSessionTest, Connect) {
249 CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
250 InitiateConnection(1, FakeAuthenticator::ACCEPT, false);
251}
252
253// Verify that we can connect two endpoints with multi-step authentication.
254TEST_F(PepperSessionTest, ConnectWithMultistep) {
255 CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
256 InitiateConnection(3, FakeAuthenticator::ACCEPT, false);
257}
258
259// Verify that connection is terminated when single-step auth fails.
260TEST_F(PepperSessionTest, ConnectWithBadAuth) {
261 CreateSessionManagers(1, FakeAuthenticator::REJECT);
262 InitiateConnection(1, FakeAuthenticator::ACCEPT, true);
263}
264
265// Verify that connection is terminated when multi-step auth fails.
266TEST_F(PepperSessionTest, ConnectWithBadMultistepAuth) {
267 CreateSessionManagers(3, FakeAuthenticator::REJECT);
268 InitiateConnection(3, FakeAuthenticator::ACCEPT, true);
269}
270
271} // namespace protocol
272} // namespace remoting