1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/diagnostics/diagnostics_model.h" 6 7 #include <algorithm> 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/command_line.h" 12 #include "base/files/file_path.h" 13 #include "base/path_service.h" 14 #include "base/stl_util.h" 15 #include "base/strings/string_util.h" 16 #include "chrome/browser/diagnostics/diagnostics_test.h" 17 #include "chrome/browser/diagnostics/recon_diagnostics.h" 18 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" 19 #include "chrome/common/chrome_paths.h" 20 #include "chrome/common/chrome_switches.h" 21 22 namespace diagnostics { 23 24 // This is the count of diagnostic tests on each platform. This should 25 // only be used by testing code. 26 #if defined(OS_WIN) 27 const int DiagnosticsModel::kDiagnosticsTestCount = 19; 28 #elif defined(OS_MACOSX) 29 const int DiagnosticsModel::kDiagnosticsTestCount = 15; 30 #elif defined(OS_POSIX) 31 #if defined(OS_CHROMEOS) 32 const int DiagnosticsModel::kDiagnosticsTestCount = 19; 33 #else 34 const int DiagnosticsModel::kDiagnosticsTestCount = 17; 35 #endif 36 #endif 37 38 namespace { 39 40 // Embodies the commonalities of the model across platforms. It manages the 41 // list of tests and can loop over them. The main job of the platform specific 42 // code becomes: 43 // 1- Inserting the appropriate tests into |tests_| 44 // 2- Overriding RunTest() to wrap it with the appropriate fatal exception 45 // handler for the OS. 46 // This class owns the all the tests and will only delete them upon 47 // destruction. 48 class DiagnosticsModelImpl : public DiagnosticsModel { 49 public: 50 DiagnosticsModelImpl() : tests_run_(0) {} 51 52 virtual ~DiagnosticsModelImpl() { 53 STLDeleteElements(&tests_); 54 } 55 56 virtual int GetTestRunCount() const OVERRIDE { 57 return tests_run_; 58 } 59 60 virtual int GetTestAvailableCount() const OVERRIDE { 61 return tests_.size(); 62 } 63 64 virtual void RunAll(DiagnosticsModel::Observer* observer) OVERRIDE { 65 size_t test_count = tests_.size(); 66 for (size_t ix = 0; ix != test_count; ++ix) { 67 bool do_next = RunTest(tests_[ix], observer, ix); 68 ++tests_run_; 69 if (!do_next) 70 break; 71 } 72 if (observer) 73 observer->OnAllTestsDone(this); 74 } 75 76 virtual void RecoverAll(DiagnosticsModel::Observer* observer) OVERRIDE { 77 size_t test_count = tests_.size(); 78 for (size_t i = 0; i != test_count; ++i) { 79 bool do_next = RunRecovery(tests_[i], observer, i); 80 if (!do_next) 81 break; 82 } 83 if (observer) 84 observer->OnAllRecoveryDone(this); 85 } 86 87 virtual const TestInfo& GetTest(size_t index) const OVERRIDE { 88 return *tests_[index]; 89 } 90 91 virtual bool GetTestInfo(const std::string& id, 92 const TestInfo** result) const OVERRIDE { 93 for (size_t i = 0; i < tests_.size(); i++) { 94 if (tests_[i]->GetId() == id) { 95 *result = tests_[i]; 96 return true; 97 } 98 } 99 return false; 100 } 101 102 protected: 103 // Run a particular diagnostic test. Return false if no other tests should be 104 // run. 105 virtual bool RunTest(DiagnosticsTest* test, 106 Observer* observer, 107 size_t index) { 108 return test->Execute(observer, this, index); 109 } 110 111 // Recover from a particular diagnostic test. Return false if no further 112 // recovery should be run. 113 virtual bool RunRecovery(DiagnosticsTest* test, 114 Observer* observer, 115 size_t index) { 116 return test->Recover(observer, this, index); 117 } 118 119 typedef std::vector<DiagnosticsTest*> TestArray; 120 TestArray tests_; 121 int tests_run_; 122 123 private: 124 DISALLOW_COPY_AND_ASSIGN(DiagnosticsModelImpl); 125 }; 126 127 // Each platform can have their own tests. For the time being there is only 128 // one test that works on all platforms. 129 #if defined(OS_WIN) 130 class DiagnosticsModelWin : public DiagnosticsModelImpl { 131 public: 132 DiagnosticsModelWin() { 133 tests_.push_back(MakeOperatingSystemTest()); 134 tests_.push_back(MakeConflictingDllsTest()); 135 tests_.push_back(MakeInstallTypeTest()); 136 tests_.push_back(MakeVersionTest()); 137 tests_.push_back(MakeUserDirTest()); 138 tests_.push_back(MakeLocalStateFileTest()); 139 tests_.push_back(MakeDictonaryDirTest()); 140 tests_.push_back(MakeResourcesFileTest()); 141 tests_.push_back(MakeDiskSpaceTest()); 142 tests_.push_back(MakePreferencesTest()); 143 tests_.push_back(MakeLocalStateTest()); 144 tests_.push_back(MakeBookMarksTest()); 145 tests_.push_back(MakeSqliteWebDbTest()); 146 tests_.push_back(MakeSqliteCookiesDbTest()); 147 tests_.push_back(MakeSqliteHistoryDbTest()); 148 tests_.push_back(MakeSqliteArchivedHistoryDbTest()); 149 tests_.push_back(MakeSqliteThumbnailsDbTest()); 150 tests_.push_back(MakeSqliteAppCacheDbTest()); 151 tests_.push_back(MakeSqliteWebDatabaseTrackerDbTest()); 152 } 153 154 private: 155 DISALLOW_COPY_AND_ASSIGN(DiagnosticsModelWin); 156 }; 157 158 #elif defined(OS_MACOSX) 159 class DiagnosticsModelMac : public DiagnosticsModelImpl { 160 public: 161 DiagnosticsModelMac() { 162 tests_.push_back(MakeInstallTypeTest()); 163 tests_.push_back(MakeUserDirTest()); 164 tests_.push_back(MakeLocalStateFileTest()); 165 tests_.push_back(MakeDictonaryDirTest()); 166 tests_.push_back(MakeDiskSpaceTest()); 167 tests_.push_back(MakePreferencesTest()); 168 tests_.push_back(MakeLocalStateTest()); 169 tests_.push_back(MakeBookMarksTest()); 170 tests_.push_back(MakeSqliteWebDbTest()); 171 tests_.push_back(MakeSqliteCookiesDbTest()); 172 tests_.push_back(MakeSqliteHistoryDbTest()); 173 tests_.push_back(MakeSqliteArchivedHistoryDbTest()); 174 tests_.push_back(MakeSqliteThumbnailsDbTest()); 175 tests_.push_back(MakeSqliteAppCacheDbTest()); 176 tests_.push_back(MakeSqliteWebDatabaseTrackerDbTest()); 177 } 178 179 private: 180 DISALLOW_COPY_AND_ASSIGN(DiagnosticsModelMac); 181 }; 182 183 #elif defined(OS_POSIX) 184 class DiagnosticsModelPosix : public DiagnosticsModelImpl { 185 public: 186 DiagnosticsModelPosix() { 187 tests_.push_back(MakeInstallTypeTest()); 188 tests_.push_back(MakeVersionTest()); 189 tests_.push_back(MakeUserDirTest()); 190 tests_.push_back(MakeLocalStateFileTest()); 191 tests_.push_back(MakeDictonaryDirTest()); 192 tests_.push_back(MakeResourcesFileTest()); 193 tests_.push_back(MakeDiskSpaceTest()); 194 tests_.push_back(MakePreferencesTest()); 195 tests_.push_back(MakeLocalStateTest()); 196 tests_.push_back(MakeBookMarksTest()); 197 tests_.push_back(MakeSqliteWebDbTest()); 198 tests_.push_back(MakeSqliteCookiesDbTest()); 199 tests_.push_back(MakeSqliteHistoryDbTest()); 200 tests_.push_back(MakeSqliteArchivedHistoryDbTest()); 201 tests_.push_back(MakeSqliteThumbnailsDbTest()); 202 tests_.push_back(MakeSqliteAppCacheDbTest()); 203 tests_.push_back(MakeSqliteWebDatabaseTrackerDbTest()); 204 #if defined(OS_CHROMEOS) 205 tests_.push_back(MakeSqliteNssCertDbTest()); 206 tests_.push_back(MakeSqliteNssKeyDbTest()); 207 #endif 208 } 209 210 private: 211 DISALLOW_COPY_AND_ASSIGN(DiagnosticsModelPosix); 212 }; 213 214 #endif 215 216 } // namespace 217 218 DiagnosticsModel* MakeDiagnosticsModel(const CommandLine& cmdline) { 219 base::FilePath user_data_dir = 220 cmdline.GetSwitchValuePath(switches::kUserDataDir); 221 if (!user_data_dir.empty()) 222 PathService::Override(chrome::DIR_USER_DATA, user_data_dir); 223 #if defined(OS_WIN) 224 return new DiagnosticsModelWin(); 225 #elif defined(OS_MACOSX) 226 return new DiagnosticsModelMac(); 227 #elif defined(OS_POSIX) 228 return new DiagnosticsModelPosix(); 229 #endif 230 } 231 232 } // namespace diagnostics 233