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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: remoting/test/app_remoting_connected_client_tests.cc
diff --git a/remoting/test/app_remoting_connected_client_tests.cc b/remoting/test/app_remoting_connected_client_tests.cc
new file mode 100644
index 0000000000000000000000000000000000000000..cd10085fa342a2937f2440341f01b323f5a4b70a
--- /dev/null
+++ b/remoting/test/app_remoting_connected_client_tests.cc
@@ -0,0 +1,256 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/test/app_remoting_connected_client_tests.h"
+
+#include "base/json/json_reader.h"
+#include "base/logging.h"
+#include "base/run_loop.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/values.h"
+#include "remoting/protocol/host_stub.h"
+#include "remoting/test/app_remoting_test_driver_environment.h"
+#include "remoting/test/remote_application_data.h"
+#include "remoting/test/test_chromoting_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+const int kDefaultDPI = 96;
+const int kDefaultWidth = 1024;
+const int kDefaultHeight = 768;
+
+void SimpleHostMessageReceivedHandler(
+ const std::string& target_message_type,
+ const std::string& target_message_data,
+ const base::Closure& done_closure,
+ bool* message_received,
+ const remoting::protocol::ExtensionMessage& message) {
+ if (message.type() == target_message_type &&
+ message.data() == target_message_data) {
+ *message_received = true;
+ done_closure.Run();
+ }
+}
+}
Wez 2015/03/16 22:19:08 nit: This is a non-trivial namespace declaration,
joedow 2015/03/18 20:13:08 Done.
+
+namespace remoting {
+namespace test {
+
+scoped_ptr<base::MessageLoopForIO>
+ 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 :(
+scoped_ptr<TestChromotingClient> AppRemotingConnectedClientTests::client_;
+bool AppRemotingConnectedClientTests::connection_is_ready_for_tests_;
+
+AppRemotingConnectedClientTests::AppRemotingConnectedClientTests()
+ : application_info_(GetRemoteApplicationInfoMap().at(GetParam())) {
+}
+
+AppRemotingConnectedClientTests::~AppRemotingConnectedClientTests() {
+}
+
+void AppRemotingConnectedClientTests::SetUp() {
+ // NOTE: Code here will be called immediately after the constructor (right
+ // 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
+ 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.
+ client_->AddRemoteConnectionObserver(this);
+
+ // If the client has not attempted to create a connection in the past, then
+ // start one now.
+ if (client_->connection_to_host_state() ==
+ protocol::ConnectionToHost::INITIALIZING &&
+ client_->connection_error_code() == protocol::OK) {
+ StartConnection();
+ }
+
+ if (!connection_is_ready_for_tests_) {
+ FAIL() << "Remote host connection could not be completed.";
+ client_->EndConnection();
+ }
+}
+
+void AppRemotingConnectedClientTests::TearDown() {
+ // NOTE: Code here will be called immediately after each test (right
+ // before the destructor).
+ DCHECK(client_);
Wez 2015/03/16 22:19:09 See above re DCHECK
joedow 2015/03/18 20:13:08 Done.
+ client_->RemoveRemoteConnectionObserver(this);
+}
+
+void AppRemotingConnectedClientTests::SetUpTestCase() {
+ // NOTE: Code here will be called before any instance constructors are called.
+ DCHECK(!message_loop_);
+ message_loop_.reset(new base::MessageLoopForIO);
+
+ DCHECK(!client_);
+ client_.reset(new TestChromotingClient());
+}
+
+void AppRemotingConnectedClientTests::TearDownTestCase() {
+ // NOTE: Code here will be called immediately after all tests are done.
+ connection_is_ready_for_tests_ = false;
+
+ // The client must be destroyed before the message loop as some of its
+ // 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
+ client_.reset();
+ message_loop_.reset();
+}
+
+bool AppRemotingConnectedClientTests::VerifyResponseForSimpleHostMessage(
+ const std::string& message_request_title,
+ const std::string& message_response_title,
+ const std::string& message_payload,
+ const base::TimeDelta& max_wait_time) {
+ base::RunLoop run_loop;
+ bool message_received = false;
+
+ 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.
+ host_message_received_callback_ =
+ base::Bind(&SimpleHostMessageReceivedHandler, message_response_title,
+ message_payload, done_closure_, &message_received);
+
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, done_closure_,
+ 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.
+
+ protocol::ExtensionMessage message;
+ message.set_type(message_request_title);
+ message.set_data(message_payload);
+ client_->host_stub()->DeliverClientMessage(message);
+
+ run_loop.Run();
+ host_message_received_callback_.Reset();
+
+ return message_received;
+}
+
+void AppRemotingConnectedClientTests::StartConnection() {
+ DCHECK(client_);
+
+ RemoteHostInfo remote_host_info;
+ remoting::test::AppRemotingSharedData->GetRemoteHostInfoForApplicationId(
+ application_info_.application_id, &remote_host_info);
+
+ if (!remote_host_info.IsReadyForConnection()) {
+ LOG(ERROR) << "Remote Host is unavailable for connections.";
+ return;
+ }
+
+ base::RunLoop run_loop;
+
+ 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.
+ host_message_received_callback_ =
+ base::Bind(&AppRemotingConnectedClientTests::AddWindowMessageHandler,
+ base::Unretained(this), application_info_.main_window_name);
+
+ // We will wait up to 30 seconds to complete the remote connection and for the
+ // main application window to become visible.
+ base::TimeDelta wait_time = base::TimeDelta::FromSeconds(30);
+
+ // Post the QuitClosure with a max timeout to ensure we don't run forever.
+ // The QuitClosure will NOP if the connection was created before the timeout.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, done_closure_,
+ wait_time);
Wez 2015/03/16 22:19:09 See above re base::Timer
joedow 2015/03/18 20:13:08 Done.
+
+ client_->StartConnection(AppRemotingSharedData->user_name(),
+ AppRemotingSharedData->access_token(),
+ remote_host_info);
+
+ run_loop.Run();
+ host_message_received_callback_.Reset();
+}
+
+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.
+ protocol::ConnectionToHost::State state,
+ protocol::ErrorCode error_code) {
+ if (state != protocol::ConnectionToHost::CONNECTED ||
+ error_code != protocol::OK) {
+ connection_is_ready_for_tests_ = false;
+ }
+
+ if (!done_closure_.is_null() &&
+ (state == protocol::ConnectionToHost::CLOSED ||
+ state == protocol::ConnectionToHost::FAILED ||
+ 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.
+ done_closure_.Run();
+ }
+}
+
+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.
+ if (ready) {
+ SendClientConnectionDetailsToHost();
+ }
+}
+
+void AppRemotingConnectedClientTests::HostMessageReceived(
+ const protocol::ExtensionMessage& message) {
+ 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
+ host_message_received_callback_.Run(message);
+ }
+}
+
+void AppRemotingConnectedClientTests::SendClientConnectionDetailsToHost() {
+ // First send an access token which will be used for GDrive access.
+ protocol::ExtensionMessage message;
+ message.set_type("accessToken");
+ message.set_data(AppRemotingSharedData->access_token());
+
+ DVLOG(1) << "Sending access token to host";
+ client_->host_stub()->DeliverClientMessage(message);
+
+ // 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.
+ protocol::ClientResolution client_resolution;
+ client_resolution.set_width(kDefaultWidth);
+ client_resolution.set_height(kDefaultHeight);
+ client_resolution.set_x_dpi(kDefaultDPI);
+ client_resolution.set_y_dpi(kDefaultDPI);
+ client_resolution.set_dips_width(kDefaultWidth);
+ client_resolution.set_dips_height(kDefaultHeight);
+
+ DVLOG(1) << "Sending ClientResolution details to host";
+ client_->host_stub()->NotifyClientResolution(client_resolution);
+
+ // Finally send a message to start sending us video packets.
+ protocol::VideoControl video_control;
+ video_control.set_enable(true);
+
Wez 2015/03/16 22:19:08 nit: No need for this blank line.
joedow 2015/03/18 20:13:08 Done.
+ video_control.set_lossless_encode(true);
+ 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.
+
+ DVLOG(1) << "Sending enable VideoControl message to host";
+ client_->host_stub()->ControlVideo(video_control);
+}
+
+void AppRemotingConnectedClientTests::AddWindowMessageHandler(
+ 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
+ const remoting::protocol::ExtensionMessage& message) {
+ if (message.type() == "onWindowAdded") {
+ const base::DictionaryValue* message_data = nullptr;
+ scoped_ptr<base::Value> host_message(
+ base::JSONReader::Read(message.data()));
+ if (!host_message.get() || !host_message->GetAsDictionary(&message_data)) {
+ 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.
+ return;
+ }
+
+ std::string current_window_title;
+ message_data->GetString("title", &current_window_title);
+
+ if (current_window_title == kHostProcessWindowTitle) {
+ LOG(WARNING) << "Host Process Window is visible, this may mean that the "
+ << "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
+ }
+
+ std::string main_window_title = main_window_name;
+ if (current_window_title.find_first_of(main_window_title) == 0) {
+ connection_is_ready_for_tests_ = true;
+
+ // Now that the main window is visible, give the app some time to settle
+ // before signaling that it is ready to run tests.
+ base::TimeDelta wait_time = base::TimeDelta::FromSeconds(5);
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ 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.
+ }
+ }
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
+}
+
+} // namespace test
+} // namespace remoting

Powered by Google App Engine
This is Rietveld 408576698