Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: remoting/test/app_remoting_connected_client_tests.cc

Issue 1008043003: Adding Test Fixture for initial test cases for the App Remoting Test Driver. Also includes the pub… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 "remoting/test/app_remoting_connected_client_tests.h"
6
7 #include "base/json/json_reader.h"
8 #include "base/logging.h"
9 #include "base/run_loop.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/values.h"
12 #include "remoting/protocol/host_stub.h"
13 #include "remoting/test/app_remoting_test_driver_environment.h"
14 #include "remoting/test/remote_application_data.h"
15 #include "remoting/test/test_chromoting_client.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace {
19 const int kDefaultDPI = 96;
20 const int kDefaultWidth = 1024;
21 const int kDefaultHeight = 768;
22
23 void SimpleHostMessageReceivedHandler(
24 const std::string& target_message_type,
25 const std::string& target_message_data,
26 const base::Closure& done_closure,
27 bool* message_received,
28 const remoting::protocol::ExtensionMessage& message) {
29 if (message.type() == target_message_type &&
30 message.data() == target_message_data) {
31 *message_received = true;
32 done_closure.Run();
33 }
34 }
35 }
Wez 2015/03/16 22:19:08 nit: This is a non-trivial namespace declaration,
joedow 2015/03/18 20:13:08 Done.
36
37 namespace remoting {
38 namespace test {
39
40 scoped_ptr<base::MessageLoopForIO>
41 AppRemotingConnectedClientTests::message_loop_;
Wez 2015/03/16 22:19:08 Does this line really need wrapping?
joedow 2015/03/18 20:13:08 It does :(
42 scoped_ptr<TestChromotingClient> AppRemotingConnectedClientTests::client_;
43 bool AppRemotingConnectedClientTests::connection_is_ready_for_tests_;
44
45 AppRemotingConnectedClientTests::AppRemotingConnectedClientTests()
46 : application_info_(GetRemoteApplicationInfoMap().at(GetParam())) {
47 }
48
49 AppRemotingConnectedClientTests::~AppRemotingConnectedClientTests() {
50 }
51
52 void AppRemotingConnectedClientTests::SetUp() {
53 // NOTE: Code here will be called immediately after the constructor (right
54 // before each test).
Wez 2015/03/16 22:19:09 Which of these properties is the important one to
joedow 2015/03/18 20:13:08 Done. Removed since I got rid of the static metho
55 DCHECK(client_);
Wez 2015/03/16 22:19:09 No point DCHECKing a pointer immediately before de
joedow 2015/03/18 20:13:08 Done.
56 client_->AddRemoteConnectionObserver(this);
57
58 // If the client has not attempted to create a connection in the past, then
59 // start one now.
60 if (client_->connection_to_host_state() ==
61 protocol::ConnectionToHost::INITIALIZING &&
62 client_->connection_error_code() == protocol::OK) {
63 StartConnection();
64 }
65
66 if (!connection_is_ready_for_tests_) {
67 FAIL() << "Remote host connection could not be completed.";
68 client_->EndConnection();
69 }
70 }
71
72 void AppRemotingConnectedClientTests::TearDown() {
73 // NOTE: Code here will be called immediately after each test (right
74 // before the destructor).
75 DCHECK(client_);
Wez 2015/03/16 22:19:09 See above re DCHECK
joedow 2015/03/18 20:13:08 Done.
76 client_->RemoveRemoteConnectionObserver(this);
77 }
78
79 void AppRemotingConnectedClientTests::SetUpTestCase() {
80 // NOTE: Code here will be called before any instance constructors are called.
81 DCHECK(!message_loop_);
82 message_loop_.reset(new base::MessageLoopForIO);
83
84 DCHECK(!client_);
85 client_.reset(new TestChromotingClient());
86 }
87
88 void AppRemotingConnectedClientTests::TearDownTestCase() {
89 // NOTE: Code here will be called immediately after all tests are done.
90 connection_is_ready_for_tests_ = false;
91
92 // The client must be destroyed before the message loop as some of its
93 // members are destroyed via DeleteSoon on the message loop's TaskRunner.
Wez 2015/03/16 22:19:09 Unless you actually run the message-loop after des
joedow 2015/03/18 20:13:08 I had thought this was happening in the D'Tor for
94 client_.reset();
95 message_loop_.reset();
96 }
97
98 bool AppRemotingConnectedClientTests::VerifyResponseForSimpleHostMessage(
99 const std::string& message_request_title,
100 const std::string& message_response_title,
101 const std::string& message_payload,
102 const base::TimeDelta& max_wait_time) {
103 base::RunLoop run_loop;
104 bool message_received = false;
105
106 done_closure_ = run_loop.QuitClosure();
Wez 2015/03/16 22:19:08 Why are you saving the QuitClosure() for a RunLoop
joedow 2015/03/18 20:13:09 Done.
107 host_message_received_callback_ =
108 base::Bind(&SimpleHostMessageReceivedHandler, message_response_title,
109 message_payload, done_closure_, &message_received);
110
111 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, done_closure_,
112 max_wait_time);
Wez 2015/03/16 22:19:09 Cleaner to use a base::Timer for this?
joedow 2015/03/18 20:13:08 Done.
113
114 protocol::ExtensionMessage message;
115 message.set_type(message_request_title);
116 message.set_data(message_payload);
117 client_->host_stub()->DeliverClientMessage(message);
118
119 run_loop.Run();
120 host_message_received_callback_.Reset();
121
122 return message_received;
123 }
124
125 void AppRemotingConnectedClientTests::StartConnection() {
126 DCHECK(client_);
127
128 RemoteHostInfo remote_host_info;
129 remoting::test::AppRemotingSharedData->GetRemoteHostInfoForApplicationId(
130 application_info_.application_id, &remote_host_info);
131
132 if (!remote_host_info.IsReadyForConnection()) {
133 LOG(ERROR) << "Remote Host is unavailable for connections.";
134 return;
135 }
136
137 base::RunLoop run_loop;
138
139 done_closure_ = run_loop.QuitClosure();
Wez 2015/03/16 22:19:09 See above, re why this needs saving.
joedow 2015/03/18 20:13:08 Done.
140 host_message_received_callback_ =
141 base::Bind(&AppRemotingConnectedClientTests::AddWindowMessageHandler,
142 base::Unretained(this), application_info_.main_window_name);
143
144 // We will wait up to 30 seconds to complete the remote connection and for the
145 // main application window to become visible.
146 base::TimeDelta wait_time = base::TimeDelta::FromSeconds(30);
147
148 // Post the QuitClosure with a max timeout to ensure we don't run forever.
149 // The QuitClosure will NOP if the connection was created before the timeout.
150 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, done_closure_,
151 wait_time);
Wez 2015/03/16 22:19:09 See above re base::Timer
joedow 2015/03/18 20:13:08 Done.
152
153 client_->StartConnection(AppRemotingSharedData->user_name(),
154 AppRemotingSharedData->access_token(),
155 remote_host_info);
156
157 run_loop.Run();
158 host_message_received_callback_.Reset();
159 }
160
161 void AppRemotingConnectedClientTests::ConnectionStateChanged(
Wez 2015/03/16 22:19:08 The RemoteConnectionObserver APIs are called by th
joedow 2015/03/18 20:13:08 Done.
162 protocol::ConnectionToHost::State state,
163 protocol::ErrorCode error_code) {
164 if (state != protocol::ConnectionToHost::CONNECTED ||
165 error_code != protocol::OK) {
166 connection_is_ready_for_tests_ = false;
167 }
168
169 if (!done_closure_.is_null() &&
170 (state == protocol::ConnectionToHost::CLOSED ||
171 state == protocol::ConnectionToHost::FAILED ||
172 error_code != protocol::OK)) {
Wez 2015/03/16 22:19:08 Why are these two connection-state checks differen
joedow 2015/03/18 20:13:08 Done.
173 done_closure_.Run();
174 }
175 }
176
177 void AppRemotingConnectedClientTests::ConnectionReady(bool ready) {
Wez 2015/03/16 22:19:09 Under what circumstances will we receive this call
joedow 2015/03/18 20:13:08 Done.
178 if (ready) {
179 SendClientConnectionDetailsToHost();
180 }
181 }
182
183 void AppRemotingConnectedClientTests::HostMessageReceived(
184 const protocol::ExtensionMessage& message) {
185 if (!host_message_received_callback_.is_null()) {
Wez 2015/03/16 22:19:09 Do we really want to ignore host messages received
joedow 2015/03/18 20:13:08 I've updated this method so that we can add defaul
186 host_message_received_callback_.Run(message);
187 }
188 }
189
190 void AppRemotingConnectedClientTests::SendClientConnectionDetailsToHost() {
191 // First send an access token which will be used for GDrive access.
192 protocol::ExtensionMessage message;
193 message.set_type("accessToken");
194 message.set_data(AppRemotingSharedData->access_token());
195
196 DVLOG(1) << "Sending access token to host";
197 client_->host_stub()->DeliverClientMessage(message);
198
199 // next send the host a description of the client screen size.
Wez 2015/03/16 22:19:09 nit: Capitalization
joedow 2015/03/18 20:13:08 Done.
200 protocol::ClientResolution client_resolution;
201 client_resolution.set_width(kDefaultWidth);
202 client_resolution.set_height(kDefaultHeight);
203 client_resolution.set_x_dpi(kDefaultDPI);
204 client_resolution.set_y_dpi(kDefaultDPI);
205 client_resolution.set_dips_width(kDefaultWidth);
206 client_resolution.set_dips_height(kDefaultHeight);
207
208 DVLOG(1) << "Sending ClientResolution details to host";
209 client_->host_stub()->NotifyClientResolution(client_resolution);
210
211 // Finally send a message to start sending us video packets.
212 protocol::VideoControl video_control;
213 video_control.set_enable(true);
214
Wez 2015/03/16 22:19:08 nit: No need for this blank line.
joedow 2015/03/18 20:13:08 Done.
215 video_control.set_lossless_encode(true);
216 video_control.set_lossless_color(true);
Wez 2015/03/16 22:19:08 By default these are currently off (false).
joedow 2015/03/18 20:13:09 Done.
217
218 DVLOG(1) << "Sending enable VideoControl message to host";
219 client_->host_stub()->ControlVideo(video_control);
220 }
221
222 void AppRemotingConnectedClientTests::AddWindowMessageHandler(
223 const std::string& main_window_name,
Wez 2015/03/16 22:19:08 It seems strange to pass main_window_name in as a
joedow 2015/03/18 20:13:08 This is an artifact of some refactoring I did, you
224 const remoting::protocol::ExtensionMessage& message) {
225 if (message.type() == "onWindowAdded") {
226 const base::DictionaryValue* message_data = nullptr;
227 scoped_ptr<base::Value> host_message(
228 base::JSONReader::Read(message.data()));
229 if (!host_message.get() || !host_message->GetAsDictionary(&message_data)) {
230 LOG(ERROR) << "Message received was not valid JSON.";
Wez 2015/03/16 22:19:08 Should we terminate the test (e.g. via |done_callb
joedow 2015/03/18 20:13:08 Done.
231 return;
232 }
233
234 std::string current_window_title;
235 message_data->GetString("title", &current_window_title);
236
237 if (current_window_title == kHostProcessWindowTitle) {
238 LOG(WARNING) << "Host Process Window is visible, this may mean that the "
239 << "underlying application is in a bad state, YMMV.";
Wez 2015/03/16 22:19:08 I'm surprised that this is ever a state we get int
joedow 2015/03/18 20:13:08 I saw this last year when we had created a snapsho
240 }
241
242 std::string main_window_title = main_window_name;
243 if (current_window_title.find_first_of(main_window_title) == 0) {
244 connection_is_ready_for_tests_ = true;
245
246 // Now that the main window is visible, give the app some time to settle
247 // before signaling that it is ready to run tests.
248 base::TimeDelta wait_time = base::TimeDelta::FromSeconds(5);
249 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
250 FROM_HERE, done_closure_, wait_time);
Wez 2015/03/16 22:19:08 Consider replacing this with a base::Timer member
joedow 2015/03/18 20:13:08 Done.
251 }
252 }
Wez 2015/03/16 22:19:08 Do we want to completely ignore all other window m
joedow 2015/03/18 20:13:08 I'd like to keep this method simple for now, we ca
253 }
254
255 } // namespace test
256 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698