Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(634)

Side by Side Diff: user_collector_test.cc

Issue 3040013: Start invoking core2md to implement full system crash reporting (Closed) Base URL: ssh://git@chromiumos-git//crash-reporter.git
Patch Set: Replace all STREQ macros Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « user_collector.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <gflags/gflags.h> 5 #include <unistd.h>
6 #include <gtest/gtest.h>
7 6
8 #include "base/file_util.h" 7 #include "base/file_util.h"
9 #include "crash-reporter/system_logging_mock.h" 8 #include "crash-reporter/system_logging_mock.h"
10 #include "crash-reporter/user_collector.h" 9 #include "crash-reporter/user_collector.h"
10 #include "gflags/gflags.h"
11 #include "gtest/gtest.h"
11 12
12 int s_crashes = 0; 13 int s_crashes = 0;
13 bool s_metrics = false; 14 bool s_metrics = false;
14 15
15 static const char kFilePath[] = "/my/path"; 16 static const char kFilePath[] = "/my/path";
16 17
17 void CountCrash() { 18 void CountCrash() {
18 ++s_crashes; 19 ++s_crashes;
19 } 20 }
20 21
21 bool IsMetrics() { 22 bool IsMetrics() {
22 return s_metrics; 23 return s_metrics;
23 } 24 }
24 25
25 class UserCollectorTest : public ::testing::Test { 26 class UserCollectorTest : public ::testing::Test {
26 void SetUp() { 27 void SetUp() {
27 s_crashes = 0; 28 s_crashes = 0;
28 collector_.Initialize(CountCrash, 29 collector_.Initialize(CountCrash,
29 kFilePath, 30 kFilePath,
30 IsMetrics, 31 IsMetrics,
31 &logging_); 32 &logging_,
33 false);
32 mkdir("test", 0777); 34 mkdir("test", 0777);
33 collector_.set_core_pattern_file("test/core_pattern"); 35 collector_.set_core_pattern_file("test/core_pattern");
36 pid_ = getpid();
34 } 37 }
35 protected: 38 protected:
39 void TestEnableOK(bool generate_diagnostics);
40
36 SystemLoggingMock logging_; 41 SystemLoggingMock logging_;
37 UserCollector collector_; 42 UserCollector collector_;
43 pid_t pid_;
38 }; 44 };
39 45
40 TEST_F(UserCollectorTest, EnableOK) { 46 TEST_F(UserCollectorTest, EnableOK) {
41 std::string contents; 47 std::string contents;
42 ASSERT_TRUE(collector_.Enable()); 48 ASSERT_TRUE(collector_.Enable());
43 ASSERT_TRUE(file_util::ReadFileToString(FilePath("test/core_pattern"), 49 ASSERT_TRUE(file_util::ReadFileToString(FilePath("test/core_pattern"),
44 &contents)); 50 &contents));
45 ASSERT_STREQ(contents.c_str(), 51 ASSERT_EQ("|/my/path --signal=%s --pid=%p", contents);
46 "|/my/path --signal=%s --pid=%p --exec=%e");
47 ASSERT_EQ(s_crashes, 0); 52 ASSERT_EQ(s_crashes, 0);
48 ASSERT_NE(logging_.log().find("Enabling crash handling"), std::string::npos); 53 ASSERT_NE(logging_.log().find("Enabling crash handling"), std::string::npos);
49 } 54 }
50 55
51 TEST_F(UserCollectorTest, EnableNoFileAccess) { 56 TEST_F(UserCollectorTest, EnableNoFileAccess) {
52 collector_.set_core_pattern_file("/does_not_exist"); 57 collector_.set_core_pattern_file("/does_not_exist");
53 ASSERT_FALSE(collector_.Enable()); 58 ASSERT_FALSE(collector_.Enable());
54 ASSERT_EQ(s_crashes, 0); 59 ASSERT_EQ(s_crashes, 0);
55 ASSERT_NE(logging_.log().find("Enabling crash handling"), std::string::npos); 60 ASSERT_NE(logging_.log().find("Enabling crash handling"), std::string::npos);
56 ASSERT_NE(logging_.log().find("Unable to write /does_not_exist"), 61 ASSERT_NE(logging_.log().find("Unable to write /does_not_exist"),
57 std::string::npos); 62 std::string::npos);
58 } 63 }
59 64
60 TEST_F(UserCollectorTest, DisableOK) { 65 TEST_F(UserCollectorTest, DisableOK) {
61 std::string contents; 66 std::string contents;
62 ASSERT_TRUE(collector_.Disable()); 67 ASSERT_TRUE(collector_.Disable());
63 ASSERT_TRUE(file_util::ReadFileToString(FilePath("test/core_pattern"), 68 ASSERT_TRUE(file_util::ReadFileToString(FilePath("test/core_pattern"),
64 &contents)); 69 &contents));
65 ASSERT_STREQ(contents.c_str(), "core"); 70 ASSERT_EQ("core", contents);
66 ASSERT_EQ(s_crashes, 0); 71 ASSERT_EQ(s_crashes, 0);
67 ASSERT_NE(logging_.log().find("Disabling crash handling"), 72 ASSERT_NE(logging_.log().find("Disabling crash handling"),
68 std::string::npos); 73 std::string::npos);
69 } 74 }
70 75
71 TEST_F(UserCollectorTest, DisableNoFileAccess) { 76 TEST_F(UserCollectorTest, DisableNoFileAccess) {
72 collector_.set_core_pattern_file("/does_not_exist"); 77 collector_.set_core_pattern_file("/does_not_exist");
73 ASSERT_FALSE(collector_.Disable()); 78 ASSERT_FALSE(collector_.Disable());
74 ASSERT_EQ(s_crashes, 0); 79 ASSERT_EQ(s_crashes, 0);
75 ASSERT_NE(logging_.log().find("Disabling crash handling"), std::string::npos); 80 ASSERT_NE(logging_.log().find("Disabling crash handling"), std::string::npos);
76 ASSERT_NE(logging_.log().find("Unable to write /does_not_exist"), 81 ASSERT_NE(logging_.log().find("Unable to write /does_not_exist"),
77 std::string::npos); 82 std::string::npos);
78 } 83 }
79 84
80
81 TEST_F(UserCollectorTest, HandleCrashWithoutMetrics) { 85 TEST_F(UserCollectorTest, HandleCrashWithoutMetrics) {
82 s_metrics = false; 86 s_metrics = false;
83 collector_.HandleCrash(10, 20, "foobar"); 87 collector_.HandleCrash(10, 20, "foobar");
84 ASSERT_NE(logging_.log().find( 88 ASSERT_NE(logging_.log().find(
85 "Received crash notification for foobar[20] sig 10"), 89 "Received crash notification for foobar[20] sig 10"),
86 std::string::npos); 90 std::string::npos);
87 ASSERT_EQ(s_crashes, 0); 91 ASSERT_EQ(s_crashes, 0);
88 } 92 }
89 93
90 TEST_F(UserCollectorTest, HandleCrashWithMetrics) { 94 TEST_F(UserCollectorTest, HandleCrashWithMetrics) {
91 s_metrics = true; 95 s_metrics = true;
92 collector_.HandleCrash(2, 5, "chrome"); 96 collector_.HandleCrash(2, 5, "chrome");
93 ASSERT_NE(logging_.log().find( 97 ASSERT_NE(logging_.log().find(
94 "Received crash notification for chrome[5] sig 2"), 98 "Received crash notification for chrome[5] sig 2"),
95 std::string::npos); 99 std::string::npos);
96 ASSERT_EQ(s_crashes, 1); 100 ASSERT_EQ(s_crashes, 1);
97 } 101 }
98 102
103 TEST_F(UserCollectorTest, GetProcessPath) {
104 FilePath path = collector_.GetProcessPath(100);
105 ASSERT_EQ("/proc/100", path.value());
106 }
107
108 TEST_F(UserCollectorTest, GetSymlinkTarget) {
109 FilePath result;
110 ASSERT_FALSE(collector_.GetSymlinkTarget(FilePath("/does_not_exist"),
111 &result));
112
113 std::string long_link;
114 for (int i = 0; i < 50; ++i)
115 long_link += "0123456789";
116 long_link += "/gold";
117
118 for (size_t len = 1; len <= long_link.size(); ++len) {
119 std::string this_link;
120 static const char kLink[] = "test/this_link";
121 this_link.assign(long_link.c_str(), len);
122 ASSERT_EQ(len, this_link.size());
123 unlink(kLink);
124 ASSERT_EQ(0, symlink(this_link.c_str(), kLink));
125 ASSERT_TRUE(collector_.GetSymlinkTarget(FilePath(kLink), &result));
126 ASSERT_EQ(this_link, result.value());
127 }
128 }
129
130 TEST_F(UserCollectorTest, GetIdFromStatus) {
131 int id = 1;
132 EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId,
133 UserCollector::kIdEffective,
134 "nothing here",
135 &id));
136 EXPECT_EQ(id, 1);
137
138 // Not enough parameters.
139 EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId,
140 UserCollector::kIdReal,
141 "line 1\nUid:\t1\n", &id));
142
143 const char valid_contents[] = "\nUid:\t1\t2\t3\t4\nGid:\t5\t6\t7\t8\n";
144 EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId,
145 UserCollector::kIdReal,
146 valid_contents,
147 &id));
148 EXPECT_EQ(1, id);
149
150 EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId,
151 UserCollector::kIdEffective,
152 valid_contents,
153 &id));
154 EXPECT_EQ(2, id);
155
156 EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId,
157 UserCollector::kIdFileSystem,
158 valid_contents,
159 &id));
160 EXPECT_EQ(4, id);
161
162 EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kGroupId,
163 UserCollector::kIdEffective,
164 valid_contents,
165 &id));
166 EXPECT_EQ(6, id);
167
168 EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kGroupId,
169 UserCollector::kIdSet,
170 valid_contents,
171 &id));
172 EXPECT_EQ(7, id);
173
174 EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kGroupId,
175 UserCollector::IdKind(5),
176 valid_contents,
177 &id));
178 EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kGroupId,
179 UserCollector::IdKind(-1),
180 valid_contents,
181 &id));
182
183 // Fail if junk after number
184 EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId,
185 UserCollector::kIdReal,
186 "Uid:\t1f\t2\t3\t4\n",
187 &id));
188 EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId,
189 UserCollector::kIdReal,
190 "Uid:\t1\t2\t3\t4\n",
191 &id));
192 EXPECT_EQ(1, id);
193
194 // Fail if more than 4 numbers.
195 EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId,
196 UserCollector::kIdReal,
197 "Uid:\t1\t2\t3\t4\t5\n",
198 &id));
199 }
200
201 TEST_F(UserCollectorTest, GetUserInfoFromName) {
202 gid_t gid = 100;
203 uid_t uid = 100;
204 EXPECT_TRUE(collector_.GetUserInfoFromName("root", &uid, &gid));
205 EXPECT_EQ(0, uid);
206 EXPECT_EQ(0, gid);
207 }
208
209 TEST_F(UserCollectorTest, GetCrashDirectoryInfo) {
210 FilePath path;
211 const int kRootUid = 0;
212 const int kRootGid = 0;
213 const int kNtpUid = 5;
214 const int kChronosUid = 1000;
215 const int kChronosGid = 1001;
216 const mode_t kExpectedSystemMode = 01755;
217 const mode_t kExpectedUserMode = 0755;
218
219 mode_t directory_mode;
220 uid_t directory_owner;
221 gid_t directory_group;
222
223 path = collector_.GetCrashDirectoryInfo(kRootUid,
224 kChronosUid,
225 kChronosGid,
226 &directory_mode,
227 &directory_owner,
228 &directory_group);
229 EXPECT_EQ("/var/spool/crash", path.value());
230 EXPECT_EQ(kExpectedSystemMode, directory_mode);
231 EXPECT_EQ(kRootUid, directory_owner);
232 EXPECT_EQ(kRootGid, directory_group);
233
234 path = collector_.GetCrashDirectoryInfo(kNtpUid,
235 kChronosUid,
236 kChronosGid,
237 &directory_mode,
238 &directory_owner,
239 &directory_group);
240 EXPECT_EQ("/var/spool/crash", path.value());
241 EXPECT_EQ(kExpectedSystemMode, directory_mode);
242 EXPECT_EQ(kRootUid, directory_owner);
243 EXPECT_EQ(kRootGid, directory_group);
244
245 path = collector_.GetCrashDirectoryInfo(kChronosUid,
246 kChronosUid,
247 kChronosGid,
248 &directory_mode,
249 &directory_owner,
250 &directory_group);
251 EXPECT_EQ("/home/chronos/user/crash", path.value());
252 EXPECT_EQ(kExpectedUserMode, directory_mode);
253 EXPECT_EQ(kChronosUid, directory_owner);
254 EXPECT_EQ(kChronosGid, directory_group);
255 }
256
257 TEST_F(UserCollectorTest, CopyOffProcFilesBadPath) {
258 // Try a path that is not writable.
259 ASSERT_FALSE(collector_.CopyOffProcFiles(pid_, FilePath("/bad/path")));
260 ASSERT_NE(logging_.log().find(
261 "Could not create /bad/path"),
262 std::string::npos);
263 }
264
265 TEST_F(UserCollectorTest, CopyOffProcFilesBadPid) {
266 FilePath container_path("test/container");
267 ASSERT_FALSE(collector_.CopyOffProcFiles(0, container_path));
268 ASSERT_NE(logging_.log().find(
269 "Path /proc/0 does not exist"),
270 std::string::npos);
271 }
272
273 TEST_F(UserCollectorTest, CopyOffProcFilesOK) {
274 FilePath container_path("test/container");
275 ASSERT_TRUE(collector_.CopyOffProcFiles(pid_, container_path));
276 ASSERT_EQ(logging_.log().find(
277 "Could not copy"), std::string::npos);
278 static struct {
279 const char *name;
280 bool exists;
281 } expectations[] = {
282 { "auxv", true },
283 { "cmdline", true },
284 { "environ", true },
285 { "maps", true },
286 { "mem", false },
287 { "mounts", false },
288 { "sched", false },
289 { "status", true }
290 };
291 for (unsigned i = 0; i < sizeof(expectations)/sizeof(expectations[0]); ++i) {
292 EXPECT_EQ(expectations[i].exists,
293 file_util::PathExists(
294 container_path.Append(expectations[i].name)));
295 }
296 }
297
298 TEST_F(UserCollectorTest, FormatDumpBasename) {
299 struct tm tm = {0};
300 tm.tm_sec = 15;
301 tm.tm_min = 50;
302 tm.tm_hour = 13;
303 tm.tm_mday = 23;
304 tm.tm_mon = 4;
305 tm.tm_year = 110;
306 tm.tm_isdst = -1;
307 std::string basename =
308 collector_.FormatDumpBasename("foo", mktime(&tm), 100);
309 ASSERT_EQ("foo.20100523.135015.100", basename);
310 }
311
99 int main(int argc, char **argv) { 312 int main(int argc, char **argv) {
100 ::testing::InitGoogleTest(&argc, argv); 313 ::testing::InitGoogleTest(&argc, argv);
101 return RUN_ALL_TESTS(); 314 return RUN_ALL_TESTS();
102 } 315 }
OLDNEW
« no previous file with comments | « user_collector.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698