summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/chrome_main_delegate.cc63
-rw-r--r--chrome/browser/diagnostics/diagnostics_controller.cc49
-rw-r--r--chrome/browser/diagnostics/diagnostics_controller.h51
-rw-r--r--chrome/browser/diagnostics/diagnostics_main.cc367
-rw-r--r--chrome/browser/diagnostics/diagnostics_main.h15
-rw-r--r--chrome/browser/diagnostics/diagnostics_model.cc32
-rw-r--r--chrome/browser/diagnostics/diagnostics_model.h50
-rw-r--r--chrome/browser/diagnostics/diagnostics_model_unittest.cc34
-rw-r--r--chrome/browser/diagnostics/diagnostics_test.cc66
-rw-r--r--chrome/browser/diagnostics/diagnostics_test.h60
-rw-r--r--chrome/browser/diagnostics/diagnostics_writer.cc281
-rw-r--r--chrome/browser/diagnostics/diagnostics_writer.h66
-rw-r--r--chrome/browser/diagnostics/recon_diagnostics.cc256
-rw-r--r--chrome/browser/diagnostics/recon_diagnostics.h83
-rw-r--r--chrome/browser/diagnostics/sqlite_diagnostics.cc220
-rw-r--r--chrome/browser/diagnostics/sqlite_diagnostics.h49
-rw-r--r--chrome/browser/history/text_database.cc1
-rw-r--r--chrome/browser/history/thumbnail_database.cc1
-rw-r--r--chrome/browser/history/top_sites_database.cc1
-rw-r--r--chrome/browser/net/sqlite_server_bound_cert_store.cc1
-rw-r--r--chrome/chrome_browser.gypi7
-rw-r--r--chrome/chrome_tests_unit.gypi1
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chromeos/chromeos_constants.cc2
-rw-r--r--chromeos/chromeos_constants.h2
26 files changed, 1060 insertions, 702 deletions
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 2d0c709..aafdd6d 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -15,7 +15,6 @@
#include "build/build_config.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/defaults.h"
-#include "chrome/browser/diagnostics/diagnostics_main.h"
#include "chrome/browser/policy/policy_path_parser.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_content_client.h"
@@ -78,6 +77,10 @@
#if defined(OS_ANDROID)
#include "chrome/common/descriptors_android.h"
+#else
+// Diagnostics is only available on non-android platforms.
+#include "chrome/browser/diagnostics/diagnostics_controller.h"
+#include "chrome/browser/diagnostics/diagnostics_writer.h"
#endif
#if defined(USE_X11)
@@ -365,16 +368,6 @@ bool ChromeMainDelegate::BasicStartupComplete(int* exit_code) {
#endif
#endif // OS_POSIX
- // No support for ANDROID yet as DiagnosticsMain needs wchar support.
-#if !defined(OS_ANDROID)
- // If we are in diagnostics mode this is the end of the line. After the
- // diagnostics are run the process will invariably exit.
- if (command_line.HasSwitch(switches::kDiagnostics)) {
- *exit_code = DiagnosticsMain(command_line);
- return true;
- }
-#endif
-
#if defined(OS_WIN)
// Must do this before any other usage of command line!
if (HasDeprecatedArguments(command_line.GetCommandLineString())) {
@@ -383,6 +376,46 @@ bool ChromeMainDelegate::BasicStartupComplete(int* exit_code) {
}
#endif
+ chrome::RegisterPathProvider();
+#if defined(OS_CHROMEOS)
+ chromeos::RegisterPathProvider();
+#endif
+#if !defined(DISABLE_NACL) && defined(OS_LINUX)
+ nacl::RegisterPathProvider();
+#endif
+
+// No support for ANDROID yet as DiagnosticsController needs wchar support.
+// TODO(gspencer): That's not true anymore, or at least there are no w-string
+// references anymore. Not sure if that means this can be enabled on Android or
+// not though: it still uses string16. As there is no easily accessible command
+// line on Android, I'm not sure this is a big deal, at least for purposes of
+// troubleshooting with a customer.
+#if !defined(OS_ANDROID)
+ // If we are in diagnostics mode this is the end of the line: after the
+ // diagnostics are run the process will invariably exit.
+ if (command_line.HasSwitch(switches::kDiagnostics)) {
+ diagnostics::DiagnosticsWriter::FormatType format =
+ diagnostics::DiagnosticsWriter::HUMAN;
+ if (command_line.HasSwitch(switches::kDiagnosticsFormat)) {
+ std::string format_str =
+ command_line.GetSwitchValueASCII(switches::kDiagnosticsFormat);
+ if (format_str == "machine") {
+ format = diagnostics::DiagnosticsWriter::MACHINE;
+ } else if (format_str == "log") {
+ format = diagnostics::DiagnosticsWriter::LOG;
+ } else {
+ DCHECK_EQ("human", format_str);
+ }
+ }
+
+ diagnostics::DiagnosticsWriter writer(format);
+ *exit_code = diagnostics::DiagnosticsController::GetInstance()->Run(
+ command_line, &writer);
+ diagnostics::DiagnosticsController::GetInstance()->ClearResults();
+ return true;
+ }
+#endif
+
content::SetContentClient(&chrome_content_client_);
return false;
@@ -481,14 +514,6 @@ void ChromeMainDelegate::PreSandboxStartup() {
std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
- chrome::RegisterPathProvider();
-#if defined(OS_CHROMEOS)
- chromeos::RegisterPathProvider();
-#endif
-#if !defined(DISABLE_NACL) && defined(OS_LINUX)
- nacl::RegisterPathProvider();
-#endif
-
#if defined(OS_MACOSX) || defined(USE_LINUX_BREAKPAD)
breakpad::SetBreakpadClient(g_chrome_breakpad_client.Pointer());
#endif
diff --git a/chrome/browser/diagnostics/diagnostics_controller.cc b/chrome/browser/diagnostics/diagnostics_controller.cc
new file mode 100644
index 0000000..a578beb
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_controller.cc
@@ -0,0 +1,49 @@
+// Copyright 2013 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.
+
+#include "chrome/browser/diagnostics/diagnostics_controller.h"
+
+#include <string>
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
+#include "chrome/browser/diagnostics/diagnostics_model.h"
+#include "chrome/browser/diagnostics/diagnostics_writer.h"
+#include "chrome/common/chrome_switches.h"
+
+namespace diagnostics {
+
+DiagnosticsController* DiagnosticsController::GetInstance() {
+ return Singleton<DiagnosticsController>::get();
+}
+
+DiagnosticsController::DiagnosticsController() : writer_(NULL) {}
+
+DiagnosticsController::~DiagnosticsController() {}
+
+const DiagnosticsModel& DiagnosticsController::GetResults() const {
+ return *model_;
+}
+
+bool DiagnosticsController::HasResults() {
+ return (model_.get() && model_->GetTestRunCount() > 0);
+}
+
+void DiagnosticsController::ClearResults() { model_.reset(); }
+
+// This entry point is called from ChromeMain() when very few things
+// have been initialized, so be careful what you use.
+int DiagnosticsController::Run(const CommandLine& command_line,
+ DiagnosticsWriter* writer) {
+ writer_ = writer;
+
+ model_.reset(MakeDiagnosticsModel(command_line));
+ model_->RunAll(writer_);
+
+ return 0;
+}
+
+} // namespace diagnostics
diff --git a/chrome/browser/diagnostics/diagnostics_controller.h b/chrome/browser/diagnostics/diagnostics_controller.h
new file mode 100644
index 0000000..706a10f
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_controller.h
@@ -0,0 +1,51 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_CONTROLLER_H_
+#define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_CONTROLLER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
+
+class CommandLine;
+
+namespace diagnostics {
+
+class DiagnosticsWriter;
+class DiagnosticsModel;
+
+class DiagnosticsController {
+ public:
+ static DiagnosticsController* GetInstance();
+
+ // Entry point for the diagnostics mode. Returns zero if able to run
+ // diagnostics successfully, regardless of the results of the diagnostics.
+ int Run(const CommandLine& command_line, DiagnosticsWriter* writer);
+
+ // Returns a model with the results that have accumulated. They can then be
+ // queried for their attributes for human consumption later.
+ const DiagnosticsModel& GetResults() const;
+
+ // Returns true if there are any results available.
+ bool HasResults();
+
+ // Clears any results that have accumulated. After calling this, do not call
+ // GetResults until after Run is called again.
+ void ClearResults();
+
+ private:
+ friend struct DefaultSingletonTraits<DiagnosticsController>;
+
+ DiagnosticsController();
+ ~DiagnosticsController();
+
+ scoped_ptr<DiagnosticsModel> model_;
+ DiagnosticsWriter* writer_;
+
+ DISALLOW_COPY_AND_ASSIGN(DiagnosticsController);
+};
+
+} // namespace diagnostics
+
+#endif // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_CONTROLLER_H_
diff --git a/chrome/browser/diagnostics/diagnostics_main.cc b/chrome/browser/diagnostics/diagnostics_main.cc
deleted file mode 100644
index 7d02a23..0000000
--- a/chrome/browser/diagnostics/diagnostics_main.cc
+++ /dev/null
@@ -1,367 +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.
-
-#include "chrome/browser/diagnostics/diagnostics_main.h"
-
-#include "build/build_config.h"
-
-#if defined(OS_POSIX)
-#include <stdio.h>
-#include <unistd.h>
-#endif
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/command_line.h"
-#include "base/i18n/icu_util.h"
-#include "base/logging.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
-#include "chrome/browser/diagnostics/diagnostics_model.h"
-#include "chrome/common/chrome_paths.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/base/ui_base_paths.h"
-
-namespace {
-// This is a minimalistic interface to wrap the platform console. This will be
-// eventually replaced by a view that can be subclassed for each platform and
-// that the approved look and feel.
-class SimpleConsole {
- public:
- enum Color {
- DEFAULT,
- RED,
- GREEN,
- };
-
- virtual ~SimpleConsole() { }
-
- // Init must be called before using any other method. If it returns
- // false there would be no console output.
- virtual bool Init() = 0;
-
- // Writes a string to the console with the current color.
- virtual bool Write(const std::wstring& text) = 0;
-
- // Called when the program is about to exit.
- virtual void OnQuit() = 0;
-
- // Sets the foreground and background color.
- virtual bool SetColor(Color color) = 0;
-
- // Create an appropriate SimpleConsole instance. May return NULL if there is
- // no implementation for the current platform.
- static SimpleConsole* Create();
-};
-
-#if defined(OS_WIN)
-// Wrapper for the windows console operating in high-level IO mode.
-class WinConsole : public SimpleConsole {
- public:
- // The ctor allocates a console always. This avoids having to ask
- // the user to start chrome from a command prompt.
- WinConsole()
- : std_out_(INVALID_HANDLE_VALUE),
- std_in_(INVALID_HANDLE_VALUE) {
- }
-
- virtual ~WinConsole() {
- ::FreeConsole();
- }
-
- virtual bool Init() {
- ::AllocConsole();
- return SetIOHandles();
- }
-
- virtual bool Write(const std::wstring& txt) {
- DWORD sz = txt.size();
- return (TRUE == ::WriteConsoleW(std_out_, txt.c_str(), sz, &sz, NULL));
- }
-
- // Reads a string from the console. Internally it is limited to 256
- // characters.
- virtual void OnQuit() {
- // Block here so the user can see the results.
- SetColor(SimpleConsole::DEFAULT);
- Write(L"Press [enter] to continue\n");
- wchar_t buf[256];
- DWORD read = arraysize(buf);
- ::ReadConsoleW(std_in_, buf, read, &read, NULL);
- }
-
- // Sets the foreground and background color.
- virtual bool SetColor(Color color) {
- uint16 color_combo =
- FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY;
- switch (color) {
- case RED:
- color_combo = FOREGROUND_RED|FOREGROUND_INTENSITY;
- break;
- case GREEN:
- color_combo = FOREGROUND_GREEN|FOREGROUND_INTENSITY;
- break;
- case DEFAULT:
- break;
- default:
- NOTREACHED();
- }
- return (TRUE == ::SetConsoleTextAttribute(std_out_, color_combo));
- }
-
- private:
- bool SetIOHandles() {
- std_out_ = ::GetStdHandle(STD_OUTPUT_HANDLE);
- std_in_ = ::GetStdHandle(STD_INPUT_HANDLE);
- return ((std_out_ != INVALID_HANDLE_VALUE) &&
- (std_in_ != INVALID_HANDLE_VALUE));
- }
-
- // The input and output handles to the screen. They seem to be
- // implemented as pipes but they have non-documented protocol.
- HANDLE std_out_;
- HANDLE std_in_;
-
- DISALLOW_COPY_AND_ASSIGN(WinConsole);
-};
-
-SimpleConsole* SimpleConsole::Create() {
- return new WinConsole();
-}
-
-#elif defined(OS_POSIX)
-
-class PosixConsole : public SimpleConsole {
- public:
- PosixConsole() : use_color_(false) { }
-
- virtual bool Init() OVERRIDE {
- // Technically, we should also check the terminal capabilities before using
- // color, but in practice this is unlikely to be an issue.
- use_color_ = isatty(STDOUT_FILENO);
- return true;
- }
-
- virtual bool Write(const std::wstring& text) OVERRIDE {
- printf("%s", base::SysWideToNativeMB(text).c_str());
- return true;
- }
-
- virtual void OnQuit() OVERRIDE {
- // The "press enter to continue" prompt isn't very unixy, so only do that on
- // Windows.
- }
-
- virtual bool SetColor(Color color) OVERRIDE {
- if (!use_color_)
- return false;
-
- const char* code = "\033[m";
- switch (color) {
- case RED:
- code = "\033[1;31m";
- break;
- case GREEN:
- code = "\033[1;32m";
- break;
- case DEFAULT:
- break;
- default:
- NOTREACHED();
- }
- printf("%s", code);
- return true;
- }
-
- private:
- bool use_color_;
-
- DISALLOW_COPY_AND_ASSIGN(PosixConsole);
-};
-
-SimpleConsole* SimpleConsole::Create() {
- return new PosixConsole();
-}
-
-#else // !defined(OS_WIN) && !defined(OS_POSIX)
-
-SimpleConsole* SimpleConsole::Create() {
- return NULL;
-}
-#endif
-
-// This class wraps a SimpleConsole for the specific use case of
-// writing the results of the diagnostic tests.
-// TODO(cpu) figure out the localization strategy.
-class TestWriter {
- public:
- // The |console| must be valid and properly initialized. This
- // class does not own it.
- explicit TestWriter(SimpleConsole* console)
- : console_(console),
- failures_(0) {
- }
-
- // How many tests reported failure.
- int failures() { return failures_; }
-
- // Write an informational line of text in white over black.
- bool WriteInfoText(const std::wstring& txt) {
- console_->SetColor(SimpleConsole::DEFAULT);
- return console_->Write(txt);
- }
-
- bool WriteInfoText(const std::string& txt) {
- return WriteInfoText(UTF8ToWide(txt));
- }
-
- // Write a result block. It consist of two lines. The first line
- // has [PASS] or [FAIL] with |name| and the second line has
- // the text in |extra|.
- bool WriteResult(bool success, const std::wstring& name,
- const std::wstring& extra) {
- if (success) {
- console_->SetColor(SimpleConsole::GREEN);
- console_->Write(L"[PASS] ");
- } else {
- console_->SetColor(SimpleConsole::RED);
- console_->Write(L"[FAIL] ");
- failures_++;
- }
- WriteInfoText(name + L"\n");
- std::wstring second_line(L" ");
- second_line.append(extra);
- return WriteInfoText(second_line + L"\n\n");
- }
-
- private:
- SimpleConsole* console_;
-
- // Keeps track of how many tests reported failure.
- int failures_;
-
- DISALLOW_COPY_AND_ASSIGN(TestWriter);
-};
-
-std::string PrintableUSCurrentTime() {
- base::Time::Exploded exploded = {0};
- base::Time::Now().UTCExplode(&exploded);
- return base::StringPrintf("%d:%d:%d.%d:%d:%d",
- exploded.year,
- exploded.month,
- exploded.day_of_month,
- exploded.hour,
- exploded.minute,
- exploded.second);
-}
-
-// This class is a basic test controller. In this design the view (TestWriter)
-// and the model (DiagnosticsModel) do not talk to each other directly but they
-// are mediated by the controller. This has a name: 'passive view'.
-// More info at http://martinfowler.com/eaaDev/PassiveScreen.html
-class TestController : public DiagnosticsModel::Observer {
- public:
- explicit TestController(TestWriter* writer)
- : model_(NULL),
- writer_(writer) {
- }
-
- // Run all the diagnostics of |model| and invoke the view as the model
- // callbacks arrive.
- void Run(DiagnosticsModel* model) {
- writer_->WriteInfoText(L"Chrome Diagnostics Mode (");
- writer_->WriteInfoText(PrintableUSCurrentTime() + ")\n");
- if (!model) {
- writer_->WriteResult(false, L"Diagnostics start", L"model is null");
- return;
- }
- bool icu_result = icu_util::Initialize();
- if (!icu_result) {
- writer_->WriteResult(false, L"Diagnostics start", L"ICU failure");
- return;
- }
- ResourceBundle::InitSharedInstanceWithLocale(std::string(), NULL);
- int count = model->GetTestAvailableCount();
- writer_->WriteInfoText(base::StringPrintf(
- "%d available test(s)\n\n", count));
- model->RunAll(this);
- }
-
- // Next four are overridden from DiagnosticsModel::Observer.
- virtual void OnProgress(int id,
- int percent,
- DiagnosticsModel* model) OVERRIDE {
- }
-
- virtual void OnSkipped(int id, DiagnosticsModel* model) OVERRIDE {
- // TODO(cpu): display skipped tests.
- }
-
- virtual void OnFinished(int id, DiagnosticsModel* model) OVERRIDE {
- // As each test completes we output the results.
- ShowResult(&model->GetTest(id));
- }
-
- virtual void OnDoneAll(DiagnosticsModel* model) OVERRIDE {
- if (writer_->failures() > 0) {
- writer_->WriteInfoText(base::StringPrintf(
- "DONE. %d failure(s)\n\n", writer_->failures()));
- } else {
- writer_->WriteInfoText(L"DONE\n\n");
- }
- }
-
- private:
- void ShowResult(DiagnosticsModel::TestInfo* test_info) {
- bool success = (DiagnosticsModel::TEST_OK == test_info->GetResult());
- writer_->WriteResult(success, UTF16ToWide(test_info->GetTitle()),
- UTF16ToWide(test_info->GetAdditionalInfo()));
- }
-
- DiagnosticsModel* model_;
- TestWriter* writer_;
-
- DISALLOW_COPY_AND_ASSIGN(TestController);
-};
-} // namespace
-
-// This entry point is called from ChromeMain() when very few things
-// have been initialized. To wit:
-// -(win) Breakpad
-// -(macOS) base::EnableTerminationOnHeapCorruption()
-// -(macOS) base::EnableTerminationOnOutOfMemory()
-// -(all) RegisterInvalidParamHandler()
-// -(all) base::AtExitManager::AtExitManager()
-// -(macOS) base::ScopedNSAutoreleasePool
-// -(posix) base::GlobalDescriptors::GetInstance()->Set(kPrimaryIPCChannel)
-// -(linux) base::GlobalDescriptors::GetInstance()->Set(kCrashDumpSignal)
-// -(posix) setlocale(LC_ALL,..)
-// -(all) CommandLine::Init();
-
-int DiagnosticsMain(const CommandLine& command_line) {
- // If we can't initialize the console exit right away.
- SimpleConsole* console = SimpleConsole::Create();
- if (!console || !console->Init())
- return 1;
-
- // We need to have the path providers registered. They both
- // return void so there is no early error signal that we can use.
- ui::RegisterPathProvider();
- chrome::RegisterPathProvider();
-
- TestWriter writer(console);
- DiagnosticsModel* model = MakeDiagnosticsModel(command_line);
- TestController controller(&writer);
-
- // Run all the diagnostic tests.
- controller.Run(model);
- delete model;
-
- console->OnQuit();
- delete console;
- return 0;
-}
diff --git a/chrome/browser/diagnostics/diagnostics_main.h b/chrome/browser/diagnostics/diagnostics_main.h
deleted file mode 100644
index 0ce1404..0000000
--- a/chrome/browser/diagnostics/diagnostics_main.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2009 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.
-
-#ifndef CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MAIN_H_
-#define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MAIN_H_
-
-class CommandLine;
-
-// Entry point for the diagnostics mode. Most of the initialization that you
-// can see in ChromeMain() will be repeated here or will be done differently.
-int DiagnosticsMain(const CommandLine& command_line);
-
-
-#endif // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MAIN_H_
diff --git a/chrome/browser/diagnostics/diagnostics_model.cc b/chrome/browser/diagnostics/diagnostics_model.cc
index 6f96d06..b52e0a5 100644
--- a/chrome/browser/diagnostics/diagnostics_model.cc
+++ b/chrome/browser/diagnostics/diagnostics_model.cc
@@ -19,30 +19,31 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
+namespace diagnostics {
+
namespace {
// Embodies the commonalities of the model across platforms. It manages the
// list of tests and can loop over them. The main job of the platform specific
// code becomes:
-// 1- Inserting the appropiate tests into |tests_|
-// 2- Overriding RunTest() to wrap it with the appropiate fatal exception
+// 1- Inserting the appropriate tests into |tests_|
+// 2- Overriding RunTest() to wrap it with the appropriate fatal exception
// handler for the OS.
// This class owns the all the tests and will only delete them upon
// destruction.
class DiagnosticsModelImpl : public DiagnosticsModel {
public:
- DiagnosticsModelImpl() : tests_run_(0) {
- }
+ DiagnosticsModelImpl() : tests_run_(0) {}
virtual ~DiagnosticsModelImpl() {
STLDeleteElements(&tests_);
}
- virtual int GetTestRunCount() OVERRIDE {
+ virtual int GetTestRunCount() const OVERRIDE {
return tests_run_;
}
- virtual int GetTestAvailableCount() OVERRIDE {
+ virtual int GetTestAvailableCount() const OVERRIDE {
return tests_.size();
}
@@ -54,20 +55,23 @@ class DiagnosticsModelImpl : public DiagnosticsModel {
if (!do_next)
break;
}
- observer->OnDoneAll(this);
+ if (observer)
+ observer->OnDoneAll(this);
}
- virtual TestInfo& GetTest(size_t id) OVERRIDE {
- return *tests_[id];
+ virtual const TestInfo& GetTest(size_t index) OVERRIDE {
+ return *tests_[index];
}
protected:
// Run a particular test. Return false if no other tests should be run.
- virtual bool RunTest(DiagnosticTest* test, Observer* observer, size_t index) {
+ virtual bool RunTest(DiagnosticsTest* test,
+ Observer* observer,
+ size_t index) {
return test->Execute(observer, this, index);
}
- typedef std::vector<DiagnosticTest*> TestArray;
+ typedef std::vector<DiagnosticsTest*> TestArray;
TestArray tests_;
int tests_run_;
@@ -153,6 +157,10 @@ class DiagnosticsModelPosix : public DiagnosticsModelImpl {
tests_.push_back(MakeSqliteThumbnailsDbTest());
tests_.push_back(MakeSqliteAppCacheDbTest());
tests_.push_back(MakeSqliteWebDatabaseTrackerDbTest());
+#if defined(OS_CHROMEOS)
+ tests_.push_back(MakeSqliteNssCertDbTest());
+ tests_.push_back(MakeSqliteNssKeyDbTest());
+#endif
}
private:
@@ -176,3 +184,5 @@ DiagnosticsModel* MakeDiagnosticsModel(const CommandLine& cmdline) {
return new DiagnosticsModelPosix();
#endif
}
+
+} // namespace diagnostics
diff --git a/chrome/browser/diagnostics/diagnostics_model.h b/chrome/browser/diagnostics/diagnostics_model.h
index 466020b..1af3ae3 100644
--- a/chrome/browser/diagnostics/diagnostics_model.h
+++ b/chrome/browser/diagnostics/diagnostics_model.h
@@ -5,14 +5,16 @@
#ifndef CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MODEL_H_
#define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MODEL_H_
-#include "base/strings/string16.h"
+#include <string>
+#include "base/time/time.h"
class CommandLine;
+namespace diagnostics {
+
// The chrome diagnostics system is a model-view-controller system. The Model
// responsible for holding and running the individual tests and providing a
// uniform interface for querying the outcome.
-// TODO(cpu): The view and the controller are not yet built.
class DiagnosticsModel {
public:
// A particular test can be in one of the following states.
@@ -31,13 +33,8 @@ class DiagnosticsModel {
class Observer {
public:
virtual ~Observer() {}
- // Called once upon test start with |percent| = 0 and periodically as the
- // test progresses. There is no cancellation method.
- virtual void OnProgress(int id, int percent, DiagnosticsModel* model) = 0;
- // Called if the test in question cannot be run.
- virtual void OnSkipped(int id, DiagnosticsModel* model) = 0;
- // Called when the test has finished regardless of outcome.
- virtual void OnFinished(int id, DiagnosticsModel* model) = 0;
+ // Called when a test has finished regardless of outcome.
+ virtual void OnFinished(int index, DiagnosticsModel* model) = 0;
// Called once all the test are run.
virtual void OnDoneAll(DiagnosticsModel* model) = 0;
};
@@ -46,32 +43,45 @@ class DiagnosticsModel {
class TestInfo {
public:
virtual ~TestInfo() {}
- // A human readable, localized string that tells you what is being tested.
- virtual string16 GetTitle() = 0;
+ // A parse-able ASCII string that indicates what is being tested.
+ virtual std::string GetId() const = 0;
+ // A human readable string that tells you what is being tested.
+ // This is not localized: it is only meant for developer consumption.
+ virtual std::string GetTitle() const = 0;
// The result of running the test. If called before the test is ran the
// answer is TEST_NOT_RUN.
- virtual TestResult GetResult() = 0;
- // A human readable, localized string that tells you what happened. If
+ virtual TestResult GetResult() const = 0;
+ // A human readable string that tells you more about what happened. If
// called before the test is run it returns the empty string.
- virtual string16 GetAdditionalInfo() = 0;
+ // This is not localized: it is only meant for developer consumption.
+ virtual std::string GetAdditionalInfo() const = 0;
+ // A test-specific code representing what happened. If called before the
+ // test is run, it should return -1.
+ virtual int GetOutcomeCode() const = 0;
+ // Returns the system time when the test was performed.
+ virtual base::Time GetStartTime() const = 0;
+ // Returns the system time when the test was finished.
+ virtual base::Time GetEndTime() const = 0;
};
virtual ~DiagnosticsModel() {}
// Returns how many tests have been run.
- virtual int GetTestRunCount() = 0;
+ virtual int GetTestRunCount() const = 0;
// Returns how many tests are available. This value never changes.
- virtual int GetTestAvailableCount() =0;
+ virtual int GetTestAvailableCount() const = 0;
// Runs all the available tests, the |observer| callbacks will be called as
- // the test progress and thus cannot be null.
+ // the diagnostics progress. |observer| maybe NULL if no observation is
+ // needed.
virtual void RunAll(DiagnosticsModel::Observer* observer) = 0;
- // Get the information for a particular test. Do not keep a pointer to the
- // returned object.
- virtual TestInfo& GetTest(size_t id) = 0;
+ // Get the information for a particular test. Lifetime of returned object is
+ // limited to the lifetime of this model.
+ virtual const TestInfo& GetTest(size_t index) = 0;
};
// The factory for the model. The main purpose is to hide the creation of
// different models for different platforms.
DiagnosticsModel* MakeDiagnosticsModel(const CommandLine& cmdline);
+} // namespace diagnostics
#endif // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MODEL_H_
diff --git a/chrome/browser/diagnostics/diagnostics_model_unittest.cc b/chrome/browser/diagnostics/diagnostics_model_unittest.cc
index e362cd4..d70a299 100644
--- a/chrome/browser/diagnostics/diagnostics_model_unittest.cc
+++ b/chrome/browser/diagnostics/diagnostics_model_unittest.cc
@@ -8,7 +8,9 @@
#include "base/compiler_specific.h"
#include "testing/gtest/include/gtest/gtest.h"
-// Basic harness to adquire and release the Diagnostic model object.
+namespace diagnostics {
+
+// Basic harness to acquire and release the Diagnostic model object.
class DiagnosticsModelTest : public testing::Test {
protected:
DiagnosticsModelTest()
@@ -36,27 +38,15 @@ class UTObserver: public DiagnosticsModel::Observer {
public:
UTObserver()
: done_(false),
- progress_called_(0),
finished_(0),
id_of_failed_stop_test(-1) {
}
- virtual void OnProgress(int id,
- int percent,
- DiagnosticsModel* model) OVERRIDE {
- EXPECT_TRUE(model != NULL);
- ++progress_called_;
- }
-
- virtual void OnSkipped(int id, DiagnosticsModel* model) OVERRIDE {
- EXPECT_TRUE(model != NULL);
- }
-
- virtual void OnFinished(int id, DiagnosticsModel* model) OVERRIDE {
+ virtual void OnFinished(int index, DiagnosticsModel* model) OVERRIDE {
EXPECT_TRUE(model != NULL);
++finished_;
- if (model->GetTest(id).GetResult() == DiagnosticsModel::TEST_FAIL_STOP) {
- id_of_failed_stop_test = id;
+ if (model->GetTest(index).GetResult() == DiagnosticsModel::TEST_FAIL_STOP) {
+ id_of_failed_stop_test = index;
ASSERT_TRUE(false);
}
}
@@ -68,25 +58,26 @@ class UTObserver: public DiagnosticsModel::Observer {
bool done() const { return done_; }
- int progress_called() const { return progress_called_; }
-
int finished() const { return finished_;}
private:
bool done_;
- int progress_called_;
int finished_;
int id_of_failed_stop_test;
};
-// We currently have more tests operational on windows.
+// This is the count of tests on each platform.
#if defined(OS_WIN)
const int kDiagnosticsTestCount = 19;
#elif defined(OS_MACOSX)
const int kDiagnosticsTestCount = 16;
#elif defined(OS_POSIX)
+#if defined(OS_CHROMEOS)
+const int kDiagnosticsTestCount = 19;
+#else
const int kDiagnosticsTestCount = 17;
#endif
+#endif
// Test that the initial state is correct.
TEST_F(DiagnosticsModelTest, BeforeRun) {
@@ -103,7 +94,8 @@ TEST_F(DiagnosticsModelTest, RunAll) {
EXPECT_FALSE(observer.done());
model_->RunAll(&observer);
EXPECT_TRUE(observer.done());
- EXPECT_GT(observer.progress_called(), 0);
EXPECT_EQ(kDiagnosticsTestCount, model_->GetTestRunCount());
EXPECT_EQ(kDiagnosticsTestCount, observer.finished());
}
+
+} // namespace diagnostics
diff --git a/chrome/browser/diagnostics/diagnostics_test.cc b/chrome/browser/diagnostics/diagnostics_test.cc
index 64d4797..fe08dd6 100644
--- a/chrome/browser/diagnostics/diagnostics_test.cc
+++ b/chrome/browser/diagnostics/diagnostics_test.cc
@@ -9,45 +9,61 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
-DiagnosticTest::DiagnosticTest(const string16& title)
- : title_(title), result_(DiagnosticsModel::TEST_NOT_RUN) {
-}
+namespace diagnostics {
-DiagnosticTest::~DiagnosticTest() {
-}
+DiagnosticsTest::DiagnosticsTest(const std::string& id,
+ const std::string& title)
+ : id_(id),
+ title_(title),
+ outcome_code_(-1),
+ result_(DiagnosticsModel::TEST_NOT_RUN) {}
+
+DiagnosticsTest::~DiagnosticsTest() {}
-bool DiagnosticTest::Execute(DiagnosticsModel::Observer* observer,
- DiagnosticsModel* model,
- size_t index) {
+bool DiagnosticsTest::Execute(DiagnosticsModel::Observer* observer,
+ DiagnosticsModel* model,
+ size_t index) {
+ start_time_ = base::Time::Now();
result_ = DiagnosticsModel::TEST_RUNNING;
- observer->OnProgress(index, 0, model);
bool keep_going = ExecuteImpl(observer);
- observer->OnFinished(index, model);
+ if (observer)
+ observer->OnFinished(index, model);
return keep_going;
}
-string16 DiagnosticTest::GetTitle() {
- return title_;
-}
-
-DiagnosticsModel::TestResult DiagnosticTest::GetResult() {
- return result_;
-}
-
-string16 DiagnosticTest::GetAdditionalInfo() {
- return additional_info_;
-}
-
-void DiagnosticTest::RecordOutcome(const string16& additional_info,
- DiagnosticsModel::TestResult result) {
+void DiagnosticsTest::RecordOutcome(int outcome_code,
+ const std::string& additional_info,
+ DiagnosticsModel::TestResult result) {
+ end_time_ = base::Time::Now();
+ outcome_code_ = outcome_code;
additional_info_ = additional_info;
result_ = result;
}
// static
-base::FilePath DiagnosticTest::GetUserDefaultProfileDir() {
+base::FilePath DiagnosticsTest::GetUserDefaultProfileDir() {
base::FilePath path;
if (!PathService::Get(chrome::DIR_USER_DATA, &path))
return base::FilePath();
return path.AppendASCII(chrome::kInitialProfile);
}
+
+std::string DiagnosticsTest::GetId() const { return id_; }
+
+std::string DiagnosticsTest::GetTitle() const { return title_; }
+
+DiagnosticsModel::TestResult DiagnosticsTest::GetResult() const {
+ return result_;
+}
+
+int DiagnosticsTest::GetOutcomeCode() const { return outcome_code_; }
+
+std::string DiagnosticsTest::GetAdditionalInfo() const {
+ return additional_info_;
+}
+
+base::Time DiagnosticsTest::GetStartTime() const { return start_time_; }
+
+base::Time DiagnosticsTest::GetEndTime() const { return end_time_; }
+
+} // namespace diagnostics
diff --git a/chrome/browser/diagnostics/diagnostics_test.h b/chrome/browser/diagnostics/diagnostics_test.h
index eed176d..20e44d9 100644
--- a/chrome/browser/diagnostics/diagnostics_test.h
+++ b/chrome/browser/diagnostics/diagnostics_test.h
@@ -6,16 +6,17 @@
#define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_TEST_H_
#include "base/compiler_specific.h"
-#include "base/strings/string16.h"
#include "chrome/browser/diagnostics/diagnostics_model.h"
namespace base {
class FilePath;
}
+namespace diagnostics {
+
// Represents a single diagnostic test and encapsulates the common
// functionality across platforms as well.
-// It also Implements the TestInfo interface providing the storage
+// It also implements the TestInfo interface providing the storage
// for the outcome of the test.
// Specific tests need (minimally) only to:
// 1- override ExecuteImpl() to implement the test.
@@ -23,52 +24,61 @@ class FilePath;
// at the end of the test.
// 3- Optionally call observer->OnProgress() if the test is long.
// 4- Optionally call observer->OnSkipped() if the test cannot be run.
-class DiagnosticTest : public DiagnosticsModel::TestInfo {
+class DiagnosticsTest : public DiagnosticsModel::TestInfo {
public:
- // |title| is the human readable, localized string that says that
- // the objective of the test is.
- explicit DiagnosticTest(const string16& title);
+ // |id| is a parse-able ASCII ID string that uniquely identifies the test. It
+ // should only have letters, numbers and underscores in it (and no spaces).
+ // |title| is the human readable string that says what the objective of the
+ // test is.
+ DiagnosticsTest(const std::string& id, const std::string& title);
- virtual ~DiagnosticTest();
+ virtual ~DiagnosticsTest();
// Runs the test. Returning false signals that no more tests should be run.
// The actual outcome of the test should be set using the RecordXX functions.
bool Execute(DiagnosticsModel::Observer* observer, DiagnosticsModel* model,
size_t index);
- virtual string16 GetTitle() OVERRIDE;
-
- virtual DiagnosticsModel::TestResult GetResult() OVERRIDE;
-
- virtual string16 GetAdditionalInfo() OVERRIDE;
-
- void RecordStopFailure(const string16& additional_info) {
- RecordOutcome(additional_info, DiagnosticsModel::TEST_FAIL_STOP);
+ void RecordStopFailure(int outcome_code, const std::string& additional_info) {
+ RecordOutcome(
+ outcome_code, additional_info, DiagnosticsModel::TEST_FAIL_STOP);
}
- void RecordFailure(const string16& additional_info) {
- RecordOutcome(additional_info, DiagnosticsModel::TEST_FAIL_CONTINUE);
+ void RecordFailure(int outcome_code, const std::string& additional_info) {
+ RecordOutcome(
+ outcome_code, additional_info, DiagnosticsModel::TEST_FAIL_CONTINUE);
}
- void RecordSuccess(const string16& additional_info) {
- RecordOutcome(additional_info, DiagnosticsModel::TEST_OK);
+ void RecordSuccess(const std::string& additional_info) {
+ RecordOutcome(0, additional_info, DiagnosticsModel::TEST_OK);
}
- void RecordOutcome(const string16& additional_info,
+ void RecordOutcome(int outcome_code,
+ const std::string& additional_info,
DiagnosticsModel::TestResult result);
static base::FilePath GetUserDefaultProfileDir();
+ // DiagnosticsModel::TestInfo overrides
+ virtual std::string GetId() const OVERRIDE;
+ virtual std::string GetTitle() const OVERRIDE;
+ virtual DiagnosticsModel::TestResult GetResult() const OVERRIDE;
+ virtual std::string GetAdditionalInfo() const OVERRIDE;
+ virtual int GetOutcomeCode() const OVERRIDE;
+ virtual base::Time GetStartTime() const OVERRIDE;
+ virtual base::Time GetEndTime() const OVERRIDE;
protected:
- // The id needs to be overridden by derived classes and must uniquely
- // identify this test so other test can refer to it.
- virtual int GetId() = 0;
// Derived classes override this method do perform the actual test.
virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) = 0;
- string16 title_;
- string16 additional_info_;
+ const std::string id_;
+ const std::string title_;
+ std::string additional_info_;
+ int outcome_code_;
DiagnosticsModel::TestResult result_;
+ base::Time start_time_;
+ base::Time end_time_;
};
+} // namespace diagnostics
#endif // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_TEST_H_
diff --git a/chrome/browser/diagnostics/diagnostics_writer.cc b/chrome/browser/diagnostics/diagnostics_writer.cc
new file mode 100644
index 0000000..bf49e3e7
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_writer.cc
@@ -0,0 +1,281 @@
+// Copyright 2013 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.
+
+#include "chrome/browser/diagnostics/diagnostics_writer.h"
+
+#include "build/build_config.h"
+
+#if defined(OS_POSIX)
+#include <stdio.h>
+#include <unistd.h>
+#endif
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/logging.h"
+#include "base/strings/string16.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/common/chrome_switches.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/ui_base_paths.h"
+
+namespace diagnostics {
+
+// This is a minimalistic interface to wrap the platform console.
+class SimpleConsole {
+ public:
+ enum Color {
+ DEFAULT,
+ RED,
+ GREEN,
+ };
+
+ virtual ~SimpleConsole() {}
+
+ // Init must be called before using any other method. If it returns
+ // false there will be no console output.
+ virtual bool Init() = 0;
+
+ // Writes a string to the console with the current color.
+ virtual bool Write(const string16& text) = 0;
+
+ // Called when the program is about to exit.
+ virtual void OnQuit() = 0;
+
+ // Sets the foreground text color.
+ virtual bool SetColor(Color color) = 0;
+
+ // Create an appropriate SimpleConsole instance. May return NULL if there is
+ // no implementation for the current platform.
+ static SimpleConsole* Create();
+};
+
+#if defined(OS_WIN)
+namespace {
+
+// Wrapper for the windows console operating in high-level IO mode.
+class WinConsole : public SimpleConsole {
+ public:
+ // The ctor allocates a console. This avoids having to ask the user to start
+ // chrome from a command prompt.
+ WinConsole()
+ : std_out_(INVALID_HANDLE_VALUE),
+ std_in_(INVALID_HANDLE_VALUE) {
+ ::AllocConsole();
+ }
+
+ virtual ~WinConsole() {
+ ::FreeConsole();
+ }
+
+ virtual bool Init() {
+ return SetIOHandles();
+ }
+
+ virtual bool Write(const string16& txt) {
+ DWORD sz = txt.size();
+ return (TRUE == ::WriteConsoleW(std_out_, txt.c_str(), sz, &sz, NULL));
+ }
+
+ // Reads a string from the console. Internally it is limited to 256
+ // characters.
+ virtual void OnQuit() {
+ // Block here so the user can see the results.
+ SetColor(SimpleConsole::DEFAULT);
+ Write(L"Press [enter] to continue\n");
+ wchar_t buf[256];
+ DWORD read = arraysize(buf);
+ ::ReadConsoleW(std_in_, buf, read, &read, NULL);
+ }
+
+ // Sets the foreground and background color.
+ virtual bool SetColor(Color color) {
+ uint16 color_combo = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
+ FOREGROUND_INTENSITY;
+ switch (color) {
+ case RED:
+ color_combo = FOREGROUND_RED | FOREGROUND_INTENSITY;
+ break;
+ case GREEN:
+ color_combo = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+ break;
+ case DEFAULT:
+ break;
+ default:
+ NOTREACHED();
+ }
+ return (TRUE == ::SetConsoleTextAttribute(std_out_, color_combo));
+ }
+
+ private:
+ bool SetIOHandles() {
+ std_out_ = ::GetStdHandle(STD_OUTPUT_HANDLE);
+ std_in_ = ::GetStdHandle(STD_INPUT_HANDLE);
+ return ((std_out_ != INVALID_HANDLE_VALUE) &&
+ (std_in_ != INVALID_HANDLE_VALUE));
+ }
+
+ // The input and output handles to the screen. They seem to be
+ // implemented as pipes but they have non-documented protocol.
+ HANDLE std_out_;
+ HANDLE std_in_;
+
+ DISALLOW_COPY_AND_ASSIGN(WinConsole);
+};
+
+} // namespace
+
+SimpleConsole* SimpleConsole::Create() { return new WinConsole(); }
+
+#elif defined(OS_POSIX)
+namespace {
+
+class PosixConsole : public SimpleConsole {
+ public:
+ PosixConsole() : use_color_(false) {}
+
+ virtual bool Init() OVERRIDE {
+ // Technically, we should also check the terminal capabilities before using
+ // color, but in practice this is unlikely to be an issue.
+ use_color_ = isatty(STDOUT_FILENO);
+ return true;
+ }
+
+ virtual bool Write(const string16& text) OVERRIDE {
+ // We're assuming that the terminal is using UTF-8 encoding.
+ printf("%s", UTF16ToUTF8(text).c_str());
+ return true;
+ }
+
+ virtual void OnQuit() OVERRIDE {
+ // The "press enter to continue" prompt isn't very unixy, so only do that on
+ // Windows.
+ }
+
+ virtual bool SetColor(Color color) OVERRIDE {
+ if (!use_color_)
+ return false;
+
+ const char* code = "\033[m";
+ switch (color) {
+ case RED:
+ code = "\033[1;31m";
+ break;
+ case GREEN:
+ code = "\033[1;32m";
+ break;
+ case DEFAULT:
+ break;
+ default:
+ NOTREACHED();
+ }
+ printf("%s", code);
+ return true;
+ }
+
+ private:
+ bool use_color_;
+
+ DISALLOW_COPY_AND_ASSIGN(PosixConsole);
+};
+
+} // namespace
+
+SimpleConsole* SimpleConsole::Create() { return new PosixConsole(); }
+
+#else // !defined(OS_WIN) && !defined(OS_POSIX)
+SimpleConsole* SimpleConsole::Create() { return NULL; }
+#endif
+
+///////////////////////////////////////////////////////////
+// DiagnosticsWriter
+
+DiagnosticsWriter::DiagnosticsWriter(FormatType format)
+ : failures_(0), format_(format) {
+ // Only create consoles for non-log output.
+ if (format_ != LOG) {
+ console_.reset(SimpleConsole::Create());
+ console_->Init();
+ }
+}
+
+DiagnosticsWriter::~DiagnosticsWriter() {
+ if (console_.get())
+ console_->OnQuit();
+}
+
+bool DiagnosticsWriter::WriteInfoLine(const std::string& info_text) {
+ if (format_ == LOG) {
+ LOG(WARNING) << info_text;
+ return true;
+ } else {
+ if (console_.get()) {
+ console_->SetColor(SimpleConsole::DEFAULT);
+ console_->Write(UTF8ToUTF16(info_text + "\n"));
+ }
+ }
+ return true;
+}
+
+void DiagnosticsWriter::OnFinished(int index, DiagnosticsModel* model) {
+ const DiagnosticsModel::TestInfo& test_info = model->GetTest(index);
+ bool success = (DiagnosticsModel::TEST_OK == test_info.GetResult());
+ WriteResult(success,
+ test_info.GetId(),
+ test_info.GetTitle(),
+ test_info.GetOutcomeCode(),
+ test_info.GetAdditionalInfo());
+}
+
+void DiagnosticsWriter::OnDoneAll(DiagnosticsModel* model) {
+ WriteInfoLine(
+ base::StringPrintf("Finished %d tests.", model->GetTestRunCount()));
+}
+
+bool DiagnosticsWriter::WriteResult(bool success,
+ const std::string& id,
+ const std::string& name,
+ int outcome_code,
+ const std::string& extra) {
+ std::string result;
+ SimpleConsole::Color color;
+
+ if (success) {
+ result = "[PASS] ";
+ color = SimpleConsole::GREEN;
+ } else {
+ color = SimpleConsole::RED;
+ result = "[FAIL] ";
+ failures_++;
+ }
+
+ if (format_ != LOG) {
+ if (console_.get()) {
+ console_->SetColor(color);
+ console_->Write(ASCIIToUTF16(result));
+ }
+ if (format_ == MACHINE) {
+ return WriteInfoLine(base::StringPrintf(
+ "%03d %s (%s)", outcome_code, id.c_str(), extra.c_str()));
+ } else {
+ return WriteInfoLine(name + "\n " + extra + "\n");
+ }
+ } else {
+ if (!success) {
+ // For log output, we only care about the tests that failed.
+ return WriteInfoLine(base::StringPrintf("%s%03d %s (%s)",
+ result.c_str(),
+ outcome_code,
+ id.c_str(),
+ extra.c_str()));
+ }
+ }
+ return true;
+}
+
+} // namespace diagnostics
diff --git a/chrome/browser/diagnostics/diagnostics_writer.h b/chrome/browser/diagnostics/diagnostics_writer.h
new file mode 100644
index 0000000..1fad047
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_writer.h
@@ -0,0 +1,66 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_WRITER_H_
+#define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_WRITER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/diagnostics/diagnostics_model.h"
+
+namespace diagnostics {
+
+// Console base class used internally.
+class SimpleConsole;
+
+class DiagnosticsWriter : public DiagnosticsModel::Observer {
+ public:
+ // The type of formatting done by this writer.
+ enum FormatType {
+ MACHINE,
+ LOG,
+ HUMAN
+ };
+
+ explicit DiagnosticsWriter(FormatType format);
+ virtual ~DiagnosticsWriter();
+
+ // How many tests reported failure.
+ int failures() { return failures_; }
+
+ // What format are we writing things in.
+ FormatType format() const { return format_; }
+
+ // Write an informational line of text in white over black. String must be
+ // UTF8 encoded. A newline will be added for non-LOG output formats.
+ bool WriteInfoLine(const std::string& info_text);
+
+ // DiagnosticsModel::Observer overrides
+ virtual void OnFinished(int id, DiagnosticsModel* model) OVERRIDE;
+ virtual void OnDoneAll(DiagnosticsModel* model) OVERRIDE;
+
+ private:
+ // Write a result block. For humans, it consists of two lines. The first line
+ // has [PASS] or [FAIL] with |name| and the second line has the text in
+ // |extra|. For machine and log formats, we just have [PASS] or [FAIL],
+ // followed by the exact error code and the id. Name and extra strings must be
+ // UTF8 encoded, as they are user-facing strings.
+ bool WriteResult(bool success,
+ const std::string& id,
+ const std::string& name,
+ int outcome_code,
+ const std::string& extra);
+
+ scoped_ptr<SimpleConsole> console_;
+
+ // Keeps track of how many tests reported failure.
+ int failures_;
+ FormatType format_;
+
+ DISALLOW_COPY_AND_ASSIGN(DiagnosticsWriter);
+};
+
+} // namespace diagnostics
+
+#endif // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_WRITER_H_
diff --git a/chrome/browser/diagnostics/recon_diagnostics.cc b/chrome/browser/diagnostics/recon_diagnostics.cc
index b66fd03..fc69ad7 100644
--- a/chrome/browser/diagnostics/recon_diagnostics.cc
+++ b/chrome/browser/diagnostics/recon_diagnostics.cc
@@ -19,7 +19,6 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_version_info.h"
-#include "ui/base/text/bytes_formatting.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
@@ -31,21 +30,35 @@
// diagnostic tests. Here we check for the existence of critical files.
// TODO(cpu): Define if it makes sense to localize strings.
-// TODO(cpu): There are a few maximum file sizes hardcoded in this file
+// TODO(cpu): There are a few maximum file sizes hard-coded in this file
// that have little or no theoretical or experimental ground. Find a way
// to justify them.
+namespace diagnostics {
+
+const char kConflictingDllsTest[] = "ConflictingDlls";
+const char kDiskSpaceTest[] = "DiskSpace";
+const char kInstallTypeTest[] = "InstallType";
+const char kJSONBookmarksTest[] = "JSONBookmarks";
+const char kJSONLocalStateTest[] = "JSONLocalState";
+const char kJSONProfileTest[] = "JSONProfile";
+const char kOperatingSystemTest[] = "OperatingSystem";
+const char kPathDictionariesTest[] = "PathDictionaries";
+const char kPathLocalStateTest[] = "PathLocalState";
+const char kPathResourcesTest[] = "PathResources";
+const char kPathUserDataTest[] = "PathUserData";
+const char kVersionTest[] = "Version";
+
namespace {
class InstallTypeTest;
InstallTypeTest* g_install_type = 0;
// Check that the flavor of the operating system is supported.
-class OperatingSystemTest : public DiagnosticTest {
+class OperatingSystemTest : public DiagnosticsTest {
public:
- OperatingSystemTest() : DiagnosticTest(ASCIIToUTF16("Operating System")) {}
-
- virtual int GetId() OVERRIDE { return 0; }
+ OperatingSystemTest()
+ : DiagnosticsTest(kOperatingSystemTest, "Operating System") {}
virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
#if defined(OS_WIN)
@@ -53,16 +66,17 @@ class OperatingSystemTest : public DiagnosticTest {
if ((version < base::win::VERSION_XP) ||
((version == base::win::VERSION_XP) &&
(base::win::OSInfo::GetInstance()->service_pack().major < 2))) {
- RecordFailure(ASCIIToUTF16("Must have Windows XP SP2 or later"));
+ RecordFailure(DIAG_RECON_PRE_WINDOW_XP_SP2,
+ "Must have Windows XP SP2 or later");
return false;
}
#else
- // TODO(port): define the OS criteria for Linux and Mac.
+// TODO(port): define the OS criteria for Linux and Mac.
#endif // defined(OS_WIN)
- RecordSuccess(ASCIIToUTF16(base::StringPrintf(
- "%s %s",
- base::SysInfo::OperatingSystemName().c_str(),
- base::SysInfo::OperatingSystemVersion().c_str())));
+ RecordSuccess(
+ base::StringPrintf("%s %s",
+ base::SysInfo::OperatingSystemName().c_str(),
+ base::SysInfo::OperatingSystemVersion().c_str()));
return true;
}
@@ -71,11 +85,10 @@ class OperatingSystemTest : public DiagnosticTest {
};
// Check if any conflicting DLLs are loaded.
-class ConflictingDllsTest : public DiagnosticTest {
+class ConflictingDllsTest : public DiagnosticsTest {
public:
- ConflictingDllsTest() : DiagnosticTest(ASCIIToUTF16("Conflicting modules")) {}
-
- virtual int GetId() OVERRIDE { return 0; }
+ ConflictingDllsTest()
+ : DiagnosticsTest(kConflictingDllsTest, "Conflicting modules") {}
virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
#if defined(OS_WIN)
@@ -85,38 +98,40 @@ class ConflictingDllsTest : public DiagnosticTest {
scoped_ptr<ListValue> list(model->GetModuleList());
if (!model->confirmed_bad_modules_detected() &&
!model->suspected_bad_modules_detected()) {
- RecordSuccess(ASCIIToUTF16("No conflicting modules found"));
+ RecordSuccess("No conflicting modules found");
return true;
}
- string16 failures = ASCIIToUTF16("Possibly conflicting modules:");
+ std::string failures = "Possibly conflicting modules:";
DictionaryValue* dictionary;
for (size_t i = 0; i < list->GetSize(); ++i) {
if (!list->GetDictionary(i, &dictionary))
- RecordFailure(ASCIIToUTF16("Dictionary lookup failed"));
+ RecordFailure(DIAG_RECON_DICTIONARY_LOOKUP_FAILED,
+ "Dictionary lookup failed");
int status;
- string16 location;
- string16 name;
+ std::string location;
+ std::string name;
if (!dictionary->GetInteger("status", &status))
- RecordFailure(ASCIIToUTF16("No 'status' field found"));
+ RecordFailure(DIAG_RECON_NO_STATUS_FIELD, "No 'status' field found");
if (status < ModuleEnumerator::SUSPECTED_BAD)
continue;
if (!dictionary->GetString("location", &location)) {
- RecordFailure(ASCIIToUTF16("No 'location' field found"));
+ RecordFailure(DIAG_RECON_NO_LOCATION_FIELD,
+ "No 'location' field found");
return true;
}
if (!dictionary->GetString("name", &name)) {
- RecordFailure(ASCIIToUTF16("No 'name' field found"));
+ RecordFailure(DIAG_RECON_NO_NAME_FIELD, "No 'name' field found");
return true;
}
- failures += ASCIIToUTF16("\n") + location + name;
+ failures += "\n" + location + name;
}
- RecordFailure(failures);
+ RecordFailure(DIAG_RECON_CONFLICTING_MODULES, failures);
return true;
#else
- RecordFailure(ASCIIToUTF16("Not implemented"));
+ RecordFailure(DIAG_RECON_NOT_IMPLEMENTED, "Not implemented");
return true;
#endif // defined(OS_WIN)
}
@@ -126,25 +141,23 @@ class ConflictingDllsTest : public DiagnosticTest {
};
// Check if it is system install or per-user install.
-class InstallTypeTest : public DiagnosticTest {
+class InstallTypeTest : public DiagnosticsTest {
public:
- InstallTypeTest() : DiagnosticTest(ASCIIToUTF16("Install Type")),
- user_level_(false) {}
-
- virtual int GetId() OVERRIDE { return 0; }
+ InstallTypeTest()
+ : DiagnosticsTest(kInstallTypeTest, "Install Type"), user_level_(false) {}
virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
#if defined(OS_WIN)
base::FilePath chrome_exe;
if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
- RecordFailure(ASCIIToUTF16("Path provider failure"));
+ RecordFailure(DIAG_RECON_INSTALL_PATH_PROVIDER, "Path provider failure");
return false;
}
user_level_ = InstallUtil::IsPerUserInstall(chrome_exe.value().c_str());
const char* type = user_level_ ? "User Level" : "System Level";
- string16 install_type(ASCIIToUTF16(type));
+ std::string install_type(type);
#else
- string16 install_type(ASCIIToUTF16("System Level"));
+ std::string install_type("System Level");
#endif // defined(OS_WIN)
RecordSuccess(install_type);
g_install_type = this;
@@ -159,21 +172,19 @@ class InstallTypeTest : public DiagnosticTest {
};
// Check the version of Chrome.
-class VersionTest : public DiagnosticTest {
+class VersionTest : public DiagnosticsTest {
public:
- VersionTest() : DiagnosticTest(ASCIIToUTF16("Browser Version")) {}
-
- virtual int GetId() OVERRIDE { return 0; }
+ VersionTest() : DiagnosticsTest(kVersionTest, "Browser Version") {}
virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
chrome::VersionInfo version_info;
if (!version_info.is_valid()) {
- RecordFailure(ASCIIToUTF16("No Version"));
+ RecordFailure(DIAG_RECON_NO_VERSION, "No Version");
return true;
}
std::string current_version = version_info.Version();
if (current_version.empty()) {
- RecordFailure(ASCIIToUTF16("Empty Version"));
+ RecordFailure(DIAG_RECON_EMPTY_VERSION, "Empty Version");
return true;
}
std::string version_modifier =
@@ -183,7 +194,7 @@ class VersionTest : public DiagnosticTest {
#if defined(GOOGLE_CHROME_BUILD)
current_version += " GCB";
#endif // defined(GOOGLE_CHROME_BUILD)
- RecordSuccess(ASCIIToUTF16(current_version));
+ RecordSuccess(current_version);
return true;
}
@@ -193,51 +204,51 @@ class VersionTest : public DiagnosticTest {
struct TestPathInfo {
const char* test_name;
- int path_id;
+ const char* test_id;
+ int path_id;
bool is_directory;
bool is_optional;
bool test_writable;
int64 max_size;
};
-const int64 kOneKilo = 1024;
-const int64 kOneMeg = 1024 * kOneKilo;
+const int64 kOneKilobyte = 1024;
+const int64 kOneMegabyte = 1024 * kOneKilobyte;
const TestPathInfo kPathsToTest[] = {
- {"User data Directory", chrome::DIR_USER_DATA,
- true, false, true, 850 * kOneMeg},
- {"Local state file", chrome::FILE_LOCAL_STATE,
- false, false, true, 500 * kOneKilo},
- {"Dictionaries Directory", chrome::DIR_APP_DICTIONARIES,
- true, true, false, 0},
- {"Resources file", chrome::FILE_RESOURCES_PACK,
- false, false, false, 0}
+ {"User data Directory", kPathUserDataTest, chrome::DIR_USER_DATA, true, false,
+ true, 850 * kOneMegabyte},
+ {"Local state file", kPathLocalStateTest, chrome::FILE_LOCAL_STATE, false,
+ false, true, 500 * kOneKilobyte},
+ {"Dictionaries Directory", kPathDictionariesTest,
+ chrome::DIR_APP_DICTIONARIES, true, true, false, 0},
+ {"Resources file", kPathResourcesTest, chrome::FILE_RESOURCES_PACK, false,
+ false, false, 0}
};
// Check that the user's data directory exists and the paths are writable.
-// If it is a systemwide install some paths are not expected to be writable.
+// If it is a system-wide install some paths are not expected to be writable.
// This test depends on |InstallTypeTest| having run successfully.
-class PathTest : public DiagnosticTest {
+class PathTest : public DiagnosticsTest {
public:
explicit PathTest(const TestPathInfo& path_info)
- : DiagnosticTest(ASCIIToUTF16(path_info.test_name)),
+ : DiagnosticsTest(path_info.test_id, path_info.test_name),
path_info_(path_info) {}
- virtual int GetId() OVERRIDE { return 0; }
-
virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
if (!g_install_type) {
- RecordStopFailure(ASCIIToUTF16("dependency failure"));
+ RecordStopFailure(DIAG_RECON_DEPENDENCY, "Install dependency failure");
return false;
}
base::FilePath dir_or_file;
if (!PathService::Get(path_info_.path_id, &dir_or_file)) {
- RecordStopFailure(ASCIIToUTF16("Path provider failure"));
+ RecordStopFailure(DIAG_RECON_PATH_PROVIDER, "Path provider failure");
return false;
}
if (!file_util::PathExists(dir_or_file)) {
- RecordFailure(ASCIIToUTF16("Path not found: ") +
- dir_or_file.LossyDisplayName());
+ RecordFailure(
+ DIAG_RECON_PATH_NOT_FOUND,
+ "Path not found: " + UTF16ToUTF8(dir_or_file.LossyDisplayName()));
return true;
}
@@ -248,32 +259,32 @@ class PathTest : public DiagnosticTest {
file_util::GetFileSize(dir_or_file, &dir_or_file_size);
}
if (!dir_or_file_size && !path_info_.is_optional) {
- RecordFailure(ASCIIToUTF16("Cannot obtain size for: ") +
- dir_or_file.LossyDisplayName());
+ RecordFailure(DIAG_RECON_CANNOT_OBTAIN_SIZE,
+ "Cannot obtain size for: " +
+ UTF16ToUTF8(dir_or_file.LossyDisplayName()));
return true;
}
- string16 printable_size = ui::FormatBytes(dir_or_file_size);
+ std::string printable_size = base::Int64ToString(dir_or_file_size);
if (path_info_.max_size > 0) {
if (dir_or_file_size > path_info_.max_size) {
- RecordFailure(ASCIIToUTF16("Path contents too large (") +
- printable_size +
- ASCIIToUTF16(") for: ") +
- dir_or_file.LossyDisplayName());
+ RecordFailure(DIAG_RECON_FILE_TOO_LARGE,
+ "Path contents too large (" + printable_size + ") for: " +
+ UTF16ToUTF8(dir_or_file.LossyDisplayName()));
return true;
}
}
if (g_install_type->system_level() && !path_info_.test_writable) {
- RecordSuccess(ASCIIToUTF16("Path exists"));
+ RecordSuccess("Path exists");
return true;
}
if (!file_util::PathIsWritable(dir_or_file)) {
- RecordFailure(ASCIIToUTF16("Path is not writable: ") +
- dir_or_file.LossyDisplayName());
+ RecordFailure(DIAG_RECON_NOT_WRITABLE,
+ "Path is not writable: " +
+ UTF16ToUTF8(dir_or_file.LossyDisplayName()));
return true;
}
- RecordSuccess(ASCIIToUTF16("Path exists and is writable: ")
- + printable_size);
+ RecordSuccess("Path exists and is writable: " + printable_size);
return true;
}
@@ -282,13 +293,11 @@ class PathTest : public DiagnosticTest {
DISALLOW_COPY_AND_ASSIGN(PathTest);
};
-// Check that the disk space in the volume where the user data dir normally
-// lives is not dangerously low.
-class DiskSpaceTest : public DiagnosticTest {
+// Check that the disk space in the volume where the user data directory
+// normally lives is not dangerously low.
+class DiskSpaceTest : public DiagnosticsTest {
public:
- DiskSpaceTest() : DiagnosticTest(ASCIIToUTF16("Disk Space")) {}
-
- virtual int GetId() OVERRIDE { return 0; }
+ DiskSpaceTest() : DiagnosticsTest(kDiskSpaceTest, "Disk Space") {}
virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
base::FilePath data_dir;
@@ -296,15 +305,16 @@ class DiskSpaceTest : public DiagnosticTest {
return false;
int64 disk_space = base::SysInfo::AmountOfFreeDiskSpace(data_dir);
if (disk_space < 0) {
- RecordFailure(ASCIIToUTF16("Unable to query free space"));
+ RecordFailure(DIAG_RECON_UNABLE_TO_QUERY, "Unable to query free space");
return true;
}
- string16 printable_size = ui::FormatBytes(disk_space);
- if (disk_space < 80 * kOneMeg) {
- RecordFailure(ASCIIToUTF16("Low disk space : ") + printable_size);
+ std::string printable_size = base::Int64ToString(disk_space);
+ if (disk_space < 80 * kOneMegabyte) {
+ RecordFailure(DIAG_RECON_LOW_DISK_SPACE,
+ "Low disk space: " + printable_size);
return true;
}
- RecordSuccess(ASCIIToUTF16("Free space : ") + printable_size);
+ RecordSuccess("Free space: " + printable_size);
return true;
}
@@ -313,36 +323,35 @@ class DiskSpaceTest : public DiagnosticTest {
};
// Checks that a given json file can be correctly parsed.
-class JSONTest : public DiagnosticTest {
+class JSONTest : public DiagnosticsTest {
public:
JSONTest(const base::FilePath& path,
- const string16& name,
+ const std::string& id,
+ const std::string& name,
int64 max_file_size)
- : DiagnosticTest(name), path_(path), max_file_size_(max_file_size) {
- }
-
- virtual int GetId() OVERRIDE { return 0; }
+ : DiagnosticsTest(id, name), path_(path), max_file_size_(max_file_size) {}
virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
if (!file_util::PathExists(path_)) {
- RecordFailure(ASCIIToUTF16("File not found"));
+ RecordFailure(DIAG_RECON_FILE_NOT_FOUND, "File not found");
return true;
}
int64 file_size;
if (!file_util::GetFileSize(path_, &file_size)) {
- RecordFailure(ASCIIToUTF16("Cannot obtain file size"));
+ RecordFailure(DIAG_RECON_CANNOT_OBTAIN_FILE_SIZE,
+ "Cannot obtain file size");
return true;
}
if (file_size > max_file_size_) {
- RecordFailure(ASCIIToUTF16("File too big"));
+ RecordFailure(DIAG_RECON_FILE_TOO_BIG, "File too big");
return true;
}
// Being small enough, we can process it in-memory.
std::string json_data;
if (!file_util::ReadFileToString(path_, &json_data)) {
- RecordFailure(ASCIIToUTF16(
- "Could not open file. Possibly locked by other process"));
+ RecordFailure(DIAG_RECON_UNABLE_TO_OPEN_FILE,
+ "Could not open file. Possibly locked by another process");
return true;
}
@@ -354,11 +363,11 @@ class JSONTest : public DiagnosticTest {
if (error_message.empty()) {
error_message = "Parse error " + base::IntToString(error_code);
}
- RecordFailure(UTF8ToUTF16(error_message));
+ RecordFailure(DIAG_RECON_PARSE_ERROR, error_message);
return true;
}
- RecordSuccess(ASCIIToUTF16("File parsed OK"));
+ RecordSuccess("File parsed OK");
return true;
}
@@ -370,57 +379,50 @@ class JSONTest : public DiagnosticTest {
} // namespace
-DiagnosticTest* MakeUserDirTest() {
- return new PathTest(kPathsToTest[0]);
-}
+DiagnosticsTest* MakeUserDirTest() { return new PathTest(kPathsToTest[0]); }
-DiagnosticTest* MakeLocalStateFileTest() {
+DiagnosticsTest* MakeLocalStateFileTest() {
return new PathTest(kPathsToTest[1]);
}
-DiagnosticTest* MakeDictonaryDirTest() {
+DiagnosticsTest* MakeDictonaryDirTest() {
return new PathTest(kPathsToTest[2]);
}
-DiagnosticTest* MakeResourcesFileTest() {
+DiagnosticsTest* MakeResourcesFileTest() {
return new PathTest(kPathsToTest[3]);
}
-DiagnosticTest* MakeVersionTest() {
- return new VersionTest();
-}
+DiagnosticsTest* MakeVersionTest() { return new VersionTest(); }
-DiagnosticTest* MakeDiskSpaceTest() {
- return new DiskSpaceTest();
-}
+DiagnosticsTest* MakeDiskSpaceTest() { return new DiskSpaceTest(); }
-DiagnosticTest* MakeOperatingSystemTest() {
- return new OperatingSystemTest();
-}
+DiagnosticsTest* MakeOperatingSystemTest() { return new OperatingSystemTest(); }
-DiagnosticTest* MakeConflictingDllsTest() {
- return new ConflictingDllsTest();
-}
+DiagnosticsTest* MakeConflictingDllsTest() { return new ConflictingDllsTest(); }
-DiagnosticTest* MakeInstallTypeTest() {
- return new InstallTypeTest();
-}
+DiagnosticsTest* MakeInstallTypeTest() { return new InstallTypeTest(); }
-DiagnosticTest* MakePreferencesTest() {
- base::FilePath path = DiagnosticTest::GetUserDefaultProfileDir();
+DiagnosticsTest* MakePreferencesTest() {
+ base::FilePath path = DiagnosticsTest::GetUserDefaultProfileDir();
path = path.Append(chrome::kPreferencesFilename);
- return new JSONTest(path, ASCIIToUTF16("Profile JSON"), 100 * kOneKilo);
+ return new JSONTest(
+ path, kJSONProfileTest, "Profile JSON", 100 * kOneKilobyte);
}
-DiagnosticTest* MakeBookMarksTest() {
- base::FilePath path = DiagnosticTest::GetUserDefaultProfileDir();
+DiagnosticsTest* MakeBookMarksTest() {
+ base::FilePath path = DiagnosticsTest::GetUserDefaultProfileDir();
path = path.Append(chrome::kBookmarksFileName);
- return new JSONTest(path, ASCIIToUTF16("BookMarks JSON"), 2 * kOneMeg);
+ return new JSONTest(
+ path, kJSONBookmarksTest, "Bookmarks JSON", 2 * kOneMegabyte);
}
-DiagnosticTest* MakeLocalStateTest() {
+DiagnosticsTest* MakeLocalStateTest() {
base::FilePath path;
PathService::Get(chrome::DIR_USER_DATA, &path);
path = path.Append(chrome::kLocalStateFilename);
- return new JSONTest(path, ASCIIToUTF16("Local State JSON"), 50 * kOneKilo);
+ return new JSONTest(
+ path, kJSONLocalStateTest, "Local State JSON", 50 * kOneKilobyte);
}
+
+} // namespace diagnostics
diff --git a/chrome/browser/diagnostics/recon_diagnostics.h b/chrome/browser/diagnostics/recon_diagnostics.h
index 3e04601..ac23e55 100644
--- a/chrome/browser/diagnostics/recon_diagnostics.h
+++ b/chrome/browser/diagnostics/recon_diagnostics.h
@@ -7,17 +7,76 @@
#include "chrome/browser/diagnostics/diagnostics_test.h"
-DiagnosticTest* MakeOperatingSystemTest();
-DiagnosticTest* MakeConflictingDllsTest();
-DiagnosticTest* MakeInstallTypeTest();
-DiagnosticTest* MakeVersionTest();
-DiagnosticTest* MakeUserDirTest();
-DiagnosticTest* MakeLocalStateFileTest();
-DiagnosticTest* MakeDictonaryDirTest();
-DiagnosticTest* MakeResourcesFileTest();
-DiagnosticTest* MakeDiskSpaceTest();
-DiagnosticTest* MakePreferencesTest();
-DiagnosticTest* MakeBookMarksTest();
-DiagnosticTest* MakeLocalStateTest();
+namespace diagnostics {
+
+enum OutcomeCodes {
+ DIAG_RECON_SUCCESS,
+
+ // OperatingSystemTest
+ DIAG_RECON_PRE_WINDOW_XP_SP2,
+
+ // ConflictingDllsTest
+ DIAG_RECON_DICTIONARY_LOOKUP_FAILED,
+ DIAG_RECON_NO_STATUS_FIELD,
+ DIAG_RECON_NO_NAME_FIELD,
+ DIAG_RECON_NO_LOCATION_FIELD,
+ DIAG_RECON_CONFLICTING_MODULES,
+ DIAG_RECON_NOT_IMPLEMENTED,
+
+ // InstallTypeTest
+ DIAG_RECON_INSTALL_PATH_PROVIDER,
+
+ // VersionTest
+ DIAG_RECON_NO_VERSION,
+ DIAG_RECON_EMPTY_VERSION,
+
+ // PathTest
+ DIAG_RECON_DEPENDENCY,
+ DIAG_RECON_PATH_PROVIDER,
+ DIAG_RECON_PATH_NOT_FOUND,
+ DIAG_RECON_CANNOT_OBTAIN_SIZE,
+ DIAG_RECON_FILE_TOO_LARGE,
+ DIAG_RECON_NOT_WRITABLE,
+
+ // DiskSpaceTest
+ DIAG_RECON_UNABLE_TO_QUERY,
+ DIAG_RECON_LOW_DISK_SPACE,
+
+ // JSONTest
+ DIAG_RECON_FILE_NOT_FOUND,
+ DIAG_RECON_CANNOT_OBTAIN_FILE_SIZE,
+ DIAG_RECON_FILE_TOO_BIG,
+ DIAG_RECON_UNABLE_TO_OPEN_FILE,
+ DIAG_RECON_PARSE_ERROR,
+};
+
+// Identifiers for the tests.
+extern const char kConflictingDllsTest[];
+extern const char kDiskSpaceTest[];
+extern const char kInstallTypeTest[];
+extern const char kJSONBookmarksTest[];
+extern const char kJSONLocalStateTest[];
+extern const char kJSONProfileTest[];
+extern const char kOperatingSystemTest[];
+extern const char kPathDictionariesTest[];
+extern const char kPathLocalStateTest[];
+extern const char kPathResourcesTest[];
+extern const char kPathUserDataTest[];
+extern const char kVersionTest[];
+
+DiagnosticsTest* MakeOperatingSystemTest();
+DiagnosticsTest* MakeConflictingDllsTest();
+DiagnosticsTest* MakeInstallTypeTest();
+DiagnosticsTest* MakeVersionTest();
+DiagnosticsTest* MakeUserDirTest();
+DiagnosticsTest* MakeLocalStateFileTest();
+DiagnosticsTest* MakeDictonaryDirTest();
+DiagnosticsTest* MakeResourcesFileTest();
+DiagnosticsTest* MakeDiskSpaceTest();
+DiagnosticsTest* MakePreferencesTest();
+DiagnosticsTest* MakeBookMarksTest();
+DiagnosticsTest* MakeLocalStateTest();
+
+} // namespace diagnostics
#endif // CHROME_BROWSER_DIAGNOSTICS_RECON_DIAGNOSTICS_H_
diff --git a/chrome/browser/diagnostics/sqlite_diagnostics.cc b/chrome/browser/diagnostics/sqlite_diagnostics.cc
index e808c5e..ed938d3 100644
--- a/chrome/browser/diagnostics/sqlite_diagnostics.cc
+++ b/chrome/browser/diagnostics/sqlite_diagnostics.cc
@@ -6,13 +6,17 @@
#include "base/file_util.h"
#include "base/logging.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
+#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
+#include "chromeos/chromeos_constants.h"
#include "components/webdata/common/webdata_constants.h"
#include "content/public/common/content_constants.h"
#include "sql/connection.h"
@@ -21,68 +25,159 @@
#include "webkit/browser/database/database_tracker.h"
#include "webkit/common/appcache/appcache_interfaces.h"
+namespace diagnostics {
+
+const char kSQLiteIntegrityAppCacheTest[] = "SQLiteIntegrityAppCache";
+const char kSQLiteIntegrityArchivedHistoryTest[] =
+ "SQLiteIntegrityArchivedHistory";
+const char kSQLiteIntegrityCookieTest[] = "SQLiteIntegrityCookie";
+const char kSQLiteIntegrityDatabaseTrackerTest[] =
+ "SQLiteIntegrityDatabaseTracker";
+const char kSQLiteIntegrityHistoryTest[] = "SQLiteIntegrityHistory";
+const char kSQLiteIntegrityThumbnailsTest[] = "SQLiteIntegrityThumbnails";
+const char kSQLiteIntegrityWebTest[] = "SQLiteIntegrityWeb";
+
+#if defined(OS_CHROMEOS)
+const char kSQLiteIntegrityNSSCertTest[] = "SQLiteIntegrityNSSCert";
+const char kSQLiteIntegrityNSSKeyTest[] = "SQLiteIntegrityNSSKey";
+#endif
+
namespace {
-// Generic diagnostic test class for checking sqlite db integrity.
-class SqliteIntegrityTest : public DiagnosticTest {
+// Generic diagnostic test class for checking SQLite database integrity.
+class SqliteIntegrityTest : public DiagnosticsTest {
public:
- SqliteIntegrityTest(bool critical, const string16& title,
- const base::FilePath& profile_relative_db_path)
- : DiagnosticTest(title),
- critical_(critical),
- db_path_(profile_relative_db_path) {
- }
- virtual int GetId() OVERRIDE { return 0; }
+ SqliteIntegrityTest(bool critical,
+ const std::string& id,
+ const std::string& title,
+ const base::FilePath& db_path)
+ : DiagnosticsTest(id, title), critical_(critical), db_path_(db_path) {}
virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
- base::FilePath path = GetUserDefaultProfileDir();
- path = path.Append(db_path_);
+ // If we're given an absolute path, use it. If not, then assume it's under
+ // the profile directory.
+ base::FilePath path;
+ if (!db_path_.IsAbsolute())
+ path = GetUserDefaultProfileDir().Append(db_path_);
+ else
+ path = db_path_;
+
if (!file_util::PathExists(path)) {
- RecordOutcome(ASCIIToUTF16("File not found"),
- critical_ ? DiagnosticsModel::TEST_FAIL_CONTINUE :
- DiagnosticsModel::TEST_OK);
+ if (critical_) {
+ RecordOutcome(DIAG_SQLITE_FILE_NOT_FOUND,
+ "File not found",
+ DiagnosticsModel::TEST_FAIL_CONTINUE);
+ } else {
+ RecordOutcome(DIAG_SQLITE_FILE_NOT_FOUND_OK,
+ "File not found (but that is OK)",
+ DiagnosticsModel::TEST_OK);
+ }
return true;
}
int errors = 0;
- { // This block scopes the lifetime of the db objects.
- sql::Connection db;
- db.set_exclusive_locking();
- if (!db.Open(path)) {
- RecordFailure(ASCIIToUTF16("Cannot open DB. Possibly corrupted"));
+ { // Scope the statement and database so they close properly.
+ sql::Connection database;
+ database.set_exclusive_locking();
+ scoped_refptr<ErrorRecorder> recorder(new ErrorRecorder);
+
+ // Set the error callback so that we can get useful results in a debug
+ // build for a corrupted database. Without setting the error callback,
+ // sql::Connection will just DCHECK.
+ database.set_error_callback(
+ base::Bind(&SqliteIntegrityTest::ErrorRecorder::RecordSqliteError,
+ recorder->AsWeakPtr(),
+ &database));
+ if (!database.Open(path)) {
+ RecordFailure(DIAG_SQLITE_CANNOT_OPEN_DB,
+ "Cannot open DB. Possibly corrupted");
return true;
}
- sql::Statement s(db.GetUniqueStatement("PRAGMA integrity_check;"));
- if (!s.is_valid()) {
- int error = db.GetErrorCode();
+ if (recorder->has_error()) {
+ RecordFailure(DIAG_SQLITE_ERROR_HANDLER_CALLED,
+ recorder->FormatError());
+ return true;
+ }
+ sql::Statement statement(
+ database.GetUniqueStatement("PRAGMA integrity_check;"));
+ if (recorder->has_error()) {
+ RecordFailure(DIAG_SQLITE_ERROR_HANDLER_CALLED,
+ recorder->FormatError());
+ return true;
+ }
+ if (!statement.is_valid()) {
+ int error = database.GetErrorCode();
if (SQLITE_BUSY == error) {
- RecordFailure(ASCIIToUTF16("DB locked by another process"));
+ RecordFailure(DIAG_SQLITE_DB_LOCKED,
+ "Database locked by another process");
} else {
- string16 str(ASCIIToUTF16("Pragma failed. Error: "));
- str += base::IntToString16(error);
- RecordFailure(str);
+ std::string str("Pragma failed. Error: ");
+ str += base::IntToString(error);
+ RecordFailure(DIAG_SQLITE_PRAGMA_FAILED, str);
}
return false;
}
- while (s.Step()) {
- std::string result(s.ColumnString(0));
+
+ while (statement.Step()) {
+ std::string result(statement.ColumnString(0));
if ("ok" != result)
++errors;
}
+ if (recorder->has_error()) {
+ RecordFailure(DIAG_SQLITE_ERROR_HANDLER_CALLED,
+ recorder->FormatError());
+ return true;
+ }
}
+
// All done. Report to the user.
if (errors != 0) {
- string16 str(ASCIIToUTF16("Database corruption detected :"));
- str += base::IntToString16(errors) + ASCIIToUTF16(" errors");
- RecordFailure(str);
+ std::string str("Database corruption detected: ");
+ str += base::IntToString(errors) + " errors";
+ RecordFailure(DIAG_SQLITE_DB_CORRUPTED, str);
return true;
}
- RecordSuccess(ASCIIToUTF16("no corruption detected"));
+ RecordSuccess("No corruption detected");
return true;
}
private:
+ class ErrorRecorder : public base::RefCounted<ErrorRecorder>,
+ public base::SupportsWeakPtr<ErrorRecorder> {
+ public:
+ ErrorRecorder() : has_error_(false), sqlite_error_(0), last_errno_(0) {}
+
+ void RecordSqliteError(sql::Connection* connection,
+ int sqlite_error,
+ sql::Statement* statement) {
+ has_error_ = true;
+ sqlite_error_ = sqlite_error;
+ last_errno_ = connection->GetLastErrno();
+ message_ = connection->GetErrorMessage();
+ }
+
+ bool has_error() const { return has_error_; }
+
+ std::string FormatError() {
+ return base::StringPrintf("SQLite error: %d, Last Errno: %d: %s",
+ sqlite_error_,
+ last_errno_,
+ message_.c_str());
+ }
+
+ private:
+ friend class base::RefCounted<ErrorRecorder>;
+ ~ErrorRecorder() {}
+
+ bool has_error_;
+ int sqlite_error_;
+ int last_errno_;
+ std::string message_;
+
+ DISALLOW_COPY_AND_ASSIGN(ErrorRecorder);
+ };
+
bool critical_;
base::FilePath db_path_;
DISALLOW_COPY_AND_ASSIGN(SqliteIntegrityTest);
@@ -90,44 +185,77 @@ class SqliteIntegrityTest : public DiagnosticTest {
} // namespace
-DiagnosticTest* MakeSqliteWebDbTest() {
- return new SqliteIntegrityTest(true, ASCIIToUTF16("Web DB"),
+DiagnosticsTest* MakeSqliteWebDbTest() {
+ return new SqliteIntegrityTest(true,
+ kSQLiteIntegrityWebTest,
+ "Web Database",
base::FilePath(kWebDataFilename));
}
-DiagnosticTest* MakeSqliteCookiesDbTest() {
- return new SqliteIntegrityTest(true, ASCIIToUTF16("Cookies DB"),
+DiagnosticsTest* MakeSqliteCookiesDbTest() {
+ return new SqliteIntegrityTest(true,
+ kSQLiteIntegrityCookieTest,
+ "Cookies Database",
base::FilePath(chrome::kCookieFilename));
}
-DiagnosticTest* MakeSqliteHistoryDbTest() {
- return new SqliteIntegrityTest(true, ASCIIToUTF16("History DB"),
+DiagnosticsTest* MakeSqliteHistoryDbTest() {
+ return new SqliteIntegrityTest(true,
+ kSQLiteIntegrityHistoryTest,
+ "History Database",
base::FilePath(chrome::kHistoryFilename));
}
-DiagnosticTest* MakeSqliteArchivedHistoryDbTest() {
+DiagnosticsTest* MakeSqliteArchivedHistoryDbTest() {
return new SqliteIntegrityTest(
- false, ASCIIToUTF16("Archived History DB"),
+ false,
+ kSQLiteIntegrityArchivedHistoryTest,
+ "Archived History Database",
base::FilePath(chrome::kArchivedHistoryFilename));
}
-DiagnosticTest* MakeSqliteThumbnailsDbTest() {
- return new SqliteIntegrityTest(false, ASCIIToUTF16("Thumbnails DB"),
+DiagnosticsTest* MakeSqliteThumbnailsDbTest() {
+ return new SqliteIntegrityTest(false,
+ kSQLiteIntegrityThumbnailsTest,
+ "Thumbnails Database",
base::FilePath(chrome::kThumbnailsFilename));
}
-DiagnosticTest* MakeSqliteAppCacheDbTest() {
+DiagnosticsTest* MakeSqliteAppCacheDbTest() {
base::FilePath appcache_dir(content::kAppCacheDirname);
base::FilePath appcache_db =
appcache_dir.Append(appcache::kAppCacheDatabaseName);
- return new SqliteIntegrityTest(false, ASCIIToUTF16("AppCache DB"),
+ return new SqliteIntegrityTest(false,
+ kSQLiteIntegrityAppCacheTest,
+ "Application Cache Database",
appcache_db);
}
-DiagnosticTest* MakeSqliteWebDatabaseTrackerDbTest() {
+DiagnosticsTest* MakeSqliteWebDatabaseTrackerDbTest() {
base::FilePath databases_dir(webkit_database::kDatabaseDirectoryName);
base::FilePath tracker_db =
databases_dir.Append(webkit_database::kTrackerDatabaseFileName);
- return new SqliteIntegrityTest(false, ASCIIToUTF16("DatabaseTracker DB"),
+ return new SqliteIntegrityTest(false,
+ kSQLiteIntegrityDatabaseTrackerTest,
+ "Database Tracker Database",
tracker_db);
}
+
+#if defined(OS_CHROMEOS)
+DiagnosticsTest* MakeSqliteNssCertDbTest() {
+ base::FilePath home_dir = file_util::GetHomeDir();
+ return new SqliteIntegrityTest(false,
+ kSQLiteIntegrityNSSCertTest,
+ "NSS Certificate Database",
+ home_dir.Append(chromeos::kNssCertDbPath));
+}
+
+DiagnosticsTest* MakeSqliteNssKeyDbTest() {
+ base::FilePath home_dir = file_util::GetHomeDir();
+ return new SqliteIntegrityTest(false,
+ kSQLiteIntegrityNSSKeyTest,
+ "NSS Key Database",
+ home_dir.Append(chromeos::kNssKeyDbPath));
+}
+#endif // defined(OS_CHROMEOS)
+} // namespace diagnostics
diff --git a/chrome/browser/diagnostics/sqlite_diagnostics.h b/chrome/browser/diagnostics/sqlite_diagnostics.h
index 2017c4b..279dd5b 100644
--- a/chrome/browser/diagnostics/sqlite_diagnostics.h
+++ b/chrome/browser/diagnostics/sqlite_diagnostics.h
@@ -7,13 +7,46 @@
#include "chrome/browser/diagnostics/diagnostics_test.h"
-// Factories for the db integrity tests we run in diagnostic mode.
-DiagnosticTest* MakeSqliteWebDbTest();
-DiagnosticTest* MakeSqliteCookiesDbTest();
-DiagnosticTest* MakeSqliteHistoryDbTest();
-DiagnosticTest* MakeSqliteArchivedHistoryDbTest();
-DiagnosticTest* MakeSqliteThumbnailsDbTest();
-DiagnosticTest* MakeSqliteAppCacheDbTest();
-DiagnosticTest* MakeSqliteWebDatabaseTrackerDbTest();
+namespace diagnostics {
+
+enum SQLiteIntegrityOutcomeCode {
+ DIAG_SQLITE_SUCCESS,
+ DIAG_SQLITE_FILE_NOT_FOUND_OK,
+ DIAG_SQLITE_FILE_NOT_FOUND,
+ DIAG_SQLITE_ERROR_HANDLER_CALLED,
+ DIAG_SQLITE_CANNOT_OPEN_DB,
+ DIAG_SQLITE_DB_LOCKED,
+ DIAG_SQLITE_PRAGMA_FAILED,
+ DIAG_SQLITE_DB_CORRUPTED
+};
+
+extern const char kSQLiteIntegrityAppCacheTest[];
+extern const char kSQLiteIntegrityArchivedHistoryTest[];
+extern const char kSQLiteIntegrityCookieTest[];
+extern const char kSQLiteIntegrityDatabaseTrackerTest[];
+extern const char kSQLiteIntegrityHistoryTest[];
+extern const char kSQLiteIntegrityThumbnailsTest[];
+extern const char kSQLiteIntegrityWebTest[];
+
+#if defined(OS_CHROMEOS)
+extern const char kSQLiteIntegrityNSSCertTest[];
+extern const char kSQLiteIntegrityNSSKeyTest[];
+#endif
+
+// Factories for the database integrity tests we run in diagnostic mode.
+DiagnosticsTest* MakeSqliteWebDbTest();
+DiagnosticsTest* MakeSqliteCookiesDbTest();
+DiagnosticsTest* MakeSqliteHistoryDbTest();
+DiagnosticsTest* MakeSqliteArchivedHistoryDbTest();
+DiagnosticsTest* MakeSqliteThumbnailsDbTest();
+DiagnosticsTest* MakeSqliteAppCacheDbTest();
+DiagnosticsTest* MakeSqliteWebDatabaseTrackerDbTest();
+
+#if defined(OS_CHROMEOS)
+DiagnosticsTest* MakeSqliteNssCertDbTest();
+DiagnosticsTest* MakeSqliteNssKeyDbTest();
+#endif // defined(OS_CHROMEOS)
+
+} // namespace diagnostics
#endif // CHROME_BROWSER_DIAGNOSTICS_SQLITE_DIAGNOSTICS_H_
diff --git a/chrome/browser/history/text_database.cc b/chrome/browser/history/text_database.cc
index b37073a..7353174 100644
--- a/chrome/browser/history/text_database.cc
+++ b/chrome/browser/history/text_database.cc
@@ -14,7 +14,6 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/diagnostics/sqlite_diagnostics.h"
#include "sql/statement.h"
#include "sql/transaction.h"
diff --git a/chrome/browser/history/thumbnail_database.cc b/chrome/browser/history/thumbnail_database.cc
index ef5c439..da34646e 100644
--- a/chrome/browser/history/thumbnail_database.cc
+++ b/chrome/browser/history/thumbnail_database.cc
@@ -20,7 +20,6 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
-#include "chrome/browser/diagnostics/sqlite_diagnostics.h"
#include "chrome/browser/history/history_publisher.h"
#include "chrome/browser/history/top_sites.h"
#include "chrome/browser/history/url_database.h"
diff --git a/chrome/browser/history/top_sites_database.cc b/chrome/browser/history/top_sites_database.cc
index ec0e1de..cf4220d 100644
--- a/chrome/browser/history/top_sites_database.cc
+++ b/chrome/browser/history/top_sites_database.cc
@@ -6,7 +6,6 @@
#include "base/memory/ref_counted.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
-#include "chrome/browser/diagnostics/sqlite_diagnostics.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/history/top_sites.h"
#include "chrome/browser/history/top_sites_database.h"
diff --git a/chrome/browser/net/sqlite_server_bound_cert_store.cc b/chrome/browser/net/sqlite_server_bound_cert_store.cc
index fe28561..865d911 100644
--- a/chrome/browser/net/sqlite_server_bound_cert_store.cc
+++ b/chrome/browser/net/sqlite_server_bound_cert_store.cc
@@ -17,7 +17,6 @@
#include "base/strings/string_util.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
-#include "chrome/browser/diagnostics/sqlite_diagnostics.h"
#include "content/public/browser/browser_thread.h"
#include "net/cert/x509_certificate.h"
#include "net/cookies/cookie_util.h"
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index cf0f80e..4852808 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -451,12 +451,14 @@
'browser/custom_home_pages_table_model.h',
'browser/defaults.cc',
'browser/defaults.h',
- 'browser/diagnostics/diagnostics_main.cc',
- 'browser/diagnostics/diagnostics_main.h',
+ 'browser/diagnostics/diagnostics_controller.cc',
+ 'browser/diagnostics/diagnostics_controller.h',
'browser/diagnostics/diagnostics_model.cc',
'browser/diagnostics/diagnostics_model.h',
'browser/diagnostics/diagnostics_test.cc',
'browser/diagnostics/diagnostics_test.h',
+ 'browser/diagnostics/diagnostics_writer.cc',
+ 'browser/diagnostics/diagnostics_writer.h',
'browser/diagnostics/recon_diagnostics.cc',
'browser/diagnostics/recon_diagnostics.h',
'browser/diagnostics/sqlite_diagnostics.cc',
@@ -3000,6 +3002,7 @@
'sources/': [
['exclude', '^browser/captive_portal/'],
['exclude', '^browser/chrome_to_mobile'],
+ ['exclude', '^browser/diagnostics/'],
['exclude', '^browser/first_run/'],
['include', '^browser/first_run/first_run.cc'], # For ctor/dtor of a struct.
['exclude', '^browser/importer/'],
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index ff34e79..1a90cd9 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -2443,6 +2443,7 @@
'sources/': [
['exclude', '^browser/captive_portal/'],
['exclude', '^browser/chrome_to_mobile'],
+ ['exclude', '^browser/diagnostics/'],
['exclude', '^browser/first_run/'],
['exclude', '^browser/importer/'],
['exclude', '^browser/lifetime/'],
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 2453994..fbff304 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -259,6 +259,9 @@ const char kDeviceManagementUrl[] = "device-management-url";
// Triggers a plethora of diagnostic modes.
const char kDiagnostics[] = "diagnostics";
+// Sets the output format for diagnostic modes enabled by diagnostics flag.
+const char kDiagnosticsFormat[] = "diagnostics-format";
+
// Replaces the audio IPC layer for <audio> and <video> with a mock audio
// device, useful when using remote desktop or machines without sound cards.
// This is temporary until we fix the underlying problem.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index f1b9f9a..a320599 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -82,6 +82,7 @@ extern const char kDebugPackedApps[];
extern const char kDebugPrint[];
extern const char kDeviceManagementUrl[];
extern const char kDiagnostics[];
+extern const char kDiagnosticsFormat[];
extern const char kDisableAsyncDns[];
extern const char kDisableAuthNegotiateCnameLookup[];
extern const char kDisableBackgroundMode[];
diff --git a/chromeos/chromeos_constants.cc b/chromeos/chromeos_constants.cc
index a8b58ae..52334b68 100644
--- a/chromeos/chromeos_constants.cc
+++ b/chromeos/chromeos_constants.cc
@@ -9,5 +9,7 @@
namespace chromeos {
const base::FilePath::CharType kDriveCacheDirname[] = FPL("GCache");
+const base::FilePath::CharType kNssCertDbPath[] = FPL(".pki/nssdb/cert9.db");
+const base::FilePath::CharType kNssKeyDbPath[] = FPL(".pki/nssdb/key4.db");
} // namespace chromeos
diff --git a/chromeos/chromeos_constants.h b/chromeos/chromeos_constants.h
index ab3f2be..938ac84 100644
--- a/chromeos/chromeos_constants.h
+++ b/chromeos/chromeos_constants.h
@@ -13,6 +13,8 @@
namespace chromeos {
CHROMEOS_EXPORT extern const base::FilePath::CharType kDriveCacheDirname[];
+CHROMEOS_EXPORT extern const base::FilePath::CharType kNssCertDbPath[];
+CHROMEOS_EXPORT extern const base::FilePath::CharType kNssKeyDbPath[];
} // namespace chromeos