Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <string> | 5 #include <string> |
| 6 #include <vector> | 6 #include <vector> |
| 7 | 7 |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
| 14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 15 #include "base/test/test_suite.h" | 15 #include "base/test/test_suite.h" |
| 16 #include "base/test/test_switches.h" | 16 #include "base/test/test_switches.h" |
| 17 #include "google_apis/google_api_keys.h" | 17 #include "google_apis/google_api_keys.h" |
| 18 #include "net/base/escape.h" | 18 #include "net/base/escape.h" |
| 19 #include "remoting/test/access_token_fetcher.h" | 19 #include "remoting/test/access_token_fetcher.h" |
| 20 #include "remoting/test/host_info.h" | 20 #include "remoting/test/host_info.h" |
| 21 #include "remoting/test/host_list_fetcher.h" | 21 #include "remoting/test/host_list_fetcher.h" |
| 22 #include "remoting/test/refresh_token_store.h" | 22 #include "remoting/test/refresh_token_store.h" |
| 23 #include "remoting/test/test_chromoting_client.h" | |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
| 24 | 25 |
| 25 namespace switches { | 26 namespace switches { |
| 26 const char kAuthCodeSwitchName[] = "authcode"; | 27 const char kAuthCodeSwitchName[] = "authcode"; |
| 28 const char kPinSwitchName[] = "pin"; | |
| 27 const char kHelpSwitchName[] = "help"; | 29 const char kHelpSwitchName[] = "help"; |
| 28 const char kHostNameSwitchName[] = "hostname"; | 30 const char kHostNameSwitchName[] = "hostname"; |
| 29 const char kLoggingLevelSwitchName[] = "verbosity"; | 31 const char kLoggingLevelSwitchName[] = "verbosity"; |
| 30 const char kRefreshTokenPathSwitchName[] = "refresh-token-path"; | 32 const char kRefreshTokenPathSwitchName[] = "refresh-token-path"; |
| 31 const char kSingleProcessTestsSwitchName[] = "single-process-tests"; | 33 const char kSingleProcessTestsSwitchName[] = "single-process-tests"; |
| 32 const char kUserNameSwitchName[] = "username"; | 34 const char kUserNameSwitchName[] = "username"; |
| 33 } | 35 } |
| 34 | 36 |
| 35 namespace { | 37 namespace { |
| 36 const char kChromotingAuthScopeValues[] = | 38 const char kChromotingAuthScopeValues[] = |
| 37 "https://www.googleapis.com/auth/chromoting " | 39 "https://www.googleapis.com/auth/chromoting " |
| 38 "https://www.googleapis.com/auth/googletalk " | 40 "https://www.googleapis.com/auth/googletalk " |
| 39 "https://www.googleapis.com/auth/userinfo.email"; | 41 "https://www.googleapis.com/auth/userinfo.email"; |
| 42 const unsigned int kTimeToConnectToHost = 10; | |
|
joedow
2015/07/16 23:26:34
newline between this value and the one above since
Sergey Ulanov
2015/07/16 23:42:09
Is that the maximum allowed time? If so, maybe cal
tonychun
2015/07/17 16:25:49
Done.
| |
| 40 | 43 |
| 41 std::string GetAuthorizationCodeUri() { | 44 std::string GetAuthorizationCodeUri() { |
| 42 // Replace space characters with a '+' sign when formatting. | 45 // Replace space characters with a '+' sign when formatting. |
| 43 bool use_plus = true; | 46 bool use_plus = true; |
| 44 return base::StringPrintf( | 47 return base::StringPrintf( |
| 45 "https://accounts.google.com/o/oauth2/auth" | 48 "https://accounts.google.com/o/oauth2/auth" |
| 46 "?scope=%s" | 49 "?scope=%s" |
| 47 "&redirect_uri=https://chromoting-oauth.talkgadget.google.com/" | 50 "&redirect_uri=https://chromoting-oauth.talkgadget.google.com/" |
| 48 "talkgadget/oauth/chrome-remote-desktop/dev" | 51 "talkgadget/oauth/chrome-remote-desktop/dev" |
| 49 "&response_type=code" | 52 "&response_type=code" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 69 switches::kUserNameSwitchName); | 72 switches::kUserNameSwitchName); |
| 70 printf(" %s: Specifies which host to connect to when running tests\n", | 73 printf(" %s: Specifies which host to connect to when running tests\n", |
| 71 switches::kHostNameSwitchName); | 74 switches::kHostNameSwitchName); |
| 72 printf("\nOptional Parameters:\n"); | 75 printf("\nOptional Parameters:\n"); |
| 73 printf(" %s: Exchanged for a refresh and access token for authentication\n", | 76 printf(" %s: Exchanged for a refresh and access token for authentication\n", |
| 74 switches::kAuthCodeSwitchName); | 77 switches::kAuthCodeSwitchName); |
| 75 printf(" %s: Displays additional usage information\n", | 78 printf(" %s: Displays additional usage information\n", |
| 76 switches::kHelpSwitchName); | 79 switches::kHelpSwitchName); |
| 77 printf(" %s: Path to a JSON file containing username/refresh_token KVPs\n", | 80 printf(" %s: Path to a JSON file containing username/refresh_token KVPs\n", |
| 78 switches::kRefreshTokenPathSwitchName); | 81 switches::kRefreshTokenPathSwitchName); |
| 82 printf(" %s: Used to authenticate a chromoting connection with the host\n", | |
| 83 switches::kPinSwitchName); | |
| 79 printf(" %s: Specifies the optional logging level of the tool (0-3)." | 84 printf(" %s: Specifies the optional logging level of the tool (0-3)." |
| 80 " [default: off]\n", | 85 " [default: off]\n", |
| 81 switches::kLoggingLevelSwitchName); | 86 switches::kLoggingLevelSwitchName); |
| 82 } | 87 } |
| 83 | 88 |
| 84 void PrintAuthCodeInfo() { | 89 void PrintAuthCodeInfo() { |
| 85 printf("\n*******************************\n"); | 90 printf("\n*******************************\n"); |
| 86 printf("*** Auth Code Example Usage ***\n"); | 91 printf("*** Auth Code Example Usage ***\n"); |
| 87 printf("*******************************\n\n"); | 92 printf("*******************************\n\n"); |
| 88 | 93 |
| 89 printf("If this is the first time you are running the tool,\n"); | 94 printf("If this is the first time you are running the tool,\n"); |
| 90 printf("you will need to provide an authorization code.\n"); | 95 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"); | 96 printf("This code will be exchanged for a long term refresh token which\n"); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 // Turn on logging for the test_driver and remoting components. | 203 // Turn on logging for the test_driver and remoting components. |
| 199 // This switch is parsed during logging::InitLogging. | 204 // This switch is parsed during logging::InitLogging. |
| 200 command_line->AppendSwitchASCII("vmodule", | 205 command_line->AppendSwitchASCII("vmodule", |
| 201 "*/remoting/*=" + verbosity_level); | 206 "*/remoting/*=" + verbosity_level); |
| 202 logging::LoggingSettings logging_settings; | 207 logging::LoggingSettings logging_settings; |
| 203 logging::InitLogging(logging_settings); | 208 logging::InitLogging(logging_settings); |
| 204 } | 209 } |
| 205 | 210 |
| 206 // The username is used to run the tests and determines which refresh token to | 211 // The username is used to run the tests and determines which refresh token to |
| 207 // select in the refresh token file. | 212 // select in the refresh token file. |
| 208 std::string username = | 213 const std::string username = |
| 209 command_line->GetSwitchValueASCII(switches::kUserNameSwitchName); | 214 command_line->GetSwitchValueASCII(switches::kUserNameSwitchName); |
| 210 | |
| 211 if (username.empty()) { | 215 if (username.empty()) { |
| 212 LOG(ERROR) << "No username passed in, can't authenticate or run tests!"; | 216 LOG(ERROR) << "No username passed in, can't authenticate or run tests!"; |
| 213 return -1; | 217 return -1; |
| 214 } | 218 } |
| 215 VLOG(1) << "Running chromoting tests as: " << username; | 219 VLOG(1) << "Running chromoting tests as: " << username; |
| 216 | 220 |
| 217 // Check to see if the user passed in a one time use auth_code for | 221 // Check to see if the user passed in a one time use auth_code for |
| 218 // refreshing their credentials. | 222 // refreshing their credentials. |
| 219 std::string auth_code = | 223 std::string auth_code = |
| 220 command_line->GetSwitchValueASCII(switches::kAuthCodeSwitchName); | 224 command_line->GetSwitchValueASCII(switches::kAuthCodeSwitchName); |
| 221 | 225 |
| 222 base::FilePath refresh_token_path = | 226 const base::FilePath refresh_token_path = |
| 223 command_line->GetSwitchValuePath(switches::kRefreshTokenPathSwitchName); | 227 command_line->GetSwitchValuePath(switches::kRefreshTokenPathSwitchName); |
| 224 | 228 |
| 225 // The hostname determines which host to initiate a session with from the list | 229 // The hostname determines which host to initiate a session with from the list |
| 226 // returned from the directory service. | 230 // returned from the directory service. |
| 227 std::string hostname = | 231 const std::string hostname = |
| 228 command_line->GetSwitchValueASCII(switches::kHostNameSwitchName); | 232 command_line->GetSwitchValueASCII(switches::kHostNameSwitchName); |
| 229 | |
| 230 if (hostname.empty()) { | 233 if (hostname.empty()) { |
| 231 LOG(ERROR) << "No hostname passed in, connect to host requires hostname!"; | 234 LOG(ERROR) << "No hostname passed in, finding the host requires hostname!"; |
| 232 return -1; | 235 return -1; |
| 233 } | 236 } |
| 234 VLOG(1) << "Chromoting tests will connect to: " << hostname; | 237 VLOG(1) << "Chromoting tests will connect to: " << hostname; |
| 235 | 238 |
| 239 const std::string pin = | |
| 240 command_line->GetSwitchValueASCII(switches::kPinSwitchName); | |
| 241 | |
| 236 // TODO(TonyChun): Move this logic into a shared environment class. | 242 // TODO(TonyChun): Move this logic into a shared environment class. |
| 237 scoped_ptr<remoting::test::RefreshTokenStore> refresh_token_store = | 243 scoped_ptr<remoting::test::RefreshTokenStore> refresh_token_store = |
| 238 remoting::test::RefreshTokenStore::OnDisk(username, refresh_token_path); | 244 remoting::test::RefreshTokenStore::OnDisk(username, refresh_token_path); |
| 239 | 245 |
| 240 std::string refresh_token = refresh_token_store->FetchRefreshToken(); | 246 std::string refresh_token = refresh_token_store->FetchRefreshToken(); |
| 241 if (auth_code.empty() && refresh_token.empty()) { | 247 if (auth_code.empty() && refresh_token.empty()) { |
| 242 // RefreshTokenStore already logs which specific error occured. | 248 // RefreshTokenStore already logs which specific error occured. |
| 243 return -1; | 249 return -1; |
| 244 } | 250 } |
| 245 | 251 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 266 access_token_fetcher.GetAccessTokenFromAuthCode(auth_code, | 272 access_token_fetcher.GetAccessTokenFromAuthCode(auth_code, |
| 267 access_token_callback); | 273 access_token_callback); |
| 268 } else { | 274 } else { |
| 269 DCHECK(!refresh_token.empty()); | 275 DCHECK(!refresh_token.empty()); |
| 270 access_token_fetcher.GetAccessTokenFromRefreshToken(refresh_token, | 276 access_token_fetcher.GetAccessTokenFromRefreshToken(refresh_token, |
| 271 access_token_callback); | 277 access_token_callback); |
| 272 } | 278 } |
| 273 | 279 |
| 274 run_loop->Run(); | 280 run_loop->Run(); |
| 275 | 281 |
| 276 // RunLoop to handle callback from directory service. | 282 // Reset runloop to use it to retrieve hostlist from directory service. |
|
Sergey Ulanov
2015/07/16 23:42:09
I don't think you need this comment.
tonychun
2015/07/17 16:25:49
Done.
| |
| 277 run_loop.reset(new base::RunLoop()); | 283 run_loop.reset(new base::RunLoop()); |
| 278 | 284 |
| 279 std::vector<remoting::test::HostInfo> hostlist; | 285 std::vector<remoting::test::HostInfo> hostlist; |
| 280 remoting::test::HostListFetcher::HostlistCallback hostlist_request_callback = | 286 remoting::test::HostListFetcher::HostlistCallback hostlist_request_callback = |
| 281 base::Bind(&OnHostlistRetrieved, run_loop->QuitClosure(), &hostlist); | 287 base::Bind(&OnHostlistRetrieved, run_loop->QuitClosure(), &hostlist); |
| 282 | 288 |
| 283 // Uses the access token to get the hostlist from the directory service. | 289 // Uses the access token to get the hostlist from the directory service. |
| 284 remoting::test::HostListFetcher hostlist_fetcher; | 290 remoting::test::HostListFetcher hostlist_fetcher; |
| 285 hostlist_fetcher.RetrieveHostlist(access_token, hostlist_request_callback); | 291 hostlist_fetcher.RetrieveHostlist(access_token, hostlist_request_callback); |
| 286 | 292 |
| 287 run_loop->Run(); | 293 run_loop->Run(); |
| 288 | 294 |
| 295 run_loop.reset(new base::RunLoop()); | |
| 296 | |
| 297 scoped_ptr<base::Timer> timer = | |
| 298 make_scoped_ptr<base::Timer>(new base::Timer(true, false)); | |
|
Sergey Ulanov
2015/07/16 23:42:09
This can be allocated on stack:
base::Timer timer(
tonychun
2015/07/17 16:25:49
Done.
| |
| 299 | |
| 300 remoting::test::TestChromotingClient test_chromoting_client; | |
| 301 | |
| 302 // Check if requested host is online and ready to receive connections. | |
| 303 auto it = std::find_if(hostlist.begin(), hostlist.end(), | |
| 304 [&hostname](const remoting::test::HostInfo& host_info) { | |
| 305 return host_info.host_name == hostname && | |
| 306 host_info.IsReadyForConnection(); | |
| 307 }); | |
| 308 if (it != hostlist.end()) { | |
|
Sergey Ulanov
2015/07/16 23:42:10
Log an error if the host wasn't found
tonychun
2015/07/17 16:25:49
Done.
| |
| 309 // Host is online and ready, initiate a remote session. | |
| 310 timer->Start(FROM_HERE, | |
| 311 base::TimeDelta::FromSeconds(kTimeToConnectToHost), | |
| 312 run_loop->QuitClosure()); | |
| 313 test_chromoting_client.StartConnection( | |
| 314 it->GenerateConnectionSetupInfo(access_token, username, pin)); | |
| 315 run_loop->Run(); | |
| 316 timer->Stop(); | |
|
Sergey Ulanov
2015/07/16 23:42:09
Don't need this if you scope |timer| inside the if
tonychun
2015/07/17 16:25:49
Done.
| |
| 317 test_chromoting_client.EndConnection(); | |
| 318 } | |
| 319 | |
| 289 return 0; | 320 return 0; |
| 290 } | 321 } |
| OLD | NEW |