OOPIF: Fix the new task manager to show the correct proc IDs of subframe procs
[chromium-blink-merge.git] / remoting / test / chromoting_test_driver_environment.cc
blob5d644640a78dd20cbcce22edf3a9f0e5aede6de9
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.
5 #include "remoting/test/chromoting_test_driver_environment.h"
7 #include <string>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/strings/stringprintf.h"
15 #include "remoting/test/access_token_fetcher.h"
16 #include "remoting/test/host_list_fetcher.h"
17 #include "remoting/test/refresh_token_store.h"
19 namespace remoting {
20 namespace test {
22 ChromotingTestDriverEnvironment* g_chromoting_shared_data = nullptr;
24 ChromotingTestDriverEnvironment::EnvironmentOptions::EnvironmentOptions() {
27 ChromotingTestDriverEnvironment::EnvironmentOptions::~EnvironmentOptions() {
30 ChromotingTestDriverEnvironment::ChromotingTestDriverEnvironment(
31 const EnvironmentOptions& options)
32 : host_name_(options.host_name),
33 user_name_(options.user_name),
34 pin_(options.pin),
35 refresh_token_file_path_(options.refresh_token_file_path),
36 test_access_token_fetcher_(nullptr),
37 test_refresh_token_store_(nullptr),
38 test_host_list_fetcher_(nullptr) {
39 DCHECK(!user_name_.empty());
40 DCHECK(!host_name_.empty());
43 ChromotingTestDriverEnvironment::~ChromotingTestDriverEnvironment() {
46 bool ChromotingTestDriverEnvironment::Initialize(
47 const std::string& auth_code) {
48 if (!access_token_.empty()) {
49 return true;
52 if (!base::MessageLoop::current()) {
53 message_loop_.reset(new base::MessageLoopForIO);
56 // If a unit test has set |test_refresh_token_store_| then we should use it
57 // below. Note that we do not want to destroy the test object.
58 scoped_ptr<RefreshTokenStore> temporary_refresh_token_store;
59 RefreshTokenStore* refresh_token_store = test_refresh_token_store_;
60 if (!refresh_token_store) {
61 temporary_refresh_token_store =
62 RefreshTokenStore::OnDisk(user_name_, refresh_token_file_path_);
63 refresh_token_store = temporary_refresh_token_store.get();
66 // Check to see if we have a refresh token stored for this user.
67 refresh_token_ = refresh_token_store->FetchRefreshToken();
68 if (refresh_token_.empty()) {
69 // This isn't necessarily an error as this might be a first run scenario.
70 VLOG(2) << "No refresh token stored for " << user_name_;
72 if (auth_code.empty()) {
73 // No token and no Auth code means no service connectivity, bail!
74 LOG(ERROR) << "Cannot retrieve an access token without a stored refresh"
75 << " token on disk or an auth_code passed into the tool";
76 return false;
80 if (!RetrieveAccessToken(auth_code) || !RetrieveHostList()) {
81 // If we cannot retrieve an access token or a host list, then nothing is
82 // going to work. We should let the caller know that our object is not ready
83 // to be used.
84 return false;
87 return true;
90 void ChromotingTestDriverEnvironment::DisplayHostList() {
91 const char kHostAvailabilityFormatString[] = "%-45s%-15s%-35s";
93 LOG(INFO) << base::StringPrintf(kHostAvailabilityFormatString,
94 "Host Name", "Host Status", "Host JID");
95 LOG(INFO) << base::StringPrintf(kHostAvailabilityFormatString,
96 "---------", "-----------", "--------");
98 std::string status;
99 for (const HostInfo& host_info : host_list_) {
100 HostStatus host_status = host_info.status;
101 if (host_status == kHostStatusOnline) {
102 status = "ONLINE";
103 } else if (host_status == kHostStatusOffline) {
104 status = "OFFLINE";
105 } else {
106 status = "UNKNOWN";
109 LOG(INFO) << base::StringPrintf(
110 kHostAvailabilityFormatString, host_info.host_name.c_str(),
111 status.c_str(), host_info.host_jid.c_str());
115 void ChromotingTestDriverEnvironment::SetAccessTokenFetcherForTest(
116 AccessTokenFetcher* access_token_fetcher) {
117 DCHECK(access_token_fetcher);
119 test_access_token_fetcher_ = access_token_fetcher;
122 void ChromotingTestDriverEnvironment::SetRefreshTokenStoreForTest(
123 RefreshTokenStore* refresh_token_store) {
124 DCHECK(refresh_token_store);
126 test_refresh_token_store_ = refresh_token_store;
129 void ChromotingTestDriverEnvironment::SetHostListFetcherForTest(
130 HostListFetcher* host_list_fetcher) {
131 DCHECK(host_list_fetcher);
133 test_host_list_fetcher_ = host_list_fetcher;
136 void ChromotingTestDriverEnvironment::TearDown() {
137 // Letting the MessageLoop tear down during the test destructor results in
138 // errors after test completion, when the MessageLoop dtor touches the
139 // registered AtExitManager. The AtExitManager is torn down before the test
140 // destructor is executed, so we tear down the MessageLoop here, while it is
141 // still valid.
142 message_loop_.reset();
145 bool ChromotingTestDriverEnvironment::RetrieveAccessToken(
146 const std::string& auth_code) {
147 base::RunLoop run_loop;
149 access_token_.clear();
151 AccessTokenCallback access_token_callback =
152 base::Bind(&ChromotingTestDriverEnvironment::OnAccessTokenRetrieved,
153 base::Unretained(this), run_loop.QuitClosure());
155 // If a unit test has set |test_access_token_fetcher_| then we should use it
156 // below. Note that we do not want to destroy the test object at the end of
157 // the function which is why we have the dance below.
158 scoped_ptr<AccessTokenFetcher> temporary_access_token_fetcher;
159 AccessTokenFetcher* access_token_fetcher = test_access_token_fetcher_;
160 if (!access_token_fetcher) {
161 temporary_access_token_fetcher.reset(new AccessTokenFetcher());
162 access_token_fetcher = temporary_access_token_fetcher.get();
165 if (!auth_code.empty()) {
166 // If the user passed in an authcode, then use it to retrieve an
167 // updated access/refresh token.
168 access_token_fetcher->GetAccessTokenFromAuthCode(auth_code,
169 access_token_callback);
170 } else {
171 DCHECK(!refresh_token_.empty());
173 access_token_fetcher->GetAccessTokenFromRefreshToken(refresh_token_,
174 access_token_callback);
177 run_loop.Run();
179 // If we were using an auth_code and received a valid refresh token,
180 // then we want to store it locally. If we had an auth code and did not
181 // receive a refresh token, then we should let the user know and exit.
182 if (!auth_code.empty()) {
183 if (!refresh_token_.empty()) {
184 // If a unit test has set |test_refresh_token_store_| then we should use
185 // it below. Note that we do not want to destroy the test object.
186 scoped_ptr<RefreshTokenStore> temporary_refresh_token_store;
187 RefreshTokenStore* refresh_token_store = test_refresh_token_store_;
188 if (!refresh_token_store) {
189 temporary_refresh_token_store =
190 RefreshTokenStore::OnDisk(user_name_, refresh_token_file_path_);
191 refresh_token_store = temporary_refresh_token_store.get();
194 if (!refresh_token_store->StoreRefreshToken(refresh_token_)) {
195 // If we failed to persist the refresh token, then we should let the
196 // user sort out the issue before continuing.
197 return false;
199 } else {
200 LOG(ERROR) << "Failed to use AUTH CODE to retrieve a refresh token.\n"
201 << "Was the one-time use AUTH CODE used more than once?";
202 return false;
206 if (access_token_.empty()) {
207 LOG(ERROR) << "Failed to retrieve access token.";
208 return false;
211 return true;
214 void ChromotingTestDriverEnvironment::OnAccessTokenRetrieved(
215 base::Closure done_closure,
216 const std::string& retrieved_access_token,
217 const std::string& retrieved_refresh_token) {
218 VLOG(1) << "OnAccessTokenRetrieved() Called";
219 VLOG(1) << "Access Token: " << retrieved_access_token;
221 access_token_ = retrieved_access_token;
222 refresh_token_ = retrieved_refresh_token;
224 done_closure.Run();
227 bool ChromotingTestDriverEnvironment::RetrieveHostList() {
228 base::RunLoop run_loop;
230 host_list_.clear();
231 host_info_ = HostInfo();
233 // If a unit test has set |test_host_list_fetcher_| then we should use it
234 // below. Note that we do not want to destroy the test object at the end of
235 // the function which is why we have the dance below.
236 scoped_ptr<HostListFetcher> temporary_host_list_fetcher;
237 HostListFetcher* host_list_fetcher = test_host_list_fetcher_;
238 if (!host_list_fetcher) {
239 temporary_host_list_fetcher.reset(new HostListFetcher());
240 host_list_fetcher = temporary_host_list_fetcher.get();
243 remoting::test::HostListFetcher::HostlistCallback host_list_callback =
244 base::Bind(&ChromotingTestDriverEnvironment::OnHostListRetrieved,
245 base::Unretained(this), run_loop.QuitClosure());
247 host_list_fetcher->RetrieveHostlist(access_token_, host_list_callback);
249 run_loop.Run();
251 if (host_list_.empty()) {
252 // Note: Access token may have expired, but it is unlikely.
253 LOG(ERROR) << "Retrieved host list is empty.\n"
254 << "Does the account have hosts set up?";
255 return false;
258 // If the host or command line parameters are not setup correctly, we want to
259 // let the user fix the issue before continuing.
260 bool found_host_name = false;
261 auto host_info_iter = std::find_if(host_list_.begin(), host_list_.end(),
262 [this, &found_host_name](const remoting::test::HostInfo& host_info) {
263 if (host_info.host_name == host_name_) {
264 found_host_name = true;
265 return host_info.IsReadyForConnection();
267 return false;
269 if (host_info_iter == host_list_.end()) {
270 if (found_host_name) {
271 LOG(ERROR) << this->host_name_ << " is not ready to connect.";
272 } else {
273 LOG(ERROR) << this->host_name_ << " was not found in the host list.";
275 DisplayHostList();
276 return false;
279 host_info_ = *host_info_iter;
281 return true;
284 void ChromotingTestDriverEnvironment::OnHostListRetrieved(
285 base::Closure done_closure,
286 const std::vector<HostInfo>& retrieved_host_list) {
287 VLOG(1) << "OnHostListRetrieved() Called";
289 host_list_ = retrieved_host_list;
291 done_closure.Run();
294 } // namespace test
295 } // namespace remoting