blob: d00a5b512f73d3fced7bf5e7c12c42540e909a3a [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>
Ben Chan7e776902014-06-18 13:19:51 -070023#include <base/strings/string_util.h>
24#include <base/strings/stringprintf.h>
Alex Vakulenko74dc6242015-10-13 09:23:34 -070025#include <brillo/syslog_logging.h>
Ben Chan7e776902014-06-18 13:19:51 -070026#include <gtest/gtest.h>
27
Steve Fung129bea52015-07-23 13:11:15 -070028#include "crash_collector.h"
Ken Mixter03403162010-08-18 15:23:16 -070029
Simon Que9f90aca2013-02-19 17:19:52 -080030using base::FilePath;
Mike Frysingera557c112014-02-05 22:55:39 -050031using base::StringPrintf;
Alex Vakulenko74dc6242015-10-13 09:23:34 -070032using brillo::FindLog;
Steve Fung6e139522015-02-05 14:54:16 -080033using ::testing::Invoke;
Mike Frysingerf19b5182013-05-17 19:36:47 -040034using ::testing::Return;
Ken Mixtera3249322011-03-03 08:47:38 -080035
Daniel Eratd257ea12015-01-28 10:23:28 -070036namespace {
37
Ken Mixter03403162010-08-18 15:23:16 -070038void CountCrash() {
39 ADD_FAILURE();
40}
41
42bool IsMetrics() {
43 ADD_FAILURE();
44 return false;
45}
46
Daniel Eratd257ea12015-01-28 10:23:28 -070047} // namespace
48
Ken Mixter03403162010-08-18 15:23:16 -070049class CrashCollectorTest : public ::testing::Test {
Ken Mixter04ec10f2010-08-26 16:02:02 -070050 public:
Ken Mixter03403162010-08-18 15:23:16 -070051 void SetUp() {
Steve Fung6e139522015-02-05 14:54:16 -080052 EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(Return());
53
Lei Zhang9b1f3002014-04-24 02:10:57 -070054 collector_.Initialize(CountCrash, IsMetrics);
Ken Mixter04ec10f2010-08-26 16:02:02 -070055 test_dir_ = FilePath("test");
Mike Frysingera557c112014-02-05 22:55:39 -050056 base::CreateDirectory(test_dir_);
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
60 void TearDown() {
Mike Frysingera557c112014-02-05 22:55:39 -050061 base::DeleteFile(test_dir_, true);
Ken Mixter04ec10f2010-08-26 16:02:02 -070062 }
63
64 bool CheckHasCapacity();
65
Ken Mixter03403162010-08-18 15:23:16 -070066 protected:
Mike Frysingerf19b5182013-05-17 19:36:47 -040067 CrashCollectorMock collector_;
Ken Mixter04ec10f2010-08-26 16:02:02 -070068 FilePath test_dir_;
Ken Mixter03403162010-08-18 15:23:16 -070069};
70
71TEST_F(CrashCollectorTest, Initialize) {
72 ASSERT_TRUE(CountCrash == collector_.count_crash_function_);
73 ASSERT_TRUE(IsMetrics == collector_.is_feedback_allowed_function_);
Ken Mixter03403162010-08-18 15:23:16 -070074}
75
Ken Mixter9b346472010-11-07 13:45:45 -080076TEST_F(CrashCollectorTest, WriteNewFile) {
77 FilePath test_file = test_dir_.Append("test_new");
78 const char kBuffer[] = "buffer";
79 EXPECT_EQ(strlen(kBuffer),
80 collector_.WriteNewFile(test_file,
81 kBuffer,
82 strlen(kBuffer)));
83 EXPECT_LT(collector_.WriteNewFile(test_file,
84 kBuffer,
85 strlen(kBuffer)), 0);
86}
87
Ken Mixteree849c52010-09-30 15:30:10 -070088TEST_F(CrashCollectorTest, Sanitize) {
89 EXPECT_EQ("chrome", collector_.Sanitize("chrome"));
90 EXPECT_EQ("CHROME", collector_.Sanitize("CHROME"));
91 EXPECT_EQ("1chrome2", collector_.Sanitize("1chrome2"));
92 EXPECT_EQ("chrome__deleted_", collector_.Sanitize("chrome (deleted)"));
93 EXPECT_EQ("foo_bar", collector_.Sanitize("foo.bar"));
94 EXPECT_EQ("", collector_.Sanitize(""));
95 EXPECT_EQ("_", collector_.Sanitize(" "));
96}
97
Ken Mixter03403162010-08-18 15:23:16 -070098TEST_F(CrashCollectorTest, FormatDumpBasename) {
99 struct tm tm = {0};
100 tm.tm_sec = 15;
101 tm.tm_min = 50;
102 tm.tm_hour = 13;
103 tm.tm_mday = 23;
104 tm.tm_mon = 4;
105 tm.tm_year = 110;
106 tm.tm_isdst = -1;
107 std::string basename =
108 collector_.FormatDumpBasename("foo", mktime(&tm), 100);
109 ASSERT_EQ("foo.20100523.135015.100", basename);
110}
111
Ken Mixter207694d2010-10-28 15:42:37 -0700112TEST_F(CrashCollectorTest, GetCrashPath) {
113 EXPECT_EQ("/var/spool/crash/myprog.20100101.1200.1234.core",
114 collector_.GetCrashPath(FilePath("/var/spool/crash"),
115 "myprog.20100101.1200.1234",
116 "core").value());
117 EXPECT_EQ("/home/chronos/user/crash/chrome.20100101.1200.1234.dmp",
118 collector_.GetCrashPath(FilePath("/home/chronos/user/crash"),
119 "chrome.20100101.1200.1234",
120 "dmp").value());
121}
122
123
Ken Mixter04ec10f2010-08-26 16:02:02 -0700124bool CrashCollectorTest::CheckHasCapacity() {
125 static const char kFullMessage[] = "Crash directory test already full";
126 bool has_capacity = collector_.CheckHasCapacity(test_dir_);
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) {
Ben Chanf30c6412014-05-22 23:09:01 -0700135 base::WriteFile(test_dir_.Append(StringPrintf("file%d.core", i)), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700136 EXPECT_TRUE(CheckHasCapacity());
Ken Mixter04ec10f2010-08-26 16:02:02 -0700137 }
138
Ken Mixteree849c52010-09-30 15:30:10 -0700139 // Test an additional kMaxCrashDirectorySize - 1 meta files fit.
140 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
Ben Chanf30c6412014-05-22 23:09:01 -0700141 base::WriteFile(test_dir_.Append(StringPrintf("file%d.meta", i)), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700142 EXPECT_TRUE(CheckHasCapacity());
143 }
144
145 // Test an additional kMaxCrashDirectorySize meta files don't fit.
Ken Mixter04ec10f2010-08-26 16:02:02 -0700146 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize; ++i) {
Ben Chanf30c6412014-05-22 23:09:01 -0700147 base::WriteFile(test_dir_.Append(StringPrintf("overage%d.meta", i)), "", 0);
Ken Mixter04ec10f2010-08-26 16:02:02 -0700148 EXPECT_FALSE(CheckHasCapacity());
149 }
150}
151
Ken Mixteree849c52010-09-30 15:30:10 -0700152TEST_F(CrashCollectorTest, CheckHasCapacityCorrectBasename) {
153 // Test kMaxCrashDirectorySize - 1 files can be added.
Ken Mixter04ec10f2010-08-26 16:02:02 -0700154 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
Ben Chanf30c6412014-05-22 23:09:01 -0700155 base::WriteFile(test_dir_.Append(StringPrintf("file.%d.core", i)), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700156 EXPECT_TRUE(CheckHasCapacity());
Ken Mixter04ec10f2010-08-26 16:02:02 -0700157 }
Ben Chanf30c6412014-05-22 23:09:01 -0700158 base::WriteFile(test_dir_.Append("file.last.core"), "", 0);
Ken Mixter04ec10f2010-08-26 16:02:02 -0700159 EXPECT_FALSE(CheckHasCapacity());
160}
161
Ken Mixteree849c52010-09-30 15:30:10 -0700162TEST_F(CrashCollectorTest, CheckHasCapacityStrangeNames) {
163 // Test many files with different extensions and same base fit.
164 for (int i = 0; i < 5 * CrashCollector::kMaxCrashDirectorySize; ++i) {
Ben Chanf30c6412014-05-22 23:09:01 -0700165 base::WriteFile(test_dir_.Append(StringPrintf("a.%d", i)), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700166 EXPECT_TRUE(CheckHasCapacity());
167 }
168 // Test dot files are treated as individual files.
169 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 2; ++i) {
Ben Chanf30c6412014-05-22 23:09:01 -0700170 base::WriteFile(test_dir_.Append(StringPrintf(".file%d", i)), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700171 EXPECT_TRUE(CheckHasCapacity());
172 }
Ben Chanf30c6412014-05-22 23:09:01 -0700173 base::WriteFile(test_dir_.Append("normal.meta"), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700174 EXPECT_FALSE(CheckHasCapacity());
175}
176
Ken Mixterafcf8082010-10-26 14:45:01 -0700177TEST_F(CrashCollectorTest, MetaData) {
Ken Mixter9b346472010-11-07 13:45:45 -0800178 const char kMetaFileBasename[] = "generated.meta";
179 FilePath meta_file = test_dir_.Append(kMetaFileBasename);
Ken Mixterafcf8082010-10-26 14:45:01 -0700180 FilePath lsb_release = test_dir_.Append("lsb-release");
181 FilePath payload_file = test_dir_.Append("payload-file");
182 std::string contents;
Lei Zhang9b1f3002014-04-24 02:10:57 -0700183 collector_.lsb_release_ = lsb_release.value();
Daniel Erat731da332015-01-28 09:48:10 -0700184 const char kLsbContents[] =
185 "CHROMEOS_RELEASE_BOARD=lumpy\n"
186 "CHROMEOS_RELEASE_VERSION=6727.0.2015_01_26_0853\n"
187 "CHROMEOS_RELEASE_NAME=Chromium OS\n";
Ben Chanf30c6412014-05-22 23:09:01 -0700188 ASSERT_TRUE(base::WriteFile(lsb_release, kLsbContents, strlen(kLsbContents)));
Ken Mixterafcf8082010-10-26 14:45:01 -0700189 const char kPayload[] = "foo";
Ben Chanf30c6412014-05-22 23:09:01 -0700190 ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
Ken Mixterafcf8082010-10-26 14:45:01 -0700191 collector_.AddCrashMetaData("foo", "bar");
192 collector_.WriteCrashMetaData(meta_file, "kernel", payload_file.value());
Mike Frysingera557c112014-02-05 22:55:39 -0500193 EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
Ken Mixter9b346472010-11-07 13:45:45 -0800194 const char kExpectedMeta[] =
195 "foo=bar\n"
196 "exec_name=kernel\n"
Daniel Erat731da332015-01-28 09:48:10 -0700197 "ver=6727.0.2015_01_26_0853\n"
Ken Mixter9b346472010-11-07 13:45:45 -0800198 "payload=test/payload-file\n"
199 "payload_size=3\n"
200 "done=1\n";
201 EXPECT_EQ(kExpectedMeta, contents);
202
203 // Test target of symlink is not overwritten.
204 payload_file = test_dir_.Append("payload2-file");
Ben Chanf30c6412014-05-22 23:09:01 -0700205 ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
Ken Mixter9b346472010-11-07 13:45:45 -0800206 FilePath meta_symlink_path = test_dir_.Append("symlink.meta");
207 ASSERT_EQ(0,
208 symlink(kMetaFileBasename,
209 meta_symlink_path.value().c_str()));
Mike Frysingera557c112014-02-05 22:55:39 -0500210 ASSERT_TRUE(base::PathExists(meta_symlink_path));
Alex Vakulenko74dc6242015-10-13 09:23:34 -0700211 brillo::ClearLog();
Ken Mixter9b346472010-11-07 13:45:45 -0800212 collector_.WriteCrashMetaData(meta_symlink_path,
213 "kernel",
214 payload_file.value());
Ken Mixtera3249322011-03-03 08:47:38 -0800215 // Target metadata contents should have stayed the same.
Ken Mixter9b346472010-11-07 13:45:45 -0800216 contents.clear();
Mike Frysingera557c112014-02-05 22:55:39 -0500217 EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
Ken Mixter9b346472010-11-07 13:45:45 -0800218 EXPECT_EQ(kExpectedMeta, contents);
Ken Mixtera3249322011-03-03 08:47:38 -0800219 EXPECT_TRUE(FindLog("Unable to write"));
Ken Mixter9b346472010-11-07 13:45:45 -0800220
221 // Test target of dangling symlink is not created.
Mike Frysingera557c112014-02-05 22:55:39 -0500222 base::DeleteFile(meta_file, false);
223 ASSERT_FALSE(base::PathExists(meta_file));
Alex Vakulenko74dc6242015-10-13 09:23:34 -0700224 brillo::ClearLog();
Ken Mixter9b346472010-11-07 13:45:45 -0800225 collector_.WriteCrashMetaData(meta_symlink_path, "kernel",
226 payload_file.value());
Mike Frysingera557c112014-02-05 22:55:39 -0500227 EXPECT_FALSE(base::PathExists(meta_file));
Ken Mixtera3249322011-03-03 08:47:38 -0800228 EXPECT_TRUE(FindLog("Unable to write"));
Ken Mixterafcf8082010-10-26 14:45:01 -0700229}
230
Ken Mixterc49dbd42010-12-14 17:44:11 -0800231TEST_F(CrashCollectorTest, GetLogContents) {
232 FilePath config_file = test_dir_.Append("crash_config");
233 FilePath output_file = test_dir_.Append("crash_log");
234 const char kConfigContents[] =
Daniel Erat731da332015-01-28 09:48:10 -0700235 "foobar=echo hello there | \\\n sed -e \"s/there/world/\"";
Ken Mixterc49dbd42010-12-14 17:44:11 -0800236 ASSERT_TRUE(
Ben Chanf30c6412014-05-22 23:09:01 -0700237 base::WriteFile(config_file, kConfigContents, strlen(kConfigContents)));
Mike Frysingera557c112014-02-05 22:55:39 -0500238 base::DeleteFile(FilePath(output_file), false);
Ken Mixterc49dbd42010-12-14 17:44:11 -0800239 EXPECT_FALSE(collector_.GetLogContents(config_file,
240 "barfoo",
241 output_file));
Mike Frysingera557c112014-02-05 22:55:39 -0500242 EXPECT_FALSE(base::PathExists(output_file));
243 base::DeleteFile(FilePath(output_file), false);
Ken Mixterc49dbd42010-12-14 17:44:11 -0800244 EXPECT_TRUE(collector_.GetLogContents(config_file,
245 "foobar",
246 output_file));
Mike Frysingera557c112014-02-05 22:55:39 -0500247 ASSERT_TRUE(base::PathExists(output_file));
Ken Mixterc49dbd42010-12-14 17:44:11 -0800248 std::string contents;
Mike Frysingera557c112014-02-05 22:55:39 -0500249 EXPECT_TRUE(base::ReadFileToString(output_file, &contents));
Ken Mixterc49dbd42010-12-14 17:44:11 -0800250 EXPECT_EQ("hello world\n", contents);
251}