| OLD | NEW |
| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 MOCK_METHOD2(SkipReportUpload, | 100 MOCK_METHOD2(SkipReportUpload, |
| 101 CrashReportDatabase::OperationStatus( | 101 CrashReportDatabase::OperationStatus( |
| 102 const UUID& uuid, | 102 const UUID& uuid, |
| 103 crashpad::Metrics::CrashSkippedReason reason)); | 103 crashpad::Metrics::CrashSkippedReason reason)); |
| 104 MOCK_METHOD1(DeleteReport, | 104 MOCK_METHOD1(DeleteReport, |
| 105 CrashReportDatabase::OperationStatus(const UUID& uuid)); | 105 CrashReportDatabase::OperationStatus(const UUID& uuid)); |
| 106 MOCK_METHOD1(RequestUpload, | 106 MOCK_METHOD1(RequestUpload, |
| 107 CrashReportDatabase::OperationStatus(const UUID& uuid)); | 107 CrashReportDatabase::OperationStatus(const UUID& uuid)); |
| 108 }; | 108 }; |
| 109 | 109 |
| 110 // Used for testing CollectAndSubmitForUpload. | 110 // Used for testing CollectAndSubmitAllPendingReports. |
| 111 class MockPostmortemReportCollector : public PostmortemReportCollector { | 111 class MockPostmortemReportCollector : public PostmortemReportCollector { |
| 112 public: | 112 public: |
| 113 MockPostmortemReportCollector() | 113 MockPostmortemReportCollector() |
| 114 : PostmortemReportCollector(kProductName, kVersionNumber, kChannelName) {} | 114 : PostmortemReportCollector(kProductName, |
| 115 kVersionNumber, |
| 116 kChannelName, |
| 117 nullptr) {} |
| 115 | 118 |
| 116 // A function that returns a unique_ptr cannot be mocked, so mock a function | 119 // A function that returns a unique_ptr cannot be mocked, so mock a function |
| 117 // that returns a raw pointer instead. | 120 // that returns a raw pointer instead. |
| 118 CollectionStatus Collect(const base::FilePath& debug_state_file, | 121 CollectionStatus CollectOneReport( |
| 119 std::unique_ptr<StabilityReport>* report) override { | 122 const base::FilePath& debug_state_file, |
| 123 std::unique_ptr<StabilityReport>* report) override { |
| 120 DCHECK_NE(nullptr, report); | 124 DCHECK_NE(nullptr, report); |
| 121 report->reset(CollectRaw(debug_state_file)); | 125 report->reset(CollectRaw(debug_state_file)); |
| 122 return SUCCESS; | 126 return SUCCESS; |
| 123 } | 127 } |
| 124 | 128 |
| 125 MOCK_METHOD3(GetDebugStateFilePaths, | 129 MOCK_METHOD3(GetDebugStateFilePaths, |
| 126 std::vector<base::FilePath>( | 130 std::vector<base::FilePath>( |
| 127 const base::FilePath& debug_info_dir, | 131 const base::FilePath& debug_info_dir, |
| 128 const base::FilePath::StringType& debug_file_pattern, | 132 const base::FilePath::StringType& debug_file_pattern, |
| 129 const std::set<base::FilePath>&)); | 133 const std::set<base::FilePath>&)); |
| 130 MOCK_METHOD1(CollectRaw, StabilityReport*(const base::FilePath&)); | 134 MOCK_METHOD1(CollectRaw, StabilityReport*(const base::FilePath&)); |
| 131 MOCK_METHOD4(WriteReportToMinidump, | 135 MOCK_METHOD4(WriteReportToMinidump, |
| 132 bool(StabilityReport* report, | 136 bool(StabilityReport* report, |
| 133 const crashpad::UUID& client_id, | 137 const crashpad::UUID& client_id, |
| 134 const crashpad::UUID& report_id, | 138 const crashpad::UUID& report_id, |
| 135 base::PlatformFile minidump_file)); | 139 base::PlatformFile minidump_file)); |
| 136 }; | 140 }; |
| 137 | 141 |
| 142 class MockSystemSessionAnalyzer : public SystemSessionAnalyzer { |
| 143 public: |
| 144 MockSystemSessionAnalyzer() : SystemSessionAnalyzer(10U) {} |
| 145 MOCK_METHOD1(IsSessionUnclean, Status(base::Time timestamp)); |
| 146 }; |
| 147 |
| 138 // Checks if two proto messages are the same based on their serializations. Note | 148 // Checks if two proto messages are the same based on their serializations. Note |
| 139 // this only works if serialization is deterministic, which is not guaranteed. | 149 // this only works if serialization is deterministic, which is not guaranteed. |
| 140 // In practice, serialization is deterministic (even for protocol buffers with | 150 // In practice, serialization is deterministic (even for protocol buffers with |
| 141 // maps) and such matchers are common in the Chromium code base. Also note that | 151 // maps) and such matchers are common in the Chromium code base. Also note that |
| 142 // in the context of this test, false positive matches are the problem and these | 152 // in the context of this test, false positive matches are the problem and these |
| 143 // are not possible (otherwise serialization would be ambiguous). False | 153 // are not possible (otherwise serialization would be ambiguous). False |
| 144 // negatives would lead to test failure and developer action. Alternatives are: | 154 // negatives would lead to test failure and developer action. Alternatives are: |
| 145 // 1) a generic matcher (likely not possible without reflections, missing from | 155 // 1) a generic matcher (likely not possible without reflections, missing from |
| 146 // lite runtime), 2) a specialized matcher or 3) implementing deterministic | 156 // lite runtime), 2) a specialized matcher or 3) implementing deterministic |
| 147 // serialization. | 157 // serialization. |
| 148 // TODO(manzagop): switch a matcher with guarantees. | 158 // TODO(manzagop): switch a matcher with guarantees. |
| 149 MATCHER_P(EqualsProto, message, "") { | 159 MATCHER_P(EqualsProto, message, "") { |
| 150 std::string expected_serialized; | 160 std::string expected_serialized; |
| 151 std::string actual_serialized; | 161 std::string actual_serialized; |
| 152 message.SerializeToString(&expected_serialized); | 162 message.SerializeToString(&expected_serialized); |
| 153 arg.SerializeToString(&actual_serialized); | 163 arg.SerializeToString(&actual_serialized); |
| 154 return expected_serialized == actual_serialized; | 164 return expected_serialized == actual_serialized; |
| 155 } | 165 } |
| 156 | 166 |
| 157 } // namespace | 167 } // namespace |
| 158 | 168 |
| 159 class PostmortemReportCollectorCollectAndSubmitTest : public testing::Test { | 169 class PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest |
| 170 : public testing::Test { |
| 160 public: | 171 public: |
| 161 void SetUp() override { | 172 void SetUp() override { |
| 162 testing::Test::SetUp(); | 173 testing::Test::SetUp(); |
| 163 // Create a dummy debug file. | 174 // Create a dummy debug file. |
| 164 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 175 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 165 debug_file_ = temp_dir_.GetPath().AppendASCII("foo-1.pma"); | 176 debug_file_ = temp_dir_.GetPath().AppendASCII("foo-1.pma"); |
| 166 { | 177 { |
| 167 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); | 178 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); |
| 168 ASSERT_NE(file.get(), nullptr); | 179 ASSERT_NE(file.get(), nullptr); |
| 169 } | 180 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 protected: | 223 protected: |
| 213 base::ScopedTempDir temp_dir_; | 224 base::ScopedTempDir temp_dir_; |
| 214 base::FilePath debug_file_; | 225 base::FilePath debug_file_; |
| 215 MockCrashReportDatabase database_; | 226 MockCrashReportDatabase database_; |
| 216 MockPostmortemReportCollector collector_; | 227 MockPostmortemReportCollector collector_; |
| 217 base::FilePath::StringType debug_file_pattern_; | 228 base::FilePath::StringType debug_file_pattern_; |
| 218 std::set<base::FilePath> no_excluded_files_; | 229 std::set<base::FilePath> no_excluded_files_; |
| 219 CrashReportDatabase::NewReport crashpad_report_; | 230 CrashReportDatabase::NewReport crashpad_report_; |
| 220 }; | 231 }; |
| 221 | 232 |
| 222 TEST_F(PostmortemReportCollectorCollectAndSubmitTest, | 233 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, |
| 223 CollectAndSubmitForUpload) { | 234 CollectAndSubmitAllPendingReports) { |
| 224 EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _)) | 235 EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _)) |
| 225 .Times(1) | 236 .Times(1) |
| 226 .WillOnce(Return(CrashReportDatabase::kNoError)); | 237 .WillOnce(Return(CrashReportDatabase::kNoError)); |
| 227 | 238 |
| 228 // Run the test. | 239 // Run the test. |
| 229 int success_cnt = collector_.CollectAndSubmitForUpload( | 240 int success_cnt = collector_.CollectAndSubmitAllPendingReports( |
| 230 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, | 241 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, |
| 231 &database_); | 242 &database_); |
| 232 ASSERT_EQ(1, success_cnt); | 243 ASSERT_EQ(1, success_cnt); |
| 233 ASSERT_FALSE(base::PathExists(debug_file_)); | 244 ASSERT_FALSE(base::PathExists(debug_file_)); |
| 234 } | 245 } |
| 235 | 246 |
| 236 TEST_F(PostmortemReportCollectorCollectAndSubmitTest, | 247 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, |
| 237 CollectAndSubmitForUploadStuckFile) { | 248 CollectAndSubmitAllPendingReportsStuckFile) { |
| 238 // Open the stability debug file to prevent its deletion. | 249 // Open the stability debug file to prevent its deletion. |
| 239 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); | 250 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); |
| 240 ASSERT_NE(file.get(), nullptr); | 251 ASSERT_NE(file.get(), nullptr); |
| 241 | 252 |
| 242 // Expect Crashpad is notified of an error writing the crash report. | 253 // Expect Crashpad is notified of an error writing the crash report. |
| 243 EXPECT_CALL(database_, ErrorWritingCrashReport(&crashpad_report_)) | 254 EXPECT_CALL(database_, ErrorWritingCrashReport(&crashpad_report_)) |
| 244 .Times(1) | 255 .Times(1) |
| 245 .WillOnce(Return(CrashReportDatabase::kNoError)); | 256 .WillOnce(Return(CrashReportDatabase::kNoError)); |
| 246 | 257 |
| 247 // Run the test. | 258 // Run the test. |
| 248 int success_cnt = collector_.CollectAndSubmitForUpload( | 259 int success_cnt = collector_.CollectAndSubmitAllPendingReports( |
| 249 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, | 260 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, |
| 250 &database_); | 261 &database_); |
| 251 ASSERT_EQ(0, success_cnt); | 262 ASSERT_EQ(0, success_cnt); |
| 252 ASSERT_TRUE(base::PathExists(debug_file_)); | 263 ASSERT_TRUE(base::PathExists(debug_file_)); |
| 253 } | 264 } |
| 254 | 265 |
| 255 TEST(PostmortemReportCollectorTest, GetDebugStateFilePaths) { | 266 TEST(PostmortemReportCollectorTest, GetDebugStateFilePaths) { |
| 256 base::ScopedTempDir temp_dir; | 267 base::ScopedTempDir temp_dir; |
| 257 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 268 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 258 | 269 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 278 ASSERT_NE(file.get(), nullptr); | 289 ASSERT_NE(file.get(), nullptr); |
| 279 expected_paths.push_back(path); | 290 expected_paths.push_back(path); |
| 280 | 291 |
| 281 // Does not match the pattern. | 292 // Does not match the pattern. |
| 282 path = temp_dir.GetPath().AppendASCII("bar.baz"); | 293 path = temp_dir.GetPath().AppendASCII("bar.baz"); |
| 283 file.reset(base::OpenFile(path, "w")); | 294 file.reset(base::OpenFile(path, "w")); |
| 284 ASSERT_NE(file.get(), nullptr); | 295 ASSERT_NE(file.get(), nullptr); |
| 285 } | 296 } |
| 286 | 297 |
| 287 PostmortemReportCollector collector(kProductName, kVersionNumber, | 298 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 288 kChannelName); | 299 kChannelName, nullptr); |
| 289 EXPECT_THAT( | 300 EXPECT_THAT( |
| 290 collector.GetDebugStateFilePaths( | 301 collector.GetDebugStateFilePaths( |
| 291 temp_dir.GetPath(), FILE_PATH_LITERAL("foo*.pma"), excluded_paths), | 302 temp_dir.GetPath(), FILE_PATH_LITERAL("foo*.pma"), excluded_paths), |
| 292 testing::UnorderedElementsAreArray(expected_paths)); | 303 testing::UnorderedElementsAreArray(expected_paths)); |
| 293 } | 304 } |
| 294 | 305 |
| 295 TEST(PostmortemReportCollectorTest, CollectEmptyFile) { | 306 TEST(PostmortemReportCollectorTest, CollectEmptyFile) { |
| 296 // Create an empty file. | 307 // Create an empty file. |
| 297 base::ScopedTempDir temp_dir; | 308 base::ScopedTempDir temp_dir; |
| 298 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 309 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 299 base::FilePath file_path = temp_dir.GetPath().AppendASCII("empty.pma"); | 310 base::FilePath file_path = temp_dir.GetPath().AppendASCII("empty.pma"); |
| 300 { | 311 { |
| 301 base::ScopedFILE file(base::OpenFile(file_path, "w")); | 312 base::ScopedFILE file(base::OpenFile(file_path, "w")); |
| 302 ASSERT_NE(file.get(), nullptr); | 313 ASSERT_NE(file.get(), nullptr); |
| 303 } | 314 } |
| 304 ASSERT_TRUE(PathExists(file_path)); | 315 ASSERT_TRUE(PathExists(file_path)); |
| 305 | 316 |
| 306 // Validate collection: an empty file cannot suppport an analyzer. | 317 // Validate collection: an empty file cannot suppport an analyzer. |
| 307 PostmortemReportCollector collector(kProductName, kVersionNumber, | 318 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 308 kChannelName); | 319 kChannelName, nullptr); |
| 309 std::unique_ptr<StabilityReport> report; | 320 std::unique_ptr<StabilityReport> report; |
| 310 ASSERT_EQ(PostmortemReportCollector::ANALYZER_CREATION_FAILED, | 321 ASSERT_EQ(PostmortemReportCollector::ANALYZER_CREATION_FAILED, |
| 311 collector.Collect(file_path, &report)); | 322 collector.CollectOneReport(file_path, &report)); |
| 312 } | 323 } |
| 313 | 324 |
| 314 TEST(PostmortemReportCollectorTest, CollectRandomFile) { | 325 TEST(PostmortemReportCollectorTest, CollectRandomFile) { |
| 315 // Create a file with content we don't expect to be valid for a debug file. | 326 // Create a file with content we don't expect to be valid for a debug file. |
| 316 base::ScopedTempDir temp_dir; | 327 base::ScopedTempDir temp_dir; |
| 317 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 328 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 318 base::FilePath file_path = | 329 base::FilePath file_path = |
| 319 temp_dir.GetPath().AppendASCII("invalid_content.pma"); | 330 temp_dir.GetPath().AppendASCII("invalid_content.pma"); |
| 320 { | 331 { |
| 321 base::ScopedFILE file(base::OpenFile(file_path, "w")); | 332 base::ScopedFILE file(base::OpenFile(file_path, "w")); |
| 322 ASSERT_NE(file.get(), nullptr); | 333 ASSERT_NE(file.get(), nullptr); |
| 323 // Assuming this size is greater than the minimum size of a debug file. | 334 // Assuming this size is greater than the minimum size of a debug file. |
| 324 std::vector<uint8_t> data(1024); | 335 std::vector<uint8_t> data(1024); |
| 325 for (size_t i = 0; i < data.size(); ++i) | 336 for (size_t i = 0; i < data.size(); ++i) |
| 326 data[i] = i % UINT8_MAX; | 337 data[i] = i % UINT8_MAX; |
| 327 ASSERT_EQ(data.size(), | 338 ASSERT_EQ(data.size(), |
| 328 fwrite(&data.at(0), sizeof(uint8_t), data.size(), file.get())); | 339 fwrite(&data.at(0), sizeof(uint8_t), data.size(), file.get())); |
| 329 } | 340 } |
| 330 ASSERT_TRUE(PathExists(file_path)); | 341 ASSERT_TRUE(PathExists(file_path)); |
| 331 | 342 |
| 332 // Validate collection: random content appears as though there is not | 343 // Validate collection: random content appears as though there is not |
| 333 // stability data. | 344 // stability data. |
| 334 PostmortemReportCollector collector(kProductName, kVersionNumber, | 345 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 335 kChannelName); | 346 kChannelName, nullptr); |
| 336 std::unique_ptr<StabilityReport> report; | 347 std::unique_ptr<StabilityReport> report; |
| 337 ASSERT_EQ(PostmortemReportCollector::DEBUG_FILE_NO_DATA, | 348 ASSERT_EQ(PostmortemReportCollector::DEBUG_FILE_NO_DATA, |
| 338 collector.Collect(file_path, &report)); | 349 collector.CollectOneReport(file_path, &report)); |
| 339 } | 350 } |
| 340 | 351 |
| 341 namespace { | 352 namespace { |
| 342 | 353 |
| 343 // Parameters for the activity tracking. | 354 // Parameters for the activity tracking. |
| 344 const size_t kFileSize = 2 * 1024; | 355 const size_t kFileSize = 2 * 1024; |
| 345 const int kStackDepth = 5; | 356 const int kStackDepth = 5; |
| 346 const uint64_t kAllocatorId = 0; | 357 const uint64_t kAllocatorId = 0; |
| 347 const char kAllocatorName[] = "PostmortemReportCollectorCollectionTest"; | 358 const char kAllocatorName[] = "PostmortemReportCollectorCollectionTest"; |
| 348 const uint64_t kTaskSequenceNum = 42; | 359 const uint64_t kTaskSequenceNum = 42; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 // Add some user data. | 463 // Add some user data. |
| 453 ActivityTrackerMemoryAllocator user_data_allocator( | 464 ActivityTrackerMemoryAllocator user_data_allocator( |
| 454 allocator_.get(), GlobalActivityTracker::kTypeIdUserDataRecord, | 465 allocator_.get(), GlobalActivityTracker::kTypeIdUserDataRecord, |
| 455 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false); | 466 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false); |
| 456 std::unique_ptr<ActivityUserData> user_data = | 467 std::unique_ptr<ActivityUserData> user_data = |
| 457 tracker_->GetUserData(activity_id, &user_data_allocator); | 468 tracker_->GetUserData(activity_id, &user_data_allocator); |
| 458 user_data->SetInt("some_int", 42); | 469 user_data->SetInt("some_int", 42); |
| 459 | 470 |
| 460 // Validate collection returns the expected report. | 471 // Validate collection returns the expected report. |
| 461 PostmortemReportCollector collector(kProductName, kVersionNumber, | 472 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 462 kChannelName); | 473 kChannelName, nullptr); |
| 463 std::unique_ptr<StabilityReport> report; | 474 std::unique_ptr<StabilityReport> report; |
| 464 ASSERT_EQ(PostmortemReportCollector::SUCCESS, | 475 ASSERT_EQ(PostmortemReportCollector::SUCCESS, |
| 465 collector.Collect(debug_file_path(), &report)); | 476 collector.CollectOneReport(debug_file_path(), &report)); |
| 466 ASSERT_NE(nullptr, report); | 477 ASSERT_NE(nullptr, report); |
| 467 | 478 |
| 468 // Validate the report. | 479 // Validate the report. |
| 469 ASSERT_EQ(1, report->process_states_size()); | 480 ASSERT_EQ(1, report->process_states_size()); |
| 470 const ProcessState& process_state = report->process_states(0); | 481 const ProcessState& process_state = report->process_states(0); |
| 471 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id()); | 482 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id()); |
| 472 ASSERT_EQ(1, process_state.threads_size()); | 483 ASSERT_EQ(1, process_state.threads_size()); |
| 473 | 484 |
| 474 const ThreadState& thread_state = process_state.threads(0); | 485 const ThreadState& thread_state = process_state.threads(0); |
| 475 EXPECT_EQ(base::PlatformThread::GetName(), thread_state.thread_name()); | 486 EXPECT_EQ(base::PlatformThread::GetName(), thread_state.thread_name()); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 551 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, | 562 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, |
| 552 LogCollection) { | 563 LogCollection) { |
| 553 // Record some log messages. | 564 // Record some log messages. |
| 554 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, | 565 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, |
| 555 "", 3); | 566 "", 3); |
| 556 GlobalActivityTracker::Get()->RecordLogMessage("hello world"); | 567 GlobalActivityTracker::Get()->RecordLogMessage("hello world"); |
| 557 GlobalActivityTracker::Get()->RecordLogMessage("foo bar"); | 568 GlobalActivityTracker::Get()->RecordLogMessage("foo bar"); |
| 558 | 569 |
| 559 // Collect the stability report. | 570 // Collect the stability report. |
| 560 PostmortemReportCollector collector(kProductName, kVersionNumber, | 571 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 561 kChannelName); | 572 kChannelName, nullptr); |
| 562 std::unique_ptr<StabilityReport> report; | 573 std::unique_ptr<StabilityReport> report; |
| 563 ASSERT_EQ(PostmortemReportCollector::SUCCESS, | 574 ASSERT_EQ(PostmortemReportCollector::SUCCESS, |
| 564 collector.Collect(debug_file_path(), &report)); | 575 collector.CollectOneReport(debug_file_path(), &report)); |
| 565 ASSERT_NE(nullptr, report); | 576 ASSERT_NE(nullptr, report); |
| 566 | 577 |
| 567 // Validate the report's log content. | 578 // Validate the report's log content. |
| 568 ASSERT_EQ(2, report->log_messages_size()); | 579 ASSERT_EQ(2, report->log_messages_size()); |
| 569 ASSERT_EQ("hello world", report->log_messages(0)); | 580 ASSERT_EQ("hello world", report->log_messages(0)); |
| 570 ASSERT_EQ("foo bar", report->log_messages(1)); | 581 ASSERT_EQ("foo bar", report->log_messages(1)); |
| 571 } | 582 } |
| 572 | 583 |
| 573 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, | 584 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, |
| 574 GlobalUserDataCollection) { | 585 GlobalUserDataCollection) { |
| 575 const char string1[] = "foo"; | 586 const char string1[] = "foo"; |
| 576 const char string2[] = "bar"; | 587 const char string2[] = "bar"; |
| 577 | 588 |
| 578 // Record some global user data. | 589 // Record some global user data. |
| 579 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, | 590 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, |
| 580 "", 3); | 591 "", 3); |
| 581 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); | 592 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); |
| 582 global_data.Set("raw", "foo", 3); | 593 global_data.Set("raw", "foo", 3); |
| 583 global_data.SetString("string", "bar"); | 594 global_data.SetString("string", "bar"); |
| 584 global_data.SetChar("char", '9'); | 595 global_data.SetChar("char", '9'); |
| 585 global_data.SetInt("int", -9999); | 596 global_data.SetInt("int", -9999); |
| 586 global_data.SetUint("uint", 9999); | 597 global_data.SetUint("uint", 9999); |
| 587 global_data.SetBool("bool", true); | 598 global_data.SetBool("bool", true); |
| 588 global_data.SetReference("ref", string1, strlen(string1)); | 599 global_data.SetReference("ref", string1, strlen(string1)); |
| 589 global_data.SetStringReference("sref", string2); | 600 global_data.SetStringReference("sref", string2); |
| 590 | 601 |
| 591 // Collect the stability report. | 602 // Collect the stability report. |
| 592 PostmortemReportCollector collector(kProductName, kVersionNumber, | 603 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 593 kChannelName); | 604 kChannelName, nullptr); |
| 594 std::unique_ptr<StabilityReport> report; | 605 std::unique_ptr<StabilityReport> report; |
| 595 ASSERT_EQ(PostmortemReportCollector::SUCCESS, | 606 ASSERT_EQ(PostmortemReportCollector::SUCCESS, |
| 596 collector.Collect(debug_file_path(), &report)); | 607 collector.CollectOneReport(debug_file_path(), &report)); |
| 597 ASSERT_NE(nullptr, report); | 608 ASSERT_NE(nullptr, report); |
| 598 | 609 |
| 599 // Validate the report's user data. | 610 // Validate the report's user data. |
| 600 const auto& collected_data = report->global_data(); | 611 const auto& collected_data = report->global_data(); |
| 601 ASSERT_EQ(12U, collected_data.size()); | 612 ASSERT_EQ(12U, collected_data.size()); |
| 602 | 613 |
| 603 ASSERT_TRUE(base::ContainsKey(collected_data, "raw")); | 614 ASSERT_TRUE(base::ContainsKey(collected_data, "raw")); |
| 604 EXPECT_EQ(TypedValue::kBytesValue, collected_data.at("raw").value_case()); | 615 EXPECT_EQ(TypedValue::kBytesValue, collected_data.at("raw").value_case()); |
| 605 EXPECT_EQ("foo", collected_data.at("raw").bytes_value()); | 616 EXPECT_EQ("foo", collected_data.at("raw").bytes_value()); |
| 606 | 617 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 // Record some data. | 665 // Record some data. |
| 655 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, | 666 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, |
| 656 "", 3); | 667 "", 3); |
| 657 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); | 668 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); |
| 658 global_data.SetString("string", "bar"); | 669 global_data.SetString("string", "bar"); |
| 659 global_data.SetString("FieldTrial.string", "bar"); | 670 global_data.SetString("FieldTrial.string", "bar"); |
| 660 global_data.SetString("FieldTrial.foo", "bar"); | 671 global_data.SetString("FieldTrial.foo", "bar"); |
| 661 | 672 |
| 662 // Collect the stability report. | 673 // Collect the stability report. |
| 663 PostmortemReportCollector collector(kProductName, kVersionNumber, | 674 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 664 kChannelName); | 675 kChannelName, nullptr); |
| 665 std::unique_ptr<StabilityReport> report; | 676 std::unique_ptr<StabilityReport> report; |
| 666 ASSERT_EQ(PostmortemReportCollector::SUCCESS, | 677 ASSERT_EQ(PostmortemReportCollector::SUCCESS, |
| 667 collector.Collect(debug_file_path(), &report)); | 678 collector.CollectOneReport(debug_file_path(), &report)); |
| 668 ASSERT_NE(nullptr, report); | 679 ASSERT_NE(nullptr, report); |
| 669 | 680 |
| 670 // Validate the report's experiment and global data. | 681 // Validate the report's experiment and global data. |
| 671 ASSERT_EQ(2, report->field_trials_size()); | 682 ASSERT_EQ(2, report->field_trials_size()); |
| 672 EXPECT_NE(0U, report->field_trials(0).name_id()); | 683 EXPECT_NE(0U, report->field_trials(0).name_id()); |
| 673 EXPECT_NE(0U, report->field_trials(0).group_id()); | 684 EXPECT_NE(0U, report->field_trials(0).group_id()); |
| 674 EXPECT_NE(0U, report->field_trials(1).name_id()); | 685 EXPECT_NE(0U, report->field_trials(1).name_id()); |
| 675 EXPECT_EQ(report->field_trials(0).group_id(), | 686 EXPECT_EQ(report->field_trials(0).group_id(), |
| 676 report->field_trials(1).group_id()); | 687 report->field_trials(1).group_id()); |
| 677 | 688 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 697 crashpad::UUID debug_uuid; | 708 crashpad::UUID debug_uuid; |
| 698 debug_uuid.InitializeFromString("11223344-5566-7788-abcd-0123456789ab"); | 709 debug_uuid.InitializeFromString("11223344-5566-7788-abcd-0123456789ab"); |
| 699 memcpy(module_info.identifier, &debug_uuid, sizeof(module_info.identifier)); | 710 memcpy(module_info.identifier, &debug_uuid, sizeof(module_info.identifier)); |
| 700 module_info.file = "foo"; | 711 module_info.file = "foo"; |
| 701 module_info.debug_file = "bar"; | 712 module_info.debug_file = "bar"; |
| 702 | 713 |
| 703 GlobalActivityTracker::Get()->RecordModuleInfo(module_info); | 714 GlobalActivityTracker::Get()->RecordModuleInfo(module_info); |
| 704 | 715 |
| 705 // Collect the stability report. | 716 // Collect the stability report. |
| 706 PostmortemReportCollector collector(kProductName, kVersionNumber, | 717 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 707 kChannelName); | 718 kChannelName, nullptr); |
| 708 std::unique_ptr<StabilityReport> report; | 719 std::unique_ptr<StabilityReport> report; |
| 709 ASSERT_EQ(PostmortemReportCollector::SUCCESS, | 720 ASSERT_EQ(PostmortemReportCollector::SUCCESS, |
| 710 collector.Collect(debug_file_path(), &report)); | 721 collector.CollectOneReport(debug_file_path(), &report)); |
| 711 ASSERT_NE(nullptr, report); | 722 ASSERT_NE(nullptr, report); |
| 712 | 723 |
| 713 // Validate the report's modules content. | 724 // Validate the report's modules content. |
| 714 ASSERT_EQ(1, report->process_states_size()); | 725 ASSERT_EQ(1, report->process_states_size()); |
| 715 const ProcessState& process_state = report->process_states(0); | 726 const ProcessState& process_state = report->process_states(0); |
| 716 ASSERT_EQ(1, process_state.modules_size()); | 727 ASSERT_EQ(1, process_state.modules_size()); |
| 717 | 728 |
| 718 const CodeModule collected_module = process_state.modules(0); | 729 const CodeModule collected_module = process_state.modules(0); |
| 719 EXPECT_EQ(module_info.address, | 730 EXPECT_EQ(module_info.address, |
| 720 static_cast<uintptr_t>(collected_module.base_address())); | 731 static_cast<uintptr_t>(collected_module.base_address())); |
| 721 EXPECT_EQ(module_info.size, static_cast<size_t>(collected_module.size())); | 732 EXPECT_EQ(module_info.size, static_cast<size_t>(collected_module.size())); |
| 722 EXPECT_EQ(module_info.file, collected_module.code_file()); | 733 EXPECT_EQ(module_info.file, collected_module.code_file()); |
| 723 EXPECT_EQ("CAFECAFE2d000", collected_module.code_identifier()); | 734 EXPECT_EQ("CAFECAFE2d000", collected_module.code_identifier()); |
| 724 EXPECT_EQ(module_info.debug_file, collected_module.debug_file()); | 735 EXPECT_EQ(module_info.debug_file, collected_module.debug_file()); |
| 725 EXPECT_EQ("1122334455667788ABCD0123456789AB1", | 736 EXPECT_EQ("1122334455667788ABCD0123456789AB1", |
| 726 collected_module.debug_identifier()); | 737 collected_module.debug_identifier()); |
| 727 EXPECT_EQ("", collected_module.version()); | 738 EXPECT_EQ("", collected_module.version()); |
| 728 EXPECT_EQ(0LL, collected_module.shrink_down_delta()); | 739 EXPECT_EQ(0LL, collected_module.shrink_down_delta()); |
| 729 EXPECT_EQ(!module_info.is_loaded, collected_module.is_unloaded()); | 740 EXPECT_EQ(!module_info.is_loaded, collected_module.is_unloaded()); |
| 730 } | 741 } |
| 731 | 742 |
| 743 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, |
| 744 SystemStateTest) { |
| 745 // Setup. |
| 746 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, |
| 747 "", 3); |
| 748 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); |
| 749 global_data.SetInt(kStabilityStartTimestamp, 12345LL); |
| 750 |
| 751 // Collect. |
| 752 MockSystemSessionAnalyzer analyzer; |
| 753 EXPECT_CALL(analyzer, |
| 754 IsSessionUnclean(base::Time::FromInternalValue(12345LL))) |
| 755 .Times(1) |
| 756 .WillOnce(Return(SystemSessionAnalyzer::CLEAN)); |
| 757 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 758 kChannelName, &analyzer); |
| 759 std::unique_ptr<StabilityReport> report; |
| 760 ASSERT_EQ(PostmortemReportCollector::SUCCESS, |
| 761 collector.CollectOneReport(debug_file_path(), &report)); |
| 762 ASSERT_NE(nullptr, report); |
| 763 |
| 764 // Validate the report. |
| 765 ASSERT_EQ(SystemState::CLEAN, report->system_state().session_state()); |
| 766 } |
| 767 |
| 732 } // namespace browser_watcher | 768 } // namespace browser_watcher |
| OLD | NEW |