OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_obser
ver.h" | 5 #include "chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_obser
ver.h" |
6 | 6 |
7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/metrics/metrics_hashes.h" |
8 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_
test_harness.h" | 9 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_
test_harness.h" |
9 #include "chrome/test/base/testing_browser_process.h" | 10 #include "chrome/test/base/testing_browser_process.h" |
| 11 #include "components/metrics/proto/ukm/entry.pb.h" |
10 #include "components/ukm/test_ukm_service.h" | 12 #include "components/ukm/test_ukm_service.h" |
| 13 #include "components/ukm/ukm_entry.h" |
11 #include "components/ukm/ukm_source.h" | 14 #include "components/ukm/ukm_source.h" |
12 | 15 |
13 namespace { | 16 namespace { |
14 | 17 |
15 const char kDefaultTestUrl[] = "https://google.com"; | 18 const char kTestUrl1[] = "https://www.google.com/"; |
| 19 const char kTestUrl2[] = "https://www.example.com/"; |
16 | 20 |
17 } // namespace | 21 } // namespace |
18 | 22 |
19 class UkmPageLoadMetricsObserverTest | 23 class UkmPageLoadMetricsObserverTest |
20 : public page_load_metrics::PageLoadMetricsObserverTestHarness { | 24 : public page_load_metrics::PageLoadMetricsObserverTestHarness { |
21 protected: | 25 protected: |
22 void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override { | 26 void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override { |
23 tracker->AddObserver(base::MakeUnique<UkmPageLoadMetricsObserver>()); | 27 tracker->AddObserver(base::MakeUnique<UkmPageLoadMetricsObserver>()); |
24 } | 28 } |
25 | 29 |
26 void SetUp() override { | 30 void SetUp() override { |
27 page_load_metrics::PageLoadMetricsObserverTestHarness::SetUp(); | 31 page_load_metrics::PageLoadMetricsObserverTestHarness::SetUp(); |
28 | 32 |
29 TestingBrowserProcess::GetGlobal()->SetUkmService( | 33 TestingBrowserProcess::GetGlobal()->SetUkmService( |
30 ukm_service_test_harness_.test_ukm_service()); | 34 ukm_service_test_harness_.test_ukm_service()); |
31 } | 35 } |
32 | 36 |
33 void InitializeTestPageLoadTiming(page_load_metrics::PageLoadTiming* timing) { | |
34 timing->navigation_start = base::Time::FromInternalValue(1); | |
35 timing->first_contentful_paint = base::TimeDelta::FromInternalValue(300); | |
36 PopulateRequiredTimingFields(timing); | |
37 } | |
38 | |
39 size_t ukm_source_count() { | 37 size_t ukm_source_count() { |
40 return ukm_service_test_harness_.test_ukm_service()->sources_count(); | 38 return ukm_service_test_harness_.test_ukm_service()->sources_count(); |
41 } | 39 } |
42 | 40 |
| 41 size_t ukm_entry_count() { |
| 42 return ukm_service_test_harness_.test_ukm_service()->entries_count(); |
| 43 } |
| 44 |
43 const ukm::UkmSource* GetUkmSource(size_t source_index) { | 45 const ukm::UkmSource* GetUkmSource(size_t source_index) { |
44 return ukm_service_test_harness_.test_ukm_service()->GetSource( | 46 return ukm_service_test_harness_.test_ukm_service()->GetSource( |
45 source_index); | 47 source_index); |
46 } | 48 } |
47 | 49 |
| 50 const ukm::UkmEntry* GetUkmEntry(size_t entry_index) { |
| 51 return ukm_service_test_harness_.test_ukm_service()->GetEntry(entry_index); |
| 52 } |
| 53 |
| 54 static const ukm::Entry_Metric* FindMetric( |
| 55 const char* name, |
| 56 const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) { |
| 57 for (const auto& metric : metrics) { |
| 58 if (metric.metric_hash() == base::HashMetricName(name)) |
| 59 return &metric; |
| 60 } |
| 61 return nullptr; |
| 62 } |
| 63 |
| 64 static bool HasMetric( |
| 65 const char* name, |
| 66 const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) { |
| 67 return FindMetric(name, metrics) != nullptr; |
| 68 } |
| 69 |
| 70 static void ExpectMetric( |
| 71 const char* name, |
| 72 int64_t expected_value, |
| 73 const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) { |
| 74 const ukm::Entry_Metric* metric = FindMetric(name, metrics); |
| 75 EXPECT_NE(nullptr, metric) << "Failed to find metric: " << name; |
| 76 EXPECT_EQ(expected_value, metric->value()); |
| 77 } |
| 78 |
48 private: | 79 private: |
49 ukm::UkmServiceTestingHarness ukm_service_test_harness_; | 80 ukm::UkmServiceTestingHarness ukm_service_test_harness_; |
50 }; | 81 }; |
51 | 82 |
52 TEST_F(UkmPageLoadMetricsObserverTest, NoMetrics) { | 83 TEST_F(UkmPageLoadMetricsObserverTest, NoMetrics) { |
53 EXPECT_EQ(0ul, ukm_source_count()); | 84 EXPECT_EQ(0ul, ukm_source_count()); |
| 85 EXPECT_EQ(0ul, ukm_entry_count()); |
54 } | 86 } |
55 | 87 |
56 TEST_F(UkmPageLoadMetricsObserverTest, FirstContentfulPaint) { | 88 TEST_F(UkmPageLoadMetricsObserverTest, FirstContentfulPaint) { |
57 page_load_metrics::PageLoadTiming timing; | 89 page_load_metrics::PageLoadTiming timing; |
58 InitializeTestPageLoadTiming(&timing); | 90 timing.navigation_start = base::Time::FromDoubleT(1); |
| 91 timing.first_contentful_paint = base::TimeDelta::FromMilliseconds(300); |
| 92 PopulateRequiredTimingFields(&timing); |
59 | 93 |
60 NavigateAndCommit(GURL(kDefaultTestUrl)); | 94 NavigateAndCommit(GURL(kTestUrl1)); |
61 SimulateTimingUpdate(timing); | 95 SimulateTimingUpdate(timing); |
62 | 96 |
63 // Simulate closing the tab. | 97 // Simulate closing the tab. |
64 DeleteContents(); | 98 DeleteContents(); |
65 | 99 |
66 EXPECT_EQ(1ul, ukm_source_count()); | 100 EXPECT_EQ(1ul, ukm_source_count()); |
| 101 const ukm::UkmSource* source = GetUkmSource(0); |
| 102 EXPECT_EQ(GURL(kTestUrl1), source->url()); |
67 | 103 |
68 const ukm::UkmSource* source = GetUkmSource(0); | 104 EXPECT_EQ(1ul, ukm_entry_count()); |
69 ASSERT_TRUE(source); | 105 const ukm::UkmEntry* entry = GetUkmEntry(0); |
| 106 EXPECT_EQ(entry->source_id(), source->id()); |
70 | 107 |
71 EXPECT_EQ(GURL(kDefaultTestUrl), source->committed_url()); | 108 ukm::Entry entry_proto; |
72 EXPECT_EQ(base::TimeDelta::FromInternalValue(300), | 109 entry->PopulateProto(&entry_proto); |
73 source->first_contentful_paint()); | 110 EXPECT_EQ(entry_proto.source_id(), source->id()); |
| 111 EXPECT_EQ(entry_proto.event_hash(), |
| 112 base::HashMetricName(internal::kUkmPageLoadEventName)); |
| 113 EXPECT_GE(entry_proto.metrics_size(), 1); |
| 114 ExpectMetric(internal::kUkmFirstContentfulPaintName, 300, |
| 115 entry_proto.metrics()); |
74 } | 116 } |
| 117 |
| 118 TEST_F(UkmPageLoadMetricsObserverTest, MultiplePageLoads) { |
| 119 page_load_metrics::PageLoadTiming timing1; |
| 120 timing1.navigation_start = base::Time::FromDoubleT(1); |
| 121 timing1.first_contentful_paint = base::TimeDelta::FromMilliseconds(200); |
| 122 PopulateRequiredTimingFields(&timing1); |
| 123 |
| 124 // Second navigation reports no timing metrics. |
| 125 page_load_metrics::PageLoadTiming timing2; |
| 126 timing2.navigation_start = base::Time::FromDoubleT(1); |
| 127 timing2.first_contentful_paint = base::TimeDelta::FromMilliseconds(300); |
| 128 PopulateRequiredTimingFields(&timing2); |
| 129 |
| 130 NavigateAndCommit(GURL(kTestUrl1)); |
| 131 SimulateTimingUpdate(timing1); |
| 132 |
| 133 NavigateAndCommit(GURL(kTestUrl2)); |
| 134 SimulateTimingUpdate(timing2); |
| 135 |
| 136 // Simulate closing the tab. |
| 137 DeleteContents(); |
| 138 |
| 139 EXPECT_EQ(2ul, ukm_source_count()); |
| 140 const ukm::UkmSource* source1 = GetUkmSource(0); |
| 141 const ukm::UkmSource* source2 = GetUkmSource(1); |
| 142 EXPECT_EQ(GURL(kTestUrl1), source1->url()); |
| 143 EXPECT_EQ(GURL(kTestUrl2), source2->url()); |
| 144 EXPECT_NE(source1->id(), source2->id()); |
| 145 |
| 146 EXPECT_EQ(2ul, ukm_entry_count()); |
| 147 const ukm::UkmEntry* entry1 = GetUkmEntry(0); |
| 148 const ukm::UkmEntry* entry2 = GetUkmEntry(1); |
| 149 EXPECT_EQ(entry1->source_id(), source1->id()); |
| 150 EXPECT_EQ(entry2->source_id(), source2->id()); |
| 151 EXPECT_NE(entry1->source_id(), entry2->source_id()); |
| 152 |
| 153 ukm::Entry entry1_proto; |
| 154 entry1->PopulateProto(&entry1_proto); |
| 155 ukm::Entry entry2_proto; |
| 156 entry2->PopulateProto(&entry2_proto); |
| 157 EXPECT_NE(entry1_proto.source_id(), entry2_proto.source_id()); |
| 158 |
| 159 EXPECT_EQ(entry1_proto.source_id(), source1->id()); |
| 160 EXPECT_EQ(entry1_proto.event_hash(), |
| 161 base::HashMetricName(internal::kUkmPageLoadEventName)); |
| 162 EXPECT_GE(entry1_proto.metrics_size(), 1); |
| 163 ExpectMetric(internal::kUkmFirstContentfulPaintName, 200, |
| 164 entry1_proto.metrics()); |
| 165 |
| 166 EXPECT_EQ(entry2_proto.source_id(), source2->id()); |
| 167 EXPECT_EQ(entry2_proto.event_hash(), |
| 168 base::HashMetricName(internal::kUkmPageLoadEventName)); |
| 169 EXPECT_GE(entry2_proto.metrics_size(), 1); |
| 170 ExpectMetric(internal::kUkmFirstContentfulPaintName, 300, |
| 171 entry2_proto.metrics()); |
| 172 } |
OLD | NEW |