[CleanUp] Move PowerApiManager to power_api and Rename
[chromium-blink-merge.git] / remoting / test / app_remoting_test_driver.cc
blob532005a59e9deb302de3f1a3b1fc1d479f63c0fe
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 "base/bind.h"
6 #include "base/command_line.h"
7 #include "base/logging.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/test/launcher/unit_test_launcher.h"
10 #include "base/test/test_suite.h"
11 #include "base/test/test_switches.h"
12 #include "google_apis/google_api_keys.h"
13 #include "net/base/escape.h"
14 #include "remoting/test/app_remoting_test_driver_environment.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 namespace switches {
18 const char kAuthCodeSwitchName[] = "authcode";
19 const char kHelpSwitchName[] = "help";
20 const char kLoggingLevelSwitchName[] = "verbosity";
21 const char kServiceEnvironmentSwitchName[] = "environment";
22 const char kSingleProcessTestsSwitchName[] = "single-process-tests";
23 const char kUserNameSwitchName[] = "username";
26 namespace {
28 // Requested permissions needed for App Remoting tests. The spaces in between
29 // scope fragments are necessary and will be escaped properly before use.
30 const char kAppRemotingAuthScopeValues[] =
31 "https://www.googleapis.com/auth/appremoting.runapplication"
32 " https://www.googleapis.com/auth/googletalk"
33 " https://www.googleapis.com/auth/userinfo.email"
34 " https://docs.google.com/feeds"
35 " https://www.googleapis.com/auth/drive";
37 std::string GetAuthorizationCodeUri() {
38 // Replace space characters with a '+' sign when formatting.
39 bool use_plus = true;
40 return base::StringPrintf(
41 "https://accounts.google.com/o/oauth2/auth"
42 "?scope=%s"
43 "&redirect_uri=https://chromoting-oauth.talkgadget.google.com/"
44 "talkgadget/oauth/chrome-remote-desktop/dev"
45 "&response_type=code"
46 "&client_id=%s"
47 "&access_type=offline"
48 "&approval_prompt=force",
49 net::EscapeUrlEncodedData(kAppRemotingAuthScopeValues, use_plus).c_str(),
50 net::EscapeUrlEncodedData(google_apis::GetOAuth2ClientID(
51 google_apis::CLIENT_REMOTING), use_plus).c_str());
54 void PrintUsage() {
55 printf("\n**************************************\n");
56 printf("*** App Remoting Test Driver Usage ***\n");
57 printf("**************************************\n");
59 printf("\nUsage:\n");
60 printf(" ar_test_driver --username=<example@gmail.com> [options]\n");
61 printf("\nRequired Parameters:\n");
62 printf(" %s: Specifies which account to use when running tests\n",
63 switches::kUserNameSwitchName);
64 printf("\nOptional Parameters:\n");
65 printf(" %s: Exchanged for a refresh and access token for authentication\n",
66 switches::kAuthCodeSwitchName);
67 printf(" %s: Displays additional usage information\n",
68 switches::kHelpSwitchName);
69 printf(" %s: Specifies the service api to use (dev|test) [default: dev]\n",
70 switches::kServiceEnvironmentSwitchName);
71 printf(
72 " %s: Specifies the optional logging level of the tool (0-3)."
73 " [default: off]\n",
74 switches::kLoggingLevelSwitchName);
77 void PrintAuthCodeInfo() {
78 printf("\n*******************************\n");
79 printf("*** Auth Code Example Usage ***\n");
80 printf("*******************************\n\n");
82 printf("If this is the first time you are running the tool,\n");
83 printf("you will need to provide an authorization code.\n");
84 printf("This code will be exchanged for a long term refresh token which\n");
85 printf("will be stored locally and used to acquire a short lived access\n");
86 printf("token to connect to the remoting service apis and establish a\n");
87 printf("remote host connection.\n\n");
89 printf("Note: You may need to repeat this step if the stored refresh token");
90 printf("\n has been revoked or expired.\n");
91 printf(" Passing in the same auth code twice will result in an error\n");
93 printf("\nFollow these steps to produce an auth code:\n"
94 " - Open the Authorization URL link shown below in your browser\n"
95 " - Approve the requested permissions for the tool\n"
96 " - Copy the 'code' value in the redirected URL\n"
97 " - Run the tool and pass in copied auth code as a parameter\n");
99 printf("\nAuthorization URL:\n");
100 printf("%s\n", GetAuthorizationCodeUri().c_str());
102 printf("\nRedirected URL Example:\n");
103 printf("https://chromoting-oauth.talkgadget.google.com/talkgadget/oauth/"
104 "chrome-remote-desktop/dev?code=4/AKtf...\n");
106 printf("\nTool usage example with the newly created auth code:\n");
107 printf("ar_test_driver --%s=example@gmail.com --%s=4/AKtf...\n\n",
108 switches::kUserNameSwitchName,
109 switches::kAuthCodeSwitchName);
112 } // namespace
114 int main(int argc, char** argv) {
115 testing::InitGoogleTest(&argc, argv);
116 TestSuite test_suite(argc, argv);
118 // The pointer returned here refers to a singleton, since we don't own the
119 // lifetime of the object, don't wrap in a scoped_ptr construct or release it.
120 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
121 DCHECK(command_line);
123 // We do not want to retry failures as a failed test should signify an error
124 // to be investigated.
125 command_line->AppendSwitchASCII(switches::kTestLauncherRetryLimit, "0");
127 // We do not want to run the tests in parallel and we do not want to retry
128 // failures. The reason for running in a single process is that some tests
129 // may share the same remoting host and they cannot be run concurrently, also
130 // the test output gets spammed with test launcher messages which reduces the
131 // readability of the results.
132 command_line->AppendSwitch(switches::kSingleProcessTestsSwitchName);
134 // If the user passed in the help flag, then show the help info for this tool
135 // and 'run' the tests which will print the gtest specific help and then exit.
136 // NOTE: We do this check after updating the switches as otherwise the gtest
137 // help is written in parallel with our text and can appear interleaved.
138 if (command_line->HasSwitch(switches::kHelpSwitchName)) {
139 PrintUsage();
140 PrintAuthCodeInfo();
141 return base::LaunchUnitTestsSerially(
142 argc,
143 argv,
144 base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite)));
147 // Verify we received the required input from the command line.
148 if (!command_line->HasSwitch(switches::kUserNameSwitchName)) {
149 LOG(ERROR) << "No user name passed in, can't authenticate without that!";
150 PrintUsage();
151 return -1;
154 std::string user_name;
155 user_name = command_line->GetSwitchValueASCII(switches::kUserNameSwitchName);
156 DVLOG(1) << "Running tests as: " << user_name;
158 std::string auth_code;
159 // Check to see if the user passed in a one time use auth_code for
160 // refreshing their credentials.
161 auth_code = command_line->GetSwitchValueASCII(switches::kAuthCodeSwitchName);
163 std::string service_environment;
164 // If the user passed in a service environment, use it, otherwise set a
165 // default value.
166 service_environment = command_line->GetSwitchValueASCII(
167 switches::kServiceEnvironmentSwitchName);
168 if (service_environment.empty()) {
169 // Default to the development service environment.
170 service_environment = "dev";
171 } else if (service_environment != "test" && service_environment != "dev") {
172 // Only two values are allowed, so validate them before proceeding.
173 LOG(ERROR) << "Invalid " << switches::kServiceEnvironmentSwitchName
174 << " argument passed in.";
175 PrintUsage();
176 return -1;
179 // Update the logging verbosity level is user specified one.
180 std::string verbosity_level;
181 verbosity_level =
182 command_line->GetSwitchValueASCII(switches::kLoggingLevelSwitchName);
183 if (!verbosity_level.empty()) {
184 // Turn on logging for the test_driver and remoting components.
185 // This switch is parsed during logging::InitLogging.
186 command_line->AppendSwitchASCII("vmodule",
187 "*/remoting/*=" + verbosity_level);
188 logging::LoggingSettings logging_settings;
189 logging::InitLogging(logging_settings);
192 // Create and register our global test data object. It will handle
193 // retrieving an access token for the user and spinning up VMs.
194 // The GTest framework will own the lifetime of this object once
195 // it is registered below.
196 scoped_ptr<remoting::test::AppRemotingTestDriverEnvironment> shared_data;
198 shared_data.reset(new remoting::test::AppRemotingTestDriverEnvironment(
199 user_name, service_environment));
201 if (!shared_data->Initialize(auth_code)) {
202 // If we failed to initialize our shared data object, then bail.
203 return -1;
206 // Since we've successfully set up our shared_data object, we'll assign the
207 // value to our global* and transfer ownership to the framework.
208 remoting::test::AppRemotingSharedData = shared_data.release();
209 testing::AddGlobalTestEnvironment(remoting::test::AppRemotingSharedData);
211 // Because many tests may access the same remoting host(s), we need to run
212 // the tests sequentially so they do not interfere with each other.
213 return base::LaunchUnitTestsSerially(
214 argc,
215 argv,
216 base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite)));