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.
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 "testing/gtest/include/gtest/gtest.h"
17 const char kUserNameSwitchName
[] = "username";
18 const char kAuthCodeSwitchName
[] = "authcode";
19 const char kServiceEnvironmentSwitchName
[] = "environment";
20 const char kHelpSwitchName
[] = "help";
21 const char kSingleProcessTestsSwitchName
[] = "single-process-tests";
26 // Requested permissions needed for App Remoting tests. The spaces in between
27 // scope fragments are necessary and will be escaped properly before use.
28 const char kAppRemotingAuthScopeValues
[] =
29 "https://www.googleapis.com/auth/appremoting.runapplication"
30 " https://www.googleapis.com/auth/googletalk"
31 " https://www.googleapis.com/auth/userinfo.email"
32 " https://docs.google.com/feeds"
33 " https://www.googleapis.com/auth/drive";
35 std::string
GetAuthorizationCodeUri() {
36 // Replace space characters with a '+' sign when formatting.
38 return base::StringPrintf(
39 "https://accounts.google.com/o/oauth2/auth"
41 "&redirect_uri=https://chromoting-oauth.talkgadget.google.com/"
42 "talkgadget/oauth/chrome-remote-desktop/dev"
45 "&access_type=offline"
46 "&approval_prompt=force",
47 net::EscapeUrlEncodedData(kAppRemotingAuthScopeValues
, use_plus
).c_str(),
48 net::EscapeUrlEncodedData(google_apis::GetOAuth2ClientID(
49 google_apis::CLIENT_REMOTING
), use_plus
).c_str());
53 printf("\n**************************************\n");
54 printf("*** App Remoting Test Driver Usage ***\n");
55 printf("**************************************\n");
58 printf(" ar_test_driver --username=<example@gmail.com> [options]\n");
59 printf("\nRequired Parameters:\n");
60 printf(" %s: Specifies which account to use when running tests\n",
61 switches::kUserNameSwitchName
);
62 printf("\nOptional Parameters:\n");
63 printf(" %s: Exchanged for a refresh and access token for authentication\n",
64 switches::kAuthCodeSwitchName
);
65 printf(" %s: Displays additional usage information\n",
66 switches::kHelpSwitchName
);
67 printf(" %s: Specifies the service api to use (dev|test) [default: dev]\n",
68 switches::kServiceEnvironmentSwitchName
);
71 void PrintAuthCodeInfo() {
72 printf("\n*******************************\n");
73 printf("*** Auth Code Example Usage ***\n");
74 printf("*******************************\n\n");
76 printf("If this is the first time you are running the tool,\n");
77 printf("you will need to provide an authorization code.\n");
78 printf("This code will be exchanged for a long term refresh token which\n");
79 printf("will be stored locally and used to acquire a short lived access\n");
80 printf("token to connect to the remoting service apis and establish a\n");
81 printf("remote host connection.\n\n");
83 printf("Note: You may need to repeat this step if the stored refresh token");
84 printf("\n has been revoked or expired.\n");
85 printf(" Passing in the same auth code twice will result in an error\n");
87 printf("\nFollow these steps to produce an auth code:\n"
88 " - Open the Authorization URL link shown below in your browser\n"
89 " - Approve the requested permissions for the tool\n"
90 " - Copy the 'code' value in the redirected URL\n"
91 " - Run the tool and pass in copied auth code as a parameter\n");
93 printf("\nAuthorization URL:\n");
94 printf("%s\n", GetAuthorizationCodeUri().c_str());
96 printf("\nRedirected URL Example:\n");
97 printf("https://chromoting-oauth.talkgadget.google.com/talkgadget/oauth/"
98 "chrome-remote-desktop/dev?code=4/AKtf...\n");
100 printf("\nTool usage example with the newly created auth code:\n");
101 printf("ar_test_driver --%s=example@gmail.com --%s=4/AKtf...\n\n",
102 switches::kUserNameSwitchName
,
103 switches::kAuthCodeSwitchName
);
108 int main(int argc
, char** argv
) {
109 testing::InitGoogleTest(&argc
, argv
);
110 TestSuite
test_suite(argc
, argv
);
112 // The pointer returned here refers to a singleton, since we don't own the
113 // lifetime of the object, don't wrap in a scoped_ptr construct or release it.
114 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
115 DCHECK(command_line
);
117 // We do not want to retry failures as a failed test should signify an error
118 // to be investigated.
119 command_line
->AppendSwitchASCII(switches::kTestLauncherRetryLimit
, "0");
121 // We do not want to run the tests in parallel and we do not want to retry
122 // failures. The reason for running in a single process is that some tests
123 // may share the same remoting host and they cannot be run concurrently, also
124 // the test output gets spammed with test launcher messages which reduces the
125 // readability of the results.
126 command_line
->AppendSwitch(switches::kSingleProcessTestsSwitchName
);
128 // If the user passed in the help flag, then show the help info for this tool
129 // and 'run' the tests which will print the gtest specific help and then exit.
130 // NOTE: We do this check after updating the switches as otherwise the gtest
131 // help is written in parallel with our text and can appear interleaved.
132 if (command_line
->HasSwitch(switches::kHelpSwitchName
)) {
135 return base::LaunchUnitTestsSerially(
138 base::Bind(&base::TestSuite::Run
, base::Unretained(&test_suite
)));
141 // Verify we received the required input from the command line.
142 if (!command_line
->HasSwitch(switches::kUserNameSwitchName
)) {
143 LOG(ERROR
) << "No user name passed in, can't authenticate without that!";
148 // Because many tests may access the same remoting host(s), we need to run
149 // the tests sequentially so they do not interfere with each other.
150 return base::LaunchUnitTestsSerially(
153 base::Bind(&base::TestSuite::Run
, base::Unretained(&test_suite
)));