| Index: chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc
|
| diff --git a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc
|
| index 7f0a754e75bfe0e47230aa7fc4978e1854b70d6e..e5bf87d86105f263d3d4c366d057e3f0fa5365d6 100644
|
| --- a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc
|
| +++ b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc
|
| @@ -51,9 +51,49 @@ class UkmPageLoadMetricsObserverTest
|
| return ukm_service_test_harness_.test_ukm_service()->GetEntry(entry_index);
|
| }
|
|
|
| + std::vector<const ukm::UkmEntry*> GetUkmEntriesForSourceID(
|
| + int32_t source_id) {
|
| + std::vector<const ukm::UkmEntry*> entries;
|
| + for (size_t i = 0; i < ukm_entry_count(); ++i) {
|
| + const ukm::UkmEntry* entry = GetUkmEntry(i);
|
| + if (entry->source_id() == source_id)
|
| + entries.push_back(entry);
|
| + }
|
| + return entries;
|
| + }
|
| +
|
| + // Provides a single merged ukm::Entry proto that contains all metrics from
|
| + // the given |entries|. |entries| must be non-empty, and all |entries| must
|
| + // have the same |source_id| and |event_hash|.
|
| + ukm::Entry GetMergedEntryProto(
|
| + const std::vector<const ukm::UkmEntry*>& entries) {
|
| + EXPECT_FALSE(entries.empty());
|
| + ukm::Entry merged_entry;
|
| + for (auto* entry : entries) {
|
| + ukm::Entry entry_proto;
|
| + entry->PopulateProto(&entry_proto);
|
| + EXPECT_TRUE(entry_proto.has_source_id());
|
| + EXPECT_TRUE(entry_proto.has_event_hash());
|
| + if (merged_entry.has_source_id()) {
|
| + EXPECT_EQ(merged_entry.source_id(), entry_proto.source_id());
|
| + EXPECT_EQ(merged_entry.event_hash(), entry_proto.event_hash());
|
| + }
|
| + merged_entry.MergeFrom(entry_proto);
|
| + }
|
| + return merged_entry;
|
| + }
|
| +
|
| + ukm::Entry GetMergedEntryProtoForSourceID(int32_t source_id) {
|
| + ukm::Entry entry = GetMergedEntryProto(GetUkmEntriesForSourceID(source_id));
|
| + EXPECT_EQ(source_id, entry.source_id());
|
| + EXPECT_TRUE(entry.has_event_hash());
|
| + return entry;
|
| + }
|
| +
|
| static const ukm::Entry_Metric* FindMetric(
|
| const char* name,
|
| - const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) {
|
| + const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics)
|
| + WARN_UNUSED_RESULT {
|
| for (const auto& metric : metrics) {
|
| if (metric.metric_hash() == base::HashMetricName(name))
|
| return &metric;
|
| @@ -63,7 +103,8 @@ class UkmPageLoadMetricsObserverTest
|
|
|
| static bool HasMetric(
|
| const char* name,
|
| - const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) {
|
| + const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics)
|
| + WARN_UNUSED_RESULT {
|
| return FindMetric(name, metrics) != nullptr;
|
| }
|
|
|
| @@ -85,10 +126,18 @@ TEST_F(UkmPageLoadMetricsObserverTest, NoMetrics) {
|
| EXPECT_EQ(0ul, ukm_entry_count());
|
| }
|
|
|
| -TEST_F(UkmPageLoadMetricsObserverTest, FirstContentfulPaint) {
|
| +TEST_F(UkmPageLoadMetricsObserverTest, Basic) {
|
| + // PageLoadTiming with all recorded metrics other than FMP. This allows us to
|
| + // verify both that all metrics are logged, and that we don't log metrics that
|
| + // aren't present in the PageLoadTiming struct. Logging of FMP is verified in
|
| + // the FirstMeaningfulPaint test below.
|
| page_load_metrics::PageLoadTiming timing;
|
| timing.navigation_start = base::Time::FromDoubleT(1);
|
| + timing.parse_start = base::TimeDelta::FromMilliseconds(100);
|
| + timing.dom_content_loaded_event_start =
|
| + base::TimeDelta::FromMilliseconds(200);
|
| timing.first_contentful_paint = base::TimeDelta::FromMilliseconds(300);
|
| + timing.load_event_start = base::TimeDelta::FromMilliseconds(500);
|
| PopulateRequiredTimingFields(&timing);
|
|
|
| NavigateAndCommit(GURL(kTestUrl1));
|
| @@ -101,18 +150,49 @@ TEST_F(UkmPageLoadMetricsObserverTest, FirstContentfulPaint) {
|
| const ukm::UkmSource* source = GetUkmSource(0);
|
| EXPECT_EQ(GURL(kTestUrl1), source->url());
|
|
|
| - EXPECT_EQ(1ul, ukm_entry_count());
|
| - const ukm::UkmEntry* entry = GetUkmEntry(0);
|
| - EXPECT_EQ(entry->source_id(), source->id());
|
| -
|
| - ukm::Entry entry_proto;
|
| - entry->PopulateProto(&entry_proto);
|
| + EXPECT_GE(ukm_entry_count(), 1ul);
|
| + ukm::Entry entry_proto = GetMergedEntryProtoForSourceID(source->id());
|
| EXPECT_EQ(entry_proto.source_id(), source->id());
|
| EXPECT_EQ(entry_proto.event_hash(),
|
| base::HashMetricName(internal::kUkmPageLoadEventName));
|
| - EXPECT_GE(entry_proto.metrics_size(), 1);
|
| + EXPECT_FALSE(entry_proto.metrics().empty());
|
| + ExpectMetric(internal::kUkmParseStartName, 100, entry_proto.metrics());
|
| + ExpectMetric(internal::kUkmDomContentLoadedName, 200, entry_proto.metrics());
|
| ExpectMetric(internal::kUkmFirstContentfulPaintName, 300,
|
| entry_proto.metrics());
|
| + ExpectMetric(internal::kUkmLoadEventName, 500, entry_proto.metrics());
|
| + EXPECT_FALSE(
|
| + HasMetric(internal::kUkmFirstMeaningfulPaintName, entry_proto.metrics()));
|
| + EXPECT_TRUE(
|
| + HasMetric(internal::kUkmForegroundDurationName, entry_proto.metrics()));
|
| +}
|
| +
|
| +TEST_F(UkmPageLoadMetricsObserverTest, FirstMeaningfulPaint) {
|
| + page_load_metrics::PageLoadTiming timing;
|
| + timing.navigation_start = base::Time::FromDoubleT(1);
|
| + timing.first_meaningful_paint = base::TimeDelta::FromMilliseconds(600);
|
| + PopulateRequiredTimingFields(&timing);
|
| +
|
| + NavigateAndCommit(GURL(kTestUrl1));
|
| + SimulateTimingUpdate(timing);
|
| +
|
| + // Simulate closing the tab.
|
| + DeleteContents();
|
| +
|
| + EXPECT_EQ(1ul, ukm_source_count());
|
| + const ukm::UkmSource* source = GetUkmSource(0);
|
| + EXPECT_EQ(GURL(kTestUrl1), source->url());
|
| +
|
| + EXPECT_GE(ukm_entry_count(), 1ul);
|
| + ukm::Entry entry_proto = GetMergedEntryProtoForSourceID(source->id());
|
| + EXPECT_EQ(entry_proto.source_id(), source->id());
|
| + EXPECT_EQ(entry_proto.event_hash(),
|
| + base::HashMetricName(internal::kUkmPageLoadEventName));
|
| + EXPECT_FALSE(entry_proto.metrics().empty());
|
| + ExpectMetric(internal::kUkmFirstMeaningfulPaintName, 600,
|
| + entry_proto.metrics());
|
| + EXPECT_TRUE(
|
| + HasMetric(internal::kUkmForegroundDurationName, entry_proto.metrics()));
|
| }
|
|
|
| TEST_F(UkmPageLoadMetricsObserverTest, MultiplePageLoads) {
|
| @@ -124,7 +204,6 @@ TEST_F(UkmPageLoadMetricsObserverTest, MultiplePageLoads) {
|
| // Second navigation reports no timing metrics.
|
| page_load_metrics::PageLoadTiming timing2;
|
| timing2.navigation_start = base::Time::FromDoubleT(1);
|
| - timing2.first_contentful_paint = base::TimeDelta::FromMilliseconds(300);
|
| PopulateRequiredTimingFields(&timing2);
|
|
|
| NavigateAndCommit(GURL(kTestUrl1));
|
| @@ -143,30 +222,31 @@ TEST_F(UkmPageLoadMetricsObserverTest, MultiplePageLoads) {
|
| EXPECT_EQ(GURL(kTestUrl2), source2->url());
|
| EXPECT_NE(source1->id(), source2->id());
|
|
|
| - EXPECT_EQ(2ul, ukm_entry_count());
|
| - const ukm::UkmEntry* entry1 = GetUkmEntry(0);
|
| - const ukm::UkmEntry* entry2 = GetUkmEntry(1);
|
| - EXPECT_EQ(entry1->source_id(), source1->id());
|
| - EXPECT_EQ(entry2->source_id(), source2->id());
|
| - EXPECT_NE(entry1->source_id(), entry2->source_id());
|
| -
|
| - ukm::Entry entry1_proto;
|
| - entry1->PopulateProto(&entry1_proto);
|
| - ukm::Entry entry2_proto;
|
| - entry2->PopulateProto(&entry2_proto);
|
| + EXPECT_GE(ukm_entry_count(), 2ul);
|
| + ukm::Entry entry1_proto = GetMergedEntryProtoForSourceID(source1->id());
|
| + ukm::Entry entry2_proto = GetMergedEntryProtoForSourceID(source2->id());
|
| EXPECT_NE(entry1_proto.source_id(), entry2_proto.source_id());
|
|
|
| EXPECT_EQ(entry1_proto.source_id(), source1->id());
|
| EXPECT_EQ(entry1_proto.event_hash(),
|
| base::HashMetricName(internal::kUkmPageLoadEventName));
|
| - EXPECT_GE(entry1_proto.metrics_size(), 1);
|
| + EXPECT_FALSE(entry1_proto.metrics().empty());
|
| ExpectMetric(internal::kUkmFirstContentfulPaintName, 200,
|
| entry1_proto.metrics());
|
| + EXPECT_FALSE(HasMetric(internal::kUkmFirstMeaningfulPaintName,
|
| + entry2_proto.metrics()));
|
| + EXPECT_TRUE(
|
| + HasMetric(internal::kUkmForegroundDurationName, entry1_proto.metrics()));
|
|
|
| EXPECT_EQ(entry2_proto.source_id(), source2->id());
|
| EXPECT_EQ(entry2_proto.event_hash(),
|
| base::HashMetricName(internal::kUkmPageLoadEventName));
|
| - EXPECT_GE(entry2_proto.metrics_size(), 1);
|
| - ExpectMetric(internal::kUkmFirstContentfulPaintName, 300,
|
| - entry2_proto.metrics());
|
| + EXPECT_FALSE(entry2_proto.metrics().empty());
|
| + EXPECT_FALSE(HasMetric(internal::kUkmParseStartName, entry2_proto.metrics()));
|
| + EXPECT_FALSE(HasMetric(internal::kUkmFirstContentfulPaintName,
|
| + entry2_proto.metrics()));
|
| + EXPECT_FALSE(HasMetric(internal::kUkmFirstMeaningfulPaintName,
|
| + entry2_proto.metrics()));
|
| + EXPECT_TRUE(
|
| + HasMetric(internal::kUkmForegroundDurationName, entry2_proto.metrics()));
|
| }
|
|
|