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

Side by Side Diff: components/browser_watcher/postmortem_report_collector_unittest.cc

Issue 2923523002: Decouple stability instrumentation recording and collection (Closed)
Patch Set: Address Siggi's comments Created 3 years, 6 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium 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 "components/browser_watcher/postmortem_report_collector.h" 5 #include "components/browser_watcher/postmortem_report_collector.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <set> 10 #include <set>
(...skipping 22 matching lines...) Expand all
33 #include "third_party/crashpad/crashpad/client/crash_report_database.h" 33 #include "third_party/crashpad/crashpad/client/crash_report_database.h"
34 34
35 namespace browser_watcher { 35 namespace browser_watcher {
36 36
37 using base::debug::ActivityData; 37 using base::debug::ActivityData;
38 using base::debug::ActivityTrackerMemoryAllocator; 38 using base::debug::ActivityTrackerMemoryAllocator;
39 using base::debug::ActivityUserData; 39 using base::debug::ActivityUserData;
40 using base::debug::GlobalActivityTracker; 40 using base::debug::GlobalActivityTracker;
41 using base::debug::ThreadActivityTracker; 41 using base::debug::ThreadActivityTracker;
42 using base::File; 42 using base::File;
43 using base::FilePath;
43 using base::FilePersistentMemoryAllocator; 44 using base::FilePersistentMemoryAllocator;
44 using base::MemoryMappedFile; 45 using base::MemoryMappedFile;
45 using base::PersistentMemoryAllocator; 46 using base::PersistentMemoryAllocator;
46 using base::WrapUnique; 47 using base::WrapUnique;
47 using crashpad::CrashReportDatabase; 48 using crashpad::CrashReportDatabase;
48 using crashpad::Settings; 49 using crashpad::Settings;
49 using crashpad::UUID; 50 using crashpad::UUID;
50 using testing::_; 51 using testing::_;
51 using testing::DoAll; 52 using testing::DoAll;
52 using testing::Return; 53 using testing::Return;
53 using testing::SetArgPointee; 54 using testing::SetArgPointee;
54 55
55 namespace { 56 namespace {
56 57
58 TEST(PostmortemDeleterTest, BasicTest) {
59 base::HistogramTester histogram_tester;
60 base::ScopedTempDir temp_dir;
61 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
62
63 // Create three files.
64 FilePath path_one = temp_dir.GetPath().AppendASCII("a.pma");
65 FilePath path_two = temp_dir.GetPath().AppendASCII("b.pma");
66 FilePath path_three = temp_dir.GetPath().AppendASCII("c.pma");
67
68 std::vector<FilePath> stability_files = {path_one, path_two, path_three};
69
70 for (const FilePath& path : stability_files) {
71 {
72 base::ScopedFILE file(base::OpenFile(path, "w"));
73 ASSERT_NE(file.get(), nullptr);
74 }
75 ASSERT_TRUE(base::PathExists(path));
76 }
77
78 // Open one stability file to prevent its deletion.
79 base::ScopedFILE file(base::OpenFile(path_two, "w"));
80 ASSERT_NE(file.get(), nullptr);
81
82 // Validate deletion and metrics.
83 PostmortemDeleter deleter;
84 deleter.Process(stability_files);
85
86 ASSERT_FALSE(base::PathExists(path_one));
87 ASSERT_FALSE(base::PathExists(path_three));
88 histogram_tester.ExpectBucketCount("ActivityTracker.Collect.Status",
89 UNCLEAN_SHUTDOWN, 2);
90
91 ASSERT_TRUE(base::PathExists(path_two));
92 histogram_tester.ExpectBucketCount("ActivityTracker.Collect.Status",
93 DEBUG_FILE_DELETION_FAILED, 1);
94
95 std::vector<CollectionStatus> unexpected_statuses = {
96 NONE,
97 SUCCESS,
98 ANALYZER_CREATION_FAILED,
99 DEBUG_FILE_NO_DATA,
100 PREPARE_NEW_CRASH_REPORT_FAILED,
101 WRITE_TO_MINIDUMP_FAILED,
102 FINISHED_WRITING_CRASH_REPORT_FAILED,
103 COLLECTION_ATTEMPT};
104 for (CollectionStatus status : unexpected_statuses) {
105 histogram_tester.ExpectBucketCount("ActivityTracker.Collect.Status", status,
106 0);
107 }
108 }
109
57 const char kProductName[] = "TestProduct"; 110 const char kProductName[] = "TestProduct";
58 const char kVersionNumber[] = "TestVersionNumber"; 111 const char kVersionNumber[] = "TestVersionNumber";
59 const char kChannelName[] = "TestChannel"; 112 const char kChannelName[] = "TestChannel";
60 113
61 // The tracker creates some data entries internally. 114 // The tracker creates some data entries internally.
62 const size_t kInternalProcessDatums = 1; 115 const size_t kInternalProcessDatums = 1;
63 116
64 void ContainsKeyValue( 117 void ContainsKeyValue(
65 const google::protobuf::Map<std::string, TypedValue>& data, 118 const google::protobuf::Map<std::string, TypedValue>& data,
66 const std::string& key, 119 const std::string& key,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 MOCK_METHOD2(SkipReportUpload, 159 MOCK_METHOD2(SkipReportUpload,
107 CrashReportDatabase::OperationStatus( 160 CrashReportDatabase::OperationStatus(
108 const UUID& uuid, 161 const UUID& uuid,
109 crashpad::Metrics::CrashSkippedReason reason)); 162 crashpad::Metrics::CrashSkippedReason reason));
110 MOCK_METHOD1(DeleteReport, 163 MOCK_METHOD1(DeleteReport,
111 CrashReportDatabase::OperationStatus(const UUID& uuid)); 164 CrashReportDatabase::OperationStatus(const UUID& uuid));
112 MOCK_METHOD1(RequestUpload, 165 MOCK_METHOD1(RequestUpload,
113 CrashReportDatabase::OperationStatus(const UUID& uuid)); 166 CrashReportDatabase::OperationStatus(const UUID& uuid));
114 }; 167 };
115 168
116 // Used for testing CollectAndSubmitAllPendingReports.
117 class MockPostmortemReportCollector : public PostmortemReportCollector { 169 class MockPostmortemReportCollector : public PostmortemReportCollector {
118 public: 170 public:
119 MockPostmortemReportCollector() 171 explicit MockPostmortemReportCollector(CrashReportDatabase* crash_database)
120 : PostmortemReportCollector(kProductName, 172 : PostmortemReportCollector(kProductName,
121 kVersionNumber, 173 kVersionNumber,
122 kChannelName, 174 kChannelName,
175 crash_database,
123 nullptr) {} 176 nullptr) {}
124 177
125 MOCK_METHOD3(GetDebugStateFilePaths,
126 std::vector<base::FilePath>(
127 const base::FilePath& debug_info_dir,
128 const base::FilePath::StringType& debug_file_pattern,
129 const std::set<base::FilePath>&));
130 MOCK_METHOD2(CollectOneReport, 178 MOCK_METHOD2(CollectOneReport,
131 CollectionStatus(const base::FilePath&, 179 CollectionStatus(const FilePath&, StabilityReport* report));
132 StabilityReport* report));
133 MOCK_METHOD4(WriteReportToMinidump, 180 MOCK_METHOD4(WriteReportToMinidump,
134 bool(StabilityReport* report, 181 bool(StabilityReport* report,
135 const crashpad::UUID& client_id, 182 const crashpad::UUID& client_id,
136 const crashpad::UUID& report_id, 183 const crashpad::UUID& report_id,
137 base::PlatformFile minidump_file)); 184 base::PlatformFile minidump_file));
138 }; 185 };
139 186
140 class MockSystemSessionAnalyzer : public SystemSessionAnalyzer { 187 class MockSystemSessionAnalyzer : public SystemSessionAnalyzer {
141 public: 188 public:
142 MockSystemSessionAnalyzer() : SystemSessionAnalyzer(10U) {} 189 MockSystemSessionAnalyzer() : SystemSessionAnalyzer(10U) {}
(...skipping 14 matching lines...) Expand all
157 MATCHER_P(EqualsProto, message, "") { 204 MATCHER_P(EqualsProto, message, "") {
158 std::string expected_serialized; 205 std::string expected_serialized;
159 std::string actual_serialized; 206 std::string actual_serialized;
160 message.SerializeToString(&expected_serialized); 207 message.SerializeToString(&expected_serialized);
161 arg.SerializeToString(&actual_serialized); 208 arg.SerializeToString(&actual_serialized);
162 return expected_serialized == actual_serialized; 209 return expected_serialized == actual_serialized;
163 } 210 }
164 211
165 } // namespace 212 } // namespace
166 213
167 class PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest 214 class PostmortemReportCollectorProcessTest : public testing::Test {
168 : public testing::Test {
169 public: 215 public:
170 void SetUpTest(bool system_session_clean) { 216 void SetUpTest(bool system_session_clean, bool expect_write_dump) {
217 collector_.reset(new MockPostmortemReportCollector(&database_));
218
171 // Create a dummy debug file. 219 // Create a dummy debug file.
172 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 220 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
173 debug_file_ = temp_dir_.GetPath().AppendASCII("foo-1.pma"); 221 debug_file_ = temp_dir_.GetPath().AppendASCII("foo-1.pma");
174 { 222 {
175 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); 223 base::ScopedFILE file(base::OpenFile(debug_file_, "w"));
176 ASSERT_NE(file.get(), nullptr); 224 ASSERT_NE(file.get(), nullptr);
177 } 225 }
178 ASSERT_TRUE(base::PathExists(debug_file_)); 226 ASSERT_TRUE(base::PathExists(debug_file_));
179 227
180 // Expect collection of the debug file paths.
181 debug_file_pattern_ = FILE_PATH_LITERAL("foo-*.pma");
182 std::vector<base::FilePath> debug_files{debug_file_};
183 EXPECT_CALL(collector_,
184 GetDebugStateFilePaths(debug_file_.DirName(),
185 debug_file_pattern_, no_excluded_files_))
186 .Times(1)
187 .WillOnce(Return(debug_files));
188
189 EXPECT_CALL(database_, GetSettings()).Times(1).WillOnce(Return(nullptr)); 228 EXPECT_CALL(database_, GetSettings()).Times(1).WillOnce(Return(nullptr));
190 229
191 // Expect a single collection call. 230 // Expect a single collection call.
192 StabilityReport report; 231 StabilityReport report;
193 report.mutable_system_state()->set_session_state( 232 report.mutable_system_state()->set_session_state(
194 system_session_clean ? SystemState::CLEAN : SystemState::UNCLEAN); 233 system_session_clean ? SystemState::CLEAN : SystemState::UNCLEAN);
195 EXPECT_CALL(collector_, CollectOneReport(debug_file_, _)) 234 EXPECT_CALL(*collector_, CollectOneReport(debug_file_, _))
196 .Times(1) 235 .Times(1)
197 .WillOnce(DoAll(SetArgPointee<1>(report), Return(SUCCESS))); 236 .WillOnce(DoAll(SetArgPointee<1>(report), Return(SUCCESS)));
198 237
238 if (!expect_write_dump)
239 return;
240
199 // Expect the call to write the proto to a minidump. This involves 241 // Expect the call to write the proto to a minidump. This involves
200 // requesting a report from the crashpad database, writing the report, then 242 // requesting a report from the crashpad database, writing the report, then
201 // finalizing it with the database. 243 // finalizing it with the database.
202 base::FilePath minidump_path = temp_dir_.GetPath().AppendASCII("foo-1.dmp"); 244 FilePath minidump_path = temp_dir_.GetPath().AppendASCII("foo-1.dmp");
203 base::File minidump_file( 245 base::File minidump_file(
204 minidump_path, base::File::FLAG_CREATE | base::File::File::FLAG_WRITE); 246 minidump_path, base::File::FLAG_CREATE | base::File::File::FLAG_WRITE);
205 crashpad::UUID new_report_uuid; 247 crashpad::UUID new_report_uuid;
206 new_report_uuid.InitializeWithNew(); 248 new_report_uuid.InitializeWithNew();
207 crashpad_report_ = {minidump_file.GetPlatformFile(), new_report_uuid, 249 crashpad_report_ = {minidump_file.GetPlatformFile(), new_report_uuid,
208 minidump_path}; 250 minidump_path};
209 EXPECT_CALL(database_, PrepareNewCrashReport(_)) 251 EXPECT_CALL(database_, PrepareNewCrashReport(_))
210 .Times(1) 252 .Times(1)
211 .WillOnce(DoAll(SetArgPointee<0>(&crashpad_report_), 253 .WillOnce(DoAll(SetArgPointee<0>(&crashpad_report_),
212 Return(CrashReportDatabase::kNoError))); 254 Return(CrashReportDatabase::kNoError)));
213 255
214 EXPECT_CALL(collector_, 256 EXPECT_CALL(*collector_,
215 WriteReportToMinidump(_, _, _, minidump_file.GetPlatformFile())) 257 WriteReportToMinidump(_, _, _, minidump_file.GetPlatformFile()))
216 .Times(1) 258 .Times(1)
217 .WillOnce(Return(true)); 259 .WillOnce(Return(true));
218 } 260 }
219 void ValidateHistograms(int unclean_cnt, int unclean_system_cnt) { 261 void ValidateHistograms(int unclean_cnt, int unclean_system_cnt) {
220 histogram_tester_.ExpectTotalCount( 262 histogram_tester_.ExpectBucketCount("ActivityTracker.Collect.Status",
221 "ActivityTracker.Collect.StabilityFileCount", 1); 263 UNCLEAN_SHUTDOWN, unclean_cnt);
222 histogram_tester_.ExpectBucketCount( 264 histogram_tester_.ExpectBucketCount("ActivityTracker.Collect.Status",
223 "ActivityTracker.Collect.StabilityFileCount", 1, 1); 265 UNCLEAN_SESSION, unclean_system_cnt);
224 histogram_tester_.ExpectTotalCount(
225 "ActivityTracker.Collect.UncleanShutdownCount", 1);
226 histogram_tester_.ExpectBucketCount(
227 "ActivityTracker.Collect.UncleanShutdownCount", unclean_cnt, 1);
228 histogram_tester_.ExpectTotalCount(
229 "ActivityTracker.Collect.UncleanSystemCount", 1);
230 histogram_tester_.ExpectBucketCount(
231 "ActivityTracker.Collect.UncleanSystemCount", unclean_system_cnt, 1);
232 } 266 }
233 void CollectReports(bool is_session_clean) { 267 void CollectReports(bool is_session_clean) {
234 SetUpTest(is_session_clean); 268 SetUpTest(is_session_clean, true);
235 269
236 EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _)) 270 EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _))
237 .Times(1) 271 .Times(1)
238 .WillOnce(Return(CrashReportDatabase::kNoError)); 272 .WillOnce(Return(CrashReportDatabase::kNoError));
239 273
240 // Run the test. 274 // Run the test.
241 int success_cnt = collector_.CollectAndSubmitAllPendingReports( 275 std::vector<FilePath> debug_files{debug_file_};
242 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, 276 collector_->Process(debug_files);
243 &database_);
244 ASSERT_EQ(1, success_cnt);
245 ASSERT_FALSE(base::PathExists(debug_file_)); 277 ASSERT_FALSE(base::PathExists(debug_file_));
246 } 278 }
247 279
248 protected: 280 protected:
249 base::HistogramTester histogram_tester_; 281 base::HistogramTester histogram_tester_;
250 base::ScopedTempDir temp_dir_; 282 base::ScopedTempDir temp_dir_;
251 base::FilePath debug_file_; 283 FilePath debug_file_;
252 MockCrashReportDatabase database_; 284 MockCrashReportDatabase database_;
253 MockPostmortemReportCollector collector_; 285 std::unique_ptr<MockPostmortemReportCollector> collector_;
254 base::FilePath::StringType debug_file_pattern_;
255 std::set<base::FilePath> no_excluded_files_;
256 CrashReportDatabase::NewReport crashpad_report_; 286 CrashReportDatabase::NewReport crashpad_report_;
257 }; 287 };
258 288
259 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, 289 TEST_F(PostmortemReportCollectorProcessTest, ProcessCleanSession) {
260 CollectAndSubmitAllPendingReportsCleanSession) {
261 CollectReports(true); 290 CollectReports(true);
262 int expected_unclean = 1; 291 int expected_unclean = 1;
263 int expected_system_unclean = 0; 292 int expected_system_unclean = 0;
264 ValidateHistograms(expected_unclean, expected_system_unclean); 293 ValidateHistograms(expected_unclean, expected_system_unclean);
265 } 294 }
266 295
267 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, 296 TEST_F(PostmortemReportCollectorProcessTest, ProcessUncleanSession) {
268 CollectAndSubmitAllPendingReportsUncleanSession) {
269 CollectReports(false); 297 CollectReports(false);
270 int expected_unclean = 1; 298 int expected_unclean = 1;
271 int expected_system_unclean = 1; 299 int expected_system_unclean = 1;
272 ValidateHistograms(expected_unclean, expected_system_unclean); 300 ValidateHistograms(expected_unclean, expected_system_unclean);
273 } 301 }
274 302
275 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, 303 TEST_F(PostmortemReportCollectorProcessTest, ProcessStuckFile) {
276 CollectAndSubmitAllPendingReportsStuckFile) { 304 bool system_session_clean = true;
277 SetUpTest(true); 305 bool expect_write_dump = false;
306 SetUpTest(system_session_clean, expect_write_dump);
278 307
279 // Open the stability debug file to prevent its deletion. 308 // Open the stability debug file to prevent its deletion.
280 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); 309 base::ScopedFILE file(base::OpenFile(debug_file_, "w"));
281 ASSERT_NE(file.get(), nullptr); 310 ASSERT_NE(file.get(), nullptr);
282 311
283 // Expect Crashpad is notified of an error writing the crash report.
284 EXPECT_CALL(database_, ErrorWritingCrashReport(&crashpad_report_))
285 .Times(1)
286 .WillOnce(Return(CrashReportDatabase::kNoError));
287
288 // Run the test. 312 // Run the test.
289 int success_cnt = collector_.CollectAndSubmitAllPendingReports( 313 std::vector<FilePath> debug_files{debug_file_};
290 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, 314 collector_->Process(debug_files);
291 &database_);
292 ASSERT_EQ(0, success_cnt);
293 ASSERT_TRUE(base::PathExists(debug_file_)); 315 ASSERT_TRUE(base::PathExists(debug_file_));
294 316
317 histogram_tester_.ExpectBucketCount("ActivityTracker.Collect.Status",
318 DEBUG_FILE_DELETION_FAILED, 1);
295 int expected_unclean = 0; 319 int expected_unclean = 0;
296 int expected_system_unclean = 0; 320 int expected_system_unclean = 0;
297 ValidateHistograms(expected_unclean, expected_system_unclean); 321 ValidateHistograms(expected_unclean, expected_system_unclean);
298 } 322 }
299 323
300 TEST(PostmortemReportCollectorTest, GetDebugStateFilePaths) {
301 base::ScopedTempDir temp_dir;
302 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
303
304 // Create files.
305 std::vector<base::FilePath> expected_paths;
306 std::set<base::FilePath> excluded_paths;
307 {
308 // Matches the pattern.
309 base::FilePath path = temp_dir.GetPath().AppendASCII("foo1.pma");
310 base::ScopedFILE file(base::OpenFile(path, "w"));
311 ASSERT_NE(file.get(), nullptr);
312 expected_paths.push_back(path);
313
314 // Matches the pattern, but is excluded.
315 path = temp_dir.GetPath().AppendASCII("foo2.pma");
316 file.reset(base::OpenFile(path, "w"));
317 ASSERT_NE(file.get(), nullptr);
318 ASSERT_TRUE(excluded_paths.insert(path).second);
319
320 // Matches the pattern.
321 path = temp_dir.GetPath().AppendASCII("foo3.pma");
322 file.reset(base::OpenFile(path, "w"));
323 ASSERT_NE(file.get(), nullptr);
324 expected_paths.push_back(path);
325
326 // Does not match the pattern.
327 path = temp_dir.GetPath().AppendASCII("bar.baz");
328 file.reset(base::OpenFile(path, "w"));
329 ASSERT_NE(file.get(), nullptr);
330 }
331
332 PostmortemReportCollector collector(kProductName, kVersionNumber,
333 kChannelName, nullptr);
334 EXPECT_THAT(
335 collector.GetDebugStateFilePaths(
336 temp_dir.GetPath(), FILE_PATH_LITERAL("foo*.pma"), excluded_paths),
337 testing::UnorderedElementsAreArray(expected_paths));
338 }
339
340 TEST(PostmortemReportCollectorTest, CollectEmptyFile) { 324 TEST(PostmortemReportCollectorTest, CollectEmptyFile) {
341 // Create an empty file. 325 // Create an empty file.
342 base::ScopedTempDir temp_dir; 326 base::ScopedTempDir temp_dir;
343 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 327 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
344 base::FilePath file_path = temp_dir.GetPath().AppendASCII("empty.pma"); 328 FilePath file_path = temp_dir.GetPath().AppendASCII("empty.pma");
345 { 329 {
346 base::ScopedFILE file(base::OpenFile(file_path, "w")); 330 base::ScopedFILE file(base::OpenFile(file_path, "w"));
347 ASSERT_NE(file.get(), nullptr); 331 ASSERT_NE(file.get(), nullptr);
348 } 332 }
349 ASSERT_TRUE(PathExists(file_path)); 333 ASSERT_TRUE(PathExists(file_path));
350 334
351 // Validate collection: an empty file cannot suppport an analyzer. 335 // Validate collection: an empty file cannot suppport an analyzer.
336 MockCrashReportDatabase crash_db;
352 PostmortemReportCollector collector(kProductName, kVersionNumber, 337 PostmortemReportCollector collector(kProductName, kVersionNumber,
353 kChannelName, nullptr); 338 kChannelName, &crash_db, nullptr);
354 StabilityReport report; 339 StabilityReport report;
355 ASSERT_EQ(ANALYZER_CREATION_FAILED, 340 ASSERT_EQ(ANALYZER_CREATION_FAILED,
356 collector.CollectOneReport(file_path, &report)); 341 collector.CollectOneReport(file_path, &report));
357 } 342 }
358 343
359 TEST(PostmortemReportCollectorTest, CollectRandomFile) { 344 TEST(PostmortemReportCollectorTest, CollectRandomFile) {
360 // Create a file with content we don't expect to be valid for a debug file. 345 // Create a file with content we don't expect to be valid for a debug file.
361 base::ScopedTempDir temp_dir; 346 base::ScopedTempDir temp_dir;
362 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 347 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
363 base::FilePath file_path = 348 FilePath file_path = temp_dir.GetPath().AppendASCII("invalid_content.pma");
364 temp_dir.GetPath().AppendASCII("invalid_content.pma");
365 { 349 {
366 base::ScopedFILE file(base::OpenFile(file_path, "w")); 350 base::ScopedFILE file(base::OpenFile(file_path, "w"));
367 ASSERT_NE(file.get(), nullptr); 351 ASSERT_NE(file.get(), nullptr);
368 // Assuming this size is greater than the minimum size of a debug file. 352 // Assuming this size is greater than the minimum size of a debug file.
369 std::vector<uint8_t> data(1024); 353 std::vector<uint8_t> data(1024);
370 for (size_t i = 0; i < data.size(); ++i) 354 for (size_t i = 0; i < data.size(); ++i)
371 data[i] = i % UINT8_MAX; 355 data[i] = i % UINT8_MAX;
372 ASSERT_EQ(data.size(), 356 ASSERT_EQ(data.size(),
373 fwrite(&data.at(0), sizeof(uint8_t), data.size(), file.get())); 357 fwrite(&data.at(0), sizeof(uint8_t), data.size(), file.get()));
374 } 358 }
375 ASSERT_TRUE(PathExists(file_path)); 359 ASSERT_TRUE(PathExists(file_path));
376 360
377 // Validate collection: random content appears as though there is not 361 // Validate collection: random content appears as though there is not
378 // stability data. 362 // stability data.
363 MockCrashReportDatabase crash_db;
379 PostmortemReportCollector collector(kProductName, kVersionNumber, 364 PostmortemReportCollector collector(kProductName, kVersionNumber,
380 kChannelName, nullptr); 365 kChannelName, &crash_db, nullptr);
381 StabilityReport report; 366 StabilityReport report;
382 ASSERT_NE(SUCCESS, collector.CollectOneReport(file_path, &report)); 367 ASSERT_NE(SUCCESS, collector.CollectOneReport(file_path, &report));
383 } 368 }
384 369
385 namespace { 370 namespace {
386 371
387 // Parameters for the activity tracking. 372 // Parameters for the activity tracking.
388 const size_t kFileSize = 64 << 10; // 64 KiB 373 const size_t kFileSize = 64 << 10; // 64 KiB
389 const int kStackDepth = 6; 374 const int kStackDepth = 6;
390 const uint64_t kAllocatorId = 0; 375 const uint64_t kAllocatorId = 0;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 PersistentMemoryAllocator::kSizeAny); 444 PersistentMemoryAllocator::kSizeAny);
460 if (mem_base == nullptr) 445 if (mem_base == nullptr)
461 return nullptr; 446 return nullptr;
462 447
463 // Make the allocation iterable so it can be found by other processes. 448 // Make the allocation iterable so it can be found by other processes.
464 allocator->MakeIterable(mem_reference); 449 allocator->MakeIterable(mem_reference);
465 450
466 return WrapUnique(new ThreadActivityTracker(mem_base, tracker_mem_size)); 451 return WrapUnique(new ThreadActivityTracker(mem_base, tracker_mem_size));
467 } 452 }
468 453
469 const base::FilePath& debug_file_path() const { return debug_file_path_; } 454 const FilePath& debug_file_path() const { return debug_file_path_; }
470 455
471 protected: 456 protected:
472 base::ScopedTempDir temp_dir_; 457 base::ScopedTempDir temp_dir_;
473 base::FilePath debug_file_path_; 458 FilePath debug_file_path_;
474 459
475 std::unique_ptr<PersistentMemoryAllocator> allocator_; 460 std::unique_ptr<PersistentMemoryAllocator> allocator_;
476 std::unique_ptr<ThreadActivityTracker> tracker_; 461 std::unique_ptr<ThreadActivityTracker> tracker_;
477 }; 462 };
478 463
479 TEST_F(PostmortemReportCollectorCollectionTest, CollectSuccess) { 464 TEST_F(PostmortemReportCollectorCollectionTest, CollectSuccess) {
480 // Create some activity data. 465 // Create some activity data.
481 tracker_->PushActivity(reinterpret_cast<void*>(kTaskOrigin), 466 tracker_->PushActivity(reinterpret_cast<void*>(kTaskOrigin),
482 base::debug::Activity::ACT_TASK_RUN, 467 base::debug::Activity::ACT_TASK_RUN,
483 ActivityData::ForTask(kTaskSequenceNum)); 468 ActivityData::ForTask(kTaskSequenceNum));
(...skipping 15 matching lines...) Expand all
499 484
500 // Add some user data. 485 // Add some user data.
501 ActivityTrackerMemoryAllocator user_data_allocator( 486 ActivityTrackerMemoryAllocator user_data_allocator(
502 allocator_.get(), GlobalActivityTracker::kTypeIdUserDataRecord, 487 allocator_.get(), GlobalActivityTracker::kTypeIdUserDataRecord,
503 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false); 488 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false);
504 std::unique_ptr<ActivityUserData> user_data = 489 std::unique_ptr<ActivityUserData> user_data =
505 tracker_->GetUserData(activity_id, &user_data_allocator); 490 tracker_->GetUserData(activity_id, &user_data_allocator);
506 user_data->SetInt("some_int", 42); 491 user_data->SetInt("some_int", 42);
507 492
508 // Validate collection returns the expected report. 493 // Validate collection returns the expected report.
494 MockCrashReportDatabase crash_db;
509 PostmortemReportCollector collector(kProductName, kVersionNumber, 495 PostmortemReportCollector collector(kProductName, kVersionNumber,
510 kChannelName, nullptr); 496 kChannelName, &crash_db, nullptr);
511 StabilityReport report; 497 StabilityReport report;
512 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 498 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
513 499
514 // Validate the report. 500 // Validate the report.
515 ASSERT_EQ(1, report.process_states_size()); 501 ASSERT_EQ(1, report.process_states_size());
516 const ProcessState& process_state = report.process_states(0); 502 const ProcessState& process_state = report.process_states(0);
517 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id()); 503 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id());
518 ASSERT_EQ(1, process_state.threads_size()); 504 ASSERT_EQ(1, process_state.threads_size());
519 505
520 const ThreadState& thread_state = process_state.threads(0); 506 const ThreadState& thread_state = process_state.threads(0);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 } 573 }
588 574
589 void SetUp() override { 575 void SetUp() override {
590 testing::Test::SetUp(); 576 testing::Test::SetUp();
591 577
592 // Set up a debug file path. 578 // Set up a debug file path.
593 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 579 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
594 debug_file_path_ = temp_dir_.GetPath().AppendASCII("debug.pma"); 580 debug_file_path_ = temp_dir_.GetPath().AppendASCII("debug.pma");
595 } 581 }
596 582
597 const base::FilePath& debug_file_path() { return debug_file_path_; } 583 const FilePath& debug_file_path() { return debug_file_path_; }
598 584
599 protected: 585 protected:
600 base::ScopedTempDir temp_dir_; 586 base::ScopedTempDir temp_dir_;
601 base::FilePath debug_file_path_; 587 FilePath debug_file_path_;
602 }; 588 };
603 589
604 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, 590 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest,
605 LogCollection) { 591 LogCollection) {
606 // Record some log messages. 592 // Record some log messages.
607 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, 593 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL,
608 "", 3); 594 "", 3);
609 GlobalActivityTracker::Get()->RecordLogMessage("hello world"); 595 GlobalActivityTracker::Get()->RecordLogMessage("hello world");
610 GlobalActivityTracker::Get()->RecordLogMessage("foo bar"); 596 GlobalActivityTracker::Get()->RecordLogMessage("foo bar");
611 597
612 // Collect the stability report. 598 // Collect the stability report.
599 MockCrashReportDatabase crash_db;
613 PostmortemReportCollector collector(kProductName, kVersionNumber, 600 PostmortemReportCollector collector(kProductName, kVersionNumber,
614 kChannelName, nullptr); 601 kChannelName, &crash_db, nullptr);
615 StabilityReport report; 602 StabilityReport report;
616 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 603 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
617 604
618 // Validate the report's log content. 605 // Validate the report's log content.
619 ASSERT_EQ(2, report.log_messages_size()); 606 ASSERT_EQ(2, report.log_messages_size());
620 ASSERT_EQ("hello world", report.log_messages(0)); 607 ASSERT_EQ("hello world", report.log_messages(0));
621 ASSERT_EQ("foo bar", report.log_messages(1)); 608 ASSERT_EQ("foo bar", report.log_messages(1));
622 } 609 }
623 610
624 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, 611 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest,
(...skipping 11 matching lines...) Expand all
636 process_data.Set("raw", "foo", 3); 623 process_data.Set("raw", "foo", 3);
637 process_data.SetString("string", "bar"); 624 process_data.SetString("string", "bar");
638 process_data.SetChar("char", '9'); 625 process_data.SetChar("char", '9');
639 process_data.SetInt("int", -9999); 626 process_data.SetInt("int", -9999);
640 process_data.SetUint("uint", 9999); 627 process_data.SetUint("uint", 9999);
641 process_data.SetBool("bool", true); 628 process_data.SetBool("bool", true);
642 process_data.SetReference("ref", string1, strlen(string1)); 629 process_data.SetReference("ref", string1, strlen(string1));
643 process_data.SetStringReference("sref", string2); 630 process_data.SetStringReference("sref", string2);
644 631
645 // Collect the stability report. 632 // Collect the stability report.
633 MockCrashReportDatabase crash_db;
646 PostmortemReportCollector collector(kProductName, kVersionNumber, 634 PostmortemReportCollector collector(kProductName, kVersionNumber,
647 kChannelName, nullptr); 635 kChannelName, &crash_db, nullptr);
648 StabilityReport report; 636 StabilityReport report;
649 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 637 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
650 638
651 // Validate the report's user data. 639 // Validate the report's user data.
652 const auto& collected_data = report.global_data(); 640 const auto& collected_data = report.global_data();
653 ASSERT_EQ(kInternalProcessDatums + 12U, collected_data.size()); 641 ASSERT_EQ(kInternalProcessDatums + 12U, collected_data.size());
654 642
655 ASSERT_TRUE(base::ContainsKey(collected_data, "raw")); 643 ASSERT_TRUE(base::ContainsKey(collected_data, "raw"));
656 EXPECT_EQ(TypedValue::kBytesValue, collected_data.at("raw").value_case()); 644 EXPECT_EQ(TypedValue::kBytesValue, collected_data.at("raw").value_case());
657 EXPECT_EQ("foo", collected_data.at("raw").bytes_value()); 645 EXPECT_EQ("foo", collected_data.at("raw").bytes_value());
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 FieldTrialCollection) { 693 FieldTrialCollection) {
706 // Record some data. 694 // Record some data.
707 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, 695 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL,
708 "", 3); 696 "", 3);
709 ActivityUserData& process_data = GlobalActivityTracker::Get()->process_data(); 697 ActivityUserData& process_data = GlobalActivityTracker::Get()->process_data();
710 process_data.SetString("string", "bar"); 698 process_data.SetString("string", "bar");
711 process_data.SetString("FieldTrial.string", "bar"); 699 process_data.SetString("FieldTrial.string", "bar");
712 process_data.SetString("FieldTrial.foo", "bar"); 700 process_data.SetString("FieldTrial.foo", "bar");
713 701
714 // Collect the stability report. 702 // Collect the stability report.
703 MockCrashReportDatabase crash_db;
715 PostmortemReportCollector collector(kProductName, kVersionNumber, 704 PostmortemReportCollector collector(kProductName, kVersionNumber,
716 kChannelName, nullptr); 705 kChannelName, &crash_db, nullptr);
717 StabilityReport report; 706 StabilityReport report;
718 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 707 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
719 708
720 // Validate the report's experiment and global data. 709 // Validate the report's experiment and global data.
721 ASSERT_EQ(2, report.field_trials_size()); 710 ASSERT_EQ(2, report.field_trials_size());
722 EXPECT_NE(0U, report.field_trials(0).name_id()); 711 EXPECT_NE(0U, report.field_trials(0).name_id());
723 EXPECT_NE(0U, report.field_trials(0).group_id()); 712 EXPECT_NE(0U, report.field_trials(0).group_id());
724 EXPECT_NE(0U, report.field_trials(1).name_id()); 713 EXPECT_NE(0U, report.field_trials(1).name_id());
725 EXPECT_EQ(report.field_trials(0).group_id(), 714 EXPECT_EQ(report.field_trials(0).group_id(),
726 report.field_trials(1).group_id()); 715 report.field_trials(1).group_id());
(...skipping 19 matching lines...) Expand all
746 module_info.age = 1; 735 module_info.age = 1;
747 crashpad::UUID debug_uuid; 736 crashpad::UUID debug_uuid;
748 debug_uuid.InitializeFromString("11223344-5566-7788-abcd-0123456789ab"); 737 debug_uuid.InitializeFromString("11223344-5566-7788-abcd-0123456789ab");
749 memcpy(module_info.identifier, &debug_uuid, sizeof(module_info.identifier)); 738 memcpy(module_info.identifier, &debug_uuid, sizeof(module_info.identifier));
750 module_info.file = "foo"; 739 module_info.file = "foo";
751 module_info.debug_file = "bar"; 740 module_info.debug_file = "bar";
752 741
753 GlobalActivityTracker::Get()->RecordModuleInfo(module_info); 742 GlobalActivityTracker::Get()->RecordModuleInfo(module_info);
754 743
755 // Collect the stability report. 744 // Collect the stability report.
745 MockCrashReportDatabase crash_db;
756 PostmortemReportCollector collector(kProductName, kVersionNumber, 746 PostmortemReportCollector collector(kProductName, kVersionNumber,
757 kChannelName, nullptr); 747 kChannelName, &crash_db, nullptr);
758 StabilityReport report; 748 StabilityReport report;
759 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 749 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
760 750
761 // Validate the report's modules content. 751 // Validate the report's modules content.
762 ASSERT_EQ(1, report.process_states_size()); 752 ASSERT_EQ(1, report.process_states_size());
763 const ProcessState& process_state = report.process_states(0); 753 const ProcessState& process_state = report.process_states(0);
764 ASSERT_EQ(1, process_state.modules_size()); 754 ASSERT_EQ(1, process_state.modules_size());
765 755
766 const CodeModule collected_module = process_state.modules(0); 756 const CodeModule collected_module = process_state.modules(0);
767 EXPECT_EQ(module_info.address, 757 EXPECT_EQ(module_info.address,
(...skipping 16 matching lines...) Expand all
784 "", 3); 774 "", 3);
785 ActivityUserData& process_data = GlobalActivityTracker::Get()->process_data(); 775 ActivityUserData& process_data = GlobalActivityTracker::Get()->process_data();
786 process_data.SetInt(kStabilityStartTimestamp, 12345LL); 776 process_data.SetInt(kStabilityStartTimestamp, 12345LL);
787 777
788 // Collect. 778 // Collect.
789 MockSystemSessionAnalyzer analyzer; 779 MockSystemSessionAnalyzer analyzer;
790 EXPECT_CALL(analyzer, 780 EXPECT_CALL(analyzer,
791 IsSessionUnclean(base::Time::FromInternalValue(12345LL))) 781 IsSessionUnclean(base::Time::FromInternalValue(12345LL)))
792 .Times(1) 782 .Times(1)
793 .WillOnce(Return(SystemSessionAnalyzer::CLEAN)); 783 .WillOnce(Return(SystemSessionAnalyzer::CLEAN));
784 MockCrashReportDatabase crash_db;
794 PostmortemReportCollector collector(kProductName, kVersionNumber, 785 PostmortemReportCollector collector(kProductName, kVersionNumber,
795 kChannelName, &analyzer); 786 kChannelName, &crash_db, &analyzer);
796 StabilityReport report; 787 StabilityReport report;
797 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 788 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
798 789
799 // Validate the report. 790 // Validate the report.
800 ASSERT_EQ(SystemState::CLEAN, report.system_state().session_state()); 791 ASSERT_EQ(SystemState::CLEAN, report.system_state().session_state());
801 } 792 }
802 793
803 } // namespace browser_watcher 794 } // namespace browser_watcher
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698