| 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..07bbde72b90ad7eec5e3e1a4da0bac3fd03e3b20
|
| --- /dev/null
|
| +++ b/remoting/test/app_remoting_test_driver.cc
|
| @@ -0,0 +1,154 @@
|
| +// 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";
|
| + const char kSingleProcessTestsSwitchName[] = "single-process-tests";
|
| +}
|
| +
|
| +namespace {
|
| +
|
| +// Requested permissions needed for App Remoting tests. The spaces in between
|
| +// scope fragments are necessary and will be escaped properly before use.
|
| +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";
|
| +
|
| +std::string GetAuthorizationCodeUri() {
|
| + // Replace space characters with a '+' sign when formatting.
|
| + bool use_plus = true;
|
| + return base::StringPrintf(
|
| + "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",
|
| + net::EscapeUrlEncodedData(kAppRemotingAuthScopeValues, use_plus).c_str(),
|
| + net::EscapeUrlEncodedData(google_apis::GetOAuth2ClientID(
|
| + google_apis::CLIENT_REMOTING), use_plus).c_str());
|
| +}
|
| +
|
| +void PrintUsage() {
|
| + printf("\n**************************************\n");
|
| + printf("*** App Remoting Test Driver Usage ***\n");
|
| + printf("**************************************\n");
|
| +
|
| + 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("\n*******************************\n");
|
| + printf("*** Auth Code Example Usage ***\n");
|
| + printf("*******************************\n\n");
|
| +
|
| + printf("If this is the first time you are running the tool,\n");
|
| + printf("you will need to provide an authorization code.\n");
|
| + printf("This code will be exchanged for a long term refresh token which\n");
|
| + printf("will be stored locally and used to acquire a short lived access\n");
|
| + printf("token to connect to the remoting service apis and establish a\n");
|
| + printf("remote host connection.\n\n");
|
| +
|
| + printf("Note: You may need to repeat this step if the stored refresh token");
|
| + printf("\n 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 'code' value in the redirected URL\n"
|
| + " - Run the tool and pass in copied auth code as a parameter\n");
|
| +
|
| + printf("\nAuthorization URL:\n");
|
| + printf("%s\n", GetAuthorizationCodeUri().c_str());
|
| +
|
| + printf("\nRedirected URL Example:\n");
|
| + printf("https://chromoting-oauth.talkgadget.google.com/talkgadget/oauth/"
|
| + "chrome-remote-desktop/dev?code=4/AKtf...\n");
|
| +
|
| + printf("\nTool usage example with the newly created auth code:\n");
|
| + printf("ar_test_driver --%s=example@gmail.com --%s=4/AKtf...\n\n",
|
| + switches::kUserNameSwitchName,
|
| + switches::kAuthCodeSwitchName);
|
| +}
|
| +
|
| +} // 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");
|
| +
|
| + // We do not want to run the tests in parallel and we do not 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(switches::kSingleProcessTestsSwitchName);
|
| +
|
| + // 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)));
|
| +}
|
|
|