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 |