OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include <string> | |
6 | |
7 #include "base/message_loop/message_loop.h" | |
8 #include "remoting/protocol/fake_connection_to_host.h" | |
9 #include "remoting/protocol/protocol_mock_objects.h" | |
10 #include "remoting/test/chromoting_instance.h" | |
11 #include "testing/gmock/include/gmock/gmock.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 | |
14 namespace { | |
15 const char kTestUserName[] = "test_user@faux_address.com"; | |
16 const char kAccessToken[] = "faux_access_token"; | |
17 } | |
18 | |
19 namespace remoting { | |
20 namespace test { | |
21 | |
22 using testing::_; | |
23 | |
24 // Provides base functionality for the ChromotingInstance Tests below. This | |
25 // fixture also creates an IO MessageLoop, if necessary, for use by the | |
26 // ChromotingInstance. Overrides a subset of the RemoteConnectionObserver | |
27 // interface to track connection status changes for result verification. | |
28 class ChromotingInstanceTest : | |
29 public ::testing::Test, | |
30 public RemoteConnectionObserver { | |
31 public: | |
32 ChromotingInstanceTest(); | |
33 ~ChromotingInstanceTest() override; | |
34 | |
35 protected: | |
36 // Test interface. | |
37 void SetUp() override; | |
38 void TearDown() override; | |
39 | |
40 // Used for result verification. | |
41 bool is_connected_to_host_; | |
42 protocol::ConnectionToHost::State connection_state_; | |
43 protocol::ErrorCode error_code_; | |
44 | |
45 // Used for simulating different conditions for the ChromotingInstance. | |
46 RemoteHostInfo remote_host_info_; | |
47 FakeConnectionToHost fake_connection_to_host_; | |
48 protocol::MockConnectionToHost* mock_connection_to_host_; | |
49 | |
50 scoped_ptr<remoting::test::ChromotingInstance> chromoting_instance_; | |
51 | |
52 private: | |
53 // RemoteConnectionObserver interface. | |
54 void ConnectionStateChanged( | |
55 protocol::ConnectionToHost::State state, | |
56 protocol::ErrorCode error_code) override; | |
57 void ConnectedToRemoteHost() override; | |
58 void DisconnectedFromRemoteHost() override; | |
59 | |
60 // Used as return values in ON_CALL overrides for MockConnectionToHost. | |
61 protocol::MockHostStub mock_host_stub_; | |
62 protocol::SessionConfig session_config_; | |
63 | |
64 scoped_ptr<base::MessageLoopForIO> message_loop_; | |
Sergey Ulanov
2015/03/09 06:44:41
Usually message_loop_ is defined as a first field
Sergey Ulanov
2015/03/09 06:44:41
Don't need this to be a pointer, see my next comme
joedow
2015/03/09 21:09:26
Done.
joedow
2015/03/09 21:09:26
Done.
| |
65 | |
66 DISALLOW_COPY_AND_ASSIGN(ChromotingInstanceTest); | |
67 }; | |
68 | |
69 ChromotingInstanceTest::ChromotingInstanceTest() : | |
70 is_connected_to_host_(false), | |
71 connection_state_(protocol::ConnectionToHost::INITIALIZING), | |
72 error_code_(protocol::OK), | |
73 mock_connection_to_host_(nullptr) {} | |
74 | |
75 ChromotingInstanceTest::~ChromotingInstanceTest() {} | |
76 | |
77 void ChromotingInstanceTest::SetUp() { | |
78 if (!base::MessageLoop::current()) { | |
79 // Create a temporary message loop if the current thread does not already | |
Sergey Ulanov
2015/03/09 06:44:41
This code is never expected to be invoked with a M
joedow
2015/03/09 21:09:26
Done.
| |
80 // have one so we can use its task runner to create a request object. | |
81 message_loop_.reset(new base::MessageLoopForIO); | |
82 } | |
83 | |
84 chromoting_instance_.reset(new remoting::test::ChromotingInstance); | |
85 chromoting_instance_->AddRemoteConnectionObserver(this); | |
86 | |
87 // Pass ownership of the MockConnectionToHost to the chromoting instance but | |
88 // keep the ptr around so we can use it to simulate state changes. It will | |
89 // remain valid until |chromoting_instance_| is destroyed. | |
90 mock_connection_to_host_ = new protocol::MockConnectionToHost(); | |
91 chromoting_instance_->SetConnectionToHostForTests( | |
92 make_scoped_ptr(mock_connection_to_host_)); | |
93 | |
94 session_config_ = protocol::SessionConfig::ForTest(); | |
95 remote_host_info_.remote_host_status = kRemoteHostStatusReady; | |
96 | |
97 // We want to redirect some of the calls to the mock objects to real objects | |
98 // which implement a simplified version of the method so ON_CALL is used. | |
99 ON_CALL(*mock_connection_to_host_, | |
100 ConnectPtr(_, _, _, _, _)).WillByDefault(testing::Invoke( | |
101 &fake_connection_to_host_, &FakeConnectionToHost::ConnectPtr)); | |
Sergey Ulanov
2015/03/09 06:44:41
Do you need MockConnectionToHost, given that there
joedow
2015/03/09 21:09:26
Thanks for this info, I see GMOCK used often in th
| |
102 ON_CALL(*mock_connection_to_host_, | |
103 OnSessionStateChange(_)).WillByDefault(testing::Invoke( | |
104 &fake_connection_to_host_, | |
105 &FakeConnectionToHost::OnSessionStateChange)); | |
106 ON_CALL(*mock_connection_to_host_, | |
107 OnVideoChannelStatus(_)).WillByDefault(testing::Invoke( | |
108 &fake_connection_to_host_, | |
109 &FakeConnectionToHost::OnVideoChannelStatus)); | |
110 ON_CALL(*mock_connection_to_host_, config()).WillByDefault( | |
111 testing::ReturnRef(session_config_)); | |
112 ON_CALL(*mock_connection_to_host_, host_stub()).WillByDefault( | |
113 testing::Return(&mock_host_stub_)); | |
114 | |
115 EXPECT_CALL(mock_host_stub_, SetCapabilities(_)) | |
116 .Times(testing::AtMost(1)); | |
117 EXPECT_CALL(*mock_connection_to_host_, ConnectPtr(_, _, _, _, _)) | |
118 .Times(testing::AtMost(1)); | |
119 EXPECT_CALL(*mock_connection_to_host_, OnSessionStateChange(_)) | |
120 .Times(testing::AnyNumber()); | |
121 EXPECT_CALL(*mock_connection_to_host_, OnVideoChannelStatus(_)) | |
122 .Times(testing::AnyNumber()); | |
123 EXPECT_CALL(*mock_connection_to_host_, config()) | |
124 .Times(testing::AnyNumber()); | |
125 EXPECT_CALL(*mock_connection_to_host_, host_stub()) | |
126 .Times(testing::AnyNumber()); | |
127 } | |
128 | |
129 void ChromotingInstanceTest::TearDown() { | |
130 chromoting_instance_->RemoveRemoteConnectionObserver(this); | |
131 mock_connection_to_host_ = nullptr; | |
132 | |
133 // The chromoting instance must be destroyed before the message loop. | |
134 chromoting_instance_.reset(); | |
135 | |
136 // The LibjingleTransportFactory destroys the PortAllocator via a DeleteSoon | |
137 // operation. If we do not allow the message loop to run here, we run the | |
138 // risk of the DeleteSoon task being dropped and incurring a memory leak. | |
139 message_loop_->RunUntilIdle(); | |
140 | |
141 // Now that the message loop is clear, we can destroy it. | |
142 message_loop_.reset(); | |
143 } | |
144 | |
145 void ChromotingInstanceTest::ConnectionStateChanged( | |
146 protocol::ConnectionToHost::State state, | |
147 protocol::ErrorCode error_code) { | |
148 connection_state_ = state; | |
149 error_code_ = error_code; | |
150 } | |
151 | |
152 void ChromotingInstanceTest::ConnectedToRemoteHost() { | |
153 is_connected_to_host_ = true; | |
154 } | |
155 | |
156 void ChromotingInstanceTest::DisconnectedFromRemoteHost() { | |
157 is_connected_to_host_ = false; | |
158 } | |
159 | |
160 TEST_F(ChromotingInstanceTest, StartConnectionAndDisconnect) { | |
161 chromoting_instance_->StartConnection( | |
162 kTestUserName, | |
163 kAccessToken, | |
164 remote_host_info_); | |
165 EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTING, connection_state_); | |
166 EXPECT_EQ(protocol::ErrorCode::OK, error_code_); | |
167 EXPECT_FALSE(is_connected_to_host_); | |
168 | |
169 // Simulate an AUTHENTICATED message being sent from the Jingle session. | |
170 mock_connection_to_host_->OnSessionStateChange( | |
171 protocol::Session::AUTHENTICATED); | |
172 EXPECT_EQ(protocol::ConnectionToHost::State::AUTHENTICATED, | |
173 connection_state_); | |
174 EXPECT_EQ(protocol::ErrorCode::OK, error_code_); | |
175 EXPECT_FALSE(is_connected_to_host_); | |
176 | |
177 // Simulate a CONNECTED message being sent from the Jingle session. | |
178 mock_connection_to_host_->OnSessionStateChange(protocol::Session::CONNECTED); | |
179 EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTED, connection_state_); | |
180 EXPECT_EQ(protocol::ErrorCode::OK, error_code_); | |
181 EXPECT_FALSE(is_connected_to_host_); | |
182 | |
183 // The chromoting instance will consider its connection to the host complete | |
184 // once the video channel is active. | |
185 mock_connection_to_host_->OnVideoChannelStatus(true); | |
186 EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTED, connection_state_); | |
187 EXPECT_EQ(protocol::ErrorCode::OK, error_code_); | |
188 EXPECT_TRUE(is_connected_to_host_); | |
189 | |
190 chromoting_instance_->EndConnection(); | |
191 EXPECT_EQ(protocol::ConnectionToHost::State::CLOSED, connection_state_); | |
192 EXPECT_EQ(protocol::ErrorCode::OK, error_code_); | |
193 EXPECT_FALSE(is_connected_to_host_); | |
194 } | |
195 | |
196 TEST_F(ChromotingInstanceTest, StartConnectionThenFailWithAuthenticationError) { | |
197 chromoting_instance_->StartConnection( | |
198 kTestUserName, | |
199 kAccessToken, | |
200 remote_host_info_); | |
201 EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTING, connection_state_); | |
202 EXPECT_EQ(protocol::ErrorCode::OK, error_code_); | |
203 EXPECT_FALSE(is_connected_to_host_); | |
204 | |
205 fake_connection_to_host_.set_session_state_change_error_code( | |
206 protocol::AUTHENTICATION_FAILED); | |
207 mock_connection_to_host_->OnSessionStateChange(protocol::Session::FAILED); | |
208 EXPECT_EQ(protocol::ConnectionToHost::State::FAILED, connection_state_); | |
209 EXPECT_EQ(protocol::ErrorCode::AUTHENTICATION_FAILED, error_code_); | |
210 EXPECT_FALSE(is_connected_to_host_); | |
211 | |
212 // Close the connection via the ChromotingInstance and verify the error state | |
213 // is persisted. | |
214 chromoting_instance_->EndConnection(); | |
215 EXPECT_EQ(protocol::ConnectionToHost::State::FAILED, connection_state_); | |
216 EXPECT_EQ(protocol::ErrorCode::AUTHENTICATION_FAILED, error_code_); | |
217 EXPECT_FALSE(is_connected_to_host_); | |
218 } | |
219 | |
220 TEST_F(ChromotingInstanceTest, StartConnectionThenFailWithUnknownError) { | |
221 chromoting_instance_->StartConnection( | |
222 kTestUserName, | |
223 kAccessToken, | |
224 remote_host_info_); | |
225 EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTING, connection_state_); | |
226 EXPECT_EQ(protocol::ErrorCode::OK, error_code_); | |
227 EXPECT_FALSE(is_connected_to_host_); | |
228 | |
229 // Simulate an AUTHENTICATED message being sent from the Jingle session. | |
230 mock_connection_to_host_->OnSessionStateChange( | |
231 protocol::Session::AUTHENTICATED); | |
232 EXPECT_EQ(protocol::ConnectionToHost::State::AUTHENTICATED, | |
233 connection_state_); | |
234 EXPECT_EQ(protocol::ErrorCode::OK, error_code_); | |
235 EXPECT_FALSE(is_connected_to_host_); | |
236 | |
237 // Simulate a CONNECTED message being sent from the Jingle session. | |
238 mock_connection_to_host_->OnSessionStateChange(protocol::Session::CONNECTED); | |
239 EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTED, connection_state_); | |
240 EXPECT_EQ(protocol::ErrorCode::OK, error_code_); | |
241 EXPECT_FALSE(is_connected_to_host_); | |
242 | |
243 // The chromoting instance will consider its connection to the host complete | |
244 // once the video channel is active. | |
245 mock_connection_to_host_->OnVideoChannelStatus(true); | |
246 EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTED, connection_state_); | |
247 EXPECT_EQ(protocol::ErrorCode::OK, error_code_); | |
248 EXPECT_TRUE(is_connected_to_host_); | |
249 | |
250 fake_connection_to_host_.set_session_state_change_error_code( | |
251 protocol::UNKNOWN_ERROR); | |
252 mock_connection_to_host_->OnSessionStateChange(protocol::Session::FAILED); | |
253 EXPECT_EQ(protocol::ConnectionToHost::State::FAILED, connection_state_); | |
254 EXPECT_EQ(protocol::ErrorCode::UNKNOWN_ERROR, error_code_); | |
255 EXPECT_FALSE(is_connected_to_host_); | |
256 | |
257 // Close the connection via the ChromotingInstance and verify the error state | |
258 // is persisted. | |
259 chromoting_instance_->EndConnection(); | |
260 EXPECT_EQ(protocol::ConnectionToHost::State::FAILED, connection_state_); | |
261 EXPECT_EQ(protocol::ErrorCode::UNKNOWN_ERROR, error_code_); | |
262 EXPECT_FALSE(is_connected_to_host_); | |
263 } | |
264 | |
265 } // namespace test | |
266 } // namespace remoting | |
OLD | NEW |