| 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 "crash-reporter/system_logging_mock.h" | 8 #include "crash-reporter/system_logging_mock.h" |
| 9 #include "crash-reporter/user_collector.h" | 9 #include "crash-reporter/user_collector.h" |
| 10 #include "gflags/gflags.h" | 10 #include "gflags/gflags.h" |
| 11 #include "gtest/gtest.h" | 11 #include "gtest/gtest.h" |
| 12 | 12 |
| 13 static int s_crashes = 0; | 13 static int s_crashes = 0; |
| 14 static bool s_metrics = false; | 14 static bool s_metrics = false; |
| 15 | 15 |
| 16 static const char kFilePath[] = "/my/path"; | 16 static const char kFilePath[] = "/my/path"; |
| 17 | 17 |
| 18 // This test assumes the following standard binaries are installed. |
| 19 static const char kBinBash[] = "/bin/bash"; |
| 20 static const char kBinCp[] = "/bin/cp"; |
| 21 static const char kBinEcho[] = "/bin/echo"; |
| 22 static const char kBinFalse[] = "/bin/false"; |
| 23 |
| 18 void CountCrash() { | 24 void CountCrash() { |
| 19 ++s_crashes; | 25 ++s_crashes; |
| 20 } | 26 } |
| 21 | 27 |
| 22 bool IsMetrics() { | 28 bool IsMetrics() { |
| 23 return s_metrics; | 29 return s_metrics; |
| 24 } | 30 } |
| 25 | 31 |
| 26 class UserCollectorTest : public ::testing::Test { | 32 class UserCollectorTest : public ::testing::Test { |
| 27 void SetUp() { | 33 void SetUp() { |
| 28 s_crashes = 0; | 34 s_crashes = 0; |
| 29 collector_.Initialize(CountCrash, | 35 collector_.Initialize(CountCrash, |
| 30 kFilePath, | 36 kFilePath, |
| 31 IsMetrics, | 37 IsMetrics, |
| 32 &logging_, | 38 &logging_, |
| 33 false); | 39 false); |
| 34 mkdir("test", 0777); | 40 mkdir("test", 0777); |
| 35 collector_.set_core_pattern_file("test/core_pattern"); | 41 collector_.set_core_pattern_file("test/core_pattern"); |
| 36 pid_ = getpid(); | 42 pid_ = getpid(); |
| 37 } | 43 } |
| 38 protected: | 44 protected: |
| 39 void TestEnableOK(bool generate_diagnostics); | 45 void TestEnableOK(bool generate_diagnostics); |
| 40 | 46 |
| 47 void ExpectFileEquals(const char *golden, |
| 48 const char *file_path) { |
| 49 std::string contents; |
| 50 EXPECT_TRUE(file_util::ReadFileToString(FilePath(file_path), |
| 51 &contents)); |
| 52 EXPECT_EQ(golden, contents); |
| 53 } |
| 54 |
| 41 SystemLoggingMock logging_; | 55 SystemLoggingMock logging_; |
| 42 UserCollector collector_; | 56 UserCollector collector_; |
| 43 pid_t pid_; | 57 pid_t pid_; |
| 44 }; | 58 }; |
| 45 | 59 |
| 46 TEST_F(UserCollectorTest, EnableOK) { | 60 TEST_F(UserCollectorTest, EnableOK) { |
| 47 std::string contents; | |
| 48 ASSERT_TRUE(collector_.Enable()); | 61 ASSERT_TRUE(collector_.Enable()); |
| 49 ASSERT_TRUE(file_util::ReadFileToString(FilePath("test/core_pattern"), | 62 ExpectFileEquals("|/my/path --signal=%s --pid=%p", "test/core_pattern"); |
| 50 &contents)); | |
| 51 ASSERT_EQ("|/my/path --signal=%s --pid=%p", contents); | |
| 52 ASSERT_EQ(s_crashes, 0); | 63 ASSERT_EQ(s_crashes, 0); |
| 53 ASSERT_NE(logging_.log().find("Enabling user crash handling"), | 64 ASSERT_NE(logging_.log().find("Enabling user crash handling"), |
| 54 std::string::npos); | 65 std::string::npos); |
| 55 } | 66 } |
| 56 | 67 |
| 57 TEST_F(UserCollectorTest, EnableNoFileAccess) { | 68 TEST_F(UserCollectorTest, EnableNoFileAccess) { |
| 58 collector_.set_core_pattern_file("/does_not_exist"); | 69 collector_.set_core_pattern_file("/does_not_exist"); |
| 59 ASSERT_FALSE(collector_.Enable()); | 70 ASSERT_FALSE(collector_.Enable()); |
| 60 ASSERT_EQ(s_crashes, 0); | 71 ASSERT_EQ(s_crashes, 0); |
| 61 ASSERT_NE(logging_.log().find("Enabling user crash handling"), | 72 ASSERT_NE(logging_.log().find("Enabling user crash handling"), |
| 62 std::string::npos); | 73 std::string::npos); |
| 63 ASSERT_NE(logging_.log().find("Unable to write /does_not_exist"), | 74 ASSERT_NE(logging_.log().find("Unable to write /does_not_exist"), |
| 64 std::string::npos); | 75 std::string::npos); |
| 65 } | 76 } |
| 66 | 77 |
| 67 TEST_F(UserCollectorTest, DisableOK) { | 78 TEST_F(UserCollectorTest, DisableOK) { |
| 68 std::string contents; | |
| 69 ASSERT_TRUE(collector_.Disable()); | 79 ASSERT_TRUE(collector_.Disable()); |
| 70 ASSERT_TRUE(file_util::ReadFileToString(FilePath("test/core_pattern"), | 80 ExpectFileEquals("core", "test/core_pattern"); |
| 71 &contents)); | |
| 72 ASSERT_EQ("core", contents); | |
| 73 ASSERT_EQ(s_crashes, 0); | 81 ASSERT_EQ(s_crashes, 0); |
| 74 ASSERT_NE(logging_.log().find("Disabling user crash handling"), | 82 ASSERT_NE(logging_.log().find("Disabling user crash handling"), |
| 75 std::string::npos); | 83 std::string::npos); |
| 76 } | 84 } |
| 77 | 85 |
| 78 TEST_F(UserCollectorTest, DisableNoFileAccess) { | 86 TEST_F(UserCollectorTest, DisableNoFileAccess) { |
| 79 collector_.set_core_pattern_file("/does_not_exist"); | 87 collector_.set_core_pattern_file("/does_not_exist"); |
| 80 ASSERT_FALSE(collector_.Disable()); | 88 ASSERT_FALSE(collector_.Disable()); |
| 81 ASSERT_EQ(s_crashes, 0); | 89 ASSERT_EQ(s_crashes, 0); |
| 82 ASSERT_NE(logging_.log().find("Disabling user crash handling"), | 90 ASSERT_NE(logging_.log().find("Disabling user crash handling"), |
| 83 std::string::npos); | 91 std::string::npos); |
| 84 ASSERT_NE(logging_.log().find("Unable to write /does_not_exist"), | 92 ASSERT_NE(logging_.log().find("Unable to write /does_not_exist"), |
| 85 std::string::npos); | 93 std::string::npos); |
| 86 } | 94 } |
| 87 | 95 |
| 96 TEST_F(UserCollectorTest, ForkExecAndPipe) { |
| 97 std::vector<const char *> args; |
| 98 char output_file[] = "test/fork_out"; |
| 99 |
| 100 // Test basic call with stdout. |
| 101 args.clear(); |
| 102 args.push_back(kBinEcho); |
| 103 args.push_back("hello world"); |
| 104 EXPECT_EQ(0, collector_.ForkExecAndPipe(args, output_file)); |
| 105 ExpectFileEquals("hello world\n", output_file); |
| 106 EXPECT_EQ("", logging_.log()); |
| 107 |
| 108 // Test non-zero return value |
| 109 logging_.clear(); |
| 110 args.clear(); |
| 111 args.push_back(kBinFalse); |
| 112 EXPECT_EQ(1, collector_.ForkExecAndPipe(args, output_file)); |
| 113 ExpectFileEquals("", output_file); |
| 114 EXPECT_EQ("", logging_.log()); |
| 115 |
| 116 // Test bad output_file. |
| 117 EXPECT_EQ(127, collector_.ForkExecAndPipe(args, "/bad/path")); |
| 118 |
| 119 // Test bad executable. |
| 120 logging_.clear(); |
| 121 args.clear(); |
| 122 args.push_back("false"); |
| 123 EXPECT_EQ(127, collector_.ForkExecAndPipe(args, output_file)); |
| 124 |
| 125 // Test stderr captured. |
| 126 std::string contents; |
| 127 logging_.clear(); |
| 128 args.clear(); |
| 129 args.push_back(kBinCp); |
| 130 EXPECT_EQ(1, collector_.ForkExecAndPipe(args, output_file)); |
| 131 EXPECT_TRUE(file_util::ReadFileToString(FilePath(output_file), |
| 132 &contents)); |
| 133 EXPECT_NE(std::string::npos, contents.find("missing file operand")); |
| 134 EXPECT_EQ("", logging_.log()); |
| 135 |
| 136 // NULL parameter. |
| 137 logging_.clear(); |
| 138 args.clear(); |
| 139 args.push_back(NULL); |
| 140 EXPECT_EQ(-1, collector_.ForkExecAndPipe(args, output_file)); |
| 141 EXPECT_NE(std::string::npos, |
| 142 logging_.log().find("Bad parameter")); |
| 143 |
| 144 // No parameters. |
| 145 args.clear(); |
| 146 EXPECT_EQ(127, collector_.ForkExecAndPipe(args, output_file)); |
| 147 |
| 148 // Segmentation faulting process. |
| 149 logging_.clear(); |
| 150 args.clear(); |
| 151 args.push_back(kBinBash); |
| 152 args.push_back("-c"); |
| 153 args.push_back("kill -SEGV $$"); |
| 154 EXPECT_EQ(-1, collector_.ForkExecAndPipe(args, output_file)); |
| 155 EXPECT_NE(std::string::npos, |
| 156 logging_.log().find("Process did not exit normally")); |
| 157 } |
| 158 |
| 88 TEST_F(UserCollectorTest, HandleCrashWithoutMetrics) { | 159 TEST_F(UserCollectorTest, HandleCrashWithoutMetrics) { |
| 89 s_metrics = false; | 160 s_metrics = false; |
| 90 collector_.HandleCrash(10, 20, "foobar"); | 161 collector_.HandleCrash(10, 20, "foobar"); |
| 91 ASSERT_NE(logging_.log().find( | 162 ASSERT_NE(logging_.log().find( |
| 92 "Received crash notification for foobar[20] sig 10"), | 163 "Received crash notification for foobar[20] sig 10"), |
| 93 std::string::npos); | 164 std::string::npos); |
| 94 ASSERT_EQ(s_crashes, 0); | 165 ASSERT_EQ(s_crashes, 0); |
| 95 } | 166 } |
| 96 | 167 |
| 97 TEST_F(UserCollectorTest, HandleCrashWithMetrics) { | 168 TEST_F(UserCollectorTest, HandleCrashWithMetrics) { |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 EXPECT_EQ(expectations[i].exists, | 318 EXPECT_EQ(expectations[i].exists, |
| 248 file_util::PathExists( | 319 file_util::PathExists( |
| 249 container_path.Append(expectations[i].name))); | 320 container_path.Append(expectations[i].name))); |
| 250 } | 321 } |
| 251 } | 322 } |
| 252 | 323 |
| 253 int main(int argc, char **argv) { | 324 int main(int argc, char **argv) { |
| 254 ::testing::InitGoogleTest(&argc, argv); | 325 ::testing::InitGoogleTest(&argc, argv); |
| 255 return RUN_ALL_TESTS(); | 326 return RUN_ALL_TESTS(); |
| 256 } | 327 } |
| OLD | NEW |