Home | History | Annotate | Download | only in diagnostics
      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