Index: chrome/test/reliability/page_load_test.cc |
diff --git a/chrome/test/reliability/page_load_test.cc b/chrome/test/reliability/page_load_test.cc |
deleted file mode 100644 |
index 932153720420013eb3ccf78d765c11184c3fd492..0000000000000000000000000000000000000000 |
--- a/chrome/test/reliability/page_load_test.cc |
+++ /dev/null |
@@ -1,796 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
-// |
-// This file provides reliablity test which runs under UI test framework. The |
-// test is intended to run within QEMU environment. |
-// |
-// Usage 1: reliability_test |
-// Upon invocation, it visits a hard coded list of sample URLs. This is mainly |
-// used by buildbot, to verify reliability_test itself runs ok. |
-// |
-// Usage 2: reliability_test --site=url --startpage=start --endpage=end [...] |
-// Upon invocation, it visits a list of URLs constructed as |
-// "http://url/page?id=k". (start <= k <= end). |
-// |
-// Usage 3: reliability_test --list=file --startline=start --endline=end [...] |
-// Upon invocation, it visits each of the URLs on line numbers between start |
-// and end, inclusive, stored in the input file. The line number starts from 1. |
-// |
-// If both "--site" and "--list" are provided, the "--site" set of arguments |
-// are ignored. |
-// |
-// Optional Switches: |
-// --iterations=num: goes through the list of URLs constructed in usage 2 or 3 |
-// num times. |
-// --continuousload: continuously visits the list of URLs without restarting |
-// browser for each page load. |
-// --memoryusage: prints out memory usage when visiting each page. |
-// --endurl=url: visits the specified url in the end. |
-// --logfile=filepath: saves the visit log to the specified path. |
-// --noclearprofile: do not clear profile dir before firing up each time. |
-// --savedebuglog: save Chrome, V8, and test debug log for each page loaded. |
-// --searchdumpsbypid: Look for crash dumps by browser process id. |
-// "crash_dir/pid/" |
- |
-#include <fstream> |
-#include <vector> |
- |
-#include "base/command_line.h" |
-#include "base/environment.h" |
-#include "base/file_util.h" |
-#include "base/file_version_info.h" |
-#include "base/files/file_enumerator.h" |
-#include "base/files/file_path.h" |
-#include "base/i18n/time_formatting.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/path_service.h" |
-#include "base/prefs/json_pref_store.h" |
-#include "base/prefs/pref_registry_simple.h" |
-#include "base/prefs/pref_service.h" |
-#include "base/process/kill.h" |
-#include "base/strings/string_number_conversions.h" |
-#include "base/strings/string_util.h" |
-#include "base/test/test_file_util.h" |
-#include "base/threading/platform_thread.h" |
-#include "base/time/time.h" |
-#include "chrome/browser/prefs/pref_service_mock_builder.h" |
-#include "chrome/common/automation_messages.h" |
-#include "chrome/common/chrome_constants.h" |
-#include "chrome/common/chrome_paths.h" |
-#include "chrome/common/chrome_switches.h" |
-#include "chrome/common/chrome_version_info.h" |
-#include "chrome/common/logging_chrome.h" |
-#include "chrome/common/net/url_fixer_upper.h" |
-#include "chrome/common/pref_names.h" |
-#include "chrome/common/render_messages.h" |
-#include "chrome/common/url_constants.h" |
-#include "chrome/test/automation/automation_proxy.h" |
-#include "chrome/test/automation/browser_proxy.h" |
-#include "chrome/test/automation/tab_proxy.h" |
-#include "chrome/test/automation/window_proxy.h" |
-#include "chrome/test/ui/ui_test.h" |
-#include "net/base/net_util.h" |
-#include "v8/include/v8-testing.h" |
- |
-namespace { |
- |
-// See comments at the beginning of the file for the definition of switches. |
-const char kSiteSwitch[] = "site"; |
-const char kStartPageSwitch[] = "startpage"; |
-const char kEndPageSwitch[] = "endpage"; |
-const char kListSwitch[] = "list"; |
-const char kStartIndexSwitch[] = "startline"; |
-const char kEndIndexSwitch[] = "endline"; |
-const char kIterationSwitch[] = "iterations"; |
-const char kContinuousLoadSwitch[] = "continuousload"; |
-const char kMemoryUsageSwitch[] = "memoryusage"; |
-const char kEndURLSwitch[] = "endurl"; |
-const char kLogFileSwitch[] = "logfile"; |
-const char kNoPageDownSwitch[] = "nopagedown"; |
-const char kNoClearProfileSwitch[] = "noclearprofile"; |
-const char kSaveDebugLogSwitch[] = "savedebuglog"; |
-const char kStressOptSwitch[] = "stress-opt"; |
-const char kStressDeoptSwitch[] = "stress-deopt"; |
- |
-const char kDefaultServerUrl[] = "http://urllist.com"; |
-std::string g_server_url; |
-const char kTestPage1[] = "page1.html"; |
-const char kTestPage2[] = "page2.html"; |
- |
-// These are copied from v8 definitions as we cannot include them. |
-const char kV8LogFileSwitch[] = "logfile"; |
-const char kV8LogFileDefaultName[] = "v8.log"; |
- |
-// String name of local chrome dll for looking up file information. |
-const wchar_t kChromeDll[] = L"chrome.dll"; |
- |
-bool g_append_page_id = false; |
-int32 g_start_page; |
-int32 g_end_page; |
-base::FilePath g_url_file_path; |
-int32 g_start_index = 1; |
-int32 g_end_index = kint32max; |
-int32 g_iterations = 1; |
-bool g_memory_usage = false; |
-bool g_continuous_load = false; |
-bool g_browser_existing = false; |
-bool g_clear_profile = true; |
-std::string g_end_url; |
-base::FilePath g_log_file_path; |
-bool g_save_debug_log = false; |
-base::FilePath g_chrome_log_path; |
-base::FilePath g_v8_log_path; |
-base::FilePath g_test_log_path; |
-bool g_stand_alone = false; |
-bool g_stress_opt = false; |
-bool g_stress_deopt = false; |
- |
-void ReportHandler(const std::string& str) { |
- // Ignore report events. |
-} |
- |
-void SetPageRange(const CommandLine& parsed_command_line) { |
- // If calling into this function, we are running as a standalone program. |
- g_stand_alone = true; |
- |
- // Since we use --enable-dcheck for reliability tests, suppress the error |
- // dialog in the test process. |
- logging::SetLogReportHandler(ReportHandler); |
- |
- if (parsed_command_line.HasSwitch(kStartPageSwitch)) { |
- ASSERT_TRUE(parsed_command_line.HasSwitch(kEndPageSwitch)); |
- ASSERT_TRUE( |
- base::StringToInt(parsed_command_line.GetSwitchValueASCII( |
- kStartPageSwitch), |
- &g_start_page)); |
- ASSERT_TRUE( |
- base::StringToInt(parsed_command_line.GetSwitchValueASCII( |
- kEndPageSwitch), |
- &g_end_page)); |
- ASSERT_TRUE(g_start_page > 0 && g_end_page > 0); |
- ASSERT_TRUE(g_start_page < g_end_page); |
- g_append_page_id = true; |
- } else { |
- ASSERT_FALSE(parsed_command_line.HasSwitch(kEndPageSwitch)); |
- } |
- |
- if (parsed_command_line.HasSwitch(kSiteSwitch)) { |
- g_server_url = parsed_command_line.GetSwitchValueASCII(kSiteSwitch); |
- } |
- |
- if (parsed_command_line.HasSwitch(kStartIndexSwitch)) { |
- ASSERT_TRUE( |
- base::StringToInt(parsed_command_line.GetSwitchValueASCII( |
- kStartIndexSwitch), |
- &g_start_index)); |
- ASSERT_GT(g_start_index, 0); |
- } |
- |
- if (parsed_command_line.HasSwitch(kEndIndexSwitch)) { |
- ASSERT_TRUE( |
- base::StringToInt(parsed_command_line.GetSwitchValueASCII( |
- kEndIndexSwitch), |
- &g_end_index)); |
- ASSERT_GT(g_end_index, 0); |
- } |
- |
- ASSERT_TRUE(g_end_index >= g_start_index); |
- |
- if (parsed_command_line.HasSwitch(kListSwitch)) |
- g_url_file_path = parsed_command_line.GetSwitchValuePath(kListSwitch); |
- |
- if (parsed_command_line.HasSwitch(kIterationSwitch)) { |
- ASSERT_TRUE( |
- base::StringToInt(parsed_command_line.GetSwitchValueASCII( |
- kIterationSwitch), |
- &g_iterations)); |
- ASSERT_GT(g_iterations, 0); |
- } |
- |
- if (parsed_command_line.HasSwitch(kMemoryUsageSwitch)) |
- g_memory_usage = true; |
- |
- if (parsed_command_line.HasSwitch(kContinuousLoadSwitch)) |
- g_continuous_load = true; |
- |
- if (parsed_command_line.HasSwitch(kEndURLSwitch)) |
- g_end_url = parsed_command_line.GetSwitchValueASCII(kEndURLSwitch); |
- |
- if (parsed_command_line.HasSwitch(kLogFileSwitch)) |
- g_log_file_path = parsed_command_line.GetSwitchValuePath(kLogFileSwitch); |
- |
- if (parsed_command_line.HasSwitch(kNoClearProfileSwitch)) |
- g_clear_profile = false; |
- |
- if (parsed_command_line.HasSwitch(kSaveDebugLogSwitch)) { |
- g_save_debug_log = true; |
- g_chrome_log_path = logging::GetLogFileName(); |
- // We won't get v8 log unless --no-sandbox is specified. |
- if (parsed_command_line.HasSwitch(switches::kNoSandbox)) { |
- PathService::Get(base::DIR_CURRENT, &g_v8_log_path); |
- g_v8_log_path = g_v8_log_path.AppendASCII(kV8LogFileDefaultName); |
- // The command line switch may override the default v8 log path. |
- if (parsed_command_line.HasSwitch(switches::kJavaScriptFlags)) { |
- CommandLine v8_command_line( |
- parsed_command_line.GetSwitchValuePath(switches::kJavaScriptFlags)); |
- if (v8_command_line.HasSwitch(kV8LogFileSwitch)) { |
- g_v8_log_path = base::MakeAbsoluteFilePath( |
- v8_command_line.GetSwitchValuePath(kV8LogFileSwitch)); |
- } |
- } |
- } |
- } |
- |
- if (parsed_command_line.HasSwitch(kStressOptSwitch)) { |
- g_stress_opt = true; |
- } |
- if (parsed_command_line.HasSwitch(kStressDeoptSwitch)) { |
- g_stress_deopt = true; |
- } |
-} |
- |
-class PageLoadTest : public UITest { |
- public: |
- enum NavigationResult { |
- NAVIGATION_ERROR = 0, |
- NAVIGATION_SUCCESS, |
- NAVIGATION_AUTH_NEEDED, |
- NAVIGATION_TIME_OUT, |
- }; |
- |
- typedef struct { |
- // These are results from the test automation that drives Chrome |
- NavigationResult result; |
- int crash_dump_count; |
- // These are stability metrics recorded by Chrome itself |
- bool browser_clean_exit; |
- int browser_launch_count; |
- int page_load_count; |
- int browser_crash_count; |
- int renderer_crash_count; |
- int plugin_crash_count; |
- } NavigationMetrics; |
- |
- PageLoadTest() { |
- show_window_ = true; |
- SetPageRange(*CommandLine::ForCurrentProcess()); |
- } |
- |
- void EnsureBrowserAndServer() { |
- if (!g_browser_existing) { |
- LaunchBrowserAndServer(); |
- g_browser_existing = true; |
- } |
- } |
- |
- // Load a URL in a browser tab and perform a couple of page down events. |
- // url_string: The URL to navigate to. Accept URL as std::string here |
- // because the url may also act as a test id and needs to |
- // be logged in its original format even if invalid. |
- // log_file: Log file for test results and possible crash dump |
- // files. This file does not need to be opened in which |
- // case nothing is logged. |
- // metrics_output: Return metrics for the page load. |
- // keep_browser: Set to true if the browser should be kept open after |
- // loading the page. |
- // log_only_errors: Set to true if only errors should be logged otherwise |
- // successful navigations will also be logged. |
- bool NavigateToURLLogResult(const std::string& url_string, |
- std::ofstream& log_file, |
- NavigationMetrics* metrics_output, |
- bool keep_browser, |
- bool log_only_error) { |
- GURL url(url_string); |
- NavigationMetrics metrics = {NAVIGATION_ERROR}; |
- std::ofstream test_log; |
- |
- // Create a test log. |
- g_test_log_path = base::FilePath(FILE_PATH_LITERAL("test_log.log")); |
- test_log.open(g_test_log_path.value().c_str()); |
- |
- // Get the version of Chrome we're running. |
- std::string last_change; |
-#if defined(OS_WIN) |
- // Check file version info for chrome dll. |
- scoped_ptr<FileVersionInfo> file_info; |
- file_info.reset( |
- FileVersionInfo::CreateFileVersionInfo(base::FilePath(kChromeDll))); |
- last_change = WideToASCII(file_info->last_change()); |
-#elif defined(OS_POSIX) |
- // TODO(fmeawad): On Mac, the version retrieved here belongs to the test |
- // module and not the chrome binary, need to be changed to chrome binary |
- // instead. |
- chrome::VersionInfo version_info; |
- last_change = version_info.LastChange(); |
-#endif // !defined(OS_WIN) |
- test_log << "Last Change: "; |
- test_log << last_change << std::endl; |
- |
- // Log timestamp for test start. |
- base::Time time_now = base::Time::Now(); |
- double time_start = time_now.ToDoubleT(); |
- test_log << "Test Start: "; |
- test_log << base::TimeFormatFriendlyDateAndTime(time_now) << std::endl; |
- |
- // Make sure the browser is running. |
- EnsureBrowserAndServer(); |
- |
- // Log Browser Launched time. |
- time_now = base::Time::Now(); |
- test_log << "browser_launched_seconds="; |
- test_log << (time_now.ToDoubleT() - time_start) << std::endl; |
- |
- int result = AUTOMATION_MSG_NAVIGATION_ERROR; |
- // This is essentially what NavigateToURL does except we don't fire |
- // assertion when page loading fails. We log the result instead. |
- { |
- // TabProxy should be released before Browser is closed. |
- scoped_refptr<TabProxy> tab_proxy(GetActiveTab()); |
- if (tab_proxy.get()) |
- result = tab_proxy->NavigateToURL(url); |
- } |
- |
- // Log navigate complete time. |
- time_now = base::Time::Now(); |
- test_log << "navigate_complete_seconds="; |
- test_log << (time_now.ToDoubleT() - time_start) << std::endl; |
- |
- if (!keep_browser) { |
- CloseBrowserAndServer(); |
- g_browser_existing = false; |
- } |
- |
- // Log end of test time. |
- time_now = base::Time::Now(); |
- test_log << "total_duration_seconds="; |
- test_log << (time_now.ToDoubleT() - time_start) << std::endl; |
- |
- // Get navigation result and metrics, and optionally write to the log file |
- // provided. The log format is: |
- // <url> <navigation_result> <browser_crash_count> <renderer_crash_count> |
- // <plugin_crash_count> <crash_dump_count> [chrome_log=<path> |
- // v8_log=<path>] crash_dump=<path> |
- switch (result) { |
- case AUTOMATION_MSG_NAVIGATION_ERROR: |
- metrics.result = NAVIGATION_ERROR; |
- break; |
- case AUTOMATION_MSG_NAVIGATION_SUCCESS: |
- metrics.result = NAVIGATION_SUCCESS; |
- break; |
- case AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED: |
- metrics.result = NAVIGATION_AUTH_NEEDED; |
- break; |
- default: |
- metrics.result = NAVIGATION_ERROR; |
- break; |
- } |
- |
- // Get crash dumps - don't delete them if logging. |
- std::vector<base::FilePath> new_crash_dumps; |
- CollectNewCrashDumps(new_crash_dumps, &metrics, !log_file.is_open()); |
- |
- bool do_log = log_file.is_open() && |
- (!log_only_error || |
- metrics.result != NAVIGATION_SUCCESS || |
- !new_crash_dumps.empty()); |
- if (do_log) { |
- log_file << url_string; |
- switch (metrics.result) { |
- case NAVIGATION_ERROR: |
- log_file << " error"; |
- break; |
- case NAVIGATION_SUCCESS: |
- log_file << " success"; |
- break; |
- case NAVIGATION_AUTH_NEEDED: |
- log_file << " auth_needed"; |
- break; |
- case NAVIGATION_TIME_OUT: |
- log_file << " timeout"; |
- break; |
- default: |
- break; |
- } |
- } |
- |
-#if !defined(OS_MACOSX) // Not used by mac chromebot. |
- // Get stability metrics recorded by Chrome itself. |
- GetStabilityMetrics(&metrics); |
-#endif |
- |
- if (do_log) { |
- log_file << " " << metrics.browser_crash_count \ |
- // The renderer crash count is flaky due to 1183283. |
- // Ignore the count since we also catch crash by |
- // crash_dump_count. |
- << " " << 0 \ |
- << " " << metrics.plugin_crash_count \ |
- << " " << metrics.crash_dump_count; |
- } |
- |
- // Close test log. |
- test_log.close(); |
- |
- if (do_log && g_save_debug_log && !g_continuous_load) |
- SaveDebugLogs(log_file); |
- |
- // Log revision information for Chrome build under test. |
- if (do_log) |
- log_file << " " << "revision=" << last_change; |
- |
- if (do_log) { |
- for (size_t i = 0; i < new_crash_dumps.size(); i++) |
- log_file << " crash_dump=" << new_crash_dumps[i].value().c_str(); |
- } |
- |
- if (do_log) |
- log_file << std::endl; |
- |
- if (metrics_output) |
- *metrics_output = metrics; |
- |
- return do_log; |
- } |
- |
- void NavigateThroughPageID(std::ofstream& log_file) { |
- if (g_append_page_id) { |
- // For usage 2 |
- for (int i = g_start_page; i <= g_end_page; ++i) { |
- const char* server = g_server_url.empty() ? kDefaultServerUrl : |
- g_server_url.c_str(); |
- std::string test_page_url( |
- base::StringPrintf("%s/page?id=%d", server, i)); |
- NavigateToURLLogResult( |
- test_page_url, log_file, NULL, g_continuous_load, false); |
- } |
- } else { |
- // Don't run if running as a standalone program which is for distributed |
- // testing, to avoid mistakenly hitting web sites with many instances. |
- if (g_stand_alone) |
- return; |
- // For usage 1 |
- NavigationMetrics metrics; |
- |
- base::FilePath sample_data_dir = GetSampleDataDir(); |
- base::FilePath test_page_1 = sample_data_dir.AppendASCII(kTestPage1); |
- base::FilePath test_page_2 = sample_data_dir.AppendASCII(kTestPage2); |
- |
- GURL test_url_1 = net::FilePathToFileURL(test_page_1); |
- GURL test_url_2 = net::FilePathToFileURL(test_page_2); |
- |
- // Convert back to string so that all calls to navigate are the same. |
- const std::string test_url_1_string = test_url_1.spec(); |
- const std::string test_url_2_string = test_url_2.spec(); |
- |
- NavigateToURLLogResult( |
- test_url_1_string, log_file, &metrics, g_continuous_load, false); |
- // Verify everything is fine |
- EXPECT_EQ(NAVIGATION_SUCCESS, metrics.result); |
- EXPECT_EQ(0, metrics.crash_dump_count); |
- EXPECT_TRUE(metrics.browser_clean_exit); |
- EXPECT_EQ(1, metrics.browser_launch_count); |
- // Both starting page and test_url_1 are loaded. |
- EXPECT_EQ(2, metrics.page_load_count); |
- EXPECT_EQ(0, metrics.browser_crash_count); |
- EXPECT_EQ(0, metrics.renderer_crash_count); |
- EXPECT_EQ(0, metrics.plugin_crash_count); |
- |
- // Go to "about:crash" |
- NavigateToURLLogResult(content::kChromeUICrashURL, |
- log_file, |
- &metrics, |
- g_continuous_load, |
- false); |
- // Found a crash dump |
- EXPECT_EQ(1, metrics.crash_dump_count) << kFailedNoCrashService; |
- // Browser did not crash, and exited cleanly. |
- EXPECT_TRUE(metrics.browser_clean_exit); |
- EXPECT_EQ(1, metrics.browser_launch_count); |
- // Only the renderer should have crashed. |
- EXPECT_EQ(0, metrics.browser_crash_count); |
- EXPECT_EQ(1, metrics.renderer_crash_count); |
- EXPECT_EQ(0, metrics.plugin_crash_count); |
- |
- NavigateToURLLogResult( |
- test_url_2_string, log_file, &metrics, g_continuous_load, false); |
- // The data on previous crash should be cleared and we should get |
- // metrics for a successful page load. |
- EXPECT_EQ(NAVIGATION_SUCCESS, metrics.result); |
- EXPECT_EQ(0, metrics.crash_dump_count); |
- EXPECT_TRUE(metrics.browser_clean_exit); |
- EXPECT_EQ(1, metrics.browser_launch_count); |
- EXPECT_EQ(0, metrics.browser_crash_count); |
- EXPECT_EQ(0, metrics.renderer_crash_count); |
- EXPECT_EQ(0, metrics.plugin_crash_count); |
- |
- // Verify metrics service does what we need when browser process crashes. |
- LaunchBrowserAndServer(); |
- { |
- // TabProxy should be released before Browser is closed. |
- scoped_refptr<TabProxy> tab_proxy(GetActiveTab()); |
- EXPECT_TRUE(tab_proxy.get()); |
- if (tab_proxy.get()) { |
- EXPECT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, |
- tab_proxy->NavigateToURL(GURL(test_url_1))); |
- } |
- } |
- // Kill browser process. |
- base::ProcessHandle browser_process = process(); |
- base::KillProcess(browser_process, 0, false); |
- |
- GetStabilityMetrics(&metrics); |
- // This is not a clean shutdown. |
- EXPECT_FALSE(metrics.browser_clean_exit); |
- EXPECT_EQ(1, metrics.browser_crash_count); |
- EXPECT_EQ(0, metrics.renderer_crash_count); |
- EXPECT_EQ(0, metrics.plugin_crash_count); |
- // Relaunch browser so UITest does not fire assertion during TearDown. |
- LaunchBrowserAndServer(); |
- } |
- } |
- |
- // For usage 3 |
- void NavigateThroughURLList(std::ofstream& log_file) { |
- std::ifstream file(g_url_file_path.value().c_str()); |
- ASSERT_TRUE(file.is_open()); |
- |
- for (int line_index = 1; |
- line_index <= g_end_index && !file.eof(); |
- ++line_index) { |
- std::string url_str; |
- std::getline(file, url_str); |
- |
- if (file.fail()) |
- break; |
- |
- if (g_start_index <= line_index) { |
- if (g_stress_opt || g_stress_deopt) { |
- // Make sure the browser is running to communicate the stress |
- // setting. |
- EnsureBrowserAndServer(); |
- v8::Testing::StressType stress_type = |
- g_stress_opt |
- ? v8::Testing::kStressTypeOpt |
- : v8::Testing::kStressTypeDeopt; |
- scoped_refptr<TabProxy> tab_proxy(GetActiveTab()); |
- if (tab_proxy.get()) { |
- tab_proxy->JavaScriptStressTestControl( |
- kJavaScriptStressTestSetStressRunType, stress_type); |
- } |
- |
- bool success = true; |
- // Load each page a number of times and keep the same browser open |
- // for these loads. This loop will end if an error is encountered |
- // during one of the loads and the error logged. |
- for (int i = 0; |
- i < v8::Testing::GetStressRuns() && success; |
- i++) { |
- bool last_load = (i == (v8::Testing::GetStressRuns() - 1)); |
- bool keep_browser = !last_load || g_continuous_load; |
- bool log_only_error = !last_load; |
- NavigationMetrics metrics; |
- |
- scoped_refptr<TabProxy> tab_proxy(GetActiveTab()); |
- if (tab_proxy.get()) { |
- tab_proxy->JavaScriptStressTestControl( |
- kJavaScriptStressTestPrepareStressRun, i); |
- } |
- bool did_log_error; |
- did_log_error = NavigateToURLLogResult(url_str, |
- log_file, |
- &metrics, |
- keep_browser, |
- log_only_error); |
- success = metrics.result == NAVIGATION_SUCCESS && !did_log_error; |
- } |
- } else { |
- NavigateToURLLogResult( |
- url_str, log_file, NULL, g_continuous_load, false); |
- } |
- } |
- } |
- |
- file.close(); |
- } |
- |
- protected: |
- // Call the base class's SetUp method and initialize our own class members. |
- virtual void SetUp() { |
- // Set UI Test members before setting up browser. |
- clear_profile_ = g_clear_profile; |
- |
- UITest::SetUp(); |
- g_browser_existing = true; |
- |
- // If 'BREAKPAD_DUMP_LOCATION' environment variable is set, use it instead. |
- scoped_ptr<base::Environment> env(base::Environment::Create()); |
- std::string alternate_minidump_location; |
- if (env->GetVar("BREAKPAD_DUMP_LOCATION", &alternate_minidump_location)) { |
- crash_dumps_dir_path_ = base::FilePath::FromUTF8Unsafe( |
- alternate_minidump_location); |
- } else { |
- PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dumps_dir_path_); |
- } |
- |
- base::FileEnumerator enumerator(crash_dumps_dir_path_, |
- false, // not recursive |
- base::FileEnumerator::FILES); |
- for (base::FilePath path = enumerator.Next(); !path.value().empty(); |
- path = enumerator.Next()) { |
- if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp"))) |
- crash_dumps_[path.BaseName()] = true; |
- } |
- } |
- |
- base::FilePath ConstructSavedDebugLogPath( |
- const base::FilePath& debug_log_path, |
- int index) { |
- std::string suffix("_"); |
- suffix.append(base::IntToString(index)); |
- return debug_log_path.InsertBeforeExtensionASCII(suffix); |
- } |
- |
- void SaveDebugLog(const base::FilePath& log_path, const std::wstring& log_id, |
- std::ofstream& log_file, int index) { |
- if (!log_path.empty()) { |
- base::FilePath saved_log_file_path = |
- ConstructSavedDebugLogPath(log_path, index); |
- if (base::Move(log_path, saved_log_file_path)) { |
- log_file << " " << log_id << "=" << saved_log_file_path.value(); |
- } |
- } |
- } |
- |
- // Rename the chrome and v8 debug log files if existing, and save the file |
- // paths in the log_file provided. |
- void SaveDebugLogs(std::ofstream& log_file) { |
- static int url_count = 1; |
- SaveDebugLog(g_chrome_log_path, L"chrome_log", log_file, url_count); |
- SaveDebugLog(g_v8_log_path, L"v8_log", log_file, url_count); |
- SaveDebugLog(g_test_log_path, L"test_log", log_file, url_count); |
- url_count++; |
- } |
- |
- // Delete a crash dump file. |
- void DeleteCrashDump(base::FilePath crash_dump_file_name) { |
- base::FilePath crash_dump_file_path(crash_dumps_dir_path_); |
- crash_dump_file_path = crash_dump_file_path.Append(crash_dump_file_name); |
- base::FilePath crash_text_file_path = |
- crash_dump_file_path.ReplaceExtension(FILE_PATH_LITERAL("txt")); |
- |
- ASSERT_TRUE(file_util::DieFileDie(crash_dump_file_path, false)); |
- ASSERT_TRUE(file_util::DieFileDie(crash_text_file_path, false)); |
- } |
- |
- bool HasNewCrashDumps() { |
- base::FileEnumerator enumerator(crash_dumps_dir_path_, |
- false, // not recursive |
- base::FileEnumerator::FILES); |
- for (base::FilePath path = enumerator.Next(); !path.value().empty(); |
- path = enumerator.Next()) { |
- if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")) && |
- !crash_dumps_[path.BaseName()]) { |
- return true; |
- } |
- } |
- |
- return false; |
- } |
- |
- // Check whether there are new .dmp files. Return the list and optionally |
- // delete them afterwards. |
- void CollectNewCrashDumps(std::vector<base::FilePath>& new_crash_dumps, |
- NavigationMetrics* metrics, |
- bool delete_dumps) { |
- int num_dumps = 0; |
- base::FileEnumerator enumerator(crash_dumps_dir_path_, |
- false, // not recursive |
- base::FileEnumerator::FILES); |
- for (base::FilePath path = enumerator.Next(); !path.value().empty(); |
- path = enumerator.Next()) { |
- if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")) && |
- !crash_dumps_[path.BaseName()]) { |
- crash_dumps_[path.BaseName()] = true; |
- base::FilePath crash_dump_file_path(crash_dumps_dir_path_); |
- crash_dump_file_path = crash_dump_file_path.Append(path.BaseName()); |
- new_crash_dumps.push_back(crash_dump_file_path); |
- if (delete_dumps) |
- DeleteCrashDump(path.BaseName()); |
- num_dumps++; |
- } |
- } |
- if (metrics) |
- metrics->crash_dump_count = num_dumps; |
- } |
- |
- // Get a PrefService whose contents correspond to the Local State file |
- // that was saved by the app as it closed. The caller takes ownership of the |
- // returned PrefService object. |
- PrefService* GetLocalState(PrefRegistry* registry) { |
- base::FilePath path = user_data_dir().Append(chrome::kLocalStateFilename); |
- PrefServiceMockBuilder builder; |
- builder.WithUserFilePrefs( |
- path, base::MessageLoop::current()->message_loop_proxy().get()); |
- return builder.Create(registry); |
- } |
- |
- void GetStabilityMetrics(NavigationMetrics* metrics) { |
- if (!metrics) |
- return; |
- scoped_refptr<PrefRegistrySimple> registry = new PrefRegistrySimple(); |
- registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, false); |
- registry->RegisterIntegerPref(prefs::kStabilityLaunchCount, -1); |
- registry->RegisterIntegerPref(prefs::kStabilityPageLoadCount, -1); |
- registry->RegisterIntegerPref(prefs::kStabilityCrashCount, 0); |
- registry->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0); |
- |
- scoped_ptr<PrefService> local_state(GetLocalState(registry.get())); |
- if (!local_state.get()) |
- return; |
- |
- metrics->browser_clean_exit = |
- local_state->GetBoolean(prefs::kStabilityExitedCleanly); |
- metrics->browser_launch_count = |
- local_state->GetInteger(prefs::kStabilityLaunchCount); |
- metrics->page_load_count = |
- local_state->GetInteger(prefs::kStabilityPageLoadCount); |
- metrics->browser_crash_count = |
- local_state->GetInteger(prefs::kStabilityCrashCount); |
- metrics->renderer_crash_count = |
- local_state->GetInteger(prefs::kStabilityRendererCrashCount); |
- // TODO(huanr) |
- metrics->plugin_crash_count = 0; |
- |
- if (!metrics->browser_clean_exit) |
- metrics->browser_crash_count++; |
- } |
- |
- base::FilePath GetSampleDataDir() { |
- base::FilePath test_dir; |
- PathService::Get(chrome::DIR_TEST_DATA, &test_dir); |
- test_dir = test_dir.AppendASCII("reliability"); |
- test_dir = test_dir.AppendASCII("sample_pages"); |
- return test_dir; |
- } |
- |
- // The pathname of Chrome's crash dumps directory. |
- base::FilePath crash_dumps_dir_path_; |
- |
- // The set of all the crash dumps we have seen. Each crash generates a |
- // .dmp and a .txt file in the crash dumps directory. We only store the |
- // .dmp files in this set. |
- // |
- // The set is implemented as a std::map. The key is the file name, and |
- // the value is false (the file is not in the set) or true (the file is |
- // in the set). The initial value for any key in std::map is 0 (false), |
- // which in this case means a new file is not in the set initially, |
- // exactly the semantics we want. |
- std::map<base::FilePath, bool> crash_dumps_; |
-}; |
- |
-TEST_F(PageLoadTest, Reliability) { |
- std::ofstream log_file; |
- |
- if (!g_log_file_path.empty()) { |
- log_file.open(g_log_file_path.value().c_str()); |
- } |
- |
- for (int k = 0; k < g_iterations; ++k) { |
- if (g_url_file_path.empty()) { |
- NavigateThroughPageID(log_file); |
- } else { |
- NavigateThroughURLList(log_file); |
- } |
- } |
- |
- if (!g_end_url.empty()) { |
- NavigateToURLLogResult( |
- g_end_url, log_file, NULL, g_continuous_load, false); |
- } |
- |
- log_file.close(); |
-} |
- |
-} // namespace |
- |