Chromium Code Reviews| Index: remoting/test/app_remoting_test_driver.cc |
| diff --git a/remoting/test/app_remoting_test_driver.cc b/remoting/test/app_remoting_test_driver.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..29a05359733005ca22e8a7a9f5a56c0cb71fb5a4 |
| --- /dev/null |
| +++ b/remoting/test/app_remoting_test_driver.cc |
| @@ -0,0 +1,174 @@ |
| +// 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 "base/bind.h" |
| +#include "base/command_line.h" |
| +#include "base/logging.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "base/test/launcher/unit_test_launcher.h" |
| +#include "base/test/test_suite.h" |
| +#include "base/test/test_switches.h" |
| +#include "google_apis/google_api_keys.h" |
| +#include "net/base/escape.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace switches { |
| + const char kUserNameSwitchName[] = "username"; |
| + const char kAuthCodeSwitchName[] = "authcode"; |
| + const char kServiceEnvironmentSwitchName[] = "environment"; |
| + const char kHelpSwitchName[] = "help"; |
| +} |
| + |
| +namespace { |
| + |
| +// Requested permissions needed for App Remoting tests. The spaces in between |
| +// scope fragments are necessary and will be escaped properly before use. |
|
Jamie
2015/02/05 00:38:40
Optional: I usually put the spaces at the start of
joedow
2015/02/05 01:19:48
Done.
|
| +const char kAppRemotingAuthScopeValues[] = |
| + "https://www.googleapis.com/auth/appremoting.runapplication " |
| + "https://www.googleapis.com/auth/googletalk " |
| + "https://www.googleapis.com/auth/userinfo.email " |
| + "https://docs.google.com/feeds " |
| + "https://www.googleapis.com/auth/drive"; |
| + |
| +// Used to generate an authorization code request string. |
|
Jamie
2015/02/05 00:38:40
There's no need for this to be declared as a globa
joedow
2015/02/05 01:19:48
Done.
|
| +const char kAuthorizationCodeFormat[] = |
| + "https://accounts.google.com/o/oauth2/auth" |
| + "?scope=%s" |
| + "&redirect_uri=https://chromoting-oauth.talkgadget.google.com/talkgadget/" |
| + "oauth/chrome-remote-desktop/dev" |
| + "&response_type=code" |
| + "&client_id=%s" |
| + "&access_type=offline" |
| + "&approval_prompt=force"; |
| + |
| +std::string GetAuthorizationCodeUri() { |
| + // Replace space characters with a '+' sign when formatting. |
| + bool use_plus = true; |
| + return base::StringPrintf( |
| + kAuthorizationCodeFormat, |
| + net::EscapeUrlEncodedData(kAppRemotingAuthScopeValues, use_plus).c_str(), |
| + net::EscapeUrlEncodedData(google_apis::GetOAuth2ClientID( |
| + google_apis::CLIENT_REMOTING), use_plus).c_str()); |
| +} |
| + |
| +// Color values used to make the tool usage output text easier to read. |
| +const char kAnsiColorGreen[] = "\x1b[32m"; |
| +const char kAnsiColorCyan[] = "\x1b[36m"; |
| +const char kAnsiColorOrange[] = "\x1b[38;5;208m"; |
| +const char kAnsiColorReset[] = "\x1b[0m"; |
|
Jamie
2015/02/05 00:38:40
These don't work for all terminal types. You shoul
joedow
2015/02/05 01:19:48
Done.
|
| + |
| +void PrintUsage() { |
| + printf(kAnsiColorCyan); |
| + printf("\n**************************************\n"); |
| + printf("*** App Remoting Test Driver Usage ***\n"); |
| + printf("**************************************\n"); |
| + printf(kAnsiColorReset); |
| + |
| + printf("\nUsage:\n"); |
| + printf(" ar_test_driver --username=<example@gmail.com> [options]\n"); |
| + printf("\nRequired Parameters:\n"); |
| + printf(" %s: Specifies which account to use when running tests\n", |
| + switches::kUserNameSwitchName); |
| + printf("\nOptional Parameters:\n"); |
| + printf(" %s: Exchanged for a refresh and access token for authentication\n", |
| + switches::kAuthCodeSwitchName); |
| + printf(" %s: Displays additional usage information\n", |
| + switches::kHelpSwitchName); |
| + printf(" %s: Specifies the service api to use (dev|test) [default: dev]\n", |
| + switches::kServiceEnvironmentSwitchName); |
| +} |
| + |
| +void PrintAuthCodeInfo() { |
| + printf(kAnsiColorCyan); |
| + printf("\n*******************************\n"); |
| + printf("*** Auth Code Example Usage ***\n"); |
| + printf("*******************************\n"); |
| + printf(kAnsiColorReset); |
| + |
| + printf("\nIf this is the first time you are running the tool, you will need" |
| + " to provide an authorization code.\n" |
| + "This code will be exchanged for a long term refresh token which will" |
| + " be stored locally and used to acquire a short lived access token to" |
| + " connect to the remoting service apis and establish a" |
| + " remote host connection.\n"); |
|
Jamie
2015/02/05 00:38:40
Word-wrap these to 80-characters (or fewer, if you
joedow
2015/02/05 01:19:48
Done.
|
| + |
| + printf("\nNote: You may need to repeat this step if the stored refresh token" |
| + " has been revoked or expired.\n"); |
| + printf(" Passing in the same auth code twice will result in an error\n"); |
| + |
| + printf("\nFollow these steps to produce an auth code:\n" |
| + " - Open the Authorization URL link shown below in your browser\n" |
| + " - Approve the requested permissions for the tool\n" |
| + " - Copy the highlighted code in the redirected URL\n" |
| + " - Run the tool and pass in copied auth code as a parameter\n"); |
| + |
| + printf("\nAuthorization URL:\n"); |
| + printf(kAnsiColorGreen); |
| + printf("%s\n", GetAuthorizationCodeUri().c_str()); |
| + printf(kAnsiColorReset); |
| + |
| + printf("\nRedirected URL Example:\n"); |
| + printf("https://chromoting-oauth.talkgadget.google.com/talkgadget/oauth/" |
| + "chrome-remote-desktop/dev?code="); |
| + printf(kAnsiColorOrange); |
| + printf("4/AKtf...\n"); |
| + printf(kAnsiColorReset); |
| + |
| + printf("\nTool usage example with the newly created auth code:\n"); |
| + printf("ar_test_driver --%s=example@gmail.com --%s=", |
| + switches::kUserNameSwitchName, |
| + switches::kAuthCodeSwitchName); |
| + printf(kAnsiColorOrange); |
| + printf("4/AKtf...\n\n"); |
| + printf(kAnsiColorReset); |
| +} |
| + |
| +} // namespace |
| + |
| +int main(int argc, char** argv) { |
| + testing::InitGoogleTest(&argc, argv); |
| + TestSuite test_suite(argc, argv); |
| + |
| + // The pointer returned here refers to a singleton, since we don't own the |
| + // lifetime of the object, don't wrap in a scoped_ptr construct or release it. |
| + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| + DCHECK(command_line); |
| + |
| + // We do not want to retry failures as a failed test should signify an error |
| + // to be investigated. |
| + command_line->AppendSwitchASCII(switches::kTestLauncherRetryLimit, "0"); |
|
Jamie
2015/02/05 00:38:40
Blank line here, I think.
joedow
2015/02/05 01:19:48
Done.
|
| + // We do not want to run the tests in parallel and we do not |
|
Jamie
2015/02/05 00:38:40
The word-wrap is a bit funky here.
joedow
2015/02/05 01:19:48
Done.
|
| + // want to retry failures. The reason for running in a single process is that |
| + // some tests may share the same remoting host and they cannot be run |
| + // concurrently, also the test output gets spammed with test launcher messages |
| + // which reduces the readability of the results. |
| + command_line->AppendSwitch("single-process-tests"); |
|
Jamie
2015/02/05 00:38:40
Maybe add this to the switches namespace for consi
joedow
2015/02/05 01:19:48
Done.
|
| + |
| + // If the user passed in the help flag, then show the help info for this tool |
| + // and 'run' the tests which will print the gtest specific help and then exit. |
| + // NOTE: We do this check after updating the switches as otherwise the gtest |
| + // help is written in parallel with our text and can appear interleaved. |
| + if (command_line->HasSwitch(switches::kHelpSwitchName)) { |
| + PrintUsage(); |
| + PrintAuthCodeInfo(); |
| + return base::LaunchUnitTestsSerially( |
| + argc, |
| + argv, |
| + base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite))); |
| + } |
| + |
| + // Verify we received the required input from the command line. |
| + if (!command_line->HasSwitch(switches::kUserNameSwitchName)) { |
| + LOG(ERROR) << "No user name passed in, can't authenticate without that!"; |
| + PrintUsage(); |
| + return -1; |
| + } |
| + |
| + // Because many tests may access the same remoting host(s), we need to run |
| + // the tests sequentially so they do not interfere with each other. |
| + return base::LaunchUnitTestsSerially( |
| + argc, |
| + argv, |
| + base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite))); |
| +} |