Home | History | Annotate | Download | only in crash_reporter
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "unclean_shutdown_collector.h"
     18 
     19 #include <unistd.h>
     20 
     21 #include <base/files/file_util.h>
     22 #include <base/files/scoped_temp_dir.h>
     23 #include <base/strings/string_util.h>
     24 #include <brillo/syslog_logging.h>
     25 #include <gmock/gmock.h>
     26 #include <gtest/gtest.h>
     27 
     28 using base::FilePath;
     29 using ::brillo::FindLog;
     30 
     31 namespace {
     32 
     33 int s_crashes = 0;
     34 bool s_metrics = true;
     35 
     36 void CountCrash() {
     37   ++s_crashes;
     38 }
     39 
     40 bool IsMetrics() {
     41   return s_metrics;
     42 }
     43 
     44 }  // namespace
     45 
     46 class UncleanShutdownCollectorMock : public UncleanShutdownCollector {
     47  public:
     48   MOCK_METHOD0(SetUpDBus, void());
     49 };
     50 
     51 class UncleanShutdownCollectorTest : public ::testing::Test {
     52   void SetUp() {
     53     s_crashes = 0;
     54 
     55     EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(testing::Return());
     56 
     57     collector_.Initialize(CountCrash,
     58                           IsMetrics);
     59 
     60     EXPECT_TRUE(test_dir_.CreateUniqueTempDir());
     61 
     62     test_directory_ = test_dir_.path().Append("test");
     63     test_unclean_ = test_dir_.path().Append("test/unclean");
     64 
     65     collector_.unclean_shutdown_file_ = test_unclean_.value().c_str();
     66     base::DeleteFile(test_unclean_, true);
     67     // Set up an alternate power manager state file as well
     68     collector_.powerd_suspended_file_ =
     69         test_dir_.path().Append("test/suspended");
     70     brillo::ClearLog();
     71   }
     72 
     73  protected:
     74   void WriteStringToFile(const FilePath &file_path,
     75                          const char *data) {
     76     ASSERT_EQ(strlen(data), base::WriteFile(file_path, data, strlen(data)));
     77   }
     78 
     79   UncleanShutdownCollectorMock collector_;
     80 
     81   // Temporary directory used for tests.
     82   base::ScopedTempDir test_dir_;
     83   FilePath test_directory_;
     84   FilePath test_unclean_;
     85 };
     86 
     87 TEST_F(UncleanShutdownCollectorTest, EnableWithoutParent) {
     88   ASSERT_TRUE(collector_.Enable());
     89   ASSERT_TRUE(base::PathExists(test_unclean_));
     90 }
     91 
     92 TEST_F(UncleanShutdownCollectorTest, EnableWithParent) {
     93   mkdir(test_directory_.value().c_str(), 0777);
     94   ASSERT_TRUE(collector_.Enable());
     95   ASSERT_TRUE(base::PathExists(test_unclean_));
     96 }
     97 
     98 TEST_F(UncleanShutdownCollectorTest, EnableCannotWrite) {
     99   collector_.unclean_shutdown_file_ = "/bad/path";
    100   ASSERT_FALSE(collector_.Enable());
    101   ASSERT_TRUE(FindLog("Unable to create shutdown check file"));
    102 }
    103 
    104 TEST_F(UncleanShutdownCollectorTest, CollectTrue) {
    105   ASSERT_TRUE(collector_.Enable());
    106   ASSERT_TRUE(base::PathExists(test_unclean_));
    107   ASSERT_TRUE(collector_.Collect());
    108   ASSERT_FALSE(base::PathExists(test_unclean_));
    109   ASSERT_EQ(1, s_crashes);
    110   ASSERT_TRUE(FindLog("Last shutdown was not clean"));
    111 }
    112 
    113 TEST_F(UncleanShutdownCollectorTest, CollectFalse) {
    114   ASSERT_FALSE(collector_.Collect());
    115   ASSERT_EQ(0, s_crashes);
    116 }
    117 
    118 TEST_F(UncleanShutdownCollectorTest, CollectDeadBatterySuspended) {
    119   ASSERT_TRUE(collector_.Enable());
    120   ASSERT_TRUE(base::PathExists(test_unclean_));
    121   base::WriteFile(collector_.powerd_suspended_file_, "", 0);
    122   ASSERT_FALSE(collector_.Collect());
    123   ASSERT_FALSE(base::PathExists(test_unclean_));
    124   ASSERT_FALSE(base::PathExists(collector_.powerd_suspended_file_));
    125   ASSERT_EQ(0, s_crashes);
    126   ASSERT_TRUE(FindLog("Unclean shutdown occurred while suspended."));
    127 }
    128 
    129 TEST_F(UncleanShutdownCollectorTest, Disable) {
    130   ASSERT_TRUE(collector_.Enable());
    131   ASSERT_TRUE(base::PathExists(test_unclean_));
    132   ASSERT_TRUE(collector_.Disable());
    133   ASSERT_FALSE(base::PathExists(test_unclean_));
    134   ASSERT_FALSE(collector_.Collect());
    135 }
    136 
    137 TEST_F(UncleanShutdownCollectorTest, DisableWhenNotEnabled) {
    138   ASSERT_TRUE(collector_.Disable());
    139 }
    140 
    141 TEST_F(UncleanShutdownCollectorTest, CantDisable) {
    142   mkdir(test_directory_.value().c_str(), 0700);
    143   if (mkdir(test_unclean_.value().c_str(), 0700)) {
    144     ASSERT_EQ(EEXIST, errno)
    145         << "Error while creating directory '" << test_unclean_.value()
    146         << "': " << strerror(errno);
    147   }
    148   ASSERT_EQ(0, base::WriteFile(test_unclean_.Append("foo"), "", 0))
    149       << "Error while creating empty file '"
    150       << test_unclean_.Append("foo").value() << "': " << strerror(errno);
    151   ASSERT_FALSE(collector_.Disable());
    152   rmdir(test_unclean_.value().c_str());
    153 }
    154