| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2006-2009 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. |
| 4 // |
| 5 // This file provides reliablity tests which run for ChromeFrame. |
| 6 // |
| 7 // Usage: |
| 8 // <reliability test exe> --list=file --startline=start --endline=end [...] |
| 9 // Upon invocation, it visits each of the URLs on line numbers between start |
| 10 // and end, inclusive, stored in the input file. The line number starts from 1. |
| 11 // |
| 12 // Optional Switches: |
| 13 // --iterations=num: goes through the list of URLs constructed in usage 2 or 3 |
| 14 // num times. |
| 15 // --continuousload: continuously visits the list of URLs without restarting |
| 16 // browser for each page load. |
| 17 // --memoryusage: prints out memory usage when visiting each page. |
| 18 // --logfile=filepath: saves the visit log to the specified path. |
| 19 // --timeout=millisecond: time out as specified in millisecond during each |
| 20 // page load. |
| 21 // --nopagedown: won't simulate page down key presses after page load. |
| 22 // --noclearprofile: do not clear profile dir before firing up each time. |
| 23 // --savedebuglog: save Chrome, V8, and test debug log for each page loaded. |
| 24 #include <fstream> |
| 25 #include <iostream> |
| 26 |
| 27 #include "base/command_line.h" |
| 28 #include "base/file_path.h" |
| 29 #include "base/file_util.h" |
| 30 #include "base/file_version_info.h" |
| 31 #include "base/keyboard_codes.h" |
| 32 #include "base/i18n/time_formatting.h" |
| 33 #include "base/path_service.h" |
| 34 #include "base/registry.h" |
| 35 #include "base/string_util.h" |
| 36 #include "base/test/test_file_util.h" |
| 37 #include "base/time.h" |
| 38 #include "chrome/browser/net/url_fixer_upper.h" |
| 39 #include "chrome/common/chrome_constants.h" |
| 40 #include "chrome/common/chrome_paths.h" |
| 41 #include "chrome/common/chrome_paths_internal.h" |
| 42 #include "chrome/common/chrome_switches.h" |
| 43 #include "chrome/common/logging_chrome.h" |
| 44 #include "chrome/common/pref_names.h" |
| 45 #include "chrome/common/pref_service.h" |
| 46 #include "chrome_frame/test/chrome_frame_test_utils.h" |
| 47 #include "chrome/test/automation/automation_messages.h" |
| 48 #include "chrome/test/automation/automation_proxy.h" |
| 49 #include "chrome/test/automation/browser_proxy.h" |
| 50 #include "chrome/test/automation/tab_proxy.h" |
| 51 #include "chrome/test/automation/window_proxy.h" |
| 52 #include "chrome/test/ui/ui_test.h" |
| 53 #include "chrome/test/reliability/page_load_test.h" |
| 54 #include "chrome_frame/utils.h" |
| 55 #include "net/base/net_util.h" |
| 56 |
| 57 |
| 58 namespace { |
| 59 |
| 60 // See comments at the beginning of the file for the definition of switches. |
| 61 const char kListSwitch[] = "list"; |
| 62 const char kStartIndexSwitch[] = "startline"; |
| 63 const char kEndIndexSwitch[] = "endline"; |
| 64 const char kIterationSwitch[] = "iterations"; |
| 65 const char kContinuousLoadSwitch[] = "continuousload"; |
| 66 const char kMemoryUsageSwitch[] = "memoryusage"; |
| 67 const char kLogFileSwitch[] = "logfile"; |
| 68 const char kTimeoutSwitch[] = "timeout"; |
| 69 const char kNoPageDownSwitch[] = "nopagedown"; |
| 70 const char kNoClearProfileSwitch[] = "noclearprofile"; |
| 71 const char kSaveDebugLogSwitch[] = "savedebuglog"; |
| 72 |
| 73 // These are copied from v8 definitions as we cannot include them. |
| 74 const char kV8LogFileSwitch[] = "logfile"; |
| 75 const char kV8LogFileDefaultName[] = "v8.log"; |
| 76 |
| 77 // String name of local chrome dll for looking up file information. |
| 78 const wchar_t kChromeDll[] = L"chrome.dll"; |
| 79 |
| 80 FilePath g_url_file_path; |
| 81 int32 g_start_index = 1; |
| 82 int32 g_end_index = kint32max; |
| 83 int32 g_iterations = 1; |
| 84 bool g_memory_usage = false; |
| 85 bool g_continuous_load = false; |
| 86 bool g_browser_existing = false; |
| 87 bool g_page_down = true; |
| 88 bool g_clear_profile = true; |
| 89 std::string g_end_url; |
| 90 FilePath g_log_file_path; |
| 91 bool g_save_debug_log = false; |
| 92 FilePath g_chrome_log_path; |
| 93 FilePath g_v8_log_path; |
| 94 FilePath g_test_log_path; |
| 95 bool g_stand_alone = false; |
| 96 |
| 97 const int kUrlNavigationTimeoutSeconds = 20; |
| 98 int g_timeout_ms = kUrlNavigationTimeoutSeconds; |
| 99 |
| 100 // Overrides a number of IWebBrowser2 event sink handlers as provided by the |
| 101 // base chrome_frame_test::WebBrowserEventSink class and provides functionality |
| 102 // for reliability testing. |
| 103 class WebBrowserEventSinkImpl : public chrome_frame_test::WebBrowserEventSink { |
| 104 public: |
| 105 typedef chrome_frame_test::WebBrowserEventSink Base; |
| 106 |
| 107 WebBrowserEventSinkImpl() |
| 108 : navigation_started_(false), |
| 109 navigation_completed_(false), |
| 110 message_loop_(NULL), |
| 111 is_chrome_frame_navigation_(false) {} |
| 112 |
| 113 ~WebBrowserEventSinkImpl() {} |
| 114 |
| 115 STDMETHOD_(void, OnDocumentComplete)(IDispatch* dispatch, VARIANT* url) { |
| 116 if (url->bstrVal && !_wcsicmp(url->bstrVal, url_.c_str())) { |
| 117 navigation_started_ = false; |
| 118 // If this is a chrome frame navigation then the OnDocumentComplete event |
| 119 // does not indicate that we actually finished navigation. For that we |
| 120 // have to wait for the OnLoad notification from ChromeFrame to arrive. |
| 121 if (!is_chrome_frame_navigation_) { |
| 122 navigation_completed_ = true; |
| 123 DCHECK(message_loop_); |
| 124 message_loop_->Quit(); |
| 125 } |
| 126 } |
| 127 } |
| 128 |
| 129 virtual void OnLoad(const wchar_t* url) { |
| 130 navigation_completed_ = true; |
| 131 DCHECK(message_loop_); |
| 132 message_loop_->Quit(); |
| 133 } |
| 134 |
| 135 virtual HRESULT Navigate(const std::wstring& navigate_url) { |
| 136 if (StartsWith(navigate_url, L"cf:", true)) { |
| 137 is_chrome_frame_navigation_ = true; |
| 138 url_ = navigate_url.substr(wcslen(L"cf:")); |
| 139 } else { |
| 140 url_ = navigate_url; |
| 141 } |
| 142 navigation_started_ = true; |
| 143 navigation_completed_ = false; |
| 144 |
| 145 return Base::Navigate(navigate_url); |
| 146 } |
| 147 |
| 148 bool navigation_started() const { |
| 149 return navigation_started_; |
| 150 } |
| 151 |
| 152 bool navigation_completed() const { |
| 153 return navigation_completed_; |
| 154 } |
| 155 |
| 156 const std::wstring& url() const { |
| 157 return url_; |
| 158 } |
| 159 |
| 160 bool is_chrome_frame_navigation() const { |
| 161 return is_chrome_frame_navigation_; |
| 162 } |
| 163 |
| 164 void set_message_loop(chrome_frame_test::TimedMsgLoop* message_loop) { |
| 165 message_loop_ = message_loop; |
| 166 } |
| 167 |
| 168 private: |
| 169 bool navigation_started_; |
| 170 bool navigation_completed_; |
| 171 std::wstring url_; |
| 172 chrome_frame_test::TimedMsgLoop* message_loop_; |
| 173 bool is_chrome_frame_navigation_; |
| 174 }; |
| 175 |
| 176 class PageLoadTest : public testing::Test { |
| 177 public: |
| 178 enum NavigationResult { |
| 179 NAVIGATION_ERROR = 0, |
| 180 NAVIGATION_SUCCESS, |
| 181 }; |
| 182 |
| 183 typedef struct { |
| 184 // These are results from the test automation that drives Chrome |
| 185 NavigationResult result; |
| 186 int crash_dump_count; |
| 187 // These are stability metrics recorded by Chrome itself |
| 188 bool browser_clean_exit; |
| 189 int browser_launch_count; |
| 190 int page_load_count; |
| 191 int browser_crash_count; |
| 192 int renderer_crash_count; |
| 193 int plugin_crash_count; |
| 194 } NavigationMetrics; |
| 195 |
| 196 PageLoadTest() {} |
| 197 |
| 198 // Accept URL as std::string here because the url may also act as a test id |
| 199 // and needs to be logged in its original format even if invalid. |
| 200 void NavigateToURLLogResult(const std::string& url_string, |
| 201 std::ofstream& log_file, |
| 202 NavigationMetrics* metrics_output) { |
| 203 GURL url(url_string); |
| 204 NavigationMetrics metrics = {NAVIGATION_ERROR}; |
| 205 std::ofstream test_log; |
| 206 |
| 207 // Create a test log. |
| 208 g_test_log_path = FilePath(FILE_PATH_LITERAL("test_log.log")); |
| 209 test_log.open(g_test_log_path.value().c_str()); |
| 210 |
| 211 // Check file version info for chrome dll. |
| 212 scoped_ptr<FileVersionInfo> file_info; |
| 213 #if defined(OS_WIN) |
| 214 file_info.reset(FileVersionInfo::CreateFileVersionInfo(kChromeDll)); |
| 215 #elif defined(OS_LINUX) || defined(OS_MACOSX) |
| 216 // TODO(fmeawad): the version retrieved here belongs to the test module and |
| 217 // not the chrome binary, need to be changed to chrome binary instead. |
| 218 file_info.reset(FileVersionInfo::CreateFileVersionInfoForCurrentModule()); |
| 219 #endif // !defined(OS_WIN) |
| 220 std::wstring last_change = file_info->last_change(); |
| 221 test_log << "Last Change: "; |
| 222 test_log << last_change << std::endl; |
| 223 |
| 224 |
| 225 // Log timestamp for test start. |
| 226 base::Time time_now = base::Time::Now(); |
| 227 double time_start = time_now.ToDoubleT(); |
| 228 test_log << "Test Start: "; |
| 229 test_log << base::TimeFormatFriendlyDateAndTime(time_now) << std::endl; |
| 230 |
| 231 HRESULT hr = E_FAIL; |
| 232 |
| 233 chrome_frame_test::TimedMsgLoop message_loop; |
| 234 |
| 235 CComObjectStack<WebBrowserEventSinkImpl> browser_event_sink; |
| 236 browser_event_sink.set_message_loop(&message_loop); |
| 237 |
| 238 if (!g_continuous_load && !g_browser_existing) { |
| 239 ScopedComPtr<IWebBrowser2> web_browser2; |
| 240 hr = chrome_frame_test::LaunchIEAsComServer(web_browser2.Receive()); |
| 241 EXPECT_HRESULT_SUCCEEDED(hr); |
| 242 EXPECT_TRUE(web_browser2.get() != NULL); |
| 243 |
| 244 EXPECT_HRESULT_SUCCEEDED(browser_event_sink.SetWebBrowser(web_browser2)); |
| 245 g_browser_existing = true; |
| 246 } |
| 247 |
| 248 // Log Browser Launched time. |
| 249 time_now = base::Time::Now(); |
| 250 test_log << "browser_launched_seconds="; |
| 251 test_log << (time_now.ToDoubleT() - time_start) << std::endl; |
| 252 |
| 253 // This is essentially what NavigateToURL does except we don't fire |
| 254 // assertion when page loading fails. We log the result instead. |
| 255 hr = browser_event_sink.Navigate(UTF8ToWide(url.spec())); |
| 256 if (SUCCEEDED(hr)) { |
| 257 message_loop.RunFor(g_timeout_ms); |
| 258 if (browser_event_sink.navigation_completed()) |
| 259 metrics.result = NAVIGATION_SUCCESS; |
| 260 } |
| 261 |
| 262 // Log navigate complete time. |
| 263 time_now = base::Time::Now(); |
| 264 test_log << "navigate_complete_seconds="; |
| 265 test_log << (time_now.ToDoubleT() - time_start) << std::endl; |
| 266 |
| 267 if (!g_continuous_load) { |
| 268 browser_event_sink.Uninitialize(); |
| 269 chrome_frame_test::CloseAllIEWindows(); |
| 270 g_browser_existing = false; |
| 271 } |
| 272 |
| 273 // Log end of test time. |
| 274 time_now = base::Time::Now(); |
| 275 test_log << "total_duration_seconds="; |
| 276 test_log << (time_now.ToDoubleT() - time_start) << std::endl; |
| 277 |
| 278 // Get navigation result and metrics, and optionally write to the log file |
| 279 // provided. The log format is: |
| 280 // <url> <navigation_result> <browser_crash_count> <renderer_crash_count> |
| 281 // <plugin_crash_count> <crash_dump_count> [chrome_log=<path> |
| 282 // v8_log=<path>] crash_dump=<path> |
| 283 if (log_file.is_open()) { |
| 284 log_file << url_string; |
| 285 switch (metrics.result) { |
| 286 case NAVIGATION_ERROR: |
| 287 log_file << " error"; |
| 288 break; |
| 289 case NAVIGATION_SUCCESS: |
| 290 log_file << " success"; |
| 291 break; |
| 292 default: |
| 293 break; |
| 294 } |
| 295 } |
| 296 |
| 297 // Get stability metrics recorded by Chrome itself. |
| 298 if (browser_event_sink.is_chrome_frame_navigation()) { |
| 299 GetStabilityMetrics(&metrics); |
| 300 } |
| 301 |
| 302 if (log_file.is_open()) { |
| 303 log_file << " " << metrics.browser_crash_count \ |
| 304 // The renderer crash count is flaky due to 1183283. |
| 305 // Ignore the count since we also catch crash by |
| 306 // crash_dump_count. |
| 307 << " " << 0 \ |
| 308 << " " << metrics.plugin_crash_count \ |
| 309 << " " << metrics.crash_dump_count; |
| 310 } |
| 311 |
| 312 // Close test log. |
| 313 test_log.close(); |
| 314 |
| 315 if (log_file.is_open() && g_save_debug_log && !g_continuous_load) |
| 316 SaveDebugLogs(log_file); |
| 317 |
| 318 // Log revision information for Chrome build under test. |
| 319 log_file << " " << "revision=" << last_change; |
| 320 |
| 321 // Get crash dumps. |
| 322 LogOrDeleteNewCrashDumps(log_file, &metrics); |
| 323 |
| 324 if (log_file.is_open()) { |
| 325 log_file << std::endl; |
| 326 } |
| 327 |
| 328 if (metrics_output) { |
| 329 *metrics_output = metrics; |
| 330 } |
| 331 } |
| 332 |
| 333 void NavigateThroughURLList(std::ofstream& log_file) { |
| 334 std::ifstream file(g_url_file_path.value().c_str()); |
| 335 ASSERT_TRUE(file.is_open()); |
| 336 |
| 337 // We navigate to URLs in the following order. |
| 338 // CF -> CF -> host -> CF -> CF -> host. |
| 339 for (int line_index = 1; |
| 340 line_index <= g_end_index && !file.eof(); |
| 341 ++line_index) { |
| 342 std::string url_str; |
| 343 std::getline(file, url_str); |
| 344 |
| 345 if (file.fail()) { |
| 346 break; |
| 347 } |
| 348 |
| 349 // Every 3rd URL goes into the host browser. |
| 350 if (line_index % 3 != 0) { |
| 351 std::string actual_url; |
| 352 actual_url = "cf:"; |
| 353 actual_url += url_str; |
| 354 url_str = actual_url; |
| 355 } |
| 356 |
| 357 if (g_start_index <= line_index) { |
| 358 NavigateToURLLogResult(url_str, log_file, NULL); |
| 359 } |
| 360 } |
| 361 |
| 362 file.close(); |
| 363 } |
| 364 |
| 365 protected: |
| 366 virtual void SetUp() { |
| 367 // Initialize crash_dumps_dir_path_. |
| 368 PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dumps_dir_path_); |
| 369 file_util::FileEnumerator enumerator(crash_dumps_dir_path_, |
| 370 false, // not recursive |
| 371 file_util::FileEnumerator::FILES); |
| 372 for (FilePath path = enumerator.Next(); !path.value().empty(); |
| 373 path = enumerator.Next()) { |
| 374 if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp"))) |
| 375 crash_dumps_[path.BaseName()] = true; |
| 376 } |
| 377 |
| 378 if (g_clear_profile) { |
| 379 FilePath user_data_dir; |
| 380 chrome::GetChromeFrameUserDataDirectory(&user_data_dir); |
| 381 ASSERT_TRUE(file_util::DieFileDie(user_data_dir, true)); |
| 382 } |
| 383 |
| 384 SetConfigBool(kChromeFrameHeadlessMode, true); |
| 385 } |
| 386 |
| 387 virtual void TearDown() { |
| 388 DeleteConfigValue(kChromeFrameHeadlessMode); |
| 389 } |
| 390 |
| 391 FilePath ConstructSavedDebugLogPath(const FilePath& debug_log_path, |
| 392 int index) { |
| 393 std::string suffix("_"); |
| 394 suffix.append(IntToString(index)); |
| 395 return debug_log_path.InsertBeforeExtensionASCII(suffix); |
| 396 } |
| 397 |
| 398 void SaveDebugLog(const FilePath& log_path, const std::wstring& log_id, |
| 399 std::ofstream& log_file, int index) { |
| 400 if (!log_path.empty()) { |
| 401 FilePath saved_log_file_path = |
| 402 ConstructSavedDebugLogPath(log_path, index); |
| 403 if (file_util::Move(log_path, saved_log_file_path)) { |
| 404 log_file << " " << log_id << "=" << saved_log_file_path.value(); |
| 405 } |
| 406 } |
| 407 } |
| 408 |
| 409 // Rename the chrome and v8 debug log files if existing, and save the file |
| 410 // paths in the log_file provided. |
| 411 void SaveDebugLogs(std::ofstream& log_file) { |
| 412 static int url_count = 1; |
| 413 SaveDebugLog(g_chrome_log_path, L"chrome_log", log_file, url_count); |
| 414 SaveDebugLog(g_v8_log_path, L"v8_log", log_file, url_count); |
| 415 SaveDebugLog(g_test_log_path, L"test_log", log_file, url_count); |
| 416 url_count++; |
| 417 } |
| 418 |
| 419 // If a log_file is provided, log the crash dump with the given path; |
| 420 // otherwise, delete the crash dump file. |
| 421 void LogOrDeleteCrashDump(std::ofstream& log_file, |
| 422 FilePath crash_dump_file_name) { |
| 423 FilePath crash_dump_file_path(crash_dumps_dir_path_); |
| 424 crash_dump_file_path = crash_dump_file_path.Append(crash_dump_file_name); |
| 425 FilePath crash_text_file_path = |
| 426 crash_dump_file_path.ReplaceExtension(FILE_PATH_LITERAL("txt")); |
| 427 |
| 428 if (log_file.is_open()) { |
| 429 crash_dumps_[crash_dump_file_name] = true; |
| 430 log_file << " crash_dump=" << crash_dump_file_path.value().c_str(); |
| 431 } else { |
| 432 ASSERT_TRUE(file_util::DieFileDie( |
| 433 crash_dump_file_path, false)); |
| 434 ASSERT_TRUE(file_util::DieFileDie( |
| 435 crash_text_file_path, false)); |
| 436 } |
| 437 } |
| 438 |
| 439 // Check whether there are new .dmp files. Additionally, write |
| 440 // " crash_dump=<full path name of the .dmp file>" |
| 441 // to log_file. |
| 442 void LogOrDeleteNewCrashDumps(std::ofstream& log_file, |
| 443 NavigationMetrics* metrics) { |
| 444 int num_dumps = 0; |
| 445 |
| 446 file_util::FileEnumerator enumerator(crash_dumps_dir_path_, |
| 447 false, // not recursive |
| 448 file_util::FileEnumerator::FILES); |
| 449 for (FilePath path = enumerator.Next(); !path.value().empty(); |
| 450 path = enumerator.Next()) { |
| 451 if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")) && |
| 452 !crash_dumps_[path.BaseName()]) { |
| 453 LogOrDeleteCrashDump(log_file, path.BaseName()); |
| 454 num_dumps++; |
| 455 } |
| 456 } |
| 457 if (metrics) |
| 458 metrics->crash_dump_count = num_dumps; |
| 459 } |
| 460 |
| 461 // Get a PrefService whose contents correspond to the Local State file |
| 462 // that was saved by the app as it closed. The caller takes ownership of the |
| 463 // returned PrefService object. |
| 464 PrefService* GetLocalState() { |
| 465 FilePath local_state_path; |
| 466 chrome::GetChromeFrameUserDataDirectory(&local_state_path); |
| 467 |
| 468 PrefService* local_state = new PrefService(local_state_path); |
| 469 return local_state; |
| 470 } |
| 471 |
| 472 void GetStabilityMetrics(NavigationMetrics* metrics) { |
| 473 if (!metrics) |
| 474 return; |
| 475 scoped_ptr<PrefService> local_state(GetLocalState()); |
| 476 if (!local_state.get()) |
| 477 return; |
| 478 local_state->RegisterBooleanPref(prefs::kStabilityExitedCleanly, false); |
| 479 local_state->RegisterIntegerPref(prefs::kStabilityLaunchCount, -1); |
| 480 local_state->RegisterIntegerPref(prefs::kStabilityPageLoadCount, -1); |
| 481 local_state->RegisterIntegerPref(prefs::kStabilityCrashCount, 0); |
| 482 local_state->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0); |
| 483 |
| 484 metrics->browser_clean_exit = |
| 485 local_state->GetBoolean(prefs::kStabilityExitedCleanly); |
| 486 metrics->browser_launch_count = |
| 487 local_state->GetInteger(prefs::kStabilityLaunchCount); |
| 488 metrics->page_load_count = |
| 489 local_state->GetInteger(prefs::kStabilityPageLoadCount); |
| 490 metrics->browser_crash_count = |
| 491 local_state->GetInteger(prefs::kStabilityCrashCount); |
| 492 metrics->renderer_crash_count = |
| 493 local_state->GetInteger(prefs::kStabilityRendererCrashCount); |
| 494 // TODO(huanr) |
| 495 metrics->plugin_crash_count = 0; |
| 496 |
| 497 if (!metrics->browser_clean_exit) |
| 498 metrics->browser_crash_count++; |
| 499 } |
| 500 |
| 501 FilePath GetSampleDataDir() { |
| 502 FilePath test_dir; |
| 503 PathService::Get(chrome::DIR_TEST_DATA, &test_dir); |
| 504 test_dir = test_dir.AppendASCII("reliability"); |
| 505 test_dir = test_dir.AppendASCII("sample_pages"); |
| 506 return test_dir; |
| 507 } |
| 508 |
| 509 // The pathname of Chrome's crash dumps directory. |
| 510 FilePath crash_dumps_dir_path_; |
| 511 |
| 512 // The set of all the crash dumps we have seen. Each crash generates a |
| 513 // .dmp and a .txt file in the crash dumps directory. We only store the |
| 514 // .dmp files in this set. |
| 515 // |
| 516 // The set is implemented as a std::map. The key is the file name, and |
| 517 // the value is false (the file is not in the set) or true (the file is |
| 518 // in the set). The initial value for any key in std::map is 0 (false), |
| 519 // which in this case means a new file is not in the set initially, |
| 520 // exactly the semantics we want. |
| 521 std::map<FilePath, bool> crash_dumps_; |
| 522 }; |
| 523 |
| 524 TEST_F(PageLoadTest, IEFullTabMode_Reliability) { |
| 525 std::ofstream log_file; |
| 526 |
| 527 if (!g_log_file_path.empty()) { |
| 528 log_file.open(g_log_file_path.value().c_str()); |
| 529 } |
| 530 |
| 531 EXPECT_FALSE(g_url_file_path.empty()); |
| 532 |
| 533 for (int k = 0; k < g_iterations; ++k) { |
| 534 NavigateThroughURLList(log_file); |
| 535 } |
| 536 |
| 537 log_file.close(); |
| 538 } |
| 539 |
| 540 } // namespace |
| 541 |
| 542 namespace { |
| 543 void ReportHandler(const std::string& str) { |
| 544 // Ignore report events. |
| 545 } |
| 546 } |
| 547 |
| 548 void SetPageRange(const CommandLine& parsed_command_line) { |
| 549 // If calling into this function, we are running as a standalone program. |
| 550 g_stand_alone = true; |
| 551 |
| 552 // Since we use --enable-dcheck for reliability tests, suppress the error |
| 553 // dialog in the test process. |
| 554 logging::SetLogReportHandler(ReportHandler); |
| 555 |
| 556 if (parsed_command_line.HasSwitch(kStartIndexSwitch)) { |
| 557 ASSERT_TRUE( |
| 558 StringToInt(WideToUTF16(parsed_command_line.GetSwitchValue( |
| 559 kStartIndexSwitch)), &g_start_index)); |
| 560 ASSERT_GT(g_start_index, 0); |
| 561 } |
| 562 |
| 563 if (parsed_command_line.HasSwitch(kEndIndexSwitch)) { |
| 564 ASSERT_TRUE( |
| 565 StringToInt(WideToUTF16(parsed_command_line.GetSwitchValue( |
| 566 kEndIndexSwitch)), &g_end_index)); |
| 567 ASSERT_GT(g_end_index, 0); |
| 568 } |
| 569 |
| 570 ASSERT_TRUE(g_end_index >= g_start_index); |
| 571 |
| 572 if (parsed_command_line.HasSwitch(kListSwitch)) |
| 573 g_url_file_path = parsed_command_line.GetSwitchValuePath(kListSwitch); |
| 574 |
| 575 if (parsed_command_line.HasSwitch(kIterationSwitch)) { |
| 576 ASSERT_TRUE( |
| 577 StringToInt(WideToUTF16(parsed_command_line.GetSwitchValue( |
| 578 kIterationSwitch)), &g_iterations)); |
| 579 ASSERT_GT(g_iterations, 0); |
| 580 } |
| 581 |
| 582 if (parsed_command_line.HasSwitch(kMemoryUsageSwitch)) |
| 583 g_memory_usage = true; |
| 584 |
| 585 if (parsed_command_line.HasSwitch(kContinuousLoadSwitch)) |
| 586 g_continuous_load = true; |
| 587 |
| 588 if (parsed_command_line.HasSwitch(kLogFileSwitch)) |
| 589 g_log_file_path = parsed_command_line.GetSwitchValuePath(kLogFileSwitch); |
| 590 |
| 591 if (parsed_command_line.HasSwitch(kTimeoutSwitch)) { |
| 592 ASSERT_TRUE( |
| 593 StringToInt(WideToUTF16(parsed_command_line.GetSwitchValue( |
| 594 kTimeoutSwitch)), &g_timeout_ms)); |
| 595 ASSERT_GT(g_timeout_ms, 0); |
| 596 } |
| 597 |
| 598 if (parsed_command_line.HasSwitch(kNoPageDownSwitch)) |
| 599 g_page_down = false; |
| 600 |
| 601 if (parsed_command_line.HasSwitch(kNoClearProfileSwitch)) |
| 602 g_clear_profile = false; |
| 603 |
| 604 if (parsed_command_line.HasSwitch(kSaveDebugLogSwitch)) { |
| 605 g_save_debug_log = true; |
| 606 g_chrome_log_path = logging::GetLogFileName(); |
| 607 // We won't get v8 log unless --no-sandbox is specified. |
| 608 if (parsed_command_line.HasSwitch(switches::kNoSandbox)) { |
| 609 PathService::Get(base::DIR_CURRENT, &g_v8_log_path); |
| 610 g_v8_log_path = g_v8_log_path.AppendASCII(kV8LogFileDefaultName); |
| 611 // The command line switch may override the default v8 log path. |
| 612 if (parsed_command_line.HasSwitch(switches::kJavaScriptFlags)) { |
| 613 CommandLine v8_command_line( |
| 614 parsed_command_line.GetSwitchValuePath(switches::kJavaScriptFlags)); |
| 615 if (v8_command_line.HasSwitch(kV8LogFileSwitch)) { |
| 616 g_v8_log_path = v8_command_line.GetSwitchValuePath(kV8LogFileSwitch); |
| 617 if (!file_util::AbsolutePath(&g_v8_log_path)) |
| 618 g_v8_log_path = FilePath(); |
| 619 } |
| 620 } |
| 621 } |
| 622 } |
| 623 } |
| 624 |
| OLD | NEW |