diff options
author | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-20 03:57:10 +0000 |
---|---|---|
committer | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-20 03:57:10 +0000 |
commit | 26f46476feaf3f7a58a92366826fc826315540e3 (patch) | |
tree | c87842e5f7191d8582deeb0d0da8fdfa42f641b9 /chrome | |
parent | 3221491bba46c30ede23f7f43c1ad05523b8ec13 (diff) | |
download | chromium_src-26f46476feaf3f7a58a92366826fc826315540e3.zip chromium_src-26f46476feaf3f7a58a92366826fc826315540e3.tar.gz chromium_src-26f46476feaf3f7a58a92366826fc826315540e3.tar.bz2 |
Add some diagnostic test to diagnostic mode
- Move the one existing test to final location
- Test more critical paths to be accessilbe and writable
- Test the OS version
- Test user or systemwide install type
BUG=27885
TEST=unit test updated
Review URL: http://codereview.chromium.org/504028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35057 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/diagnostics/diagnostics_model.cc | 63 | ||||
-rw-r--r-- | chrome/browser/diagnostics/diagnostics_model_unittest.cc | 27 | ||||
-rw-r--r-- | chrome/browser/diagnostics/diagnostics_test.h | 7 | ||||
-rw-r--r-- | chrome/browser/diagnostics/recon_diagnostics.cc | 196 | ||||
-rw-r--r-- | chrome/browser/diagnostics/recon_diagnostics.h | 21 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 2 |
6 files changed, 268 insertions, 48 deletions
diff --git a/chrome/browser/diagnostics/diagnostics_model.cc b/chrome/browser/diagnostics/diagnostics_model.cc index dc6b35a..54da906 100644 --- a/chrome/browser/diagnostics/diagnostics_model.cc +++ b/chrome/browser/diagnostics/diagnostics_model.cc @@ -13,6 +13,7 @@ #include "base/string_util.h" #include "base/path_service.h" #include "chrome/browser/diagnostics/diagnostics_test.h" +#include "chrome/browser/diagnostics/recon_diagnostics.h" #include "chrome/common/chrome_paths.h" namespace { @@ -45,7 +46,7 @@ class DiagnosticsModelImpl : public DiagnosticsModel { virtual void RunAll(DiagnosticsModel::Observer* observer) { size_t test_count = tests_.size(); for (size_t ix = 0; ix != test_count; ++ix) { - bool do_next = RunTest(tests_[ix], observer); + bool do_next = RunTest(tests_[ix], observer, ix); ++tests_run_; if (!do_next) break; @@ -59,8 +60,8 @@ class DiagnosticsModelImpl : public DiagnosticsModel { protected: // Run a particular test. Return false if no other tests should be run. - virtual bool RunTest(DiagnosticTest* test, Observer* observer) { - return test->Execute(observer, this); + virtual bool RunTest(DiagnosticTest* test, Observer* observer, size_t index) { + return test->Execute(observer, this, index); } typedef std::vector<DiagnosticTest*> TestArray; @@ -71,47 +72,19 @@ class DiagnosticsModelImpl : public DiagnosticsModel { DISALLOW_COPY_AND_ASSIGN(DiagnosticsModelImpl); }; -// Simple basic diagnostic test. Check that the user's data directory -// exists. This test works for all platforms. -// TODO(cpu): Move to its final place. -// TODO(cpu): Localize strings. -class UserPathsTest : public DiagnosticTest { - public: - UserPathsTest() : DiagnosticTest(ASCIIToUTF16("User data Directory")) {} - - // Not used at the moment but it allows one test to query the status - // of another test so we can build test dependencies. - virtual int GetId() { return 0; } - - virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) { - FilePath dir; - if (!PathService::Get(chrome::DIR_USER_DATA, &dir)) { - RecordStopFailure(ASCIIToUTF16("Path provider failure")); - return false; - } - if (!file_util::PathExists(dir)) { - RecordFailure(ASCIIToUTF16("No user data dir found")); - return true; - } - if (!file_util::PathIsWritable(dir)) { - RecordFailure(ASCIIToUTF16("User data dir is not writable")); - return true; - } - RecordSuccess(ASCIIToUTF16("Directory exists and is writable")); - return true; - } - - private: - DISALLOW_COPY_AND_ASSIGN(UserPathsTest); -}; - // Each platform can have their own tests. For the time being there is only // one test that works on all platforms. #if defined(OS_WIN) class DiagnosticsModelWin : public DiagnosticsModelImpl { public: DiagnosticsModelWin() { - tests_.push_back(new UserPathsTest()); + tests_.push_back(MakeWinOsIdTest()); + tests_.push_back(MakeInstallTypeTest()); + tests_.push_back(MakeUserDirTest()); + tests_.push_back(MakeResourceFileTest()); + tests_.push_back(MakeLocalStateFileTest()); + tests_.push_back(MakeDictonaryDirTest()); + tests_.push_back(MakeInspectorDirTest()); } private: @@ -122,7 +95,12 @@ class DiagnosticsModelWin : public DiagnosticsModelImpl { class DiagnosticsModelMac : public DiagnosticsModelImpl { public: DiagnosticsModelMac() { - tests_.push_back(new UserPathsTest()); + tests_.push_back(MakeInstallTypeTest()); + tests_.push_back(MakeUserDirTest()); + tests_.push_back(MakeResourceFileTest()); + tests_.push_back(MakeLocalStateFileTest()); + tests_.push_back(MakeDictonaryDirTest()); + tests_.push_back(MakeInspectorDirTest()); } private: DISALLOW_COPY_AND_ASSIGN(DiagnosticsModelMac); @@ -132,7 +110,12 @@ class DiagnosticsModelMac : public DiagnosticsModelImpl { class DiagnosticsModelLinux : public DiagnosticsModelImpl { public: DiagnosticsModelLinux() { - tests_.push_back(new UserPathsTest()); + tests_.push_back(MakeInstallTypeTest()); + tests_.push_back(MakeUserDirTest()); + tests_.push_back(MakeResourceFileTest()); + tests_.push_back(MakeLocalStateFileTest()); + tests_.push_back(MakeDictonaryDirTest()); + tests_.push_back(MakeInspectorDirTest()); } private: DISALLOW_COPY_AND_ASSIGN(DiagnosticsModelLinux); diff --git a/chrome/browser/diagnostics/diagnostics_model_unittest.cc b/chrome/browser/diagnostics/diagnostics_model_unittest.cc index 442db84..5aef7f4 100644 --- a/chrome/browser/diagnostics/diagnostics_model_unittest.cc +++ b/chrome/browser/diagnostics/diagnostics_model_unittest.cc @@ -27,7 +27,12 @@ class DiagnosticsModelTest : public testing::Test { // The test observer is used to know if the callbacks are being called. class UTObserver: public DiagnosticsModel::Observer { public: - UTObserver() : done_(false), progress_called_(0), finished_(0) {} + UTObserver() + : done_(false), + progress_called_(0), + finished_(0), + id_of_failed_stop_test(-1) { + } virtual void OnProgress(int id, int percent, DiagnosticsModel* model) { EXPECT_TRUE(model != NULL); @@ -41,6 +46,10 @@ class UTObserver: public DiagnosticsModel::Observer { virtual void OnFinished(int id, DiagnosticsModel* model) { EXPECT_TRUE(model != NULL); ++finished_; + if (model->GetTest(id).GetResult() == DiagnosticsModel::TEST_FAIL_STOP) { + id_of_failed_stop_test = id; + ASSERT_TRUE(false); + } } virtual void OnDoneAll(DiagnosticsModel* model) { @@ -58,12 +67,20 @@ class UTObserver: public DiagnosticsModel::Observer { bool done_; int progress_called_; int finished_; + int id_of_failed_stop_test; }; -// Test that the initial state is correct. We only have one test +// We currently have more tests operational on windows. +#if defined(OS_WIN) +const int kDiagnosticsTestCount = 7; +#else +const int kDiagnosticsTestCount = 6; +#endif + +// Test that the initial state is correct. TEST_F(DiagnosticsModelTest, BeforeRun) { int available = model_->GetTestAvailableCount(); - EXPECT_EQ(1, available); + EXPECT_EQ(kDiagnosticsTestCount, available); EXPECT_EQ(0, model_->GetTestRunCount()); EXPECT_EQ(DiagnosticsModel::TEST_NOT_RUN, model_->GetTest(0).GetResult()); } @@ -76,6 +93,6 @@ TEST_F(DiagnosticsModelTest, RunAll) { model_->RunAll(&observer); EXPECT_TRUE(observer.done()); EXPECT_GT(observer.progress_called(), 0); - EXPECT_EQ(1, model_->GetTestRunCount()); - EXPECT_EQ(1, observer.finished()); + EXPECT_EQ(kDiagnosticsTestCount, model_->GetTestRunCount()); + EXPECT_EQ(kDiagnosticsTestCount, observer.finished()); } diff --git a/chrome/browser/diagnostics/diagnostics_test.h b/chrome/browser/diagnostics/diagnostics_test.h index c6b6924..d0a0947 100644 --- a/chrome/browser/diagnostics/diagnostics_test.h +++ b/chrome/browser/diagnostics/diagnostics_test.h @@ -29,11 +29,12 @@ class DiagnosticTest : public DiagnosticsModel::TestInfo { // 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) { + bool Execute(DiagnosticsModel::Observer* observer, DiagnosticsModel* model, + size_t index) { result_ = DiagnosticsModel::TEST_RUNNING; - observer->OnProgress(GetId(), 0, model); + observer->OnProgress(index, 0, model); bool keep_going = ExecuteImpl(observer); - observer->OnFinished(GetId(), model); + observer->OnFinished(index, model); return keep_going; } diff --git a/chrome/browser/diagnostics/recon_diagnostics.cc b/chrome/browser/diagnostics/recon_diagnostics.cc new file mode 100644 index 0000000..7c6bc9b --- /dev/null +++ b/chrome/browser/diagnostics/recon_diagnostics.cc @@ -0,0 +1,196 @@ +// 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. + +#include "base/file_util.h" +#include "base/string_util.h" +#include "base/path_service.h" +#include "chrome/browser/diagnostics/diagnostics_test.h" +#include "chrome/common/chrome_paths.h" +#include "app/app_paths.h" + +#if defined(OS_WIN) +#include "base/win_util.h" +#include "chrome/installer/util/install_util.h" +#endif + +// Reconnaissance diagnostics. These are the first and most critical +// diagnostic tests. Here we check for the existence of critical files. +// TODO(cpu): Define if it makes sense to localize strings. + +namespace { + +class InstallTypeTest; +InstallTypeTest* g_install_type = 0; + +#if defined(OS_WIN) +// Check that we know what flavor of windows is and that is not an +// unsuported operating system. +class WinOSIdTest : public DiagnosticTest { + public: + WinOSIdTest() : DiagnosticTest(ASCIIToUTF16("Operating System")) {} + + virtual int GetId() { return 0; } + + virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) { + win_util::WinVersion version = win_util::GetWinVersion(); + if (version < win_util::WINVERSION_XP) { + RecordFailure(ASCIIToUTF16("Windows 2000 or earlier")); + return false; + } + int major = 0; + int minor = 0; + string16 os_name; + win_util::GetServicePackLevel(&major, &minor); + if ((version == win_util::WINVERSION_XP) && (major < 2)) { + RecordFailure(ASCIIToUTF16("XP Service Pack 1 or earlier")); + return false; + } + RecordSuccess(ASCIIToUTF16(StringPrintf("Windows %d [%d:%d]", + version, major, minor))); + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(WinOSIdTest); +}; + +// Check if it is system install or per-user install. +class InstallTypeTest : public DiagnosticTest { + public: + InstallTypeTest() : DiagnosticTest(ASCIIToUTF16("Install Type")), + user_level_(false) {} + + virtual int GetId() { return 0; } + + virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) { + FilePath chrome_exe; + if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { + RecordFailure(ASCIIToUTF16("Path provider failure")); + return false; + } + user_level_ = InstallUtil::IsPerUserInstall( + chrome_exe.ToWStringHack().c_str()); + string16 install_type(ASCIIToUTF16(user_level_ ? "User Level" : + "System Level")); + RecordSuccess(install_type); + g_install_type = this; + return true; + } + + bool system_level() const { return !user_level_; } + + private: + bool user_level_; + DISALLOW_COPY_AND_ASSIGN(InstallTypeTest); +}; + +#else +// For Mac and Linux we just assume is a system level install. +class InstallTypeTest : public DiagnosticTest { + public: + InstallTypeTest() : DiagnosticTest(ASCIIToUTF16("Install Type")) {} + + virtual int GetId() { return 0; } + + virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) { + g_install_type = this; + RecordSuccess(ASCIIToUTF16("OK")); + return true; + } + + bool system_level() const { return true; } + + private: + DISALLOW_COPY_AND_ASSIGN(InstallTypeTest); +}; +#endif // defined(OS_WIN) + +struct TestPathInfo { + const char* test_name; + int dir_id; + bool test_writable; +}; + +const TestPathInfo kPathsToTest[] = { + {"User data Directory", chrome::DIR_USER_DATA, true}, + {"Local state file", chrome::FILE_LOCAL_STATE, true}, + {"Resources module", chrome::FILE_RESOURCE_MODULE, false}, + {"Dictionaries Directory", chrome::DIR_APP_DICTIONARIES, false}, + {"Inspector Directory", chrome::DIR_INSPECTOR, false} +}; + +// Check that the user's data directory exists and the paths are writeable. +// If it is a systemwide install some paths are not expected to be writeable. +// This test depends on |InstallTypeTest| having run succesfuly. +class PathTest : public DiagnosticTest { + public: + explicit PathTest(const TestPathInfo& path_info) + : DiagnosticTest(ASCIIToUTF16(path_info.test_name)), + path_info_(path_info) {} + + virtual int GetId() { return 0; } + + virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) { + if (!g_install_type) { + RecordStopFailure(ASCIIToUTF16("dependency failure")); + return false; + } + FilePath dir; + if (!PathService::Get(path_info_.dir_id, &dir)) { + RecordStopFailure(ASCIIToUTF16("Path provider failure")); + return false; + } + if (!file_util::PathExists(dir)) { + RecordFailure(ASCIIToUTF16("Path not found")); + return true; + } + if (g_install_type->system_level() && !path_info_.test_writable) { + RecordSuccess(ASCIIToUTF16("Path exists")); + return true; + } + if (!file_util::PathIsWritable(dir)) { + RecordFailure(ASCIIToUTF16("Path is not writable")); + return true; + } + RecordSuccess(ASCIIToUTF16("Path exists and is writable")); + return true; + } + + private: + TestPathInfo path_info_; + DISALLOW_COPY_AND_ASSIGN(PathTest); +}; + +} // namespace + +DiagnosticTest* MakeUserDirTest() { + return new PathTest(kPathsToTest[0]); +} + +DiagnosticTest* MakeLocalStateFileTest() { + return new PathTest(kPathsToTest[1]); +} + +DiagnosticTest* MakeResourceFileTest() { + return new PathTest(kPathsToTest[2]); +} + +DiagnosticTest* MakeDictonaryDirTest() { + return new PathTest(kPathsToTest[3]); +} + +DiagnosticTest* MakeInspectorDirTest() { + return new PathTest(kPathsToTest[4]); +} + +#if defined(OS_WIN) +DiagnosticTest* MakeWinOsIdTest() { + return new WinOSIdTest(); +} +#endif // defined(OS_WIN) + +DiagnosticTest* MakeInstallTypeTest() { + return new InstallTypeTest(); +} + diff --git a/chrome/browser/diagnostics/recon_diagnostics.h b/chrome/browser/diagnostics/recon_diagnostics.h new file mode 100644 index 0000000..f283e1e --- /dev/null +++ b/chrome/browser/diagnostics/recon_diagnostics.h @@ -0,0 +1,21 @@ +// 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_RECON_DIAGNOSTICS_H_ +#define CHROME_BROWSER_DIAGNOSTICS_RECON_DIAGNOSTICS_H_ + +#include "base/string16.h" +#include "chrome/browser/diagnostics/diagnostics_test.h" + +#if defined(OS_WIN) +DiagnosticTest* MakeWinOsIdTest(); +#endif +DiagnosticTest* MakeInstallTypeTest(); +DiagnosticTest* MakeUserDirTest(); +DiagnosticTest* MakeResourceFileTest(); +DiagnosticTest* MakeLocalStateFileTest(); +DiagnosticTest* MakeDictonaryDirTest(); +DiagnosticTest* MakeInspectorDirTest(); + +#endif // CHROME_BROWSER_DIAGNOSTICS_RECON_DIAGNOSTICS_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 71ad681..1214947 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -568,6 +568,8 @@ 'browser/diagnostics/diagnostics_test.h', 'browser/diagnostics/sqlite_diagnostics.cc', 'browser/diagnostics/sqlite_diagnostics.h', + 'browser/diagnostics/recon_diagnostics.cc', + 'browser/diagnostics/recon_diagnostics.h', 'browser/dock_info_gtk.cc', 'browser/dock_info_win.cc', 'browser/dock_info.cc', |