blob: a386cd118262d326e165ba734878832be655051f [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";
James Hawkinsa28317d2016-02-26 11:24:38 -080077 unsigned int numBytesWritten = collector_.WriteNewFile(
78 test_file,
79 kBuffer,
80 strlen(kBuffer));
81 EXPECT_EQ(strlen(kBuffer), numBytesWritten);
Ken Mixter9b346472010-11-07 13:45:45 -080082 EXPECT_LT(collector_.WriteNewFile(test_file,
83 kBuffer,
84 strlen(kBuffer)), 0);
85}
86
Ken Mixteree849c52010-09-30 15:30:10 -070087TEST_F(CrashCollectorTest, Sanitize) {
88 EXPECT_EQ("chrome", collector_.Sanitize("chrome"));
89 EXPECT_EQ("CHROME", collector_.Sanitize("CHROME"));
90 EXPECT_EQ("1chrome2", collector_.Sanitize("1chrome2"));
91 EXPECT_EQ("chrome__deleted_", collector_.Sanitize("chrome (deleted)"));
92 EXPECT_EQ("foo_bar", collector_.Sanitize("foo.bar"));
93 EXPECT_EQ("", collector_.Sanitize(""));
94 EXPECT_EQ("_", collector_.Sanitize(" "));
95}
96
Ken Mixter03403162010-08-18 15:23:16 -070097TEST_F(CrashCollectorTest, FormatDumpBasename) {
James Hawkins69bd21f2016-02-26 15:15:06 -080098 struct tm tm = {};
Ken Mixter03403162010-08-18 15:23:16 -070099 tm.tm_sec = 15;
100 tm.tm_min = 50;
101 tm.tm_hour = 13;
102 tm.tm_mday = 23;
103 tm.tm_mon = 4;
104 tm.tm_year = 110;
105 tm.tm_isdst = -1;
106 std::string basename =
107 collector_.FormatDumpBasename("foo", mktime(&tm), 100);
108 ASSERT_EQ("foo.20100523.135015.100", basename);
109}
110
Ken Mixter207694d2010-10-28 15:42:37 -0700111TEST_F(CrashCollectorTest, GetCrashPath) {
112 EXPECT_EQ("/var/spool/crash/myprog.20100101.1200.1234.core",
113 collector_.GetCrashPath(FilePath("/var/spool/crash"),
114 "myprog.20100101.1200.1234",
115 "core").value());
116 EXPECT_EQ("/home/chronos/user/crash/chrome.20100101.1200.1234.dmp",
117 collector_.GetCrashPath(FilePath("/home/chronos/user/crash"),
118 "chrome.20100101.1200.1234",
119 "dmp").value());
120}
121
122
Ken Mixter04ec10f2010-08-26 16:02:02 -0700123bool CrashCollectorTest::CheckHasCapacity() {
Steve Fung78fcf662016-01-20 01:45:11 -0800124 const char* kFullMessage =
125 StringPrintf("Crash directory %s already full",
126 test_dir_.path().value().c_str()).c_str();
127 bool has_capacity = collector_.CheckHasCapacity(test_dir_.path());
Ken Mixtera3249322011-03-03 08:47:38 -0800128 bool has_message = FindLog(kFullMessage);
Ken Mixter04ec10f2010-08-26 16:02:02 -0700129 EXPECT_EQ(has_message, !has_capacity);
130 return has_capacity;
131}
132
Ken Mixteree849c52010-09-30 15:30:10 -0700133TEST_F(CrashCollectorTest, CheckHasCapacityUsual) {
134 // Test kMaxCrashDirectorySize - 1 non-meta files can be added.
Ken Mixter04ec10f2010-08-26 16:02:02 -0700135 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800136 base::WriteFile(test_dir_.path().Append(StringPrintf("file%d.core", i)),
137 "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700138 EXPECT_TRUE(CheckHasCapacity());
Ken Mixter04ec10f2010-08-26 16:02:02 -0700139 }
140
Ken Mixteree849c52010-09-30 15:30:10 -0700141 // Test an additional kMaxCrashDirectorySize - 1 meta files fit.
142 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800143 base::WriteFile(test_dir_.path().Append(StringPrintf("file%d.meta", i)),
144 "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700145 EXPECT_TRUE(CheckHasCapacity());
146 }
147
148 // Test an additional kMaxCrashDirectorySize meta files don't fit.
Ken Mixter04ec10f2010-08-26 16:02:02 -0700149 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800150 base::WriteFile(test_dir_.path().Append(StringPrintf("overage%d.meta", i)),
151 "", 0);
Ken Mixter04ec10f2010-08-26 16:02:02 -0700152 EXPECT_FALSE(CheckHasCapacity());
153 }
154}
155
Ken Mixteree849c52010-09-30 15:30:10 -0700156TEST_F(CrashCollectorTest, CheckHasCapacityCorrectBasename) {
157 // Test kMaxCrashDirectorySize - 1 files can be added.
Ken Mixter04ec10f2010-08-26 16:02:02 -0700158 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800159 base::WriteFile(test_dir_.path().Append(StringPrintf("file.%d.core", i)),
160 "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700161 EXPECT_TRUE(CheckHasCapacity());
Ken Mixter04ec10f2010-08-26 16:02:02 -0700162 }
Steve Fung78fcf662016-01-20 01:45:11 -0800163 base::WriteFile(test_dir_.path().Append("file.last.core"), "", 0);
Ken Mixter04ec10f2010-08-26 16:02:02 -0700164 EXPECT_FALSE(CheckHasCapacity());
165}
166
Ken Mixteree849c52010-09-30 15:30:10 -0700167TEST_F(CrashCollectorTest, CheckHasCapacityStrangeNames) {
168 // Test many files with different extensions and same base fit.
169 for (int i = 0; i < 5 * CrashCollector::kMaxCrashDirectorySize; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800170 base::WriteFile(test_dir_.path().Append(StringPrintf("a.%d", i)), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700171 EXPECT_TRUE(CheckHasCapacity());
172 }
173 // Test dot files are treated as individual files.
174 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 2; ++i) {
Steve Fung78fcf662016-01-20 01:45:11 -0800175 base::WriteFile(test_dir_.path().Append(StringPrintf(".file%d", i)), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700176 EXPECT_TRUE(CheckHasCapacity());
177 }
Steve Fung78fcf662016-01-20 01:45:11 -0800178 base::WriteFile(test_dir_.path().Append("normal.meta"), "", 0);
Ken Mixteree849c52010-09-30 15:30:10 -0700179 EXPECT_FALSE(CheckHasCapacity());
180}
181
Ken Mixterafcf8082010-10-26 14:45:01 -0700182TEST_F(CrashCollectorTest, MetaData) {
Ken Mixter9b346472010-11-07 13:45:45 -0800183 const char kMetaFileBasename[] = "generated.meta";
Steve Fung78fcf662016-01-20 01:45:11 -0800184 FilePath meta_file = test_dir_.path().Append(kMetaFileBasename);
185 FilePath payload_file = test_dir_.path().Append("payload-file");
Steve Fungb3a48e12016-02-25 03:37:33 -0800186 FilePath osreleased_directory =
187 test_dir_.path().Append("etc").Append("os-release.d");
188 ASSERT_TRUE(base::CreateDirectory(osreleased_directory));
189 collector_.ForceOsReleaseDDirectory(test_dir_.path());
190
Ken Mixterafcf8082010-10-26 14:45:01 -0700191 std::string contents;
Ken Mixterafcf8082010-10-26 14:45:01 -0700192 const char kPayload[] = "foo";
Ben Chanf30c6412014-05-22 23:09:01 -0700193 ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
Steve Fungb3a48e12016-02-25 03:37:33 -0800194 const char kBdkVersion[] = "1";
195 ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("bdk_version"),
196 kBdkVersion,
197 strlen(kBdkVersion)));
198 const char kProductId[] = "baz";
199 ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("product_id"),
200 kProductId,
201 strlen(kProductId)));
202 const char kProductVersion[] = "1.2.3.4";
203 ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("product_version"),
204 kProductVersion,
205 strlen(kProductVersion)));
Ken Mixterafcf8082010-10-26 14:45:01 -0700206 collector_.AddCrashMetaData("foo", "bar");
207 collector_.WriteCrashMetaData(meta_file, "kernel", payload_file.value());
Mike Frysingera557c112014-02-05 22:55:39 -0500208 EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
Steve Fung78fcf662016-01-20 01:45:11 -0800209 const std::string kExpectedMeta =
210 StringPrintf("foo=bar\n"
211 "exec_name=kernel\n"
212 "payload=%s\n"
213 "payload_size=3\n"
Steve Fungb3a48e12016-02-25 03:37:33 -0800214 "bdk_version=1\n"
215 "product_id=baz\n"
216 "product_version=1.2.3.4\n"
Steve Fung78fcf662016-01-20 01:45:11 -0800217 "done=1\n",
218 test_dir_.path().Append("payload-file").value().c_str());
Ken Mixter9b346472010-11-07 13:45:45 -0800219 EXPECT_EQ(kExpectedMeta, contents);
220
221 // Test target of symlink is not overwritten.
Steve Fung78fcf662016-01-20 01:45:11 -0800222 payload_file = test_dir_.path().Append("payload2-file");
Ben Chanf30c6412014-05-22 23:09:01 -0700223 ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
Steve Fung78fcf662016-01-20 01:45:11 -0800224 FilePath meta_symlink_path = test_dir_.path().Append("symlink.meta");
Ken Mixter9b346472010-11-07 13:45:45 -0800225 ASSERT_EQ(0,
226 symlink(kMetaFileBasename,
227 meta_symlink_path.value().c_str()));
Mike Frysingera557c112014-02-05 22:55:39 -0500228 ASSERT_TRUE(base::PathExists(meta_symlink_path));
Alex Vakulenko74dc6242015-10-13 09:23:34 -0700229 brillo::ClearLog();
Ken Mixter9b346472010-11-07 13:45:45 -0800230 collector_.WriteCrashMetaData(meta_symlink_path,
231 "kernel",
232 payload_file.value());
Ken Mixtera3249322011-03-03 08:47:38 -0800233 // Target metadata contents should have stayed the same.
Ken Mixter9b346472010-11-07 13:45:45 -0800234 contents.clear();
Mike Frysingera557c112014-02-05 22:55:39 -0500235 EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
Ken Mixter9b346472010-11-07 13:45:45 -0800236 EXPECT_EQ(kExpectedMeta, contents);
Ken Mixtera3249322011-03-03 08:47:38 -0800237 EXPECT_TRUE(FindLog("Unable to write"));
Ken Mixter9b346472010-11-07 13:45:45 -0800238
239 // Test target of dangling symlink is not created.
Mike Frysingera557c112014-02-05 22:55:39 -0500240 base::DeleteFile(meta_file, false);
241 ASSERT_FALSE(base::PathExists(meta_file));
Alex Vakulenko74dc6242015-10-13 09:23:34 -0700242 brillo::ClearLog();
Ken Mixter9b346472010-11-07 13:45:45 -0800243 collector_.WriteCrashMetaData(meta_symlink_path, "kernel",
244 payload_file.value());
Mike Frysingera557c112014-02-05 22:55:39 -0500245 EXPECT_FALSE(base::PathExists(meta_file));
Ken Mixtera3249322011-03-03 08:47:38 -0800246 EXPECT_TRUE(FindLog("Unable to write"));
Ken Mixterafcf8082010-10-26 14:45:01 -0700247}
248
Ken Mixterc49dbd42010-12-14 17:44:11 -0800249TEST_F(CrashCollectorTest, GetLogContents) {
Steve Fung78fcf662016-01-20 01:45:11 -0800250 FilePath config_file = test_dir_.path().Append("crash_config");
251 FilePath output_file = test_dir_.path().Append("crash_log");
Ken Mixterc49dbd42010-12-14 17:44:11 -0800252 const char kConfigContents[] =
Daniel Erat731da332015-01-28 09:48:10 -0700253 "foobar=echo hello there | \\\n sed -e \"s/there/world/\"";
Ken Mixterc49dbd42010-12-14 17:44:11 -0800254 ASSERT_TRUE(
Ben Chanf30c6412014-05-22 23:09:01 -0700255 base::WriteFile(config_file, kConfigContents, strlen(kConfigContents)));
Mike Frysingera557c112014-02-05 22:55:39 -0500256 base::DeleteFile(FilePath(output_file), false);
Ken Mixterc49dbd42010-12-14 17:44:11 -0800257 EXPECT_FALSE(collector_.GetLogContents(config_file,
258 "barfoo",
259 output_file));
Mike Frysingera557c112014-02-05 22:55:39 -0500260 EXPECT_FALSE(base::PathExists(output_file));
261 base::DeleteFile(FilePath(output_file), false);
Ken Mixterc49dbd42010-12-14 17:44:11 -0800262 EXPECT_TRUE(collector_.GetLogContents(config_file,
263 "foobar",
264 output_file));
Mike Frysingera557c112014-02-05 22:55:39 -0500265 ASSERT_TRUE(base::PathExists(output_file));
Ken Mixterc49dbd42010-12-14 17:44:11 -0800266 std::string contents;
Mike Frysingera557c112014-02-05 22:55:39 -0500267 EXPECT_TRUE(base::ReadFileToString(output_file, &contents));
Ken Mixterc49dbd42010-12-14 17:44:11 -0800268 EXPECT_EQ("hello world\n", contents);
269}