Home | History | Annotate | Download | only in diagnostics
      1 // Copyright 2013 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_controller.h"
      6 
      7 #include "base/base_paths.h"
      8 #include "base/command_line.h"
      9 #include "base/files/file_util.h"
     10 #include "base/files/scoped_temp_dir.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/path_service.h"
     13 #include "chrome/browser/diagnostics/diagnostics_model.h"
     14 #include "chrome/browser/diagnostics/diagnostics_writer.h"
     15 #include "chrome/browser/diagnostics/sqlite_diagnostics.h"
     16 #include "chrome/common/chrome_paths.h"
     17 #include "chrome/common/chrome_switches.h"
     18 #include "chromeos/chromeos_constants.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 namespace diagnostics {
     22 
     23 // Basic harness to acquire and release the required temporary environment to
     24 // run a test in.
     25 class DiagnosticsControllerTest : public testing::Test {
     26  protected:
     27   DiagnosticsControllerTest() : cmdline_(CommandLine::NO_PROGRAM) {}
     28 
     29   virtual ~DiagnosticsControllerTest() {}
     30 
     31   virtual void SetUp() {
     32     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     33     base::FilePath test_data;
     34     PathService::Get(chrome::DIR_TEST_DATA, &test_data);
     35     test_data = test_data.Append(FILE_PATH_LITERAL("diagnostics"));
     36     test_data = test_data.Append(FILE_PATH_LITERAL("user"));
     37     base::CopyDirectory(test_data, temp_dir_.path(), true);
     38     profile_dir_ = temp_dir_.path().Append(FILE_PATH_LITERAL("user"));
     39 
     40 #if defined(OS_CHROMEOS)
     41     // Redirect the home dir to the profile directory. We have to do this
     42     // because NSS uses the HOME directory to find where to store it's database,
     43     // so that's where the diagnostics and recovery code looks for it.
     44     PathService::Get(base::DIR_HOME, &old_home_dir_);
     45     PathService::Override(base::DIR_HOME, profile_dir_);
     46 #endif
     47 
     48     cmdline_ = CommandLine(CommandLine::NO_PROGRAM);
     49     cmdline_.AppendSwitchPath(switches::kUserDataDir, profile_dir_);
     50     cmdline_.AppendSwitch(switches::kDiagnostics);
     51     cmdline_.AppendSwitch(switches::kDiagnosticsRecovery);
     52     writer_.reset();
     53     // Use this writer instead, if you want to see the diagnostics output.
     54     // writer_.reset(new DiagnosticsWriter(DiagnosticsWriter::MACHINE));
     55   }
     56 
     57   virtual void TearDown() {
     58     DiagnosticsController::GetInstance()->ClearResults();
     59 #if defined(OS_CHROMEOS)
     60     PathService::Override(base::DIR_HOME, old_home_dir_);
     61     old_home_dir_.clear();
     62 #endif
     63   }
     64 
     65   void CorruptDataFile(const base::FilePath& path) {
     66     // Just write some random characters into the file tInvaludUsero "corrupt"
     67     // it.
     68     const char bogus_data[] = "wwZ2uNYNuyUVzFbDm3DL";
     69     base::WriteFile(path, bogus_data, arraysize(bogus_data));
     70   }
     71 
     72   scoped_ptr<DiagnosticsModel> model_;
     73   CommandLine cmdline_;
     74   base::ScopedTempDir temp_dir_;
     75   scoped_ptr<DiagnosticsWriter> writer_;
     76   base::FilePath profile_dir_;
     77 
     78 #if defined(OS_CHROMEOS)
     79   base::FilePath old_home_dir_;
     80 #endif
     81 
     82   DISALLOW_COPY_AND_ASSIGN(DiagnosticsControllerTest);
     83 };
     84 
     85 TEST_F(DiagnosticsControllerTest, Diagnostics) {
     86   DiagnosticsController::GetInstance()->Run(cmdline_, writer_.get());
     87   EXPECT_TRUE(DiagnosticsController::GetInstance()->HasResults());
     88   const DiagnosticsModel& results =
     89       DiagnosticsController::GetInstance()->GetResults();
     90   EXPECT_EQ(results.GetTestRunCount(), results.GetTestAvailableCount());
     91   EXPECT_EQ(DiagnosticsModel::kDiagnosticsTestCount, results.GetTestRunCount());
     92   for (int i = 0; i < results.GetTestRunCount(); ++i) {
     93     const DiagnosticsModel::TestInfo& info(results.GetTest(i));
     94     EXPECT_EQ(DiagnosticsModel::TEST_OK, info.GetResult()) << "Test: "
     95                                                            << info.GetName();
     96   }
     97 }
     98 
     99 TEST_F(DiagnosticsControllerTest, RecoverAllOK) {
    100   DiagnosticsController::GetInstance()->Run(cmdline_, writer_.get());
    101   DiagnosticsController::GetInstance()->RunRecovery(cmdline_, writer_.get());
    102   EXPECT_TRUE(DiagnosticsController::GetInstance()->HasResults());
    103   const DiagnosticsModel& results =
    104       DiagnosticsController::GetInstance()->GetResults();
    105   EXPECT_EQ(results.GetTestRunCount(), results.GetTestAvailableCount());
    106   EXPECT_EQ(DiagnosticsModel::kDiagnosticsTestCount, results.GetTestRunCount());
    107   for (int i = 0; i < results.GetTestRunCount(); ++i) {
    108     const DiagnosticsModel::TestInfo& info(results.GetTest(i));
    109     EXPECT_EQ(DiagnosticsModel::RECOVERY_OK, info.GetResult())
    110         << "Test: " << info.GetName();
    111   }
    112 }
    113 
    114 #if defined(OS_CHROMEOS)
    115 TEST_F(DiagnosticsControllerTest, RecoverFromNssCertDbFailure) {
    116   base::FilePath db_path = profile_dir_.Append(chromeos::kNssCertDbPath);
    117   EXPECT_TRUE(base::PathExists(db_path));
    118   CorruptDataFile(db_path);
    119   DiagnosticsController::GetInstance()->Run(cmdline_, writer_.get());
    120   ASSERT_TRUE(DiagnosticsController::GetInstance()->HasResults());
    121   const DiagnosticsModel& results =
    122       DiagnosticsController::GetInstance()->GetResults();
    123   EXPECT_EQ(results.GetTestRunCount(), results.GetTestAvailableCount());
    124   EXPECT_EQ(DiagnosticsModel::kDiagnosticsTestCount, results.GetTestRunCount());
    125 
    126   const DiagnosticsModel::TestInfo* info = NULL;
    127   EXPECT_TRUE(
    128       results.GetTestInfo(DIAGNOSTICS_SQLITE_INTEGRITY_NSS_CERT_TEST, &info));
    129   EXPECT_EQ(DiagnosticsModel::TEST_FAIL_CONTINUE, info->GetResult());
    130   EXPECT_EQ(DIAG_SQLITE_ERROR_HANDLER_CALLED, info->GetOutcomeCode());
    131 
    132   DiagnosticsController::GetInstance()->RunRecovery(cmdline_, writer_.get());
    133   EXPECT_EQ(DiagnosticsModel::RECOVERY_OK, info->GetResult());
    134   EXPECT_FALSE(base::PathExists(db_path));
    135 }
    136 
    137 TEST_F(DiagnosticsControllerTest, RecoverFromNssKeyDbFailure) {
    138   base::FilePath db_path = profile_dir_.Append(chromeos::kNssKeyDbPath);
    139   EXPECT_TRUE(base::PathExists(db_path));
    140   CorruptDataFile(db_path);
    141   DiagnosticsController::GetInstance()->Run(cmdline_, writer_.get());
    142   ASSERT_TRUE(DiagnosticsController::GetInstance()->HasResults());
    143   const DiagnosticsModel& results =
    144       DiagnosticsController::GetInstance()->GetResults();
    145   EXPECT_EQ(results.GetTestRunCount(), results.GetTestAvailableCount());
    146   EXPECT_EQ(DiagnosticsModel::kDiagnosticsTestCount, results.GetTestRunCount());
    147 
    148   const DiagnosticsModel::TestInfo* info = NULL;
    149   EXPECT_TRUE(
    150       results.GetTestInfo(DIAGNOSTICS_SQLITE_INTEGRITY_NSS_KEY_TEST, &info));
    151   EXPECT_EQ(DiagnosticsModel::TEST_FAIL_CONTINUE, info->GetResult());
    152   EXPECT_EQ(DIAG_SQLITE_ERROR_HANDLER_CALLED, info->GetOutcomeCode());
    153 
    154   DiagnosticsController::GetInstance()->RunRecovery(cmdline_, writer_.get());
    155   EXPECT_EQ(DiagnosticsModel::RECOVERY_OK, info->GetResult());
    156   EXPECT_FALSE(base::PathExists(db_path));
    157 }
    158 #endif
    159 
    160 }  // namespace diagnostics
    161