summaryrefslogtreecommitdiffstats
path: root/chrome/test/reliability
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/test/reliability
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/reliability')
-rw-r--r--chrome/test/reliability/SConscript125
-rw-r--r--chrome/test/reliability/page_load_test.cc600
-rw-r--r--chrome/test/reliability/page_load_test.h41
-rw-r--r--chrome/test/reliability/reliability_test_suite.h50
-rw-r--r--chrome/test/reliability/reliability_tests.vcproj218
-rw-r--r--chrome/test/reliability/run_all_unittests.cc34
6 files changed, 1068 insertions, 0 deletions
diff --git a/chrome/test/reliability/SConscript b/chrome/test/reliability/SConscript
new file mode 100644
index 0000000..e0b0a32
--- /dev/null
+++ b/chrome/test/reliability/SConscript
@@ -0,0 +1,125 @@
+# Copyright 2008, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Import('env_test')
+
+env_test = env_test.Clone()
+
+
+env_test.Prepend(
+ CPPDEFINES = [
+ 'RELIABILITY_TEST', # seems to be unused
+ 'UI_TEST',
+ 'UNIT_TEST',
+ 'CERT_CHAIN_PARA_HAS_EXTRA_FIELDS',
+ 'WIN32_LEAN_AND_MEAN',
+ ],
+ CPPPATH = [
+ '$GTEST_DIR/include',
+ '$GTEST_DIR',
+ '$SKIA_DIR/include',
+ '$SKIA_DIR/include/corecg',
+ '$SKIA_DIR/platform',
+ '#/..',
+ ],
+ LINKFLAGS = [
+ '/INCREMENTAL',
+ '/DEBUG',
+
+ '/DELAYLOAD:"dwmapi.dll"',
+ '/DELAYLOAD:"uxtheme.dll"',
+
+ '/MACHINE:X86',
+ '/FIXED:No',
+
+ '/safeseh',
+ '/dynamicbase',
+ '/ignore:4199',
+ '/nxcompat',
+ ],
+ LIBS = [
+ 'winmm.lib',
+ 'psapi.lib',
+ 'rpcrt4.lib',
+ 'oleacc.lib',
+ 'comsupp.lib',
+
+ 'wininet.lib',
+ 'version.lib',
+ 'msimg32.lib',
+ 'ws2_32.lib',
+ 'usp10.lib',
+ 'psapi.lib',
+ 'kernel32.lib',
+ 'user32.lib',
+ 'gdi32.lib',
+ 'winspool.lib',
+ 'comdlg32.lib',
+ 'advapi32.lib',
+ 'shell32.lib',
+ 'ole32.lib',
+ 'oleaut32.lib',
+ 'uuid.lib',
+ 'odbc32.lib',
+ 'odbccp32.lib',
+
+ 'DelayImp.lib',
+ ],
+)
+
+input_files = [
+ '$CHROME_DIR/test/perf/mem_usage$OBJSUFFIX',
+ '$CHROME_DIR/test/ui/ui_test$OBJSUFFIX',
+ '$CHROME_DIR/test/ui/ui_test_suite$OBJSUFFIX',
+ '$CHROME_DIR/test/test_file_util$OBJSUFFIX',
+ 'page_load_test.cc',
+ 'run_all_unittests.cc',
+]
+
+libs = [
+ '$GOOGLEURL_DIR/googleurl.lib',
+ '$SKIA_DIR/skia.lib',
+ '$LIBPNG_DIR/libpng.lib',
+ '$TESTING_DIR/gtest.lib',
+ '$BASE_DIR/gfx/base_gfx.lib',
+ '$ICU38_DIR/icuuc.lib',
+ '$CHROME_DIR/common/common.lib',
+ '$ZLIB_DIR/zlib.lib',
+ '$CHROME_DIR/browser/browser.lib',
+ '$BASE_DIR/base.lib',
+ '$CHROME_DIR/test/automation/automation.lib',
+]
+
+
+exe = env_test.Program(['reliability_tests',
+ 'reliability_tests.pdb'],
+ input_files + libs)
+i = env_test.Install('$TARGET_ROOT', exe)
+
+env_test.Alias('chrome', i)
diff --git a/chrome/test/reliability/page_load_test.cc b/chrome/test/reliability/page_load_test.cc
new file mode 100644
index 0000000..ee59ad6
--- /dev/null
+++ b/chrome/test/reliability/page_load_test.cc
@@ -0,0 +1,600 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// 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 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.
+// --timeout=millisecond: time out as specified in millisecond during each
+// page load.
+// --nopagedown: won't simulate page down key presses after page load.
+
+#include <fstream>
+#include <iostream>
+
+#include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/string_util.h"
+#include "chrome/browser/url_fixer_upper.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/pref_service.h"
+#include "chrome/test/automation/automation_messages.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 "chrome/test/perf/mem_usage.h"
+#include "chrome/test/reliability/page_load_test.h"
+#include "net/base/net_util.h"
+
+namespace {
+
+// See comments at the beginning of the file for the definition of switches.
+const wchar_t kSiteSwitch[] = L"site";
+const wchar_t kStartPageSwitch[] = L"startpage";
+const wchar_t kEndPageSwitch[] = L"endpage";
+const wchar_t kListSwitch[] = L"list";
+const wchar_t kStartIndexSwitch[] = L"startline";
+const wchar_t kEndIndexSwitch[] = L"endline";
+const wchar_t kIterationSwitch[] = L"iterations";
+const wchar_t kContinuousLoadSwitch[] = L"continuousload";
+const wchar_t kMemoryUsageSwitch[] = L"memoryusage";
+const wchar_t kEndURLSwitch[] = L"endurl";
+const wchar_t kLogFileSwitch[] = L"logfile";
+const wchar_t kTimeoutSwitch[] = L"timeout";
+const wchar_t kNoPageDownSwitch[] = L"nopagedown";
+
+std::wstring server_url = L"http://urllist.com";
+const wchar_t test_url_1[] = L"http://www.google.com";
+const wchar_t test_url_2[] = L"about:crash";
+const wchar_t test_url_3[] = L"http://www.youtube.com";
+bool append_page_id = false;
+int32 start_page;
+int32 end_page;
+std::wstring url_file_path;
+int32 start_index = 1;
+int32 end_index = kint32max;
+int32 iterations = 1;
+bool memory_usage = false;
+bool continuous_load = false;
+bool browser_existing = false;
+bool page_down = true;
+std::wstring end_url;
+std::wstring log_file_path;
+uint32 timeout_ms = INFINITE;
+
+int kWaitForActionMsec = 4000;
+
+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;
+ }
+
+ void NavigateToURLLogResult(const GURL& url, std::ofstream& log_file,
+ NavigationMetrics* metrics_output) {
+ NavigationMetrics metrics = {NAVIGATION_ERROR};
+
+ if (!continuous_load && !browser_existing) {
+ LaunchBrowserAndServer();
+ browser_existing = true;
+ }
+
+ bool is_timeout = false;
+ 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_ptr<TabProxy> tab_proxy(GetActiveTab());
+ if (tab_proxy.get()) {
+ result = tab_proxy->NavigateToURLWithTimeout(url, timeout_ms,
+ &is_timeout);
+ }
+
+ if (!is_timeout && result == AUTOMATION_MSG_NAVIGATION_SUCCESS) {
+ if (page_down) {
+ // Page down twice.
+ scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ if (browser.get()) {
+ scoped_ptr<WindowProxy> window(
+ automation()->GetWindowForBrowser(browser.get()));
+ if (window.get()) {
+ bool activation_timeout;
+ browser->BringToFrontWithTimeout(kWaitForActionMsec,
+ &activation_timeout);
+ if (!activation_timeout) {
+ window->SimulateOSKeyPress(VK_NEXT, 0);
+ Sleep(kWaitForActionMsec);
+ window->SimulateOSKeyPress(VK_NEXT, 0);
+ Sleep(kWaitForActionMsec);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!continuous_load) {
+ CloseBrowserAndServer();
+ browser_existing = false;
+ }
+
+ // 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> crash_dump=<path>
+ if (is_timeout) {
+ metrics.result = NAVIGATION_TIME_OUT;
+ // After timeout, the test automation is in the transition state since
+ // there might be pending IPC messages and the browser (automation
+ // provider) is still working on the request. Here we just skip the url
+ // and send the next request. The pending IPC messages will be properly
+ // discarded by automation message filter. The browser will accept the
+ // new request and visit the next URL.
+ // We will revisit the issue if we encounter the situation where browser
+ // needs to be restarted after timeout.
+ } else {
+ 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;
+ }
+ }
+
+ if (log_file.is_open()) {
+ log_file << url.spec();
+ 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;
+ }
+ }
+
+ // Get stability metrics recorded by Chrome itself.
+ GetStabilityMetrics(&metrics);
+
+ if (log_file.is_open()) {
+ 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;
+ }
+
+ // Get crash dumps.
+ LogOrDeleteNewCrashDumps(log_file, &metrics);
+
+ if (log_file.is_open()) {
+ log_file << std::endl;
+ }
+
+ if (metrics_output) {
+ *metrics_output = metrics;
+ }
+ }
+
+ void NavigateThroughPageID(std::ofstream& log_file) {
+ if (append_page_id) {
+ // For usage 2
+ for (int i = start_page; i <= end_page; ++i) {
+ std::wstring test_page_url(
+ StringPrintf(L"%s/page?id=%d", server_url.c_str(), i));
+ NavigateToURLLogResult(GURL(test_page_url), log_file, NULL);
+ }
+ } else {
+ // Don't run if single process mode.
+ if (in_process_renderer())
+ return;
+ // For usage 1
+ NavigationMetrics metrics;
+ if (timeout_ms == INFINITE)
+ timeout_ms = 30000;
+
+ NavigateToURLLogResult(GURL(test_url_1), log_file, &metrics);
+ // Verify everything is fine
+ EXPECT_EQ(NAVIGATION_SUCCESS, metrics.result);
+ EXPECT_EQ(0, metrics.crash_dump_count);
+ EXPECT_EQ(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"
+ uint32 crash_timeout_ms = timeout_ms / 2;
+ std::swap(timeout_ms, crash_timeout_ms);
+ NavigateToURLLogResult(GURL(test_url_2), log_file, &metrics);
+ std::swap(timeout_ms, crash_timeout_ms);
+ // Page load crashed and test automation timed out.
+ EXPECT_EQ(NAVIGATION_TIME_OUT, metrics.result);
+ // Found a crash dump
+ EXPECT_EQ(1, metrics.crash_dump_count);
+ // Browser did not crash, and exited cleanly.
+ EXPECT_EQ(true, metrics.browser_clean_exit);
+ EXPECT_EQ(1, metrics.browser_launch_count);
+ // Only starting page was loaded.
+ EXPECT_EQ(1, metrics.page_load_count);
+ EXPECT_EQ(0, metrics.browser_crash_count);
+ // Renderer crashed.
+ EXPECT_EQ(1, metrics.renderer_crash_count);
+ EXPECT_EQ(0, metrics.plugin_crash_count);
+
+ uint32 youtube_timeout_ms = timeout_ms * 2;
+ std::swap(timeout_ms, youtube_timeout_ms);
+ NavigateToURLLogResult(GURL(test_url_3), log_file, &metrics);
+ std::swap(timeout_ms, youtube_timeout_ms);
+ // 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_EQ(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.
+ HANDLE browser_process;
+ LaunchBrowserAndServer();
+ {
+ // TabProxy should be released before Browser is closed.
+ scoped_ptr<TabProxy> tab_proxy(GetActiveTab());
+ if (tab_proxy.get()) {
+ tab_proxy->NavigateToURL(GURL(test_url_1));
+ }
+ }
+ // Kill browser process.
+ browser_process = process();
+ TerminateProcess(browser_process, 0);
+
+ GetStabilityMetrics(&metrics);
+ // This is not a clean shutdown.
+ EXPECT_EQ(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(url_file_path.c_str());
+ ASSERT_TRUE(file.is_open());
+
+ for (int line_index = 1;
+ line_index <= end_index && !file.eof();
+ ++line_index) {
+ std::string url_str;
+ std::getline(file, url_str);
+
+ if (file.fail())
+ break;
+
+ if (start_index <= line_index) {
+ NavigateToURLLogResult(GURL(url_str), log_file, NULL);
+ }
+ }
+
+ file.close();
+ }
+
+ protected:
+ // Call the base class's SetUp method and initialize our own class members.
+ virtual void SetUp() {
+ UITest::SetUp();
+ browser_existing = true;
+
+ // Initialize crash_dumps_dir_path_.
+ PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dumps_dir_path_);
+ // Initialize crash_dumps_.
+ WIN32_FIND_DATAW find_data;
+ HANDLE find_handle;
+ std::wstring dir_spec(crash_dumps_dir_path_);
+ dir_spec.append(L"\\*"); // list all files in the directory
+ find_handle = FindFirstFileW(dir_spec.c_str(), &find_data);
+ if (find_handle != INVALID_HANDLE_VALUE) {
+ if (wcsstr(find_data.cFileName, L".dmp"))
+ crash_dumps_[std::wstring(find_data.cFileName)] = true;
+ while (FindNextFile(find_handle, &find_data)) {
+ if (wcsstr(find_data.cFileName, L".dmp"))
+ crash_dumps_[std::wstring(find_data.cFileName)] = true;
+ }
+ FindClose(find_handle);
+ }
+ }
+
+ // If a log_file is provided, log the crash dump with the given path;
+ // otherwise, delete the crash dump file.
+ void LogOrDeleteCrashDump(std::ofstream& log_file,
+ std::wstring crash_dump_file_name) {
+
+ std::wstring crash_dump_file_path(crash_dumps_dir_path_);
+ crash_dump_file_path.append(L"\\");
+ crash_dump_file_path.append(crash_dump_file_name);
+ std::wstring crash_text_file_path(crash_dump_file_path);
+ crash_text_file_path.replace(crash_text_file_path.length() - 3,
+ 3, L"txt");
+
+ if (log_file.is_open()) {
+ crash_dumps_[crash_dump_file_name] = true;
+ log_file << " crash_dump=" << crash_dump_file_path;
+ } else {
+ ASSERT_TRUE(DeleteFileW(crash_dump_file_path.c_str()));
+ ASSERT_TRUE(DeleteFileW(crash_text_file_path.c_str()));
+ }
+ }
+
+ // Check whether there are new .dmp files. Additionally, write
+ // " crash_dump=<full path name of the .dmp file>"
+ // to log_file.
+ void LogOrDeleteNewCrashDumps(std::ofstream& log_file,
+ NavigationMetrics* metrics) {
+ WIN32_FIND_DATAW find_data;
+ HANDLE find_handle;
+ int num_dumps = 0;
+
+ std::wstring dir_spec(crash_dumps_dir_path_);
+ dir_spec.append(L"\\*"); // list all files in the directory
+ find_handle = FindFirstFileW(dir_spec.c_str(), &find_data);
+ if (find_handle != INVALID_HANDLE_VALUE) {
+ if (wcsstr(find_data.cFileName, L".dmp") &&
+ !crash_dumps_[std::wstring(find_data.cFileName)]) {
+ LogOrDeleteCrashDump(log_file, find_data.cFileName);
+ num_dumps++;
+ }
+ while (FindNextFile(find_handle, &find_data)) {
+ if (wcsstr(find_data.cFileName, L".dmp") &&
+ !crash_dumps_[std::wstring(find_data.cFileName)]) {
+ LogOrDeleteCrashDump(log_file, find_data.cFileName);
+ num_dumps++;
+ }
+ }
+ FindClose(find_handle);
+ }
+
+ 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() {
+ std::wstring local_state_path = user_data_dir();
+ file_util::AppendToPath(&local_state_path, chrome::kLocalStateFilename);
+
+ PrefService* local_state(new PrefService(local_state_path));
+ return local_state;
+ }
+
+ void GetStabilityMetrics(NavigationMetrics* metrics) {
+ if (!metrics)
+ return;
+ scoped_ptr<PrefService> local_state(GetLocalState());
+ if (!local_state.get())
+ return;
+ local_state->RegisterBooleanPref(prefs::kStabilityExitedCleanly, false);
+ local_state->RegisterIntegerPref(prefs::kStabilityLaunchCount, -1);
+ local_state->RegisterIntegerPref(prefs::kStabilityPageLoadCount, -1);
+ local_state->RegisterIntegerPref(prefs::kStabilityCrashCount, 0);
+ local_state->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
+
+ 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++;
+ }
+
+ // The pathname of Chrome's crash dumps directory.
+ std::wstring 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<std::wstring, bool> crash_dumps_;
+};
+
+} // namespace
+
+TEST_F(PageLoadTest, Reliability) {
+ std::ofstream log_file;
+
+ if (!log_file_path.empty()) {
+ log_file.open(log_file_path.c_str());
+ }
+
+ for (int k = 0; k < iterations; ++k) {
+ if (url_file_path.empty()) {
+ NavigateThroughPageID(log_file);
+ } else {
+ NavigateThroughURLList(log_file);
+ }
+
+ if (memory_usage)
+ PrintChromeMemoryUsageInfo();
+ }
+
+ if (!end_url.empty()) {
+ NavigateToURLLogResult(GURL(end_url), log_file, NULL);
+ }
+
+ log_file.close();
+}
+
+void SetPageRange(const CommandLine& parsed_command_line) {
+ if (parsed_command_line.HasSwitch(kStartPageSwitch)) {
+ ASSERT_TRUE(parsed_command_line.HasSwitch(kEndPageSwitch));
+ start_page =
+ _wtoi(parsed_command_line.GetSwitchValue(kStartPageSwitch).c_str());
+ end_page =
+ _wtoi(parsed_command_line.GetSwitchValue(kEndPageSwitch).c_str());
+ ASSERT_TRUE(start_page > 0 && end_page > 0);
+ ASSERT_TRUE(start_page < end_page);
+ append_page_id = true;
+ } else {
+ ASSERT_FALSE(parsed_command_line.HasSwitch(kEndPageSwitch));
+ }
+
+ if (parsed_command_line.HasSwitch(kSiteSwitch))
+ server_url.assign(parsed_command_line.GetSwitchValue(kSiteSwitch));
+
+ if (parsed_command_line.HasSwitch(kStartIndexSwitch)) {
+ start_index =
+ _wtoi(parsed_command_line.GetSwitchValue(kStartIndexSwitch).c_str());
+ ASSERT_TRUE(start_index > 0);
+ }
+
+ if (parsed_command_line.HasSwitch(kEndIndexSwitch)) {
+ end_index =
+ _wtoi(parsed_command_line.GetSwitchValue(kEndIndexSwitch).c_str());
+ ASSERT_TRUE(end_index > 0);
+ }
+
+ ASSERT_TRUE(end_index >= start_index);
+
+ if (parsed_command_line.HasSwitch(kListSwitch))
+ url_file_path.assign(parsed_command_line.GetSwitchValue(kListSwitch));
+
+ if (parsed_command_line.HasSwitch(kIterationSwitch)) {
+ iterations =
+ _wtoi(parsed_command_line.GetSwitchValue(kIterationSwitch).c_str());
+ ASSERT_TRUE(iterations > 0);
+ }
+
+ if (parsed_command_line.HasSwitch(kMemoryUsageSwitch))
+ memory_usage = true;
+
+ if (parsed_command_line.HasSwitch(kContinuousLoadSwitch))
+ continuous_load = true;
+
+ if (parsed_command_line.HasSwitch(kEndURLSwitch))
+ end_url.assign(parsed_command_line.GetSwitchValue(kEndURLSwitch));
+
+ if (parsed_command_line.HasSwitch(kLogFileSwitch))
+ log_file_path.assign(parsed_command_line.GetSwitchValue(kLogFileSwitch));
+
+ if (parsed_command_line.HasSwitch(kTimeoutSwitch)) {
+ timeout_ms =
+ _wtoi(parsed_command_line.GetSwitchValue(kTimeoutSwitch).c_str());
+ ASSERT_TRUE(timeout_ms > 0);
+ }
+
+ if (parsed_command_line.HasSwitch(kNoPageDownSwitch))
+ page_down = false;
+}
diff --git a/chrome/test/reliability/page_load_test.h b/chrome/test/reliability/page_load_test.h
new file mode 100644
index 0000000..8f3c2da
--- /dev/null
+++ b/chrome/test/reliability/page_load_test.h
@@ -0,0 +1,41 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// This file declares helper functions necessary to run reliablity test under
+// UI test framework.
+
+#ifndef CHROME_TEST_RELIABILITY_PAGE_LOAD_TEST_H__
+#define CHROME_TEST_RELIABILITY_PAGE_LOAD_TEST_H__
+
+#include "base/command_line.h"
+
+// Parse the command line options and set the page range accordingly.
+void SetPageRange(const CommandLine&);
+
+#endif // CHROME_TEST_RELIABILITY_PAGE_LOAD_TEST_H__
diff --git a/chrome/test/reliability/reliability_test_suite.h b/chrome/test/reliability/reliability_test_suite.h
new file mode 100644
index 0000000..1e971e6
--- /dev/null
+++ b/chrome/test/reliability/reliability_test_suite.h
@@ -0,0 +1,50 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CHROME_TEST_RELIABILITY_RELIABILITY_TEST_SUITE_H_
+#define CHROME_TEST_RELIABILITY_RELIABILITY_TEST_SUITE_H_
+
+#include "chrome/test/reliability/page_load_test.h"
+#include "chrome/test/ui/ui_test_suite.h"
+
+class ReliabilityTestSuite : public UITestSuite {
+public:
+ ReliabilityTestSuite(int argc, char** argv) : UITestSuite(argc, argv) {
+ }
+
+protected:
+
+ virtual void Initialize() {
+ UITestSuite::Initialize();
+
+ SetPageRange(parsed_command_line_);
+ }
+};
+
+#endif // CHROME_TEST_RELIABILITY_RELIABILITY_TEST_SUITE_H_
diff --git a/chrome/test/reliability/reliability_tests.vcproj b/chrome/test/reliability/reliability_tests.vcproj
new file mode 100644
index 0000000..04f0ef9
--- /dev/null
+++ b/chrome/test/reliability/reliability_tests.vcproj
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="reliability_tests"
+ ProjectGUID="{8A3E1774-1DE9-445C-982D-3EE37C8A752A}"
+ RootNamespace="reliability_tests"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\build\debug.vsprops;..\..\tools\build\win\precompiled_wtl.vsprops;..\..\tools\build\win\unit_test.vsprops;..\..\tools\build\win\ui_test.vsprops;..\..\tools\build\win\test_memory_usage.vsprops;..\..\tools\build\win\reliability_test.vsprops;$(SolutionDir)..\skia\using_skia.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\build\release.vsprops;..\..\tools\build\win\unit_test.vsprops;..\..\tools\build\win\ui_test.vsprops;..\..\tools\build\win\test_memory_usage.vsprops;..\..\tools\build\win\reliability_test.vsprops;$(SolutionDir)..\skia\using_skia.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Common"
+ >
+ <File
+ RelativePath="..\..\tools\build\win\precompiled_wtl.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\tools\build\win\precompiled_wtl.h"
+ >
+ </File>
+ <File
+ RelativePath=".\reliability_test_suite.h"
+ >
+ </File>
+ <File
+ RelativePath=".\run_all_unittests.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\test_file_util.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\testing_browser_process.h"
+ >
+ </File>
+ <File
+ RelativePath="..\ui\ui_test.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\ui\ui_test.h"
+ >
+ </File>
+ <File
+ RelativePath="..\ui\ui_test_suite.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="MemoryUsage"
+ >
+ <File
+ RelativePath="..\perf\mem_usage.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\perf\mem_usage.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="TestPageLoader"
+ >
+ <File
+ RelativePath=".\page_load_test.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\page_load_test.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/chrome/test/reliability/run_all_unittests.cc b/chrome/test/reliability/run_all_unittests.cc
new file mode 100644
index 0000000..a5d3da3
--- /dev/null
+++ b/chrome/test/reliability/run_all_unittests.cc
@@ -0,0 +1,34 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/test/reliability/reliability_test_suite.h"
+
+int main(int argc, char **argv) {
+ return ReliabilityTestSuite(argc, argv).Run();
+}