| 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 MOCK_METHOD2(SkipReportUpload, | 101 MOCK_METHOD2(SkipReportUpload, |
| 102 CrashReportDatabase::OperationStatus( | 102 CrashReportDatabase::OperationStatus( |
| 103 const UUID& uuid, | 103 const UUID& uuid, |
| 104 crashpad::Metrics::CrashSkippedReason reason)); | 104 crashpad::Metrics::CrashSkippedReason reason)); |
| 105 MOCK_METHOD1(DeleteReport, | 105 MOCK_METHOD1(DeleteReport, |
| 106 CrashReportDatabase::OperationStatus(const UUID& uuid)); | 106 CrashReportDatabase::OperationStatus(const UUID& uuid)); |
| 107 MOCK_METHOD1(RequestUpload, | 107 MOCK_METHOD1(RequestUpload, |
| 108 CrashReportDatabase::OperationStatus(const UUID& uuid)); | 108 CrashReportDatabase::OperationStatus(const UUID& uuid)); |
| 109 }; | 109 }; |
| 110 | 110 |
| 111 // Used for testing CollectAndSubmitForUpload. | 111 // Used for testing CollectAndSubmitAllPendingReports. |
| 112 class MockPostmortemReportCollector : public PostmortemReportCollector { | 112 class MockPostmortemReportCollector : public PostmortemReportCollector { |
| 113 public: | 113 public: |
| 114 MockPostmortemReportCollector() | 114 MockPostmortemReportCollector() |
| 115 : PostmortemReportCollector(kProductName, kVersionNumber, kChannelName) {} | 115 : PostmortemReportCollector(kProductName, |
| 116 kVersionNumber, |
| 117 kChannelName, |
| 118 nullptr) {} |
| 116 | 119 |
| 117 MOCK_METHOD3(GetDebugStateFilePaths, | 120 MOCK_METHOD3(GetDebugStateFilePaths, |
| 118 std::vector<base::FilePath>( | 121 std::vector<base::FilePath>( |
| 119 const base::FilePath& debug_info_dir, | 122 const base::FilePath& debug_info_dir, |
| 120 const base::FilePath::StringType& debug_file_pattern, | 123 const base::FilePath::StringType& debug_file_pattern, |
| 121 const std::set<base::FilePath>&)); | 124 const std::set<base::FilePath>&)); |
| 122 MOCK_METHOD2(Collect, | 125 MOCK_METHOD2(CollectOneReport, |
| 123 CollectionStatus(const base::FilePath&, | 126 CollectionStatus(const base::FilePath&, |
| 124 StabilityReport* report)); | 127 StabilityReport* report)); |
| 125 MOCK_METHOD4(WriteReportToMinidump, | 128 MOCK_METHOD4(WriteReportToMinidump, |
| 126 bool(StabilityReport* report, | 129 bool(StabilityReport* report, |
| 127 const crashpad::UUID& client_id, | 130 const crashpad::UUID& client_id, |
| 128 const crashpad::UUID& report_id, | 131 const crashpad::UUID& report_id, |
| 129 base::PlatformFile minidump_file)); | 132 base::PlatformFile minidump_file)); |
| 130 }; | 133 }; |
| 131 | 134 |
| 135 class MockSystemSessionAnalyzer : public SystemSessionAnalyzer { |
| 136 public: |
| 137 MockSystemSessionAnalyzer() : SystemSessionAnalyzer(10U) {} |
| 138 MOCK_METHOD1(IsSessionUnclean, Status(base::Time timestamp)); |
| 139 }; |
| 140 |
| 132 // Checks if two proto messages are the same based on their serializations. Note | 141 // Checks if two proto messages are the same based on their serializations. Note |
| 133 // this only works if serialization is deterministic, which is not guaranteed. | 142 // this only works if serialization is deterministic, which is not guaranteed. |
| 134 // In practice, serialization is deterministic (even for protocol buffers with | 143 // In practice, serialization is deterministic (even for protocol buffers with |
| 135 // maps) and such matchers are common in the Chromium code base. Also note that | 144 // maps) and such matchers are common in the Chromium code base. Also note that |
| 136 // in the context of this test, false positive matches are the problem and these | 145 // in the context of this test, false positive matches are the problem and these |
| 137 // are not possible (otherwise serialization would be ambiguous). False | 146 // are not possible (otherwise serialization would be ambiguous). False |
| 138 // negatives would lead to test failure and developer action. Alternatives are: | 147 // negatives would lead to test failure and developer action. Alternatives are: |
| 139 // 1) a generic matcher (likely not possible without reflections, missing from | 148 // 1) a generic matcher (likely not possible without reflections, missing from |
| 140 // lite runtime), 2) a specialized matcher or 3) implementing deterministic | 149 // lite runtime), 2) a specialized matcher or 3) implementing deterministic |
| 141 // serialization. | 150 // serialization. |
| 142 // TODO(manzagop): switch a matcher with guarantees. | 151 // TODO(manzagop): switch a matcher with guarantees. |
| 143 MATCHER_P(EqualsProto, message, "") { | 152 MATCHER_P(EqualsProto, message, "") { |
| 144 std::string expected_serialized; | 153 std::string expected_serialized; |
| 145 std::string actual_serialized; | 154 std::string actual_serialized; |
| 146 message.SerializeToString(&expected_serialized); | 155 message.SerializeToString(&expected_serialized); |
| 147 arg.SerializeToString(&actual_serialized); | 156 arg.SerializeToString(&actual_serialized); |
| 148 return expected_serialized == actual_serialized; | 157 return expected_serialized == actual_serialized; |
| 149 } | 158 } |
| 150 | 159 |
| 151 } // namespace | 160 } // namespace |
| 152 | 161 |
| 153 class PostmortemReportCollectorCollectAndSubmitTest : public testing::Test { | 162 class PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest |
| 163 : public testing::Test { |
| 154 public: | 164 public: |
| 155 void SetUp() override { | 165 void SetUp() override { |
| 156 testing::Test::SetUp(); | 166 testing::Test::SetUp(); |
| 157 // Create a dummy debug file. | 167 // Create a dummy debug file. |
| 158 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 168 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 159 debug_file_ = temp_dir_.GetPath().AppendASCII("foo-1.pma"); | 169 debug_file_ = temp_dir_.GetPath().AppendASCII("foo-1.pma"); |
| 160 { | 170 { |
| 161 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); | 171 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); |
| 162 ASSERT_NE(file.get(), nullptr); | 172 ASSERT_NE(file.get(), nullptr); |
| 163 } | 173 } |
| 164 ASSERT_TRUE(base::PathExists(debug_file_)); | 174 ASSERT_TRUE(base::PathExists(debug_file_)); |
| 165 | 175 |
| 166 // Expect collection of the debug file paths. | 176 // Expect collection of the debug file paths. |
| 167 debug_file_pattern_ = FILE_PATH_LITERAL("foo-*.pma"); | 177 debug_file_pattern_ = FILE_PATH_LITERAL("foo-*.pma"); |
| 168 std::vector<base::FilePath> debug_files{debug_file_}; | 178 std::vector<base::FilePath> debug_files{debug_file_}; |
| 169 EXPECT_CALL(collector_, | 179 EXPECT_CALL(collector_, |
| 170 GetDebugStateFilePaths(debug_file_.DirName(), | 180 GetDebugStateFilePaths(debug_file_.DirName(), |
| 171 debug_file_pattern_, no_excluded_files_)) | 181 debug_file_pattern_, no_excluded_files_)) |
| 172 .Times(1) | 182 .Times(1) |
| 173 .WillOnce(Return(debug_files)); | 183 .WillOnce(Return(debug_files)); |
| 174 | 184 |
| 175 EXPECT_CALL(database_, GetSettings()).Times(1).WillOnce(Return(nullptr)); | 185 EXPECT_CALL(database_, GetSettings()).Times(1).WillOnce(Return(nullptr)); |
| 176 | 186 |
| 177 // Expect a single collection call. | 187 // Expect a single collection call. |
| 178 EXPECT_CALL(collector_, Collect(debug_file_, _)) | 188 EXPECT_CALL(collector_, CollectOneReport(debug_file_, _)) |
| 179 .Times(1) | 189 .Times(1) |
| 180 .WillOnce(Return(SUCCESS)); | 190 .WillOnce(Return(SUCCESS)); |
| 181 | 191 |
| 182 // Expect the call to write the proto to a minidump. This involves | 192 // Expect the call to write the proto to a minidump. This involves |
| 183 // requesting a report from the crashpad database, writing the report, then | 193 // requesting a report from the crashpad database, writing the report, then |
| 184 // finalizing it with the database. | 194 // finalizing it with the database. |
| 185 base::FilePath minidump_path = temp_dir_.GetPath().AppendASCII("foo-1.dmp"); | 195 base::FilePath minidump_path = temp_dir_.GetPath().AppendASCII("foo-1.dmp"); |
| 186 base::File minidump_file( | 196 base::File minidump_file( |
| 187 minidump_path, base::File::FLAG_CREATE | base::File::File::FLAG_WRITE); | 197 minidump_path, base::File::FLAG_CREATE | base::File::File::FLAG_WRITE); |
| 188 crashpad::UUID new_report_uuid; | 198 crashpad::UUID new_report_uuid; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 203 protected: | 213 protected: |
| 204 base::ScopedTempDir temp_dir_; | 214 base::ScopedTempDir temp_dir_; |
| 205 base::FilePath debug_file_; | 215 base::FilePath debug_file_; |
| 206 MockCrashReportDatabase database_; | 216 MockCrashReportDatabase database_; |
| 207 MockPostmortemReportCollector collector_; | 217 MockPostmortemReportCollector collector_; |
| 208 base::FilePath::StringType debug_file_pattern_; | 218 base::FilePath::StringType debug_file_pattern_; |
| 209 std::set<base::FilePath> no_excluded_files_; | 219 std::set<base::FilePath> no_excluded_files_; |
| 210 CrashReportDatabase::NewReport crashpad_report_; | 220 CrashReportDatabase::NewReport crashpad_report_; |
| 211 }; | 221 }; |
| 212 | 222 |
| 213 TEST_F(PostmortemReportCollectorCollectAndSubmitTest, | 223 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, |
| 214 CollectAndSubmitForUpload) { | 224 CollectAndSubmitAllPendingReports) { |
| 215 EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _)) | 225 EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _)) |
| 216 .Times(1) | 226 .Times(1) |
| 217 .WillOnce(Return(CrashReportDatabase::kNoError)); | 227 .WillOnce(Return(CrashReportDatabase::kNoError)); |
| 218 | 228 |
| 219 // Run the test. | 229 // Run the test. |
| 220 int success_cnt = collector_.CollectAndSubmitForUpload( | 230 int success_cnt = collector_.CollectAndSubmitAllPendingReports( |
| 221 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, | 231 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, |
| 222 &database_); | 232 &database_); |
| 223 ASSERT_EQ(1, success_cnt); | 233 ASSERT_EQ(1, success_cnt); |
| 224 ASSERT_FALSE(base::PathExists(debug_file_)); | 234 ASSERT_FALSE(base::PathExists(debug_file_)); |
| 225 } | 235 } |
| 226 | 236 |
| 227 TEST_F(PostmortemReportCollectorCollectAndSubmitTest, | 237 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, |
| 228 CollectAndSubmitForUploadStuckFile) { | 238 CollectAndSubmitAllPendingReportsStuckFile) { |
| 229 // Open the stability debug file to prevent its deletion. | 239 // Open the stability debug file to prevent its deletion. |
| 230 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); | 240 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); |
| 231 ASSERT_NE(file.get(), nullptr); | 241 ASSERT_NE(file.get(), nullptr); |
| 232 | 242 |
| 233 // Expect Crashpad is notified of an error writing the crash report. | 243 // Expect Crashpad is notified of an error writing the crash report. |
| 234 EXPECT_CALL(database_, ErrorWritingCrashReport(&crashpad_report_)) | 244 EXPECT_CALL(database_, ErrorWritingCrashReport(&crashpad_report_)) |
| 235 .Times(1) | 245 .Times(1) |
| 236 .WillOnce(Return(CrashReportDatabase::kNoError)); | 246 .WillOnce(Return(CrashReportDatabase::kNoError)); |
| 237 | 247 |
| 238 // Run the test. | 248 // Run the test. |
| 239 int success_cnt = collector_.CollectAndSubmitForUpload( | 249 int success_cnt = collector_.CollectAndSubmitAllPendingReports( |
| 240 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, | 250 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, |
| 241 &database_); | 251 &database_); |
| 242 ASSERT_EQ(0, success_cnt); | 252 ASSERT_EQ(0, success_cnt); |
| 243 ASSERT_TRUE(base::PathExists(debug_file_)); | 253 ASSERT_TRUE(base::PathExists(debug_file_)); |
| 244 } | 254 } |
| 245 | 255 |
| 246 TEST(PostmortemReportCollectorTest, GetDebugStateFilePaths) { | 256 TEST(PostmortemReportCollectorTest, GetDebugStateFilePaths) { |
| 247 base::ScopedTempDir temp_dir; | 257 base::ScopedTempDir temp_dir; |
| 248 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 258 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 249 | 259 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 269 ASSERT_NE(file.get(), nullptr); | 279 ASSERT_NE(file.get(), nullptr); |
| 270 expected_paths.push_back(path); | 280 expected_paths.push_back(path); |
| 271 | 281 |
| 272 // Does not match the pattern. | 282 // Does not match the pattern. |
| 273 path = temp_dir.GetPath().AppendASCII("bar.baz"); | 283 path = temp_dir.GetPath().AppendASCII("bar.baz"); |
| 274 file.reset(base::OpenFile(path, "w")); | 284 file.reset(base::OpenFile(path, "w")); |
| 275 ASSERT_NE(file.get(), nullptr); | 285 ASSERT_NE(file.get(), nullptr); |
| 276 } | 286 } |
| 277 | 287 |
| 278 PostmortemReportCollector collector(kProductName, kVersionNumber, | 288 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 279 kChannelName); | 289 kChannelName, nullptr); |
| 280 EXPECT_THAT( | 290 EXPECT_THAT( |
| 281 collector.GetDebugStateFilePaths( | 291 collector.GetDebugStateFilePaths( |
| 282 temp_dir.GetPath(), FILE_PATH_LITERAL("foo*.pma"), excluded_paths), | 292 temp_dir.GetPath(), FILE_PATH_LITERAL("foo*.pma"), excluded_paths), |
| 283 testing::UnorderedElementsAreArray(expected_paths)); | 293 testing::UnorderedElementsAreArray(expected_paths)); |
| 284 } | 294 } |
| 285 | 295 |
| 286 TEST(PostmortemReportCollectorTest, CollectEmptyFile) { | 296 TEST(PostmortemReportCollectorTest, CollectEmptyFile) { |
| 287 // Create an empty file. | 297 // Create an empty file. |
| 288 base::ScopedTempDir temp_dir; | 298 base::ScopedTempDir temp_dir; |
| 289 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 299 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 290 base::FilePath file_path = temp_dir.GetPath().AppendASCII("empty.pma"); | 300 base::FilePath file_path = temp_dir.GetPath().AppendASCII("empty.pma"); |
| 291 { | 301 { |
| 292 base::ScopedFILE file(base::OpenFile(file_path, "w")); | 302 base::ScopedFILE file(base::OpenFile(file_path, "w")); |
| 293 ASSERT_NE(file.get(), nullptr); | 303 ASSERT_NE(file.get(), nullptr); |
| 294 } | 304 } |
| 295 ASSERT_TRUE(PathExists(file_path)); | 305 ASSERT_TRUE(PathExists(file_path)); |
| 296 | 306 |
| 297 // Validate collection: an empty file cannot suppport an analyzer. | 307 // Validate collection: an empty file cannot suppport an analyzer. |
| 298 PostmortemReportCollector collector(kProductName, kVersionNumber, | 308 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 299 kChannelName); | 309 kChannelName, nullptr); |
| 300 StabilityReport report; | 310 StabilityReport report; |
| 301 ASSERT_EQ(ANALYZER_CREATION_FAILED, collector.Collect(file_path, &report)); | 311 ASSERT_EQ(ANALYZER_CREATION_FAILED, |
| 312 collector.CollectOneReport(file_path, &report)); |
| 302 } | 313 } |
| 303 | 314 |
| 304 TEST(PostmortemReportCollectorTest, CollectRandomFile) { | 315 TEST(PostmortemReportCollectorTest, CollectRandomFile) { |
| 305 // Create a file with content we don't expect to be valid for a debug file. | 316 // Create a file with content we don't expect to be valid for a debug file. |
| 306 base::ScopedTempDir temp_dir; | 317 base::ScopedTempDir temp_dir; |
| 307 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 318 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 308 base::FilePath file_path = | 319 base::FilePath file_path = |
| 309 temp_dir.GetPath().AppendASCII("invalid_content.pma"); | 320 temp_dir.GetPath().AppendASCII("invalid_content.pma"); |
| 310 { | 321 { |
| 311 base::ScopedFILE file(base::OpenFile(file_path, "w")); | 322 base::ScopedFILE file(base::OpenFile(file_path, "w")); |
| 312 ASSERT_NE(file.get(), nullptr); | 323 ASSERT_NE(file.get(), nullptr); |
| 313 // Assuming this size is greater than the minimum size of a debug file. | 324 // Assuming this size is greater than the minimum size of a debug file. |
| 314 std::vector<uint8_t> data(1024); | 325 std::vector<uint8_t> data(1024); |
| 315 for (size_t i = 0; i < data.size(); ++i) | 326 for (size_t i = 0; i < data.size(); ++i) |
| 316 data[i] = i % UINT8_MAX; | 327 data[i] = i % UINT8_MAX; |
| 317 ASSERT_EQ(data.size(), | 328 ASSERT_EQ(data.size(), |
| 318 fwrite(&data.at(0), sizeof(uint8_t), data.size(), file.get())); | 329 fwrite(&data.at(0), sizeof(uint8_t), data.size(), file.get())); |
| 319 } | 330 } |
| 320 ASSERT_TRUE(PathExists(file_path)); | 331 ASSERT_TRUE(PathExists(file_path)); |
| 321 | 332 |
| 322 // Validate collection: random content appears as though there is not | 333 // Validate collection: random content appears as though there is not |
| 323 // stability data. | 334 // stability data. |
| 324 PostmortemReportCollector collector(kProductName, kVersionNumber, | 335 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 325 kChannelName); | 336 kChannelName, nullptr); |
| 326 StabilityReport report; | 337 StabilityReport report; |
| 327 ASSERT_EQ(DEBUG_FILE_NO_DATA, collector.Collect(file_path, &report)); | 338 ASSERT_EQ(DEBUG_FILE_NO_DATA, collector.CollectOneReport(file_path, &report)); |
| 328 } | 339 } |
| 329 | 340 |
| 330 namespace { | 341 namespace { |
| 331 | 342 |
| 332 // Parameters for the activity tracking. | 343 // Parameters for the activity tracking. |
| 333 const size_t kFileSize = 2 * 1024; | 344 const size_t kFileSize = 2 * 1024; |
| 334 const int kStackDepth = 5; | 345 const int kStackDepth = 5; |
| 335 const uint64_t kAllocatorId = 0; | 346 const uint64_t kAllocatorId = 0; |
| 336 const char kAllocatorName[] = "PostmortemReportCollectorCollectionTest"; | 347 const char kAllocatorName[] = "PostmortemReportCollectorCollectionTest"; |
| 337 const uint64_t kTaskSequenceNum = 42; | 348 const uint64_t kTaskSequenceNum = 42; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 // Add some user data. | 452 // Add some user data. |
| 442 ActivityTrackerMemoryAllocator user_data_allocator( | 453 ActivityTrackerMemoryAllocator user_data_allocator( |
| 443 allocator_.get(), GlobalActivityTracker::kTypeIdUserDataRecord, | 454 allocator_.get(), GlobalActivityTracker::kTypeIdUserDataRecord, |
| 444 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false); | 455 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false); |
| 445 std::unique_ptr<ActivityUserData> user_data = | 456 std::unique_ptr<ActivityUserData> user_data = |
| 446 tracker_->GetUserData(activity_id, &user_data_allocator); | 457 tracker_->GetUserData(activity_id, &user_data_allocator); |
| 447 user_data->SetInt("some_int", 42); | 458 user_data->SetInt("some_int", 42); |
| 448 | 459 |
| 449 // Validate collection returns the expected report. | 460 // Validate collection returns the expected report. |
| 450 PostmortemReportCollector collector(kProductName, kVersionNumber, | 461 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 451 kChannelName); | 462 kChannelName, nullptr); |
| 452 StabilityReport report; | 463 StabilityReport report; |
| 453 ASSERT_EQ(SUCCESS, collector.Collect(debug_file_path(), &report)); | 464 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); |
| 454 | 465 |
| 455 // Validate the report. | 466 // Validate the report. |
| 456 ASSERT_EQ(1, report.process_states_size()); | 467 ASSERT_EQ(1, report.process_states_size()); |
| 457 const ProcessState& process_state = report.process_states(0); | 468 const ProcessState& process_state = report.process_states(0); |
| 458 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id()); | 469 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id()); |
| 459 ASSERT_EQ(1, process_state.threads_size()); | 470 ASSERT_EQ(1, process_state.threads_size()); |
| 460 | 471 |
| 461 const ThreadState& thread_state = process_state.threads(0); | 472 const ThreadState& thread_state = process_state.threads(0); |
| 462 EXPECT_EQ(base::PlatformThread::GetName(), thread_state.thread_name()); | 473 EXPECT_EQ(base::PlatformThread::GetName(), thread_state.thread_name()); |
| 463 #if defined(OS_WIN) | 474 #if defined(OS_WIN) |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, | 549 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, |
| 539 LogCollection) { | 550 LogCollection) { |
| 540 // Record some log messages. | 551 // Record some log messages. |
| 541 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, | 552 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, |
| 542 "", 3); | 553 "", 3); |
| 543 GlobalActivityTracker::Get()->RecordLogMessage("hello world"); | 554 GlobalActivityTracker::Get()->RecordLogMessage("hello world"); |
| 544 GlobalActivityTracker::Get()->RecordLogMessage("foo bar"); | 555 GlobalActivityTracker::Get()->RecordLogMessage("foo bar"); |
| 545 | 556 |
| 546 // Collect the stability report. | 557 // Collect the stability report. |
| 547 PostmortemReportCollector collector(kProductName, kVersionNumber, | 558 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 548 kChannelName); | 559 kChannelName, nullptr); |
| 549 StabilityReport report; | 560 StabilityReport report; |
| 550 ASSERT_EQ(SUCCESS, collector.Collect(debug_file_path(), &report)); | 561 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); |
| 551 | 562 |
| 552 // Validate the report's log content. | 563 // Validate the report's log content. |
| 553 ASSERT_EQ(2, report.log_messages_size()); | 564 ASSERT_EQ(2, report.log_messages_size()); |
| 554 ASSERT_EQ("hello world", report.log_messages(0)); | 565 ASSERT_EQ("hello world", report.log_messages(0)); |
| 555 ASSERT_EQ("foo bar", report.log_messages(1)); | 566 ASSERT_EQ("foo bar", report.log_messages(1)); |
| 556 } | 567 } |
| 557 | 568 |
| 558 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, | 569 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, |
| 559 GlobalUserDataCollection) { | 570 GlobalUserDataCollection) { |
| 560 const char string1[] = "foo"; | 571 const char string1[] = "foo"; |
| 561 const char string2[] = "bar"; | 572 const char string2[] = "bar"; |
| 562 | 573 |
| 563 // Record some global user data. | 574 // Record some global user data. |
| 564 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, | 575 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, |
| 565 "", 3); | 576 "", 3); |
| 566 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); | 577 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); |
| 567 global_data.Set("raw", "foo", 3); | 578 global_data.Set("raw", "foo", 3); |
| 568 global_data.SetString("string", "bar"); | 579 global_data.SetString("string", "bar"); |
| 569 global_data.SetChar("char", '9'); | 580 global_data.SetChar("char", '9'); |
| 570 global_data.SetInt("int", -9999); | 581 global_data.SetInt("int", -9999); |
| 571 global_data.SetUint("uint", 9999); | 582 global_data.SetUint("uint", 9999); |
| 572 global_data.SetBool("bool", true); | 583 global_data.SetBool("bool", true); |
| 573 global_data.SetReference("ref", string1, strlen(string1)); | 584 global_data.SetReference("ref", string1, strlen(string1)); |
| 574 global_data.SetStringReference("sref", string2); | 585 global_data.SetStringReference("sref", string2); |
| 575 | 586 |
| 576 // Collect the stability report. | 587 // Collect the stability report. |
| 577 PostmortemReportCollector collector(kProductName, kVersionNumber, | 588 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 578 kChannelName); | 589 kChannelName, nullptr); |
| 579 StabilityReport report; | 590 StabilityReport report; |
| 580 ASSERT_EQ(SUCCESS, collector.Collect(debug_file_path(), &report)); | 591 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); |
| 581 | 592 |
| 582 // Validate the report's user data. | 593 // Validate the report's user data. |
| 583 const auto& collected_data = report.global_data(); | 594 const auto& collected_data = report.global_data(); |
| 584 ASSERT_EQ(12U, collected_data.size()); | 595 ASSERT_EQ(12U, collected_data.size()); |
| 585 | 596 |
| 586 ASSERT_TRUE(base::ContainsKey(collected_data, "raw")); | 597 ASSERT_TRUE(base::ContainsKey(collected_data, "raw")); |
| 587 EXPECT_EQ(TypedValue::kBytesValue, collected_data.at("raw").value_case()); | 598 EXPECT_EQ(TypedValue::kBytesValue, collected_data.at("raw").value_case()); |
| 588 EXPECT_EQ("foo", collected_data.at("raw").bytes_value()); | 599 EXPECT_EQ("foo", collected_data.at("raw").bytes_value()); |
| 589 | 600 |
| 590 ASSERT_TRUE(base::ContainsKey(collected_data, "string")); | 601 ASSERT_TRUE(base::ContainsKey(collected_data, "string")); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 // Record some data. | 648 // Record some data. |
| 638 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, | 649 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, |
| 639 "", 3); | 650 "", 3); |
| 640 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); | 651 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); |
| 641 global_data.SetString("string", "bar"); | 652 global_data.SetString("string", "bar"); |
| 642 global_data.SetString("FieldTrial.string", "bar"); | 653 global_data.SetString("FieldTrial.string", "bar"); |
| 643 global_data.SetString("FieldTrial.foo", "bar"); | 654 global_data.SetString("FieldTrial.foo", "bar"); |
| 644 | 655 |
| 645 // Collect the stability report. | 656 // Collect the stability report. |
| 646 PostmortemReportCollector collector(kProductName, kVersionNumber, | 657 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 647 kChannelName); | 658 kChannelName, nullptr); |
| 648 StabilityReport report; | 659 StabilityReport report; |
| 649 ASSERT_EQ(SUCCESS, collector.Collect(debug_file_path(), &report)); | 660 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); |
| 650 | 661 |
| 651 // Validate the report's experiment and global data. | 662 // Validate the report's experiment and global data. |
| 652 ASSERT_EQ(2, report.field_trials_size()); | 663 ASSERT_EQ(2, report.field_trials_size()); |
| 653 EXPECT_NE(0U, report.field_trials(0).name_id()); | 664 EXPECT_NE(0U, report.field_trials(0).name_id()); |
| 654 EXPECT_NE(0U, report.field_trials(0).group_id()); | 665 EXPECT_NE(0U, report.field_trials(0).group_id()); |
| 655 EXPECT_NE(0U, report.field_trials(1).name_id()); | 666 EXPECT_NE(0U, report.field_trials(1).name_id()); |
| 656 EXPECT_EQ(report.field_trials(0).group_id(), | 667 EXPECT_EQ(report.field_trials(0).group_id(), |
| 657 report.field_trials(1).group_id()); | 668 report.field_trials(1).group_id()); |
| 658 | 669 |
| 659 // Expect 5 key/value pairs (including product details). | 670 // Expect 5 key/value pairs (including product details). |
| (...skipping 18 matching lines...) Expand all Loading... |
| 678 crashpad::UUID debug_uuid; | 689 crashpad::UUID debug_uuid; |
| 679 debug_uuid.InitializeFromString("11223344-5566-7788-abcd-0123456789ab"); | 690 debug_uuid.InitializeFromString("11223344-5566-7788-abcd-0123456789ab"); |
| 680 memcpy(module_info.identifier, &debug_uuid, sizeof(module_info.identifier)); | 691 memcpy(module_info.identifier, &debug_uuid, sizeof(module_info.identifier)); |
| 681 module_info.file = "foo"; | 692 module_info.file = "foo"; |
| 682 module_info.debug_file = "bar"; | 693 module_info.debug_file = "bar"; |
| 683 | 694 |
| 684 GlobalActivityTracker::Get()->RecordModuleInfo(module_info); | 695 GlobalActivityTracker::Get()->RecordModuleInfo(module_info); |
| 685 | 696 |
| 686 // Collect the stability report. | 697 // Collect the stability report. |
| 687 PostmortemReportCollector collector(kProductName, kVersionNumber, | 698 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 688 kChannelName); | 699 kChannelName, nullptr); |
| 689 StabilityReport report; | 700 StabilityReport report; |
| 690 ASSERT_EQ(SUCCESS, collector.Collect(debug_file_path(), &report)); | 701 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); |
| 691 | 702 |
| 692 // Validate the report's modules content. | 703 // Validate the report's modules content. |
| 693 ASSERT_EQ(1, report.process_states_size()); | 704 ASSERT_EQ(1, report.process_states_size()); |
| 694 const ProcessState& process_state = report.process_states(0); | 705 const ProcessState& process_state = report.process_states(0); |
| 695 ASSERT_EQ(1, process_state.modules_size()); | 706 ASSERT_EQ(1, process_state.modules_size()); |
| 696 | 707 |
| 697 const CodeModule collected_module = process_state.modules(0); | 708 const CodeModule collected_module = process_state.modules(0); |
| 698 EXPECT_EQ(module_info.address, | 709 EXPECT_EQ(module_info.address, |
| 699 static_cast<uintptr_t>(collected_module.base_address())); | 710 static_cast<uintptr_t>(collected_module.base_address())); |
| 700 EXPECT_EQ(module_info.size, static_cast<size_t>(collected_module.size())); | 711 EXPECT_EQ(module_info.size, static_cast<size_t>(collected_module.size())); |
| 701 EXPECT_EQ(module_info.file, collected_module.code_file()); | 712 EXPECT_EQ(module_info.file, collected_module.code_file()); |
| 702 EXPECT_EQ("CAFECAFE2d000", collected_module.code_identifier()); | 713 EXPECT_EQ("CAFECAFE2d000", collected_module.code_identifier()); |
| 703 EXPECT_EQ(module_info.debug_file, collected_module.debug_file()); | 714 EXPECT_EQ(module_info.debug_file, collected_module.debug_file()); |
| 704 EXPECT_EQ("1122334455667788ABCD0123456789AB1", | 715 EXPECT_EQ("1122334455667788ABCD0123456789AB1", |
| 705 collected_module.debug_identifier()); | 716 collected_module.debug_identifier()); |
| 706 EXPECT_EQ("", collected_module.version()); | 717 EXPECT_EQ("", collected_module.version()); |
| 707 EXPECT_EQ(0LL, collected_module.shrink_down_delta()); | 718 EXPECT_EQ(0LL, collected_module.shrink_down_delta()); |
| 708 EXPECT_EQ(!module_info.is_loaded, collected_module.is_unloaded()); | 719 EXPECT_EQ(!module_info.is_loaded, collected_module.is_unloaded()); |
| 709 } | 720 } |
| 710 | 721 |
| 722 TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, |
| 723 SystemStateTest) { |
| 724 // Setup. |
| 725 GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, |
| 726 "", 3); |
| 727 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); |
| 728 global_data.SetInt(kStabilityStartTimestamp, 12345LL); |
| 729 |
| 730 // Collect. |
| 731 MockSystemSessionAnalyzer analyzer; |
| 732 EXPECT_CALL(analyzer, |
| 733 IsSessionUnclean(base::Time::FromInternalValue(12345LL))) |
| 734 .Times(1) |
| 735 .WillOnce(Return(SystemSessionAnalyzer::CLEAN)); |
| 736 PostmortemReportCollector collector(kProductName, kVersionNumber, |
| 737 kChannelName, &analyzer); |
| 738 StabilityReport report; |
| 739 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); |
| 740 |
| 741 // Validate the report. |
| 742 ASSERT_EQ(SystemState::CLEAN, report.system_state().session_state()); |
| 743 } |
| 744 |
| 711 } // namespace browser_watcher | 745 } // namespace browser_watcher |
| OLD | NEW |