blob: 11c8c0d8257af949d1c7117f04516cc4ab53520b [file] [log] [blame]
Steve Fung6c34c252015-08-20 00:27:30 -07001/*
2 * Copyright (C) 2012 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 */
Ken Mixter03403162010-08-18 15:23:16 -070016
Steve Fung129bea52015-07-23 13:11:15 -070017#include "crash_collector_test.h"
Mike Frysingerf19b5182013-05-17 19:36:47 -040018
Ken Mixter03403162010-08-18 15:23:16 -070019#include <unistd.h>
Steve Fung6e139522015-02-05 14:54:16 -080020#include <utility>
Mike Frysingerf19b5182013-05-17 19:36:47 -040021
Ben Chanab6cc902014-09-05 08:21:06 -070022#include <base/files/file_util.h>
Steve Fung78fcf662016-01-20 01:45:11 -080023#include <base/files/scoped_temp_dir.h>
Ben Chan7e776902014-06-18 13:19:51 -070024#include <base/strings/string_util.h>
25#include <base/strings/stringprintf.h>
Alex Vakulenko74dc6242015-10-13 09:23:34 -070026#include <brillo/syslog_logging.h>
Ben Chan7e776902014-06-18 13:19:51 -070027#include <gtest/gtest.h>
28
Steve Fung129bea52015-07-23 13:11:15 -070029#include "crash_collector.h"
Ken Mixter03403162010-08-18 15:23:16 -070030
Simon Que9f90aca2013-02-19 17:19:52 -080031using base::FilePath;
Mike Frysingera557c112014-02-05 22:55:39 -050032using base::StringPrintf;
Alex Vakulenko74dc6242015-10-13 09:23:34 -070033using brillo::FindLog;
Steve Fung6e139522015-02-05 14:54:16 -080034using ::testing::Invoke;
Mike Frysingerf19b5182013-05-17 19:36:47 -040035using ::testing::Return;
Ken Mixtera3249322011-03-03 08:47:38 -080036
Daniel Eratd257ea12015-01-28 10:23:28 -070037namespace {
38
Ken Mixter03403162010-08-18 15:23:16 -070039void CountCrash() {
40 ADD_FAILURE();
41}
42
43bool IsMetrics() {
44 ADD_FAILURE();
45 return false;
46}
47
Daniel Eratd257ea12015-01-28 10:23:28 -070048} // namespace
49
Ken Mixter03403162010-08-18 15:23:16 -070050class CrashCollectorTest : public ::testing::Test {
Ken Mixter04ec10f2010-08-26 16:02:02 -070051 public:
Ken Mixter03403162010-08-18 15:23:16 -070052 void SetUp() {
Steve Fung6e139522015-02-05 14:54:16 -080053 EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(Return());
54
Lei Zhang9b1f3002014-04-24 02:10:57 -070055 collector_.Initialize(CountCrash, IsMetrics);
Steve Fung78fcf662016-01-20 01:45:11 -080056 EXPECT_TRUE(test_dir_.CreateUniqueTempDir());
Alex Vakulenko74dc6242015-10-13 09:23:34 -070057 brillo::ClearLog();
Ken Mixter03403162010-08-18 15:23:16 -070058 }
Ken Mixter04ec10f2010-08-26 16:02:02 -070059
Ken Mixter04ec10f2010-08-26 16:02:02 -070060 bool CheckHasCapacity();
61
Ken Mixter03403162010-08-18 15:23:16 -070062 protected:
Mike Frysingerf19b5182013-05-17 19:36:47 -040063 CrashCollectorMock collector_;
Steve Fung78fcf662016-01-20 01:45:11 -080064
65 // Temporary directory used for tests.
66 base::ScopedTempDir test_dir_;
Ken Mixter03403162010-08-18 15:23:16 -070067};
68
69TEST_F(CrashCollectorTest, Initialize) {
70 ASSERT_TRUE(CountCrash == collector_.count_crash_function_);
71 ASSERT_TRUE(IsMetrics == collector_.is_feedback_allowed_function_);
Ken Mixter03403162010-08-18 15:23:16 -070072}
73
Ken Mixter9b346472010-11-07 13:45:45 -080074TEST_F(CrashCollectorTest, WriteNewFile) {
Steve Fung78fcf662016-01-20 01:45:11 -080075 FilePath test_file = test_dir_.path().Append("test_new");
Ken Mixter9b346472010-11-07 13:45:45 -080076 const char kBuffer[] = "buffer";
77 EXPECT_EQ(strlen(kBuffer),
78 collector_.WriteNewFile(test_file,
79 kBuffer,
80 strlen(kBuffer)));
81 EXPECT_LT(collector_.WriteNewFile(test_file,
82 kBuffer,
83 strlen(kBuffer)), 0);
84}
85
Ken Mixteree849c52010-09-30 15:30:10 -070086TEST_F(CrashCollectorTest, Sanitize) {
87 EXPECT_EQ("chrome", collector_.Sanitize("chrome"));
88 EXPECT_EQ("CHROME", collector_.Sanitize("CHROME"));
89 EXPECT_EQ("1chrome2", collector_.Sanitize("1chrome2"));
90 EXPECT_EQ("chrome__deleted_", collector_.Sanitize("chrome (deleted)"));
91 EXPECT_EQ("foo_bar", collector_.Sanitize("foo.bar"));
92 EXPECT_EQ("", collector_.Sanitize(""));
93 EXPECT_EQ("_", collector_.Sanitize(" "));
94}
95
Ken Mixter03403162010-08-18 15:23:16 -070096TEST_F(CrashCollectorTest, FormatDumpBasename) {
97 struct tm tm = {0};
98 tm.tm_sec = 15;
99 tm.tm_min = 50;
100 tm.tm_hour = 13;
101 tm.tm_mday = 23;
102 tm.tm_mon = 4;
103 tm.tm_year = 110;
104 tm.tm_isdst = -1;
105 std::string basename =
106 collector_.FormatDumpBasename("foo", mktime(&tm), 100);
107 ASSERT_EQ("foo.20100523.135015.100", basename);
108}
109
Ken Mixter207694d2010-10-28 15:42:37 -0700110TEST_F(CrashCollectorTest, GetCrashPath) {
111 EXPECT_EQ("/var/spool/crash/myprog.20100101.1200.1234.core",
112 collector_.GetCrashPath(FilePath("/var/spool/crash"),
113 "myprog.20100101.1200.1234",
114 "core").value());
115 EXPECT_EQ("/home/chronos/user/crash/chrome.20100101.1200.1234.dmp",
116 collector_.GetCrashPath(FilePath("/home/chronos/user/crash"),
117 "chrome.20100101.1200.1234",
118 "dmp").value());
119}
120
121
Ken Mixter04ec10f2010-08-26 16:02:02 -0700122bool CrashCollectorTest::CheckHasCapacity() {
Steve Fung78fcf662016-01-20 01:45:11 -0800123 const char* kFullMessage =
124 StringPrintf("Crash directory %s already full",
125 test_dir_.path().value().c_str()).c_str();
126 bool has_capacity = collector_.CheckHasCapacity(test_dir_.path());
Ken Mixtera3249322011-03-03 08:47:38 -0800127 bool has_message = FindLog(kFullMessage);
Ken Mixter04ec10f2010-08-26 16:02:02 -0700128 EXPECT_EQ(has_message, !has_capacity);
129 return has_capacity;
130}
131
Ken Mixteree849c52010-09-30 15:30:10 -0700132TEST_F(CrashCollectorTest, CheckHasCapacityUsual) {
133 // Test kMaxCrashDirectorySize - 1 non-meta files can be added.
Ken Mixter04ec10f2010-08-26 16:02:02 -0700134 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800135 base::WriteFile(test_dir_.path().Append(StringPrintf("file%d.core", i)),
136 "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700137 EXPECT_TRUE(CheckHasCapacity());
Ken Mixter04ec10f2010-08-26 16:02:02 -0700138 }
139
Ken Mixteree849c52010-09-30 15:30:10 -0700140 // Test an additional kMaxCrashDirectorySize - 1 meta files fit.
141 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800142 base::WriteFile(test_dir_.path().Append(StringPrintf("file%d.meta", i)),
143 "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700144 EXPECT_TRUE(CheckHasCapacity());
145 }
146
147 // Test an additional kMaxCrashDirectorySize meta files don't fit.
Ken Mixter04ec10f2010-08-26 16:02:02 -0700148 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800149 base::WriteFile(test_dir_.path().Append(StringPrintf("overage%d.meta", i)),
150 "", 0);
Ken Mixter04ec10f2010-08-26 16:02:02 -0700151 EXPECT_FALSE(CheckHasCapacity());
152 }
153}
154
Ken Mixteree849c52010-09-30 15:30:10 -0700155TEST_F(CrashCollectorTest, CheckHasCapacityCorrectBasename) {
156 // Test kMaxCrashDirectorySize - 1 files can be added.
Ken Mixter04ec10f2010-08-26 16:02:02 -0700157 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800158 base::WriteFile(test_dir_.path().Append(StringPrintf("file.%d.core", i)),
159 "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700160 EXPECT_TRUE(CheckHasCapacity());
Ken Mixter04ec10f2010-08-26 16:02:02 -0700161 }
Steve Fung78fcf662016-01-20 01:45:11 -0800162 base::WriteFile(test_dir_.path().Append("file.last.core"), "", 0);
Ken Mixter04ec10f2010-08-26 16:02:02 -0700163 EXPECT_FALSE(CheckHasCapacity());
164}
165
Ken Mixteree849c52010-09-30 15:30:10 -0700166TEST_F(CrashCollectorTest, CheckHasCapacityStrangeNames) {
167 // Test many files with different extensions and same base fit.
168 for (int i = 0; i < 5 * CrashCollector::kMaxCrashDirectorySize; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800169 base::WriteFile(test_dir_.path().Append(StringPrintf("a.%d", i)), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700170 EXPECT_TRUE(CheckHasCapacity());
171 }
172 // Test dot files are treated as individual files.
173 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 2; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800174 base::WriteFile(test_dir_.path().Append(StringPrintf(".file%d", i)), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700175 EXPECT_TRUE(CheckHasCapacity());
176 }
Steve Fung78fcf662016-01-20 01:45:11 -0800177 base::WriteFile(test_dir_.path().Append("normal.meta"), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700178 EXPECT_FALSE(CheckHasCapacity());
179}
180
Ken Mixterafcf8082010-10-26 14:45:01 -0700181TEST_F(CrashCollectorTest, MetaData) {
Ken Mixter9b346472010-11-07 13:45:45 -0800182 const char kMetaFileBasename[] = "generated.meta";
Steve Fung78fcf662016-01-20 01:45:11 -0800183 FilePath meta_file = test_dir_.path().Append(kMetaFileBasename);
184 FilePath payload_file = test_dir_.path().Append("payload-file");
Ken Mixterafcf8082010-10-26 14:45:01 -0700185 std::string contents;
Ken Mixterafcf8082010-10-26 14:45:01 -0700186 const char kPayload[] = "foo";
Ben Chanf30c6412014-05-22 23:09:01 -0700187 ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
Ken Mixterafcf8082010-10-26 14:45:01 -0700188 collector_.AddCrashMetaData("foo", "bar");
189 collector_.WriteCrashMetaData(meta_file, "kernel", payload_file.value());
Mike Frysingera557c112014-02-05 22:55:39 -0500190 EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
Steve Fung78fcf662016-01-20 01:45:11 -0800191 const std::string kExpectedMeta =
192 StringPrintf("foo=bar\n"
193 "exec_name=kernel\n"
194 "payload=%s\n"
195 "payload_size=3\n"
196 "done=1\n",
197 test_dir_.path().Append("payload-file").value().c_str());
Ken Mixter9b346472010-11-07 13:45:45 -0800198 EXPECT_EQ(kExpectedMeta, contents);
199
200 // Test target of symlink is not overwritten.
Steve Fung78fcf662016-01-20 01:45:11 -0800201 payload_file = test_dir_.path().Append("payload2-file");
Ben Chanf30c6412014-05-22 23:09:01 -0700202 ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
Steve Fung78fcf662016-01-20 01:45:11 -0800203 FilePath meta_symlink_path = test_dir_.path().Append("symlink.meta");
Ken Mixter9b346472010-11-07 13:45:45 -0800204 ASSERT_EQ(0,
205 symlink(kMetaFileBasename,
206 meta_symlink_path.value().c_str()));
Mike Frysingera557c112014-02-05 22:55:39 -0500207 ASSERT_TRUE(base::PathExists(meta_symlink_path));
Alex Vakulenko74dc6242015-10-13 09:23:34 -0700208 brillo::ClearLog();
Ken Mixter9b346472010-11-07 13:45:45 -0800209 collector_.WriteCrashMetaData(meta_symlink_path,
210 "kernel",
211 payload_file.value());
Ken Mixtera3249322011-03-03 08:47:38 -0800212 // Target metadata contents should have stayed the same.
Ken Mixter9b346472010-11-07 13:45:45 -0800213 contents.clear();
Mike Frysingera557c112014-02-05 22:55:39 -0500214 EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
Ken Mixter9b346472010-11-07 13:45:45 -0800215 EXPECT_EQ(kExpectedMeta, contents);
Ken Mixtera3249322011-03-03 08:47:38 -0800216 EXPECT_TRUE(FindLog("Unable to write"));
Ken Mixter9b346472010-11-07 13:45:45 -0800217
218 // Test target of dangling symlink is not created.
Mike Frysingera557c112014-02-05 22:55:39 -0500219 base::DeleteFile(meta_file, false);
220 ASSERT_FALSE(base::PathExists(meta_file));
Alex Vakulenko74dc6242015-10-13 09:23:34 -0700221 brillo::ClearLog();
Ken Mixter9b346472010-11-07 13:45:45 -0800222 collector_.WriteCrashMetaData(meta_symlink_path, "kernel",
223 payload_file.value());
Mike Frysingera557c112014-02-05 22:55:39 -0500224 EXPECT_FALSE(base::PathExists(meta_file));
Ken Mixtera3249322011-03-03 08:47:38 -0800225 EXPECT_TRUE(FindLog("Unable to write"));
Ken Mixterafcf8082010-10-26 14:45:01 -0700226}
227
Ken Mixterc49dbd42010-12-14 17:44:11 -0800228TEST_F(CrashCollectorTest, GetLogContents) {
Steve Fung78fcf662016-01-20 01:45:11 -0800229 FilePath config_file = test_dir_.path().Append("crash_config");
230 FilePath output_file = test_dir_.path().Append("crash_log");
Ken Mixterc49dbd42010-12-14 17:44:11 -0800231 const char kConfigContents[] =
Daniel Erat731da332015-01-28 09:48:10 -0700232 "foobar=echo hello there | \\\n sed -e \"s/there/world/\"";
Ken Mixterc49dbd42010-12-14 17:44:11 -0800233 ASSERT_TRUE(
Ben Chanf30c6412014-05-22 23:09:01 -0700234 base::WriteFile(config_file, kConfigContents, strlen(kConfigContents)));
Mike Frysingera557c112014-02-05 22:55:39 -0500235 base::DeleteFile(FilePath(output_file), false);
Ken Mixterc49dbd42010-12-14 17:44:11 -0800236 EXPECT_FALSE(collector_.GetLogContents(config_file,
237 "barfoo",
238 output_file));
Mike Frysingera557c112014-02-05 22:55:39 -0500239 EXPECT_FALSE(base::PathExists(output_file));
240 base::DeleteFile(FilePath(output_file), false);
Ken Mixterc49dbd42010-12-14 17:44:11 -0800241 EXPECT_TRUE(collector_.GetLogContents(config_file,
242 "foobar",
243 output_file));
Mike Frysingera557c112014-02-05 22:55:39 -0500244 ASSERT_TRUE(base::PathExists(output_file));
Ken Mixterc49dbd42010-12-14 17:44:11 -0800245 std::string contents;
Mike Frysingera557c112014-02-05 22:55:39 -0500246 EXPECT_TRUE(base::ReadFileToString(output_file, &contents));
Ken Mixterc49dbd42010-12-14 17:44:11 -0800247 EXPECT_EQ("hello world\n", contents);
248}