Compute if a layer is clipped outside CalcDrawProps
[chromium-blink-merge.git] / remoting / test / chromoting_test_driver.cc
blobbae3ca7713427369038505a01edac12f1e4b9ff6
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 <string>
6 #include <vector>
8 #include "base/bind.h"
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/test/test_suite.h"
16 #include "base/test/test_switches.h"
17 #include "google_apis/google_api_keys.h"
18 #include "net/base/escape.h"
19 #include "remoting/test/access_token_fetcher.h"
20 #include "remoting/test/host_info.h"
21 #include "remoting/test/host_list_fetcher.h"
22 #include "remoting/test/refresh_token_store.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 namespace switches {
26 const char kAuthCodeSwitchName[] = "authcode";
27 const char kHelpSwitchName[] = "help";
28 const char kHostNameSwitchName[] = "hostname";
29 const char kLoggingLevelSwitchName[] = "verbosity";
30 const char kRefreshTokenPathSwitchName[] = "refresh-token-path";
31 const char kSingleProcessTestsSwitchName[] = "single-process-tests";
32 const char kUserNameSwitchName[] = "username";
35 namespace {
36 const char kChromotingAuthScopeValues[] =
37 "https://www.googleapis.com/auth/chromoting "
38 "https://www.googleapis.com/auth/googletalk "
39 "https://www.googleapis.com/auth/userinfo.email";
41 std::string GetAuthorizationCodeUri() {
42 // Replace space characters with a '+' sign when formatting.
43 bool use_plus = true;
44 return base::StringPrintf(
45 "https://accounts.google.com/o/oauth2/auth"
46 "?scope=%s"
47 "&redirect_uri=https://chromoting-oauth.talkgadget.google.com/"
48 "talkgadget/oauth/chrome-remote-desktop/dev"
49 "&response_type=code"
50 "&client_id=%s"
51 "&access_type=offline"
52 "&approval_prompt=force",
53 net::EscapeUrlEncodedData(kChromotingAuthScopeValues, use_plus).c_str(),
54 net::EscapeUrlEncodedData(
55 google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING),
56 use_plus).c_str());
59 void PrintUsage() {
60 printf("\n************************************\n");
61 printf("*** Chromoting Test Driver Usage ***\n");
62 printf("************************************\n");
64 printf("\nUsage:\n");
65 printf(" chromoting_test_driver --username=<example@gmail.com> [options]"
66 " --hostname=<example hostname>\n");
67 printf("\nRequired Parameters:\n");
68 printf(" %s: Specifies which account to use when running tests\n",
69 switches::kUserNameSwitchName);
70 printf(" %s: Specifies which host to connect to when running tests\n",
71 switches::kHostNameSwitchName);
72 printf("\nOptional Parameters:\n");
73 printf(" %s: Exchanged for a refresh and access token for authentication\n",
74 switches::kAuthCodeSwitchName);
75 printf(" %s: Displays additional usage information\n",
76 switches::kHelpSwitchName);
77 printf(" %s: Path to a JSON file containing username/refresh_token KVPs\n",
78 switches::kRefreshTokenPathSwitchName);
79 printf(" %s: Specifies the optional logging level of the tool (0-3)."
80 " [default: off]\n",
81 switches::kLoggingLevelSwitchName);
84 void PrintAuthCodeInfo() {
85 printf("\n*******************************\n");
86 printf("*** Auth Code Example Usage ***\n");
87 printf("*******************************\n\n");
89 printf("If this is the first time you are running the tool,\n");
90 printf("you will need to provide an authorization code.\n");
91 printf("This code will be exchanged for a long term refresh token which\n");
92 printf("will be stored locally and used to acquire a short lived access\n");
93 printf("token to connect to the remoting service apis and establish a\n");
94 printf("remote host connection.\n\n");
96 printf("Note: You may need to repeat this step if the stored refresh token");
97 printf("\n has been revoked or expired.\n");
98 printf(" Passing in the same auth code twice will result in an error\n");
100 printf("\nFollow these steps to produce an auth code:\n"
101 " - Open the Authorization URL link shown below in your browser\n"
102 " - Approve the requested permissions for the tool\n"
103 " - Copy the 'code' value in the redirected URL\n"
104 " - Run the tool and pass in copied auth code as a parameter\n");
106 printf("\nAuthorization URL:\n");
107 printf("%s\n", GetAuthorizationCodeUri().c_str());
109 printf("\nRedirected URL Example:\n");
110 printf("https://chromoting-oauth.talkgadget.google.com/talkgadget/oauth/"
111 "chrome-remote-desktop/dev?code=4/AKtf...\n");
113 printf("\nTool usage example with the newly created auth code:\n");
114 printf("chromoting_test_driver --%s=example@gmail.com --%s=example_host_name"
115 " --%s=4/AKtf...\n\n",
116 switches::kUserNameSwitchName,
117 switches::kHostNameSwitchName,
118 switches::kAuthCodeSwitchName);
121 void PrintJsonFileInfo() {
122 printf("\n****************************************\n");
123 printf("*** Refresh Token File Example Usage ***\n");
124 printf("****************************************\n\n");
126 printf("In order to use this option, a valid JSON file must exist, be\n");
127 printf("properly formatted, and contain a username/token KVP.\n");
128 printf("Contents of example_file.json\n");
129 printf("{\n");
130 printf(" \"username1@fauxdomain.com\": \"1/3798Gsdf898shksdvfyi8sshad\",\n");
131 printf(" \"username2@fauxdomain.com\": \"1/8974sdf87asdgadfgaerhfRsAa\",\n");
132 printf("}\n\n");
134 printf("\nTool usage example:\n");
135 printf("chromoting_test_driver --%s=%s --%s=example_host_name"
136 " --%s=./example_file.json\n\n",
137 switches::kUserNameSwitchName, "username1@fauxdomain.com",
138 switches::kHostNameSwitchName, switches::kRefreshTokenPathSwitchName);
141 } // namespace
143 void OnHostlistRetrieved(
144 base::Closure done_closure,
145 std::vector<remoting::test::HostInfo>* hostlist,
146 const std::vector<remoting::test::HostInfo>& retrieved_hostlist) {
148 VLOG(1) << "OnHostlistRetrieved() Called";
150 DCHECK(hostlist);
152 *hostlist = retrieved_hostlist;
154 VLOG(1) << "There are " << hostlist->size() << " hosts in the hostlist";
156 done_closure.Run();
159 void OnAccessTokenRetrieved(
160 base::Closure done_closure,
161 std::string* access_token,
162 const std::string& retrieved_access_token,
163 const std::string& retrieved_refresh_token) {
165 VLOG(1) << "OnAccessTokenRetrieved() Called";
166 VLOG(1) << "Access Token: " << retrieved_access_token;
168 *access_token = retrieved_access_token;
170 done_closure.Run();
173 int main(int argc, char* argv[]) {
174 testing::InitGoogleTest(&argc, argv);
175 base::TestSuite test_suite(argc, argv);
177 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
178 DCHECK(command_line);
180 // Do not retry if tests fails.
181 command_line->AppendSwitchASCII(switches::kTestLauncherRetryLimit, "0");
183 // Different tests may require access to the same host if run in parallel.
184 // To avoid shared resource contention, tests will be run one at a time.
185 command_line->AppendSwitch(switches::kSingleProcessTestsSwitchName);
187 if (command_line->HasSwitch(switches::kHelpSwitchName)) {
188 PrintUsage();
189 PrintJsonFileInfo();
190 PrintAuthCodeInfo();
191 return 0;
194 // Update the logging verbosity level is user specified one.
195 std::string verbosity_level(
196 command_line->GetSwitchValueASCII(switches::kLoggingLevelSwitchName));
197 if (!verbosity_level.empty()) {
198 // Turn on logging for the test_driver and remoting components.
199 // This switch is parsed during logging::InitLogging.
200 command_line->AppendSwitchASCII("vmodule",
201 "*/remoting/*=" + verbosity_level);
202 logging::LoggingSettings logging_settings;
203 logging::InitLogging(logging_settings);
206 // The username is used to run the tests and determines which refresh token to
207 // select in the refresh token file.
208 std::string username =
209 command_line->GetSwitchValueASCII(switches::kUserNameSwitchName);
211 if (username.empty()) {
212 LOG(ERROR) << "No username passed in, can't authenticate or run tests!";
213 return -1;
215 VLOG(1) << "Running chromoting tests as: " << username;
217 // Check to see if the user passed in a one time use auth_code for
218 // refreshing their credentials.
219 std::string auth_code =
220 command_line->GetSwitchValueASCII(switches::kAuthCodeSwitchName);
222 base::FilePath refresh_token_path =
223 command_line->GetSwitchValuePath(switches::kRefreshTokenPathSwitchName);
225 // The hostname determines which host to initiate a session with from the list
226 // returned from the directory service.
227 std::string hostname =
228 command_line->GetSwitchValueASCII(switches::kHostNameSwitchName);
230 if (hostname.empty()) {
231 LOG(ERROR) << "No hostname passed in, connect to host requires hostname!";
232 return -1;
234 VLOG(1) << "Chromoting tests will connect to: " << hostname;
236 // TODO(TonyChun): Move this logic into a shared environment class.
237 scoped_ptr<remoting::test::RefreshTokenStore> refresh_token_store =
238 remoting::test::RefreshTokenStore::OnDisk(username, refresh_token_path);
240 std::string refresh_token = refresh_token_store->FetchRefreshToken();
241 if (auth_code.empty() && refresh_token.empty()) {
242 // RefreshTokenStore already logs which specific error occured.
243 return -1;
246 // Used for running network request tasks.
247 // TODO(TonyChun): Move this logic into a shared environment class.
248 base::MessageLoopForIO message_loop;
250 // Uses the refresh token to get the access token from GAIA.
251 remoting::test::AccessTokenFetcher access_token_fetcher;
253 // A RunLoop that yields to the thread's MessageLoop.
254 scoped_ptr<base::RunLoop> run_loop;
256 // RunLoop to handle callback from GAIA.
257 run_loop.reset(new base::RunLoop());
259 std::string access_token;
260 remoting::test::AccessTokenCallback access_token_callback =
261 base::Bind(&OnAccessTokenRetrieved,
262 run_loop->QuitClosure(),
263 &access_token);
265 if (!auth_code.empty()) {
266 access_token_fetcher.GetAccessTokenFromAuthCode(auth_code,
267 access_token_callback);
268 } else {
269 DCHECK(!refresh_token.empty());
270 access_token_fetcher.GetAccessTokenFromRefreshToken(refresh_token,
271 access_token_callback);
274 run_loop->Run();
276 // RunLoop to handle callback from directory service.
277 run_loop.reset(new base::RunLoop());
279 std::vector<remoting::test::HostInfo> hostlist;
280 remoting::test::HostListFetcher::HostlistCallback hostlist_request_callback =
281 base::Bind(&OnHostlistRetrieved, run_loop->QuitClosure(), &hostlist);
283 // Uses the access token to get the hostlist from the directory service.
284 remoting::test::HostListFetcher hostlist_fetcher;
285 hostlist_fetcher.RetrieveHostlist(access_token, hostlist_request_callback);
287 run_loop->Run();
289 return 0;