OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <unistd.h> | 5 #include <unistd.h> |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "chromeos/syslog_logging.h" |
| 10 #include "chromeos/test_helpers.h" |
9 #include "crash-reporter/crash_collector.h" | 11 #include "crash-reporter/crash_collector.h" |
10 #include "crash-reporter/system_logging_mock.h" | |
11 #include "crash-reporter/test_helpers.h" | |
12 #include "gflags/gflags.h" | 12 #include "gflags/gflags.h" |
13 #include "gtest/gtest.h" | 13 #include "gtest/gtest.h" |
14 | 14 |
15 // This test assumes the following standard binaries are installed. | 15 // This test assumes the following standard binaries are installed. |
16 static const char kBinBash[] = "/bin/bash"; | 16 static const char kBinBash[] = "/bin/bash"; |
17 static const char kBinCp[] = "/bin/cp"; | 17 static const char kBinCp[] = "/bin/cp"; |
18 static const char kBinEcho[] = "/bin/echo"; | 18 static const char kBinEcho[] = "/bin/echo"; |
19 static const char kBinFalse[] = "/bin/false"; | 19 static const char kBinFalse[] = "/bin/false"; |
20 | 20 |
21 void CountCrash() { | 21 void CountCrash() { |
22 ADD_FAILURE(); | 22 ADD_FAILURE(); |
23 } | 23 } |
24 | 24 |
25 bool IsMetrics() { | 25 bool IsMetrics() { |
26 ADD_FAILURE(); | 26 ADD_FAILURE(); |
27 return false; | 27 return false; |
28 } | 28 } |
29 | 29 |
30 class CrashCollectorTest : public ::testing::Test { | 30 class CrashCollectorTest : public ::testing::Test { |
31 public: | 31 public: |
32 void SetUp() { | 32 void SetUp() { |
33 collector_.Initialize(CountCrash, | 33 collector_.Initialize(CountCrash, |
34 IsMetrics, | 34 IsMetrics); |
35 &logging_); | |
36 test_dir_ = FilePath("test"); | 35 test_dir_ = FilePath("test"); |
37 file_util::CreateDirectory(test_dir_); | 36 file_util::CreateDirectory(test_dir_); |
| 37 syslog_logging::ClearAccumulatedLog(); |
38 } | 38 } |
39 | 39 |
40 void TearDown() { | 40 void TearDown() { |
41 file_util::Delete(test_dir_, true); | 41 file_util::Delete(test_dir_, true); |
42 } | 42 } |
43 | 43 |
44 bool CheckHasCapacity(); | 44 bool CheckHasCapacity(); |
45 | 45 |
46 protected: | 46 protected: |
47 SystemLoggingMock logging_; | |
48 CrashCollector collector_; | 47 CrashCollector collector_; |
49 FilePath test_dir_; | 48 FilePath test_dir_; |
50 }; | 49 }; |
51 | 50 |
52 TEST_F(CrashCollectorTest, Initialize) { | 51 TEST_F(CrashCollectorTest, Initialize) { |
53 ASSERT_TRUE(CountCrash == collector_.count_crash_function_); | 52 ASSERT_TRUE(CountCrash == collector_.count_crash_function_); |
54 ASSERT_TRUE(IsMetrics == collector_.is_feedback_allowed_function_); | 53 ASSERT_TRUE(IsMetrics == collector_.is_feedback_allowed_function_); |
55 ASSERT_TRUE(&logging_ == collector_.logger_); | |
56 } | 54 } |
57 | 55 |
58 TEST_F(CrashCollectorTest, WriteNewFile) { | 56 TEST_F(CrashCollectorTest, WriteNewFile) { |
59 FilePath test_file = test_dir_.Append("test_new"); | 57 FilePath test_file = test_dir_.Append("test_new"); |
60 const char kBuffer[] = "buffer"; | 58 const char kBuffer[] = "buffer"; |
61 EXPECT_EQ(strlen(kBuffer), | 59 EXPECT_EQ(strlen(kBuffer), |
62 collector_.WriteNewFile(test_file, | 60 collector_.WriteNewFile(test_file, |
63 kBuffer, | 61 kBuffer, |
64 strlen(kBuffer))); | 62 strlen(kBuffer))); |
65 EXPECT_LT(collector_.WriteNewFile(test_file, | 63 EXPECT_LT(collector_.WriteNewFile(test_file, |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 EXPECT_EQ("/home/chronos/user/crash/chrome.20100101.1200.1234.dmp", | 145 EXPECT_EQ("/home/chronos/user/crash/chrome.20100101.1200.1234.dmp", |
148 collector_.GetCrashPath(FilePath("/home/chronos/user/crash"), | 146 collector_.GetCrashPath(FilePath("/home/chronos/user/crash"), |
149 "chrome.20100101.1200.1234", | 147 "chrome.20100101.1200.1234", |
150 "dmp").value()); | 148 "dmp").value()); |
151 } | 149 } |
152 | 150 |
153 | 151 |
154 bool CrashCollectorTest::CheckHasCapacity() { | 152 bool CrashCollectorTest::CheckHasCapacity() { |
155 static const char kFullMessage[] = "Crash directory test already full"; | 153 static const char kFullMessage[] = "Crash directory test already full"; |
156 bool has_capacity = collector_.CheckHasCapacity(test_dir_); | 154 bool has_capacity = collector_.CheckHasCapacity(test_dir_); |
157 bool has_message = (logging_.log().find(kFullMessage) != std::string::npos); | 155 bool has_message = syslog_logging::Contains(kFullMessage); |
158 EXPECT_EQ(has_message, !has_capacity); | 156 EXPECT_EQ(has_message, !has_capacity); |
159 return has_capacity; | 157 return has_capacity; |
160 } | 158 } |
161 | 159 |
162 TEST_F(CrashCollectorTest, CheckHasCapacityUsual) { | 160 TEST_F(CrashCollectorTest, CheckHasCapacityUsual) { |
163 // Test kMaxCrashDirectorySize - 1 non-meta files can be added. | 161 // Test kMaxCrashDirectorySize - 1 non-meta files can be added. |
164 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) { | 162 for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) { |
165 file_util::WriteFile(test_dir_.Append(StringPrintf("file%d.core", i)), | 163 file_util::WriteFile(test_dir_.Append(StringPrintf("file%d.core", i)), |
166 "", 0); | 164 "", 0); |
167 EXPECT_TRUE(CheckHasCapacity()); | 165 EXPECT_TRUE(CheckHasCapacity()); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 // Test target of symlink is not overwritten. | 289 // Test target of symlink is not overwritten. |
292 payload_file = test_dir_.Append("payload2-file"); | 290 payload_file = test_dir_.Append("payload2-file"); |
293 ASSERT_TRUE( | 291 ASSERT_TRUE( |
294 file_util::WriteFile(payload_file, | 292 file_util::WriteFile(payload_file, |
295 kPayload, strlen(kPayload))); | 293 kPayload, strlen(kPayload))); |
296 FilePath meta_symlink_path = test_dir_.Append("symlink.meta"); | 294 FilePath meta_symlink_path = test_dir_.Append("symlink.meta"); |
297 ASSERT_EQ(0, | 295 ASSERT_EQ(0, |
298 symlink(kMetaFileBasename, | 296 symlink(kMetaFileBasename, |
299 meta_symlink_path.value().c_str())); | 297 meta_symlink_path.value().c_str())); |
300 ASSERT_TRUE(file_util::PathExists(meta_symlink_path)); | 298 ASSERT_TRUE(file_util::PathExists(meta_symlink_path)); |
301 logging_.clear(); | 299 syslog_logging::ClearAccumulatedLog(); |
302 collector_.WriteCrashMetaData(meta_symlink_path, | 300 collector_.WriteCrashMetaData(meta_symlink_path, |
303 "kernel", | 301 "kernel", |
304 payload_file.value()); | 302 payload_file.value()); |
305 // Target metadata contents sould have stayed the same. | 303 // Target metadata contents should have stayed the same. |
306 contents.clear(); | 304 contents.clear(); |
307 EXPECT_TRUE(file_util::ReadFileToString(meta_file, &contents)); | 305 EXPECT_TRUE(file_util::ReadFileToString(meta_file, &contents)); |
308 EXPECT_EQ(kExpectedMeta, contents); | 306 EXPECT_EQ(kExpectedMeta, contents); |
309 EXPECT_NE(std::string::npos, logging_.log().find("Unable to write")); | 307 EXPECT_TRUE(syslog_logging::Contains("Unable to write")); |
310 | 308 |
311 // Test target of dangling symlink is not created. | 309 // Test target of dangling symlink is not created. |
312 file_util::Delete(meta_file, false); | 310 file_util::Delete(meta_file, false); |
313 ASSERT_FALSE(file_util::PathExists(meta_file)); | 311 ASSERT_FALSE(file_util::PathExists(meta_file)); |
314 logging_.clear(); | 312 syslog_logging::ClearAccumulatedLog(); |
315 collector_.WriteCrashMetaData(meta_symlink_path, "kernel", | 313 collector_.WriteCrashMetaData(meta_symlink_path, "kernel", |
316 payload_file.value()); | 314 payload_file.value()); |
317 EXPECT_FALSE(file_util::PathExists(meta_file)); | 315 EXPECT_FALSE(file_util::PathExists(meta_file)); |
318 EXPECT_NE(std::string::npos, logging_.log().find("Unable to write")); | 316 EXPECT_TRUE(syslog_logging::Contains("Unable to write")); |
319 } | 317 } |
320 | 318 |
321 TEST_F(CrashCollectorTest, GetLogContents) { | 319 TEST_F(CrashCollectorTest, GetLogContents) { |
322 FilePath config_file = test_dir_.Append("crash_config"); | 320 FilePath config_file = test_dir_.Append("crash_config"); |
323 FilePath output_file = test_dir_.Append("crash_log"); | 321 FilePath output_file = test_dir_.Append("crash_log"); |
324 const char kConfigContents[] = | 322 const char kConfigContents[] = |
325 "foobar:echo hello there | sed -e \"s/there/world/\""; | 323 "foobar:echo hello there | sed -e \"s/there/world/\""; |
326 ASSERT_TRUE( | 324 ASSERT_TRUE( |
327 file_util::WriteFile(config_file, | 325 file_util::WriteFile(config_file, |
328 kConfigContents, strlen(kConfigContents))); | 326 kConfigContents, strlen(kConfigContents))); |
329 file_util::Delete(FilePath(output_file), false); | 327 file_util::Delete(FilePath(output_file), false); |
330 EXPECT_FALSE(collector_.GetLogContents(config_file, | 328 EXPECT_FALSE(collector_.GetLogContents(config_file, |
331 "barfoo", | 329 "barfoo", |
332 output_file)); | 330 output_file)); |
333 EXPECT_FALSE(file_util::PathExists(output_file)); | 331 EXPECT_FALSE(file_util::PathExists(output_file)); |
334 file_util::Delete(FilePath(output_file), false); | 332 file_util::Delete(FilePath(output_file), false); |
335 EXPECT_TRUE(collector_.GetLogContents(config_file, | 333 EXPECT_TRUE(collector_.GetLogContents(config_file, |
336 "foobar", | 334 "foobar", |
337 output_file)); | 335 output_file)); |
338 ASSERT_TRUE(file_util::PathExists(output_file)); | 336 ASSERT_TRUE(file_util::PathExists(output_file)); |
339 std::string contents; | 337 std::string contents; |
340 EXPECT_TRUE(file_util::ReadFileToString(output_file, &contents)); | 338 EXPECT_TRUE(file_util::ReadFileToString(output_file, &contents)); |
341 EXPECT_EQ("hello world\n", contents); | 339 EXPECT_EQ("hello world\n", contents); |
342 } | 340 } |
343 | 341 |
344 class ForkExecAndPipeTest : public CrashCollectorTest { | |
345 public: | |
346 void SetUp() { | |
347 CrashCollectorTest::SetUp(); | |
348 output_file_ = "test/fork_out"; | |
349 file_util::Delete(FilePath(output_file_), false); | |
350 } | |
351 | |
352 void TearDown() { | |
353 CrashCollectorTest::TearDown(); | |
354 } | |
355 | |
356 protected: | |
357 std::vector<const char *> args_; | |
358 const char *output_file_; | |
359 }; | |
360 | |
361 TEST_F(ForkExecAndPipeTest, Basic) { | |
362 args_.push_back(kBinEcho); | |
363 args_.push_back("hello world"); | |
364 EXPECT_EQ(0, collector_.ForkExecAndPipe(args_, output_file_)); | |
365 ExpectFileEquals("hello world\n", output_file_); | |
366 EXPECT_EQ("", logging_.log()); | |
367 } | |
368 | |
369 TEST_F(ForkExecAndPipeTest, NonZeroReturnValue) { | |
370 args_.push_back(kBinFalse); | |
371 EXPECT_EQ(1, collector_.ForkExecAndPipe(args_, output_file_)); | |
372 ExpectFileEquals("", output_file_); | |
373 EXPECT_EQ("", logging_.log()); | |
374 } | |
375 | |
376 TEST_F(ForkExecAndPipeTest, BadOutputFile) { | |
377 EXPECT_EQ(127, collector_.ForkExecAndPipe(args_, "/bad/path")); | |
378 } | |
379 | |
380 TEST_F(ForkExecAndPipeTest, ExistingOutputFile) { | |
381 args_.push_back(kBinEcho); | |
382 args_.push_back("hello world"); | |
383 EXPECT_FALSE(file_util::PathExists(FilePath(output_file_))); | |
384 EXPECT_EQ(0, collector_.ForkExecAndPipe(args_, output_file_)); | |
385 EXPECT_TRUE(file_util::PathExists(FilePath(output_file_))); | |
386 EXPECT_EQ(127, collector_.ForkExecAndPipe(args_, output_file_)); | |
387 } | |
388 | |
389 TEST_F(ForkExecAndPipeTest, BadExecutable) { | |
390 args_.push_back("false"); | |
391 EXPECT_EQ(127, collector_.ForkExecAndPipe(args_, output_file_)); | |
392 } | |
393 | |
394 TEST_F(ForkExecAndPipeTest, StderrCaptured) { | |
395 std::string contents; | |
396 args_.push_back(kBinCp); | |
397 EXPECT_EQ(1, collector_.ForkExecAndPipe(args_, output_file_)); | |
398 EXPECT_TRUE(file_util::ReadFileToString(FilePath(output_file_), | |
399 &contents)); | |
400 EXPECT_NE(std::string::npos, contents.find("missing file operand")); | |
401 EXPECT_EQ("", logging_.log()); | |
402 } | |
403 | |
404 TEST_F(ForkExecAndPipeTest, NULLParam) { | |
405 args_.push_back(NULL); | |
406 EXPECT_EQ(-1, collector_.ForkExecAndPipe(args_, output_file_)); | |
407 EXPECT_NE(std::string::npos, | |
408 logging_.log().find("Bad parameter")); | |
409 } | |
410 | |
411 TEST_F(ForkExecAndPipeTest, NoParams) { | |
412 EXPECT_EQ(127, collector_.ForkExecAndPipe(args_, output_file_)); | |
413 } | |
414 | |
415 TEST_F(ForkExecAndPipeTest, SegFaultHandling) { | |
416 args_.push_back(kBinBash); | |
417 args_.push_back("-c"); | |
418 args_.push_back("kill -SEGV $$"); | |
419 EXPECT_EQ(-1, collector_.ForkExecAndPipe(args_, output_file_)); | |
420 EXPECT_NE(std::string::npos, | |
421 logging_.log().find("Process did not exit normally")); | |
422 } | |
423 | |
424 int main(int argc, char **argv) { | 342 int main(int argc, char **argv) { |
425 ::testing::InitGoogleTest(&argc, argv); | 343 SetUpTests(&argc, argv, false); |
426 return RUN_ALL_TESTS(); | 344 return RUN_ALL_TESTS(); |
427 } | 345 } |
OLD | NEW |