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

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

Issue 2923523002: Decouple stability instrumentation recording and collection (Closed)
Patch Set: PostmortemDeleter unittest 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);
Sigurður Ásgeirsson 2017/06/05 15:39:39 nice. Stupid question, though - wouldn't the Postm
manzagop (departed) 2017/06/05 18:02:16 Done.
94 }
95
57 const char kProductName[] = "TestProduct"; 96 const char kProductName[] = "TestProduct";
58 const char kVersionNumber[] = "TestVersionNumber"; 97 const char kVersionNumber[] = "TestVersionNumber";
59 const char kChannelName[] = "TestChannel"; 98 const char kChannelName[] = "TestChannel";
60 99
61 // The tracker creates some data entries internally. 100 // The tracker creates some data entries internally.
62 const size_t kInternalProcessDatums = 1; 101 const size_t kInternalProcessDatums = 1;
63 102
64 void ContainsKeyValue( 103 void ContainsKeyValue(
65 const google::protobuf::Map<std::string, TypedValue>& data, 104 const google::protobuf::Map<std::string, TypedValue>& data,
66 const std::string& key, 105 const std::string& key,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 MOCK_METHOD2(SkipReportUpload, 145 MOCK_METHOD2(SkipReportUpload,
107 CrashReportDatabase::OperationStatus( 146 CrashReportDatabase::OperationStatus(
108 const UUID& uuid, 147 const UUID& uuid,
109 crashpad::Metrics::CrashSkippedReason reason)); 148 crashpad::Metrics::CrashSkippedReason reason));
110 MOCK_METHOD1(DeleteReport, 149 MOCK_METHOD1(DeleteReport,
111 CrashReportDatabase::OperationStatus(const UUID& uuid)); 150 CrashReportDatabase::OperationStatus(const UUID& uuid));
112 MOCK_METHOD1(RequestUpload, 151 MOCK_METHOD1(RequestUpload,
113 CrashReportDatabase::OperationStatus(const UUID& uuid)); 152 CrashReportDatabase::OperationStatus(const UUID& uuid));
114 }; 153 };
115 154
116 // Used for testing CollectAndSubmitAllPendingReports.
117 class MockPostmortemReportCollector : public PostmortemReportCollector { 155 class MockPostmortemReportCollector : public PostmortemReportCollector {
118 public: 156 public:
119 MockPostmortemReportCollector() 157 explicit MockPostmortemReportCollector(CrashReportDatabase* crash_database)
120 : PostmortemReportCollector(kProductName, 158 : PostmortemReportCollector(kProductName,
121 kVersionNumber, 159 kVersionNumber,
122 kChannelName, 160 kChannelName,
161 crash_database,
123 nullptr) {} 162 nullptr) {}
124 163
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, 164 MOCK_METHOD2(CollectOneReport,
131 CollectionStatus(const base::FilePath&, 165 CollectionStatus(const FilePath&, StabilityReport* report));
132 StabilityReport* report));
133 MOCK_METHOD4(WriteReportToMinidump, 166 MOCK_METHOD4(WriteReportToMinidump,
134 bool(StabilityReport* report, 167 bool(StabilityReport* report,
135 const crashpad::UUID& client_id, 168 const crashpad::UUID& client_id,
136 const crashpad::UUID& report_id, 169 const crashpad::UUID& report_id,
137 base::PlatformFile minidump_file)); 170 base::PlatformFile minidump_file));
138 }; 171 };
139 172
140 class MockSystemSessionAnalyzer : public SystemSessionAnalyzer { 173 class MockSystemSessionAnalyzer : public SystemSessionAnalyzer {
141 public: 174 public:
142 MockSystemSessionAnalyzer() : SystemSessionAnalyzer(10U) {} 175 MockSystemSessionAnalyzer() : SystemSessionAnalyzer(10U) {}
(...skipping 14 matching lines...) Expand all
157 MATCHER_P(EqualsProto, message, "") { 190 MATCHER_P(EqualsProto, message, "") {
158 std::string expected_serialized; 191 std::string expected_serialized;
159 std::string actual_serialized; 192 std::string actual_serialized;
160 message.SerializeToString(&expected_serialized); 193 message.SerializeToString(&expected_serialized);
161 arg.SerializeToString(&actual_serialized); 194 arg.SerializeToString(&actual_serialized);
162 return expected_serialized == actual_serialized; 195 return expected_serialized == actual_serialized;
163 } 196 }
164 197
165 } // namespace 198 } // namespace
166 199
167 class PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest 200 class PostmortemReportCollectorProcessTest : public testing::Test {
168 : public testing::Test {
169 public: 201 public:
170 void SetUpTest(bool system_session_clean) { 202 void SetUpTest(bool system_session_clean, bool expect_write_dump) {
203 collector_.reset(new MockPostmortemReportCollector(&database_));
204
171 // Create a dummy debug file. 205 // Create a dummy debug file.
172 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 206 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
173 debug_file_ = temp_dir_.GetPath().AppendASCII("foo-1.pma"); 207 debug_file_ = temp_dir_.GetPath().AppendASCII("foo-1.pma");
174 { 208 {
175 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); 209 base::ScopedFILE file(base::OpenFile(debug_file_, "w"));
176 ASSERT_NE(file.get(), nullptr); 210 ASSERT_NE(file.get(), nullptr);
177 } 211 }
178 ASSERT_TRUE(base::PathExists(debug_file_)); 212 ASSERT_TRUE(base::PathExists(debug_file_));
179 213
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)); 214 EXPECT_CALL(database_, GetSettings()).Times(1).WillOnce(Return(nullptr));
190 215
191 // Expect a single collection call. 216 // Expect a single collection call.
192 StabilityReport report; 217 StabilityReport report;
193 report.mutable_system_state()->set_session_state( 218 report.mutable_system_state()->set_session_state(
194 system_session_clean ? SystemState::CLEAN : SystemState::UNCLEAN); 219 system_session_clean ? SystemState::CLEAN : SystemState::UNCLEAN);
195 EXPECT_CALL(collector_, CollectOneReport(debug_file_, _)) 220 EXPECT_CALL(*collector_, CollectOneReport(debug_file_, _))
196 .Times(1) 221 .Times(1)
197 .WillOnce(DoAll(SetArgPointee<1>(report), Return(SUCCESS))); 222 .WillOnce(DoAll(SetArgPointee<1>(report), Return(SUCCESS)));
198 223
224 if (!expect_write_dump)
225 return;
226
199 // Expect the call to write the proto to a minidump. This involves 227 // Expect the call to write the proto to a minidump. This involves
200 // requesting a report from the crashpad database, writing the report, then 228 // requesting a report from the crashpad database, writing the report, then
201 // finalizing it with the database. 229 // finalizing it with the database.
202 base::FilePath minidump_path = temp_dir_.GetPath().AppendASCII("foo-1.dmp"); 230 FilePath minidump_path = temp_dir_.GetPath().AppendASCII("foo-1.dmp");
203 base::File minidump_file( 231 base::File minidump_file(
204 minidump_path, base::File::FLAG_CREATE | base::File::File::FLAG_WRITE); 232 minidump_path, base::File::FLAG_CREATE | base::File::File::FLAG_WRITE);
205 crashpad::UUID new_report_uuid; 233 crashpad::UUID new_report_uuid;
206 new_report_uuid.InitializeWithNew(); 234 new_report_uuid.InitializeWithNew();
207 crashpad_report_ = {minidump_file.GetPlatformFile(), new_report_uuid, 235 crashpad_report_ = {minidump_file.GetPlatformFile(), new_report_uuid,
208 minidump_path}; 236 minidump_path};
209 EXPECT_CALL(database_, PrepareNewCrashReport(_)) 237 EXPECT_CALL(database_, PrepareNewCrashReport(_))
210 .Times(1) 238 .Times(1)
211 .WillOnce(DoAll(SetArgPointee<0>(&crashpad_report_), 239 .WillOnce(DoAll(SetArgPointee<0>(&crashpad_report_),
212 Return(CrashReportDatabase::kNoError))); 240 Return(CrashReportDatabase::kNoError)));
213 241
214 EXPECT_CALL(collector_, 242 EXPECT_CALL(*collector_,
215 WriteReportToMinidump(_, _, _, minidump_file.GetPlatformFile())) 243 WriteReportToMinidump(_, _, _, minidump_file.GetPlatformFile()))
216 .Times(1) 244 .Times(1)
217 .WillOnce(Return(true)); 245 .WillOnce(Return(true));
218 } 246 }
219 void ValidateHistograms(int unclean_cnt, int unclean_system_cnt) { 247 void ValidateHistograms(int unclean_cnt, int unclean_system_cnt) {
220 histogram_tester_.ExpectTotalCount( 248 histogram_tester_.ExpectBucketCount("ActivityTracker.Collect.Status",
221 "ActivityTracker.Collect.StabilityFileCount", 1); 249 UNCLEAN_SHUTDOWN, unclean_cnt);
222 histogram_tester_.ExpectBucketCount( 250 histogram_tester_.ExpectBucketCount("ActivityTracker.Collect.Status",
223 "ActivityTracker.Collect.StabilityFileCount", 1, 1); 251 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 } 252 }
233 void CollectReports(bool is_session_clean) { 253 void CollectReports(bool is_session_clean) {
234 SetUpTest(is_session_clean); 254 SetUpTest(is_session_clean, true);
235 255
236 EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _)) 256 EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _))
237 .Times(1) 257 .Times(1)
238 .WillOnce(Return(CrashReportDatabase::kNoError)); 258 .WillOnce(Return(CrashReportDatabase::kNoError));
239 259
240 // Run the test. 260 // Run the test.
241 int success_cnt = collector_.CollectAndSubmitAllPendingReports( 261 std::vector<FilePath> debug_files{debug_file_};
242 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, 262 collector_->Process(debug_files);
243 &database_);
244 ASSERT_EQ(1, success_cnt);
245 ASSERT_FALSE(base::PathExists(debug_file_)); 263 ASSERT_FALSE(base::PathExists(debug_file_));
246 } 264 }
247 265
248 protected: 266 protected:
249 base::HistogramTester histogram_tester_; 267 base::HistogramTester histogram_tester_;
250 base::ScopedTempDir temp_dir_; 268 base::ScopedTempDir temp_dir_;
251 base::FilePath debug_file_; 269 FilePath debug_file_;
252 MockCrashReportDatabase database_; 270 MockCrashReportDatabase database_;
253 MockPostmortemReportCollector collector_; 271 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_; 272 CrashReportDatabase::NewReport crashpad_report_;
257 }; 273 };
258 274
259 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, 275 TEST_F(PostmortemReportCollectorProcessTest, ProcessCleanSession) {
260 CollectAndSubmitAllPendingReportsCleanSession) {
261 CollectReports(true); 276 CollectReports(true);
262 int expected_unclean = 1; 277 int expected_unclean = 1;
263 int expected_system_unclean = 0; 278 int expected_system_unclean = 0;
264 ValidateHistograms(expected_unclean, expected_system_unclean); 279 ValidateHistograms(expected_unclean, expected_system_unclean);
265 } 280 }
266 281
267 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, 282 TEST_F(PostmortemReportCollectorProcessTest, ProcessUncleanSession) {
268 CollectAndSubmitAllPendingReportsUncleanSession) {
269 CollectReports(false); 283 CollectReports(false);
270 int expected_unclean = 1; 284 int expected_unclean = 1;
271 int expected_system_unclean = 1; 285 int expected_system_unclean = 1;
272 ValidateHistograms(expected_unclean, expected_system_unclean); 286 ValidateHistograms(expected_unclean, expected_system_unclean);
273 } 287 }
274 288
275 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, 289 TEST_F(PostmortemReportCollectorProcessTest, ProcessStuckFile) {
276 CollectAndSubmitAllPendingReportsStuckFile) { 290 bool system_session_clean = true;
277 SetUpTest(true); 291 bool expect_write_dump = false;
292 SetUpTest(system_session_clean, expect_write_dump);
278 293
279 // Open the stability debug file to prevent its deletion. 294 // Open the stability debug file to prevent its deletion.
280 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); 295 base::ScopedFILE file(base::OpenFile(debug_file_, "w"));
281 ASSERT_NE(file.get(), nullptr); 296 ASSERT_NE(file.get(), nullptr);
282 297
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. 298 // Run the test.
289 int success_cnt = collector_.CollectAndSubmitAllPendingReports( 299 std::vector<FilePath> debug_files{debug_file_};
290 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, 300 collector_->Process(debug_files);
291 &database_);
292 ASSERT_EQ(0, success_cnt);
293 ASSERT_TRUE(base::PathExists(debug_file_)); 301 ASSERT_TRUE(base::PathExists(debug_file_));
294 302
303 histogram_tester_.ExpectBucketCount("ActivityTracker.Collect.Status",
304 DEBUG_FILE_DELETION_FAILED, 1);
295 int expected_unclean = 0; 305 int expected_unclean = 0;
296 int expected_system_unclean = 0; 306 int expected_system_unclean = 0;
297 ValidateHistograms(expected_unclean, expected_system_unclean); 307 ValidateHistograms(expected_unclean, expected_system_unclean);
298 } 308 }
299 309
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) { 310 TEST(PostmortemReportCollectorTest, CollectEmptyFile) {
341 // Create an empty file. 311 // Create an empty file.
342 base::ScopedTempDir temp_dir; 312 base::ScopedTempDir temp_dir;
343 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 313 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
344 base::FilePath file_path = temp_dir.GetPath().AppendASCII("empty.pma"); 314 FilePath file_path = temp_dir.GetPath().AppendASCII("empty.pma");
345 { 315 {
346 base::ScopedFILE file(base::OpenFile(file_path, "w")); 316 base::ScopedFILE file(base::OpenFile(file_path, "w"));
347 ASSERT_NE(file.get(), nullptr); 317 ASSERT_NE(file.get(), nullptr);
348 } 318 }
349 ASSERT_TRUE(PathExists(file_path)); 319 ASSERT_TRUE(PathExists(file_path));
350 320
351 // Validate collection: an empty file cannot suppport an analyzer. 321 // Validate collection: an empty file cannot suppport an analyzer.
322 MockCrashReportDatabase crash_db;
352 PostmortemReportCollector collector(kProductName, kVersionNumber, 323 PostmortemReportCollector collector(kProductName, kVersionNumber,
353 kChannelName, nullptr); 324 kChannelName, &crash_db, nullptr);
354 StabilityReport report; 325 StabilityReport report;
355 ASSERT_EQ(ANALYZER_CREATION_FAILED, 326 ASSERT_EQ(ANALYZER_CREATION_FAILED,
356 collector.CollectOneReport(file_path, &report)); 327 collector.CollectOneReport(file_path, &report));
357 } 328 }
358 329
359 TEST(PostmortemReportCollectorTest, CollectRandomFile) { 330 TEST(PostmortemReportCollectorTest, CollectRandomFile) {
360 // Create a file with content we don't expect to be valid for a debug file. 331 // Create a file with content we don't expect to be valid for a debug file.
361 base::ScopedTempDir temp_dir; 332 base::ScopedTempDir temp_dir;
362 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 333 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
363 base::FilePath file_path = 334 FilePath file_path = temp_dir.GetPath().AppendASCII("invalid_content.pma");
364 temp_dir.GetPath().AppendASCII("invalid_content.pma");
365 { 335 {
366 base::ScopedFILE file(base::OpenFile(file_path, "w")); 336 base::ScopedFILE file(base::OpenFile(file_path, "w"));
367 ASSERT_NE(file.get(), nullptr); 337 ASSERT_NE(file.get(), nullptr);
368 // Assuming this size is greater than the minimum size of a debug file. 338 // Assuming this size is greater than the minimum size of a debug file.
369 std::vector<uint8_t> data(1024); 339 std::vector<uint8_t> data(1024);
370 for (size_t i = 0; i < data.size(); ++i) 340 for (size_t i = 0; i < data.size(); ++i)
371 data[i] = i % UINT8_MAX; 341 data[i] = i % UINT8_MAX;
372 ASSERT_EQ(data.size(), 342 ASSERT_EQ(data.size(),
373 fwrite(&data.at(0), sizeof(uint8_t), data.size(), file.get())); 343 fwrite(&data.at(0), sizeof(uint8_t), data.size(), file.get()));
374 } 344 }
375 ASSERT_TRUE(PathExists(file_path)); 345 ASSERT_TRUE(PathExists(file_path));
376 346
377 // Validate collection: random content appears as though there is not 347 // Validate collection: random content appears as though there is not
378 // stability data. 348 // stability data.
349 MockCrashReportDatabase crash_db;
379 PostmortemReportCollector collector(kProductName, kVersionNumber, 350 PostmortemReportCollector collector(kProductName, kVersionNumber,
380 kChannelName, nullptr); 351 kChannelName, &crash_db, nullptr);
381 StabilityReport report; 352 StabilityReport report;
382 ASSERT_NE(SUCCESS, collector.CollectOneReport(file_path, &report)); 353 ASSERT_NE(SUCCESS, collector.CollectOneReport(file_path, &report));
383 } 354 }
384 355
385 namespace { 356 namespace {
386 357
387 // Parameters for the activity tracking. 358 // Parameters for the activity tracking.
388 const size_t kFileSize = 64 << 10; // 64 KiB 359 const size_t kFileSize = 64 << 10; // 64 KiB
389 const int kStackDepth = 6; 360 const int kStackDepth = 6;
390 const uint64_t kAllocatorId = 0; 361 const uint64_t kAllocatorId = 0;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 PersistentMemoryAllocator::kSizeAny); 430 PersistentMemoryAllocator::kSizeAny);
460 if (mem_base == nullptr) 431 if (mem_base == nullptr)
461 return nullptr; 432 return nullptr;
462 433
463 // Make the allocation iterable so it can be found by other processes. 434 // Make the allocation iterable so it can be found by other processes.
464 allocator->MakeIterable(mem_reference); 435 allocator->MakeIterable(mem_reference);
465 436
466 return WrapUnique(new ThreadActivityTracker(mem_base, tracker_mem_size)); 437 return WrapUnique(new ThreadActivityTracker(mem_base, tracker_mem_size));
467 } 438 }
468 439
469 const base::FilePath& debug_file_path() const { return debug_file_path_; } 440 const FilePath& debug_file_path() const { return debug_file_path_; }
470 441
471 protected: 442 protected:
472 base::ScopedTempDir temp_dir_; 443 base::ScopedTempDir temp_dir_;
473 base::FilePath debug_file_path_; 444 FilePath debug_file_path_;
474 445
475 std::unique_ptr<PersistentMemoryAllocator> allocator_; 446 std::unique_ptr<PersistentMemoryAllocator> allocator_;
476 std::unique_ptr<ThreadActivityTracker> tracker_; 447 std::unique_ptr<ThreadActivityTracker> tracker_;
477 }; 448 };
478 449
479 TEST_F(PostmortemReportCollectorCollectionTest, CollectSuccess) { 450 TEST_F(PostmortemReportCollectorCollectionTest, CollectSuccess) {
480 // Create some activity data. 451 // Create some activity data.
481 tracker_->PushActivity(reinterpret_cast<void*>(kTaskOrigin), 452 tracker_->PushActivity(reinterpret_cast<void*>(kTaskOrigin),
482 base::debug::Activity::ACT_TASK_RUN, 453 base::debug::Activity::ACT_TASK_RUN,
483 ActivityData::ForTask(kTaskSequenceNum)); 454 ActivityData::ForTask(kTaskSequenceNum));
(...skipping 15 matching lines...) Expand all
499 470
500 // Add some user data. 471 // Add some user data.
501 ActivityTrackerMemoryAllocator user_data_allocator( 472 ActivityTrackerMemoryAllocator user_data_allocator(
502 allocator_.get(), GlobalActivityTracker::kTypeIdUserDataRecord, 473 allocator_.get(), GlobalActivityTracker::kTypeIdUserDataRecord,
503 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false); 474 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false);
504 std::unique_ptr<ActivityUserData> user_data = 475 std::unique_ptr<ActivityUserData> user_data =
505 tracker_->GetUserData(activity_id, &user_data_allocator); 476 tracker_->GetUserData(activity_id, &user_data_allocator);
506 user_data->SetInt("some_int", 42); 477 user_data->SetInt("some_int", 42);
507 478
508 // Validate collection returns the expected report. 479 // Validate collection returns the expected report.
480 MockCrashReportDatabase crash_db;
509 PostmortemReportCollector collector(kProductName, kVersionNumber, 481 PostmortemReportCollector collector(kProductName, kVersionNumber,
510 kChannelName, nullptr); 482 kChannelName, &crash_db, nullptr);
511 StabilityReport report; 483 StabilityReport report;
512 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 484 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
513 485
514 // Validate the report. 486 // Validate the report.
515 ASSERT_EQ(1, report.process_states_size()); 487 ASSERT_EQ(1, report.process_states_size());
516 const ProcessState& process_state = report.process_states(0); 488 const ProcessState& process_state = report.process_states(0);
517 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id()); 489 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id());
518 ASSERT_EQ(1, process_state.threads_size()); 490 ASSERT_EQ(1, process_state.threads_size());
519 491
520 const ThreadState& thread_state = process_state.threads(0); 492 const ThreadState& thread_state = process_state.threads(0);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 } 559 }
588 560
589 void SetUp() override { 561 void SetUp() override {
590 testing::Test::SetUp(); 562 testing::Test::SetUp();
591 563
592 // Set up a debug file path. 564 // Set up a debug file path.
593 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 565 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
594 debug_file_path_ = temp_dir_.GetPath().AppendASCII("debug.pma"); 566 debug_file_path_ = temp_dir_.GetPath().AppendASCII("debug.pma");
595 } 567 }
596 568
597 const base::FilePath& debug_file_path() { return debug_file_path_; } 569 const FilePath& debug_file_path() { return debug_file_path_; }
598 570
599 protected: 571 protected:
600 base::ScopedTempDir temp_dir_; 572 base::ScopedTempDir temp_dir_;
601 base::FilePath debug_file_path_; 573 FilePath debug_file_path_;
602 }; 574 };
603 575
604 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, 576 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest,
605 LogCollection) { 577 LogCollection) {
606 // Record some log messages. 578 // Record some log messages.
607 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, 579 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL,
608 "", 3); 580 "", 3);
609 GlobalActivityTracker::Get()->RecordLogMessage("hello world"); 581 GlobalActivityTracker::Get()->RecordLogMessage("hello world");
610 GlobalActivityTracker::Get()->RecordLogMessage("foo bar"); 582 GlobalActivityTracker::Get()->RecordLogMessage("foo bar");
611 583
612 // Collect the stability report. 584 // Collect the stability report.
585 MockCrashReportDatabase crash_db;
613 PostmortemReportCollector collector(kProductName, kVersionNumber, 586 PostmortemReportCollector collector(kProductName, kVersionNumber,
614 kChannelName, nullptr); 587 kChannelName, &crash_db, nullptr);
615 StabilityReport report; 588 StabilityReport report;
616 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 589 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
617 590
618 // Validate the report's log content. 591 // Validate the report's log content.
619 ASSERT_EQ(2, report.log_messages_size()); 592 ASSERT_EQ(2, report.log_messages_size());
620 ASSERT_EQ("hello world", report.log_messages(0)); 593 ASSERT_EQ("hello world", report.log_messages(0));
621 ASSERT_EQ("foo bar", report.log_messages(1)); 594 ASSERT_EQ("foo bar", report.log_messages(1));
622 } 595 }
623 596
624 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, 597 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest,
(...skipping 11 matching lines...) Expand all
636 process_data.Set("raw", "foo", 3); 609 process_data.Set("raw", "foo", 3);
637 process_data.SetString("string", "bar"); 610 process_data.SetString("string", "bar");
638 process_data.SetChar("char", '9'); 611 process_data.SetChar("char", '9');
639 process_data.SetInt("int", -9999); 612 process_data.SetInt("int", -9999);
640 process_data.SetUint("uint", 9999); 613 process_data.SetUint("uint", 9999);
641 process_data.SetBool("bool", true); 614 process_data.SetBool("bool", true);
642 process_data.SetReference("ref", string1, strlen(string1)); 615 process_data.SetReference("ref", string1, strlen(string1));
643 process_data.SetStringReference("sref", string2); 616 process_data.SetStringReference("sref", string2);
644 617
645 // Collect the stability report. 618 // Collect the stability report.
619 MockCrashReportDatabase crash_db;
646 PostmortemReportCollector collector(kProductName, kVersionNumber, 620 PostmortemReportCollector collector(kProductName, kVersionNumber,
647 kChannelName, nullptr); 621 kChannelName, &crash_db, nullptr);
648 StabilityReport report; 622 StabilityReport report;
649 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 623 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
650 624
651 // Validate the report's user data. 625 // Validate the report's user data.
652 const auto& collected_data = report.global_data(); 626 const auto& collected_data = report.global_data();
653 ASSERT_EQ(kInternalProcessDatums + 12U, collected_data.size()); 627 ASSERT_EQ(kInternalProcessDatums + 12U, collected_data.size());
654 628
655 ASSERT_TRUE(base::ContainsKey(collected_data, "raw")); 629 ASSERT_TRUE(base::ContainsKey(collected_data, "raw"));
656 EXPECT_EQ(TypedValue::kBytesValue, collected_data.at("raw").value_case()); 630 EXPECT_EQ(TypedValue::kBytesValue, collected_data.at("raw").value_case());
657 EXPECT_EQ("foo", collected_data.at("raw").bytes_value()); 631 EXPECT_EQ("foo", collected_data.at("raw").bytes_value());
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 FieldTrialCollection) { 679 FieldTrialCollection) {
706 // Record some data. 680 // Record some data.
707 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, 681 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL,
708 "", 3); 682 "", 3);
709 ActivityUserData& process_data = GlobalActivityTracker::Get()->process_data(); 683 ActivityUserData& process_data = GlobalActivityTracker::Get()->process_data();
710 process_data.SetString("string", "bar"); 684 process_data.SetString("string", "bar");
711 process_data.SetString("FieldTrial.string", "bar"); 685 process_data.SetString("FieldTrial.string", "bar");
712 process_data.SetString("FieldTrial.foo", "bar"); 686 process_data.SetString("FieldTrial.foo", "bar");
713 687
714 // Collect the stability report. 688 // Collect the stability report.
689 MockCrashReportDatabase crash_db;
715 PostmortemReportCollector collector(kProductName, kVersionNumber, 690 PostmortemReportCollector collector(kProductName, kVersionNumber,
716 kChannelName, nullptr); 691 kChannelName, &crash_db, nullptr);
717 StabilityReport report; 692 StabilityReport report;
718 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 693 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
719 694
720 // Validate the report's experiment and global data. 695 // Validate the report's experiment and global data.
721 ASSERT_EQ(2, report.field_trials_size()); 696 ASSERT_EQ(2, report.field_trials_size());
722 EXPECT_NE(0U, report.field_trials(0).name_id()); 697 EXPECT_NE(0U, report.field_trials(0).name_id());
723 EXPECT_NE(0U, report.field_trials(0).group_id()); 698 EXPECT_NE(0U, report.field_trials(0).group_id());
724 EXPECT_NE(0U, report.field_trials(1).name_id()); 699 EXPECT_NE(0U, report.field_trials(1).name_id());
725 EXPECT_EQ(report.field_trials(0).group_id(), 700 EXPECT_EQ(report.field_trials(0).group_id(),
726 report.field_trials(1).group_id()); 701 report.field_trials(1).group_id());
(...skipping 19 matching lines...) Expand all
746 module_info.age = 1; 721 module_info.age = 1;
747 crashpad::UUID debug_uuid; 722 crashpad::UUID debug_uuid;
748 debug_uuid.InitializeFromString("11223344-5566-7788-abcd-0123456789ab"); 723 debug_uuid.InitializeFromString("11223344-5566-7788-abcd-0123456789ab");
749 memcpy(module_info.identifier, &debug_uuid, sizeof(module_info.identifier)); 724 memcpy(module_info.identifier, &debug_uuid, sizeof(module_info.identifier));
750 module_info.file = "foo"; 725 module_info.file = "foo";
751 module_info.debug_file = "bar"; 726 module_info.debug_file = "bar";
752 727
753 GlobalActivityTracker::Get()->RecordModuleInfo(module_info); 728 GlobalActivityTracker::Get()->RecordModuleInfo(module_info);
754 729
755 // Collect the stability report. 730 // Collect the stability report.
731 MockCrashReportDatabase crash_db;
756 PostmortemReportCollector collector(kProductName, kVersionNumber, 732 PostmortemReportCollector collector(kProductName, kVersionNumber,
757 kChannelName, nullptr); 733 kChannelName, &crash_db, nullptr);
758 StabilityReport report; 734 StabilityReport report;
759 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 735 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
760 736
761 // Validate the report's modules content. 737 // Validate the report's modules content.
762 ASSERT_EQ(1, report.process_states_size()); 738 ASSERT_EQ(1, report.process_states_size());
763 const ProcessState& process_state = report.process_states(0); 739 const ProcessState& process_state = report.process_states(0);
764 ASSERT_EQ(1, process_state.modules_size()); 740 ASSERT_EQ(1, process_state.modules_size());
765 741
766 const CodeModule collected_module = process_state.modules(0); 742 const CodeModule collected_module = process_state.modules(0);
767 EXPECT_EQ(module_info.address, 743 EXPECT_EQ(module_info.address,
(...skipping 16 matching lines...) Expand all
784 "", 3); 760 "", 3);
785 ActivityUserData& process_data = GlobalActivityTracker::Get()->process_data(); 761 ActivityUserData& process_data = GlobalActivityTracker::Get()->process_data();
786 process_data.SetInt(kStabilityStartTimestamp, 12345LL); 762 process_data.SetInt(kStabilityStartTimestamp, 12345LL);
787 763
788 // Collect. 764 // Collect.
789 MockSystemSessionAnalyzer analyzer; 765 MockSystemSessionAnalyzer analyzer;
790 EXPECT_CALL(analyzer, 766 EXPECT_CALL(analyzer,
791 IsSessionUnclean(base::Time::FromInternalValue(12345LL))) 767 IsSessionUnclean(base::Time::FromInternalValue(12345LL)))
792 .Times(1) 768 .Times(1)
793 .WillOnce(Return(SystemSessionAnalyzer::CLEAN)); 769 .WillOnce(Return(SystemSessionAnalyzer::CLEAN));
770 MockCrashReportDatabase crash_db;
794 PostmortemReportCollector collector(kProductName, kVersionNumber, 771 PostmortemReportCollector collector(kProductName, kVersionNumber,
795 kChannelName, &analyzer); 772 kChannelName, &crash_db, &analyzer);
796 StabilityReport report; 773 StabilityReport report;
797 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 774 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
798 775
799 // Validate the report. 776 // Validate the report.
800 ASSERT_EQ(SystemState::CLEAN, report.system_state().session_state()); 777 ASSERT_EQ(SystemState::CLEAN, report.system_state().session_state());
801 } 778 }
802 779
803 } // namespace browser_watcher 780 } // namespace browser_watcher
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698