// 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

