| Index: components/browser_watcher/postmortem_report_collector_unittest.cc
|
| diff --git a/components/browser_watcher/postmortem_report_collector_unittest.cc b/components/browser_watcher/postmortem_report_collector_unittest.cc
|
| index 9b19bdb5c5f377064009f4633085ebc468e6a7d7..d7c2307ce33b64a8f3dfbb2b2eddad98af807110 100644
|
| --- a/components/browser_watcher/postmortem_report_collector_unittest.cc
|
| +++ b/components/browser_watcher/postmortem_report_collector_unittest.cc
|
| @@ -12,6 +12,7 @@
|
| #include <utility>
|
| #include <vector>
|
|
|
| +#include "base/debug/activity_analyzer.h"
|
| #include "base/debug/activity_tracker.h"
|
| #include "base/files/file.h"
|
| #include "base/files/file_path.h"
|
| @@ -22,6 +23,7 @@
|
| #include "base/memory/ptr_util.h"
|
| #include "base/metrics/persistent_memory_allocator.h"
|
| #include "base/process/process_handle.h"
|
| +#include "base/stl_util.h"
|
| #include "base/threading/platform_thread.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| @@ -30,6 +32,8 @@
|
| namespace browser_watcher {
|
|
|
| using base::debug::ActivityData;
|
| +using base::debug::ActivityTrackerMemoryAllocator;
|
| +using base::debug::ActivityUserData;
|
| using base::debug::GlobalActivityTracker;
|
| using base::debug::ThreadActivityTracker;
|
| using base::File;
|
| @@ -423,7 +427,7 @@ TEST_F(PostmortemReportCollectorCollectionTest, CollectSuccess) {
|
| tracker_->PushActivity(
|
| nullptr, base::debug::Activity::ACT_LOCK_ACQUIRE,
|
| ActivityData::ForLock(reinterpret_cast<void*>(kLockAddress)));
|
| - tracker_->PushActivity(
|
| + ThreadActivityTracker::ActivityId activity_id = tracker_->PushActivity(
|
| nullptr, base::debug::Activity::ACT_EVENT_WAIT,
|
| ActivityData::ForEvent(reinterpret_cast<void*>(kEventAddress)));
|
| tracker_->PushActivity(nullptr, base::debug::Activity::ACT_THREAD_JOIN,
|
| @@ -434,6 +438,14 @@ TEST_F(PostmortemReportCollectorCollectionTest, CollectSuccess) {
|
| tracker_->PushActivity(nullptr, base::debug::Activity::ACT_THREAD_JOIN,
|
| ActivityData::ForThread(kAnotherThreadId));
|
|
|
| + // Add some user data.
|
| + ActivityTrackerMemoryAllocator user_data_allocator(
|
| + allocator_.get(), GlobalActivityTracker::kTypeIdUserDataRecord,
|
| + GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false);
|
| + std::unique_ptr<ActivityUserData> user_data =
|
| + tracker_->GetUserData(activity_id, &user_data_allocator);
|
| + user_data->SetInt("some_int", 42);
|
| +
|
| // Validate collection returns the expected report.
|
| PostmortemReportCollector collector(kProductName, kVersionNumber,
|
| kChannelName);
|
| @@ -464,26 +476,35 @@ TEST_F(PostmortemReportCollectorCollectionTest, CollectSuccess) {
|
| EXPECT_EQ(Activity::ACT_TASK_RUN, activity.type());
|
| EXPECT_EQ(kTaskOrigin, activity.origin_address());
|
| EXPECT_EQ(kTaskSequenceNum, activity.task_sequence_id());
|
| + EXPECT_EQ(0U, activity.user_data().size());
|
| }
|
| {
|
| const Activity& activity = thread_state.activities(1);
|
| EXPECT_EQ(Activity::ACT_LOCK_ACQUIRE, activity.type());
|
| EXPECT_EQ(kLockAddress, activity.lock_address());
|
| + EXPECT_EQ(0U, activity.user_data().size());
|
| }
|
| {
|
| const Activity& activity = thread_state.activities(2);
|
| EXPECT_EQ(Activity::ACT_EVENT_WAIT, activity.type());
|
| EXPECT_EQ(kEventAddress, activity.event_address());
|
| + ASSERT_EQ(1U, activity.user_data().size());
|
| + ASSERT_TRUE(base::ContainsKey(activity.user_data(), "some_int"));
|
| + EXPECT_EQ(TypedValue::kSignedValue,
|
| + activity.user_data().at("some_int").value_case());
|
| + EXPECT_EQ(42, activity.user_data().at("some_int").signed_value());
|
| }
|
| {
|
| const Activity& activity = thread_state.activities(3);
|
| EXPECT_EQ(Activity::ACT_THREAD_JOIN, activity.type());
|
| EXPECT_EQ(kThreadId, activity.thread_id());
|
| + EXPECT_EQ(0U, activity.user_data().size());
|
| }
|
| {
|
| const Activity& activity = thread_state.activities(4);
|
| EXPECT_EQ(Activity::ACT_PROCESS_WAIT, activity.type());
|
| EXPECT_EQ(kProcessId, activity.process_id());
|
| + EXPECT_EQ(0U, activity.user_data().size());
|
| }
|
| }
|
|
|
| @@ -538,4 +559,73 @@ TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest,
|
| ASSERT_EQ("foo bar", report->log_messages(1));
|
| }
|
|
|
| +TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest,
|
| + GlobalUserDataCollection) {
|
| + const char string1[] = "foo";
|
| + const char string2[] = "bar";
|
| +
|
| + // Record some global user data.
|
| + GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL,
|
| + "", 3);
|
| + ActivityUserData& global_data = GlobalActivityTracker::Get()->user_data();
|
| + global_data.Set("raw", "foo", 3);
|
| + global_data.SetString("string", "bar");
|
| + global_data.SetChar("char", '9');
|
| + global_data.SetInt("int", -9999);
|
| + global_data.SetUint("uint", 9999);
|
| + global_data.SetBool("bool", true);
|
| + global_data.SetReference("ref", string1, strlen(string1));
|
| + global_data.SetStringReference("sref", string2);
|
| +
|
| + // Collect the stability report.
|
| + PostmortemReportCollector collector(kProductName, kVersionNumber,
|
| + kChannelName);
|
| + std::unique_ptr<StabilityReport> report;
|
| + ASSERT_EQ(PostmortemReportCollector::SUCCESS,
|
| + collector.Collect(debug_file_path(), &report));
|
| + ASSERT_NE(nullptr, report);
|
| +
|
| + // Validate the report's log content.
|
| + const auto& collected_data = report->global_data();
|
| + ASSERT_EQ(8U, collected_data.size());
|
| +
|
| + ASSERT_TRUE(base::ContainsKey(collected_data, "raw"));
|
| + EXPECT_EQ(TypedValue::kBytesValue, collected_data.at("raw").value_case());
|
| + EXPECT_EQ("foo", collected_data.at("raw").bytes_value());
|
| +
|
| + ASSERT_TRUE(base::ContainsKey(collected_data, "string"));
|
| + EXPECT_EQ(TypedValue::kStringValue, collected_data.at("string").value_case());
|
| + EXPECT_EQ("bar", collected_data.at("string").string_value());
|
| +
|
| + ASSERT_TRUE(base::ContainsKey(collected_data, "char"));
|
| + EXPECT_EQ(TypedValue::kCharValue, collected_data.at("char").value_case());
|
| + EXPECT_EQ("9", collected_data.at("char").char_value());
|
| +
|
| + ASSERT_TRUE(base::ContainsKey(collected_data, "int"));
|
| + EXPECT_EQ(TypedValue::kSignedValue, collected_data.at("int").value_case());
|
| + EXPECT_EQ(-9999, collected_data.at("int").signed_value());
|
| +
|
| + ASSERT_TRUE(base::ContainsKey(collected_data, "uint"));
|
| + EXPECT_EQ(TypedValue::kUnsignedValue, collected_data.at("uint").value_case());
|
| + EXPECT_EQ(9999U, collected_data.at("uint").unsigned_value());
|
| +
|
| + ASSERT_TRUE(base::ContainsKey(collected_data, "bool"));
|
| + EXPECT_EQ(TypedValue::kBoolValue, collected_data.at("bool").value_case());
|
| + EXPECT_TRUE(collected_data.at("bool").bool_value());
|
| +
|
| + ASSERT_TRUE(base::ContainsKey(collected_data, "ref"));
|
| + EXPECT_EQ(TypedValue::kBytesReference, collected_data.at("ref").value_case());
|
| + const TypedValue::Reference& ref = collected_data.at("ref").bytes_reference();
|
| + EXPECT_EQ(reinterpret_cast<uintptr_t>(string1), ref.address());
|
| + EXPECT_EQ(strlen(string1), static_cast<uint64_t>(ref.size()));
|
| +
|
| + ASSERT_TRUE(base::ContainsKey(collected_data, "sref"));
|
| + EXPECT_EQ(TypedValue::kStringReference,
|
| + collected_data.at("sref").value_case());
|
| + const TypedValue::Reference& sref =
|
| + collected_data.at("sref").string_reference();
|
| + EXPECT_EQ(reinterpret_cast<uintptr_t>(string2), sref.address());
|
| + EXPECT_EQ(strlen(string2), static_cast<uint64_t>(sref.size()));
|
| +}
|
| +
|
| } // namespace browser_watcher
|
|
|