Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: chrome/test/chromedriver/chrome/devtools_http_client.cc

Issue 605143002: [chromedriver] Accept git hashes in blink version strings from devtools (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "chrome/test/chromedriver/chrome/devtools_http_client.h" 5 #include "chrome/test/chromedriver/chrome/devtools_http_client.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/json/json_reader.h" 9 #include "base/json/json_reader.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_split.h" 11 #include "base/strings/string_split.h"
12 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
13 #include "base/threading/platform_thread.h" 14 #include "base/threading/platform_thread.h"
14 #include "base/time/time.h" 15 #include "base/time/time.h"
15 #include "base/values.h" 16 #include "base/values.h"
16 #include "chrome/test/chromedriver/chrome/device_metrics.h" 17 #include "chrome/test/chromedriver/chrome/device_metrics.h"
17 #include "chrome/test/chromedriver/chrome/devtools_client_impl.h" 18 #include "chrome/test/chromedriver/chrome/devtools_client_impl.h"
18 #include "chrome/test/chromedriver/chrome/log.h" 19 #include "chrome/test/chromedriver/chrome/log.h"
19 #include "chrome/test/chromedriver/chrome/status.h" 20 #include "chrome/test/chromedriver/chrome/status.h"
20 #include "chrome/test/chromedriver/chrome/version.h" 21 #include "chrome/test/chromedriver/chrome/version.h"
21 #include "chrome/test/chromedriver/chrome/web_view_impl.h" 22 #include "chrome/test/chromedriver/chrome/web_view_impl.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 socket_factory_(socket_factory), 67 socket_factory_(socket_factory),
67 server_url_("http://" + address.ToString()), 68 server_url_("http://" + address.ToString()),
68 web_socket_url_prefix_(base::StringPrintf( 69 web_socket_url_prefix_(base::StringPrintf(
69 "ws://%s/devtools/page/", address.ToString().c_str())), 70 "ws://%s/devtools/page/", address.ToString().c_str())),
70 device_metrics_(device_metrics.Pass()) {} 71 device_metrics_(device_metrics.Pass()) {}
71 72
72 DevToolsHttpClient::~DevToolsHttpClient() {} 73 DevToolsHttpClient::~DevToolsHttpClient() {}
73 74
74 Status DevToolsHttpClient::Init(const base::TimeDelta& timeout) { 75 Status DevToolsHttpClient::Init(const base::TimeDelta& timeout) {
75 base::TimeTicks deadline = base::TimeTicks::Now() + timeout; 76 base::TimeTicks deadline = base::TimeTicks::Now() + timeout;
76 std::string browser_version; 77 std::string version_url = server_url_ + "/json/version";
77 std::string blink_version; 78 std::string data;
78 79
79 while (true) { 80 while (!FetchUrlAndLog(version_url, context_getter_.get(), &data)) {
stgao 2014/09/29 23:09:54 I see once the returned data is empty. Add "|| dat
samuong 2014/09/30 04:03:49 Done.
80 Status status = GetVersion(&browser_version, &blink_version); 81 if (base::TimeTicks::Now() > deadline)
81 if (status.IsOk()) 82 return Status(kChromeNotReachable);
82 break;
83 if (status.code() != kChromeNotReachable ||
84 base::TimeTicks::Now() > deadline) {
85 return status;
86 }
87 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(50)); 83 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(50));
88 } 84 }
89 85
90 // |blink_version| is should look something like "537.36 (@159105)", and for 86 return internal::ParseBrowserInfo(data, &browser_info_);
91 // this example |blink_revision| should be 159105
92 size_t before = blink_version.find('@');
93 size_t after = blink_version.find(')');
94 if (before == std::string::npos || after == std::string::npos) {
95 return Status(kUnknownError,
96 "unrecognized Blink version: " + blink_version);
97 }
98
99 std::string blink_revision_string = blink_version.substr(before + 1,
100 after - before - 1);
101 int blink_revision_int;
102 if (!base::StringToInt(blink_revision_string, &blink_revision_int)) {
103 return Status(kUnknownError,
104 "unrecognized Blink revision: " + blink_revision_string);
105 }
106
107 browser_info_.blink_revision = blink_revision_int;
108
109 if (browser_version.empty()) {
110 browser_info_.browser_name = "content shell";
111 return Status(kOk);
112 }
113 if (browser_version.find("Version/") == 0u) {
114 browser_info_.browser_name = "webview";
115 return Status(kOk);
116 }
117 std::string prefix = "Chrome/";
118 if (browser_version.find(prefix) != 0u) {
119 return Status(kUnknownError,
120 "unrecognized Chrome version: " + browser_version);
121 }
122
123 std::string stripped_version = browser_version.substr(prefix.length());
124 int temp_build_no;
125 std::vector<std::string> version_parts;
126 base::SplitString(stripped_version, '.', &version_parts);
127 if (version_parts.size() != 4 ||
128 !base::StringToInt(version_parts[2], &temp_build_no)) {
129 return Status(kUnknownError,
130 "unrecognized Chrome version: " + browser_version);
131 }
132
133 browser_info_.browser_name = "chrome";
134 browser_info_.browser_version = stripped_version;
135 browser_info_.build_no = temp_build_no;
136
137 return Status(kOk);
138 } 87 }
139 88
140 Status DevToolsHttpClient::GetWebViewsInfo(WebViewsInfo* views_info) { 89 Status DevToolsHttpClient::GetWebViewsInfo(WebViewsInfo* views_info) {
141 std::string data; 90 std::string data;
142 if (!FetchUrlAndLog(server_url_ + "/json", context_getter_.get(), &data)) 91 if (!FetchUrlAndLog(server_url_ + "/json", context_getter_.get(), &data))
143 return Status(kChromeNotReachable); 92 return Status(kChromeNotReachable);
144 93
145 return internal::ParseWebViewsInfo(data, views_info); 94 return internal::ParseWebViewsInfo(data, views_info);
146 } 95 }
147 96
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 } 137 }
189 138
190 const BrowserInfo* DevToolsHttpClient::browser_info() { 139 const BrowserInfo* DevToolsHttpClient::browser_info() {
191 return &browser_info_; 140 return &browser_info_;
192 } 141 }
193 142
194 const DeviceMetrics* DevToolsHttpClient::device_metrics() { 143 const DeviceMetrics* DevToolsHttpClient::device_metrics() {
195 return device_metrics_.get(); 144 return device_metrics_.get();
196 } 145 }
197 146
198 Status DevToolsHttpClient::GetVersion(std::string* browser_version,
199 std::string* blink_version) {
200 std::string data;
201 if (!FetchUrlAndLog(
202 server_url_ + "/json/version", context_getter_.get(), &data))
203 return Status(kChromeNotReachable);
204
205 return internal::ParseVersionInfo(data, browser_version, blink_version);
206 }
207
208 Status DevToolsHttpClient::CloseFrontends(const std::string& for_client_id) { 147 Status DevToolsHttpClient::CloseFrontends(const std::string& for_client_id) {
209 WebViewsInfo views_info; 148 WebViewsInfo views_info;
210 Status status = GetWebViewsInfo(&views_info); 149 Status status = GetWebViewsInfo(&views_info);
211 if (status.IsError()) 150 if (status.IsError())
212 return status; 151 return status;
213 152
214 // Close frontends. Usually frontends are docked in the same page, although 153 // Close frontends. Usually frontends are docked in the same page, although
215 // some may be in tabs (undocked, chrome://inspect, the DevTools 154 // some may be in tabs (undocked, chrome://inspect, the DevTools
216 // discovery page, etc.). Tabs can be closed via the DevTools HTTP close 155 // discovery page, etc.). Tabs can be closed via the DevTools HTTP close
217 // URL, but docked frontends can only be closed, by design, by connecting 156 // URL, but docked frontends can only be closed, by design, by connecting
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 type = WebViewInfo::kOther; 275 type = WebViewInfo::kOther;
337 else 276 else
338 return Status(kUnknownError, 277 return Status(kUnknownError,
339 "DevTools returned unknown type:" + type_as_string); 278 "DevTools returned unknown type:" + type_as_string);
340 temp_views_info.push_back(WebViewInfo(id, debugger_url, url, type)); 279 temp_views_info.push_back(WebViewInfo(id, debugger_url, url, type));
341 } 280 }
342 *views_info = WebViewsInfo(temp_views_info); 281 *views_info = WebViewsInfo(temp_views_info);
343 return Status(kOk); 282 return Status(kOk);
344 } 283 }
345 284
346 Status ParseVersionInfo(const std::string& data, 285 Status ParseBrowserInfo(const std::string& data, BrowserInfo* browser_info) {
347 std::string* browser_version,
348 std::string* blink_version) {
349 scoped_ptr<base::Value> value(base::JSONReader::Read(data)); 286 scoped_ptr<base::Value> value(base::JSONReader::Read(data));
350 if (!value.get()) 287 if (!value.get())
351 return Status(kUnknownError, "version info not in JSON"); 288 return Status(kUnknownError, "version info not in JSON");
289
352 base::DictionaryValue* dict; 290 base::DictionaryValue* dict;
353 if (!value->GetAsDictionary(&dict)) 291 if (!value->GetAsDictionary(&dict))
354 return Status(kUnknownError, "version info not a dictionary"); 292 return Status(kUnknownError, "version info not a dictionary");
355 if (!dict->GetString("Browser", browser_version)) { 293
356 return Status( 294 std::string browser;
357 kUnknownError, 295 if (!dict->GetString("Browser", &browser)) {
358 "Chrome version must be >= " + GetMinimumSupportedChromeVersion(), 296 return Status(kUnknownError,
359 Status(kUnknownError, "version info doesn't include string 'Browser'")); 297 "version info doesn't include string 'Browser'");
360 } 298 }
361 if (!dict->GetString("WebKit-Version", blink_version)) { 299
300 std::string blink_version;
301 if (!dict->GetString("WebKit-Version", &blink_version)) {
362 return Status(kUnknownError, 302 return Status(kUnknownError,
363 "version info doesn't include string 'WebKit-Version'"); 303 "version info doesn't include string 'WebKit-Version'");
364 } 304 }
305
306 Status status = internal::ParseBrowserString(browser,
307 &browser_info->browser_name,
308 &browser_info->browser_version,
309 &browser_info->build_no);
310
311 if (status.IsError())
312 return status;
313
314 return internal::ParseBlinkVersionString(blink_version,
315 &browser_info->blink_revision);
316 }
317
318 Status ParseBrowserString(const std::string& browser_string,
319 std::string* browser_name,
320 std::string* browser_version,
321 int* build_no) {
322 if (browser_string.empty()) {
323 *browser_name = "content shell";
324 return Status(kOk);
325 }
326
327 if (browser_string.find("Version/") == 0u) {
328 *browser_name = "webview";
329 return Status(kOk);
330 }
331
332 std::string prefix = "Chrome/";
333 if (browser_string.find(prefix) == 0u) {
334 *browser_name = std::string("chrome");
stgao 2014/09/29 23:09:54 remove std::string?
samuong 2014/09/30 04:03:49 Done.
335 *browser_version = browser_string.substr(prefix.length());
336
337 std::vector<std::string> version_parts;
338 base::SplitString(*browser_version, '.', &version_parts);
339 if (version_parts.size() != 4 ||
340 !base::StringToInt(version_parts[2], build_no)) {
341 return Status(kUnknownError,
342 "unrecognized Chrome version: " + *browser_version);
343 }
344
345 return Status(kOk);
346 }
347
348 return Status(kUnknownError,
349 "unrecognized Chrome version: " + browser_string);
350 }
351
352 Status ParseBlinkVersionString(const std::string& blink_version,
353 int* blink_revision) {
354 size_t before = blink_version.find('@');
355 size_t after = blink_version.find(')');
356 if (before == std::string::npos || after == std::string::npos) {
357 return Status(kUnknownError,
358 "unrecognized Blink version string: " + blink_version);
359 }
360
361 // Chrome OS reports its Blink revision as a (non-abbreviated) git hash. In
362 // this case, ignore it and use the default blink revision, otherwise convert
stgao 2014/09/29 23:09:54 Will using the default blink revision support back
samuong 2014/09/30 04:03:48 This is just the code to parse the version json an
363 // the svn revision number to an int.
364 std::string revision = blink_version.substr(before + 1, after - before - 1);
365 if (!IsGitHash(revision) && !base::StringToInt(revision, blink_revision)) {
366 return Status(kUnknownError, "unrecognized Blink revision: " + revision);
367 }
368
365 return Status(kOk); 369 return Status(kOk);
366 } 370 }
367 371
372 bool IsGitHash(const std::string& revision) {
373 const int kGitHashLength = 40;
stgao 2014/09/29 23:09:54 Constant variable could be defined outside of meth
samuong 2014/09/30 04:03:48 Is there any reason you prefer this? Defining it i
stgao 2014/09/30 18:13:37 The style guide says it is optional, not required.
374 return revision.size() == kGitHashLength
375 && base::ContainsOnlyChars(revision, "0123456789abcdef");
stgao 2014/09/29 23:09:54 Does the function test with uppercase and lowercas
samuong 2014/09/30 04:03:48 Done.
376 }
377
368 } // namespace internal 378 } // namespace internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698