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 |