| 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 "base/metrics/metrics_hashes.h" |
| 9 #include "base/optional.h" | 9 #include "base/optional.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| 11 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_
test_harness.h" | 11 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_
test_harness.h" |
| 12 #include "chrome/test/base/testing_browser_process.h" | 12 #include "chrome/test/base/testing_browser_process.h" |
| 13 #include "components/metrics/proto/ukm/entry.pb.h" | 13 #include "components/ukm/test_ukm_recorder.h" |
| 14 #include "components/ukm/test_ukm_service.h" | |
| 15 #include "components/ukm/ukm_entry.h" | |
| 16 #include "components/ukm/ukm_source.h" | 14 #include "components/ukm/ukm_source.h" |
| 17 #include "testing/gmock/include/gmock/gmock.h" | 15 #include "testing/gmock/include/gmock/gmock.h" |
| 18 | 16 |
| 19 using testing::AnyNumber; | 17 using testing::AnyNumber; |
| 20 using testing::Mock; | 18 using testing::Mock; |
| 21 using testing::Return; | 19 using testing::Return; |
| 22 | 20 |
| 23 namespace { | 21 namespace { |
| 24 | 22 |
| 25 const char kTestUrl1[] = "https://www.google.com/"; | 23 const char kTestUrl1[] = "https://www.google.com/"; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 .WillRepeatedly(Return(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN)); | 62 .WillRepeatedly(Return(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN)); |
| 65 | 63 |
| 66 EXPECT_CALL(mock_network_quality_provider_, GetHttpRTT()) | 64 EXPECT_CALL(mock_network_quality_provider_, GetHttpRTT()) |
| 67 .Times(AnyNumber()) | 65 .Times(AnyNumber()) |
| 68 .WillRepeatedly(Return(base::Optional<base::TimeDelta>())); | 66 .WillRepeatedly(Return(base::Optional<base::TimeDelta>())); |
| 69 | 67 |
| 70 EXPECT_CALL(mock_network_quality_provider_, GetTransportRTT()) | 68 EXPECT_CALL(mock_network_quality_provider_, GetTransportRTT()) |
| 71 .Times(AnyNumber()) | 69 .Times(AnyNumber()) |
| 72 .WillRepeatedly(Return(base::Optional<base::TimeDelta>())); | 70 .WillRepeatedly(Return(base::Optional<base::TimeDelta>())); |
| 73 | 71 |
| 74 TestingBrowserProcess::GetGlobal()->SetUkmService( | 72 TestingBrowserProcess::GetGlobal()->SetUkmRecorder(&test_ukm_recorder_); |
| 75 ukm_service_test_harness_.test_ukm_service()); | |
| 76 } | 73 } |
| 77 | 74 |
| 78 size_t ukm_source_count() { | 75 size_t ukm_source_count() { return test_ukm_recorder_.sources_count(); } |
| 79 return ukm_service_test_harness_.test_ukm_service()->sources_count(); | |
| 80 } | |
| 81 | 76 |
| 82 size_t ukm_entry_count() { | 77 size_t ukm_entry_count() { return test_ukm_recorder_.entries_count(); } |
| 83 return ukm_service_test_harness_.test_ukm_service()->entries_count(); | |
| 84 } | |
| 85 | 78 |
| 86 MockNetworkQualityProvider& mock_network_quality_provider() { | 79 MockNetworkQualityProvider& mock_network_quality_provider() { |
| 87 return mock_network_quality_provider_; | 80 return mock_network_quality_provider_; |
| 88 } | 81 } |
| 89 | 82 |
| 90 const ukm::UkmSource* GetUkmSourceForUrl(const char* url) { | 83 const ukm::UkmSource* GetUkmSourceForUrl(const char* url) { |
| 91 return ukm_service_test_harness_.test_ukm_service()->GetSourceForUrl(url); | 84 return test_ukm_recorder_.GetSourceForUrl(url); |
| 92 } | 85 } |
| 93 | 86 |
| 94 const ukm::UkmEntry* GetUkmEntry(size_t entry_index) { | 87 const ukm::mojom::UkmEntry* GetUkmEntry(size_t entry_index) { |
| 95 return ukm_service_test_harness_.test_ukm_service()->GetEntry(entry_index); | 88 return test_ukm_recorder_.GetEntry(entry_index); |
| 96 } | 89 } |
| 97 | 90 |
| 98 std::vector<const ukm::UkmEntry*> GetUkmEntriesForSourceID( | 91 std::vector<const ukm::mojom::UkmEntry*> GetUkmEntriesForSourceID( |
| 99 int32_t source_id) { | 92 ukm::SourceId source_id) { |
| 100 std::vector<const ukm::UkmEntry*> entries; | 93 std::vector<const ukm::mojom::UkmEntry*> entries; |
| 101 for (size_t i = 0; i < ukm_entry_count(); ++i) { | 94 for (size_t i = 0; i < ukm_entry_count(); ++i) { |
| 102 const ukm::UkmEntry* entry = GetUkmEntry(i); | 95 const ukm::mojom::UkmEntry* entry = GetUkmEntry(i); |
| 103 if (entry->source_id() == source_id) | 96 if (entry->source_id == source_id) |
| 104 entries.push_back(entry); | 97 entries.push_back(entry); |
| 105 } | 98 } |
| 106 return entries; | 99 return entries; |
| 107 } | 100 } |
| 108 | 101 |
| 109 // Provides a single merged ukm::Entry proto that contains all metrics from | 102 // Provides a single merged ukm::mojom::UkmEntry proto that contains all |
| 110 // the given |entries|. |entries| must be non-empty, and all |entries| must | 103 // metrics from the given |entries|. |entries| must be non-empty, and all |
| 111 // have the same |source_id| and |event_hash|. | 104 // |entries| must have the same |source_id| and |event_hash|. |
| 112 ukm::Entry GetMergedEntryProto( | 105 ukm::mojom::UkmEntryPtr GetMergedEntry( |
| 113 const std::vector<const ukm::UkmEntry*>& entries) { | 106 const std::vector<const ukm::mojom::UkmEntry*>& entries) { |
| 114 EXPECT_FALSE(entries.empty()); | 107 EXPECT_FALSE(entries.empty()); |
| 115 ukm::Entry merged_entry; | 108 ukm::mojom::UkmEntryPtr merged_entry = ukm::mojom::UkmEntry::New(); |
| 116 for (auto* entry : entries) { | 109 for (const auto* entry : entries) { |
| 117 ukm::Entry entry_proto; | 110 if (merged_entry->event_hash) { |
| 118 entry->PopulateProto(&entry_proto); | 111 EXPECT_EQ(merged_entry->source_id, entry->source_id); |
| 119 EXPECT_TRUE(entry_proto.has_source_id()); | 112 EXPECT_EQ(merged_entry->event_hash, entry->event_hash); |
| 120 EXPECT_TRUE(entry_proto.has_event_hash()); | 113 } else { |
| 121 if (merged_entry.has_source_id()) { | 114 merged_entry->event_hash = entry->event_hash; |
| 122 EXPECT_EQ(merged_entry.source_id(), entry_proto.source_id()); | 115 merged_entry->source_id = entry->source_id; |
| 123 EXPECT_EQ(merged_entry.event_hash(), entry_proto.event_hash()); | |
| 124 } | 116 } |
| 125 merged_entry.MergeFrom(entry_proto); | 117 for (const auto& metric : entry->metrics) { |
| 118 merged_entry->metrics.emplace_back(metric->Clone()); |
| 119 } |
| 126 } | 120 } |
| 127 return merged_entry; | 121 return merged_entry; |
| 128 } | 122 } |
| 129 | 123 |
| 130 ukm::Entry GetMergedEntryProtoForSourceID(int32_t source_id) { | 124 ukm::mojom::UkmEntryPtr GetMergedEntryForSourceID(ukm::SourceId source_id) { |
| 131 ukm::Entry entry = GetMergedEntryProto(GetUkmEntriesForSourceID(source_id)); | 125 ukm::mojom::UkmEntryPtr entry = |
| 132 EXPECT_EQ(source_id, entry.source_id()); | 126 GetMergedEntry(GetUkmEntriesForSourceID(source_id)); |
| 133 EXPECT_TRUE(entry.has_event_hash()); | 127 EXPECT_EQ(source_id, entry->source_id); |
| 128 EXPECT_NE(0UL, entry->event_hash); |
| 134 return entry; | 129 return entry; |
| 135 } | 130 } |
| 136 | 131 |
| 137 static const ukm::Entry_Metric* FindMetric( | 132 static bool HasMetric(const char* name, |
| 138 const char* name, | 133 const ukm::mojom::UkmEntry* entry) WARN_UNUSED_RESULT { |
| 139 const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) | 134 return ukm::TestUkmRecorder::FindMetric(entry, name) != nullptr; |
| 140 WARN_UNUSED_RESULT { | |
| 141 for (const auto& metric : metrics) { | |
| 142 if (metric.metric_hash() == base::HashMetricName(name)) | |
| 143 return &metric; | |
| 144 } | |
| 145 return nullptr; | |
| 146 } | 135 } |
| 147 | 136 |
| 148 static bool HasMetric( | 137 static void ExpectMetric(const char* name, |
| 149 const char* name, | 138 int64_t expected_value, |
| 150 const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) | 139 const ukm::mojom::UkmEntry* entry) { |
| 151 WARN_UNUSED_RESULT { | 140 const ukm::mojom::UkmMetric* metric = |
| 152 return FindMetric(name, metrics) != nullptr; | 141 ukm::TestUkmRecorder::FindMetric(entry, name); |
| 153 } | |
| 154 | |
| 155 static void ExpectMetric( | |
| 156 const char* name, | |
| 157 int64_t expected_value, | |
| 158 const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) { | |
| 159 const ukm::Entry_Metric* metric = FindMetric(name, metrics); | |
| 160 EXPECT_NE(nullptr, metric) << "Failed to find metric: " << name; | 142 EXPECT_NE(nullptr, metric) << "Failed to find metric: " << name; |
| 161 EXPECT_EQ(expected_value, metric->value()); | 143 EXPECT_EQ(expected_value, metric->value); |
| 162 } | 144 } |
| 163 | 145 |
| 164 private: | 146 private: |
| 165 MockNetworkQualityProvider mock_network_quality_provider_; | 147 MockNetworkQualityProvider mock_network_quality_provider_; |
| 166 ukm::UkmServiceTestingHarness ukm_service_test_harness_; | 148 ukm::TestUkmRecorder test_ukm_recorder_; |
| 167 }; | 149 }; |
| 168 | 150 |
| 169 TEST_F(UkmPageLoadMetricsObserverTest, NoMetrics) { | 151 TEST_F(UkmPageLoadMetricsObserverTest, NoMetrics) { |
| 170 EXPECT_EQ(0ul, ukm_source_count()); | 152 EXPECT_EQ(0ul, ukm_source_count()); |
| 171 EXPECT_EQ(0ul, ukm_entry_count()); | 153 EXPECT_EQ(0ul, ukm_entry_count()); |
| 172 } | 154 } |
| 173 | 155 |
| 174 TEST_F(UkmPageLoadMetricsObserverTest, Basic) { | 156 TEST_F(UkmPageLoadMetricsObserverTest, Basic) { |
| 175 // PageLoadTiming with all recorded metrics other than FMP. This allows us to | 157 // PageLoadTiming with all recorded metrics other than FMP. This allows us to |
| 176 // verify both that all metrics are logged, and that we don't log metrics that | 158 // verify both that all metrics are logged, and that we don't log metrics that |
| (...skipping 15 matching lines...) Expand all Loading... |
| 192 SimulateTimingUpdate(timing); | 174 SimulateTimingUpdate(timing); |
| 193 | 175 |
| 194 // Simulate closing the tab. | 176 // Simulate closing the tab. |
| 195 DeleteContents(); | 177 DeleteContents(); |
| 196 | 178 |
| 197 EXPECT_EQ(1ul, ukm_source_count()); | 179 EXPECT_EQ(1ul, ukm_source_count()); |
| 198 const ukm::UkmSource* source = GetUkmSourceForUrl(kTestUrl1); | 180 const ukm::UkmSource* source = GetUkmSourceForUrl(kTestUrl1); |
| 199 EXPECT_EQ(GURL(kTestUrl1), source->url()); | 181 EXPECT_EQ(GURL(kTestUrl1), source->url()); |
| 200 | 182 |
| 201 EXPECT_GE(ukm_entry_count(), 1ul); | 183 EXPECT_GE(ukm_entry_count(), 1ul); |
| 202 ukm::Entry entry_proto = GetMergedEntryProtoForSourceID(source->id()); | 184 ukm::mojom::UkmEntryPtr entry = GetMergedEntryForSourceID(source->id()); |
| 203 EXPECT_EQ(entry_proto.source_id(), source->id()); | 185 EXPECT_EQ(entry->source_id, source->id()); |
| 204 EXPECT_EQ(entry_proto.event_hash(), | 186 EXPECT_EQ(entry->event_hash, |
| 205 base::HashMetricName(internal::kUkmPageLoadEventName)); | 187 base::HashMetricName(internal::kUkmPageLoadEventName)); |
| 206 EXPECT_FALSE(entry_proto.metrics().empty()); | 188 EXPECT_FALSE(entry->metrics.empty()); |
| 207 ExpectMetric(internal::kUkmPageTransition, ui::PAGE_TRANSITION_LINK, | 189 ExpectMetric(internal::kUkmPageTransition, ui::PAGE_TRANSITION_LINK, |
| 208 entry_proto.metrics()); | 190 entry.get()); |
| 209 ExpectMetric(internal::kUkmParseStartName, 100, entry_proto.metrics()); | 191 ExpectMetric(internal::kUkmParseStartName, 100, entry.get()); |
| 210 ExpectMetric(internal::kUkmDomContentLoadedName, 200, entry_proto.metrics()); | 192 ExpectMetric(internal::kUkmDomContentLoadedName, 200, entry.get()); |
| 211 ExpectMetric(internal::kUkmFirstContentfulPaintName, 300, | 193 ExpectMetric(internal::kUkmFirstContentfulPaintName, 300, entry.get()); |
| 212 entry_proto.metrics()); | 194 ExpectMetric(internal::kUkmLoadEventName, 500, entry.get()); |
| 213 ExpectMetric(internal::kUkmLoadEventName, 500, entry_proto.metrics()); | 195 EXPECT_FALSE(HasMetric(internal::kUkmFirstMeaningfulPaintName, entry.get())); |
| 214 EXPECT_FALSE( | 196 EXPECT_TRUE(HasMetric(internal::kUkmForegroundDurationName, entry.get())); |
| 215 HasMetric(internal::kUkmFirstMeaningfulPaintName, entry_proto.metrics())); | |
| 216 EXPECT_TRUE( | |
| 217 HasMetric(internal::kUkmForegroundDurationName, entry_proto.metrics())); | |
| 218 } | 197 } |
| 219 | 198 |
| 220 TEST_F(UkmPageLoadMetricsObserverTest, FailedProvisionalLoad) { | 199 TEST_F(UkmPageLoadMetricsObserverTest, FailedProvisionalLoad) { |
| 221 EXPECT_CALL(mock_network_quality_provider(), GetEffectiveConnectionType()) | 200 EXPECT_CALL(mock_network_quality_provider(), GetEffectiveConnectionType()) |
| 222 .WillRepeatedly(Return(net::EFFECTIVE_CONNECTION_TYPE_2G)); | 201 .WillRepeatedly(Return(net::EFFECTIVE_CONNECTION_TYPE_2G)); |
| 223 | 202 |
| 224 GURL url(kTestUrl1); | 203 GURL url(kTestUrl1); |
| 225 content::RenderFrameHostTester* rfh_tester = | 204 content::RenderFrameHostTester* rfh_tester = |
| 226 content::RenderFrameHostTester::For(main_rfh()); | 205 content::RenderFrameHostTester::For(main_rfh()); |
| 227 rfh_tester->SimulateNavigationStart(url); | 206 rfh_tester->SimulateNavigationStart(url); |
| 228 rfh_tester->SimulateNavigationError(url, net::ERR_TIMED_OUT); | 207 rfh_tester->SimulateNavigationError(url, net::ERR_TIMED_OUT); |
| 229 rfh_tester->SimulateNavigationStop(); | 208 rfh_tester->SimulateNavigationStop(); |
| 230 | 209 |
| 231 // Simulate closing the tab. | 210 // Simulate closing the tab. |
| 232 DeleteContents(); | 211 DeleteContents(); |
| 233 | 212 |
| 234 EXPECT_EQ(1ul, ukm_source_count()); | 213 EXPECT_EQ(1ul, ukm_source_count()); |
| 235 const ukm::UkmSource* source = GetUkmSourceForUrl(kTestUrl1); | 214 const ukm::UkmSource* source = GetUkmSourceForUrl(kTestUrl1); |
| 236 EXPECT_EQ(GURL(kTestUrl1), source->url()); | 215 EXPECT_EQ(GURL(kTestUrl1), source->url()); |
| 237 | 216 |
| 238 EXPECT_GE(ukm_entry_count(), 1ul); | 217 EXPECT_GE(ukm_entry_count(), 1ul); |
| 239 ukm::Entry entry_proto = GetMergedEntryProtoForSourceID(source->id()); | 218 ukm::mojom::UkmEntryPtr entry = GetMergedEntryForSourceID(source->id()); |
| 240 EXPECT_EQ(entry_proto.source_id(), source->id()); | 219 EXPECT_EQ(entry->source_id, source->id()); |
| 241 EXPECT_EQ(entry_proto.event_hash(), | 220 EXPECT_EQ(entry->event_hash, |
| 242 base::HashMetricName(internal::kUkmPageLoadEventName)); | 221 base::HashMetricName(internal::kUkmPageLoadEventName)); |
| 243 | 222 |
| 244 // Make sure that only the following metrics are logged. In particular, no | 223 // Make sure that only the following metrics are logged. In particular, no |
| 245 // paint/document/etc timing metrics should be logged for failed provisional | 224 // paint/document/etc timing metrics should be logged for failed provisional |
| 246 // loads. | 225 // loads. |
| 247 EXPECT_EQ(5, entry_proto.metrics().size()); | 226 EXPECT_EQ(5ul, entry->metrics.size()); |
| 248 ExpectMetric(internal::kUkmPageTransition, ui::PAGE_TRANSITION_LINK, | 227 ExpectMetric(internal::kUkmPageTransition, ui::PAGE_TRANSITION_LINK, |
| 249 entry_proto.metrics()); | 228 entry.get()); |
| 250 ExpectMetric(internal::kUkmEffectiveConnectionType, | 229 ExpectMetric(internal::kUkmEffectiveConnectionType, |
| 251 net::EFFECTIVE_CONNECTION_TYPE_2G, entry_proto.metrics()); | 230 net::EFFECTIVE_CONNECTION_TYPE_2G, entry.get()); |
| 252 ExpectMetric(internal::kUkmNetErrorCode, | 231 ExpectMetric(internal::kUkmNetErrorCode, |
| 253 static_cast<int64_t>(net::ERR_TIMED_OUT) * -1, | 232 static_cast<int64_t>(net::ERR_TIMED_OUT) * -1, entry.get()); |
| 254 entry_proto.metrics()); | 233 EXPECT_TRUE(HasMetric(internal::kUkmForegroundDurationName, entry.get())); |
| 255 EXPECT_TRUE( | 234 EXPECT_TRUE(HasMetric(internal::kUkmFailedProvisionaLoadName, entry.get())); |
| 256 HasMetric(internal::kUkmForegroundDurationName, entry_proto.metrics())); | |
| 257 EXPECT_TRUE( | |
| 258 HasMetric(internal::kUkmFailedProvisionaLoadName, entry_proto.metrics())); | |
| 259 } | 235 } |
| 260 | 236 |
| 261 TEST_F(UkmPageLoadMetricsObserverTest, FirstMeaningfulPaint) { | 237 TEST_F(UkmPageLoadMetricsObserverTest, FirstMeaningfulPaint) { |
| 262 page_load_metrics::mojom::PageLoadTiming timing; | 238 page_load_metrics::mojom::PageLoadTiming timing; |
| 263 page_load_metrics::InitPageLoadTimingForTest(&timing); | 239 page_load_metrics::InitPageLoadTimingForTest(&timing); |
| 264 timing.navigation_start = base::Time::FromDoubleT(1); | 240 timing.navigation_start = base::Time::FromDoubleT(1); |
| 265 timing.paint_timing->first_meaningful_paint = | 241 timing.paint_timing->first_meaningful_paint = |
| 266 base::TimeDelta::FromMilliseconds(600); | 242 base::TimeDelta::FromMilliseconds(600); |
| 267 PopulateRequiredTimingFields(&timing); | 243 PopulateRequiredTimingFields(&timing); |
| 268 | 244 |
| 269 NavigateAndCommit(GURL(kTestUrl1)); | 245 NavigateAndCommit(GURL(kTestUrl1)); |
| 270 SimulateTimingUpdate(timing); | 246 SimulateTimingUpdate(timing); |
| 271 | 247 |
| 272 // Simulate closing the tab. | 248 // Simulate closing the tab. |
| 273 DeleteContents(); | 249 DeleteContents(); |
| 274 | 250 |
| 275 EXPECT_EQ(1ul, ukm_source_count()); | 251 EXPECT_EQ(1ul, ukm_source_count()); |
| 276 const ukm::UkmSource* source = GetUkmSourceForUrl(kTestUrl1); | 252 const ukm::UkmSource* source = GetUkmSourceForUrl(kTestUrl1); |
| 277 EXPECT_EQ(GURL(kTestUrl1), source->url()); | 253 EXPECT_EQ(GURL(kTestUrl1), source->url()); |
| 278 | 254 |
| 279 EXPECT_GE(ukm_entry_count(), 1ul); | 255 EXPECT_GE(ukm_entry_count(), 1ul); |
| 280 ukm::Entry entry_proto = GetMergedEntryProtoForSourceID(source->id()); | 256 ukm::mojom::UkmEntryPtr entry = GetMergedEntryForSourceID(source->id()); |
| 281 EXPECT_EQ(entry_proto.source_id(), source->id()); | 257 EXPECT_EQ(entry->source_id, source->id()); |
| 282 EXPECT_EQ(entry_proto.event_hash(), | 258 EXPECT_EQ(entry->event_hash, |
| 283 base::HashMetricName(internal::kUkmPageLoadEventName)); | 259 base::HashMetricName(internal::kUkmPageLoadEventName)); |
| 284 EXPECT_FALSE(entry_proto.metrics().empty()); | 260 EXPECT_FALSE(entry->metrics.empty()); |
| 285 ExpectMetric(internal::kUkmFirstMeaningfulPaintName, 600, | 261 ExpectMetric(internal::kUkmFirstMeaningfulPaintName, 600, entry.get()); |
| 286 entry_proto.metrics()); | 262 EXPECT_TRUE(HasMetric(internal::kUkmForegroundDurationName, entry.get())); |
| 287 EXPECT_TRUE( | |
| 288 HasMetric(internal::kUkmForegroundDurationName, entry_proto.metrics())); | |
| 289 } | 263 } |
| 290 | 264 |
| 291 TEST_F(UkmPageLoadMetricsObserverTest, MultiplePageLoads) { | 265 TEST_F(UkmPageLoadMetricsObserverTest, MultiplePageLoads) { |
| 292 page_load_metrics::mojom::PageLoadTiming timing1; | 266 page_load_metrics::mojom::PageLoadTiming timing1; |
| 293 page_load_metrics::InitPageLoadTimingForTest(&timing1); | 267 page_load_metrics::InitPageLoadTimingForTest(&timing1); |
| 294 timing1.navigation_start = base::Time::FromDoubleT(1); | 268 timing1.navigation_start = base::Time::FromDoubleT(1); |
| 295 timing1.paint_timing->first_contentful_paint = | 269 timing1.paint_timing->first_contentful_paint = |
| 296 base::TimeDelta::FromMilliseconds(200); | 270 base::TimeDelta::FromMilliseconds(200); |
| 297 PopulateRequiredTimingFields(&timing1); | 271 PopulateRequiredTimingFields(&timing1); |
| 298 | 272 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 312 DeleteContents(); | 286 DeleteContents(); |
| 313 | 287 |
| 314 EXPECT_EQ(2ul, ukm_source_count()); | 288 EXPECT_EQ(2ul, ukm_source_count()); |
| 315 const ukm::UkmSource* source1 = GetUkmSourceForUrl(kTestUrl1); | 289 const ukm::UkmSource* source1 = GetUkmSourceForUrl(kTestUrl1); |
| 316 const ukm::UkmSource* source2 = GetUkmSourceForUrl(kTestUrl2); | 290 const ukm::UkmSource* source2 = GetUkmSourceForUrl(kTestUrl2); |
| 317 EXPECT_EQ(GURL(kTestUrl1), source1->url()); | 291 EXPECT_EQ(GURL(kTestUrl1), source1->url()); |
| 318 EXPECT_EQ(GURL(kTestUrl2), source2->url()); | 292 EXPECT_EQ(GURL(kTestUrl2), source2->url()); |
| 319 EXPECT_NE(source1->id(), source2->id()); | 293 EXPECT_NE(source1->id(), source2->id()); |
| 320 | 294 |
| 321 EXPECT_GE(ukm_entry_count(), 2ul); | 295 EXPECT_GE(ukm_entry_count(), 2ul); |
| 322 ukm::Entry entry1_proto = GetMergedEntryProtoForSourceID(source1->id()); | 296 ukm::mojom::UkmEntryPtr entry1 = GetMergedEntryForSourceID(source1->id()); |
| 323 ukm::Entry entry2_proto = GetMergedEntryProtoForSourceID(source2->id()); | 297 ukm::mojom::UkmEntryPtr entry2 = GetMergedEntryForSourceID(source2->id()); |
| 324 EXPECT_NE(entry1_proto.source_id(), entry2_proto.source_id()); | 298 EXPECT_NE(entry1->source_id, entry2->source_id); |
| 325 | 299 |
| 326 EXPECT_EQ(entry1_proto.source_id(), source1->id()); | 300 EXPECT_EQ(entry1->source_id, source1->id()); |
| 327 EXPECT_EQ(entry1_proto.event_hash(), | 301 EXPECT_EQ(entry1->event_hash, |
| 328 base::HashMetricName(internal::kUkmPageLoadEventName)); | 302 base::HashMetricName(internal::kUkmPageLoadEventName)); |
| 329 EXPECT_FALSE(entry1_proto.metrics().empty()); | 303 EXPECT_FALSE(entry1->metrics.empty()); |
| 330 ExpectMetric(internal::kUkmFirstContentfulPaintName, 200, | 304 ExpectMetric(internal::kUkmFirstContentfulPaintName, 200, entry1.get()); |
| 331 entry1_proto.metrics()); | 305 EXPECT_FALSE(HasMetric(internal::kUkmFirstMeaningfulPaintName, entry2.get())); |
| 332 EXPECT_FALSE(HasMetric(internal::kUkmFirstMeaningfulPaintName, | 306 EXPECT_TRUE(HasMetric(internal::kUkmForegroundDurationName, entry1.get())); |
| 333 entry2_proto.metrics())); | |
| 334 EXPECT_TRUE( | |
| 335 HasMetric(internal::kUkmForegroundDurationName, entry1_proto.metrics())); | |
| 336 | 307 |
| 337 EXPECT_EQ(entry2_proto.source_id(), source2->id()); | 308 EXPECT_EQ(entry2->source_id, source2->id()); |
| 338 EXPECT_EQ(entry2_proto.event_hash(), | 309 EXPECT_EQ(entry2->event_hash, |
| 339 base::HashMetricName(internal::kUkmPageLoadEventName)); | 310 base::HashMetricName(internal::kUkmPageLoadEventName)); |
| 340 EXPECT_FALSE(entry2_proto.metrics().empty()); | 311 EXPECT_FALSE(entry2->metrics.empty()); |
| 341 EXPECT_FALSE(HasMetric(internal::kUkmParseStartName, entry2_proto.metrics())); | 312 EXPECT_FALSE(HasMetric(internal::kUkmParseStartName, entry2.get())); |
| 342 EXPECT_FALSE(HasMetric(internal::kUkmFirstContentfulPaintName, | 313 EXPECT_FALSE(HasMetric(internal::kUkmFirstContentfulPaintName, entry2.get())); |
| 343 entry2_proto.metrics())); | 314 EXPECT_FALSE(HasMetric(internal::kUkmFirstMeaningfulPaintName, entry2.get())); |
| 344 EXPECT_FALSE(HasMetric(internal::kUkmFirstMeaningfulPaintName, | 315 EXPECT_TRUE(HasMetric(internal::kUkmForegroundDurationName, entry2.get())); |
| 345 entry2_proto.metrics())); | |
| 346 EXPECT_TRUE( | |
| 347 HasMetric(internal::kUkmForegroundDurationName, entry2_proto.metrics())); | |
| 348 } | 316 } |
| 349 | 317 |
| 350 TEST_F(UkmPageLoadMetricsObserverTest, NetworkQualityEstimates) { | 318 TEST_F(UkmPageLoadMetricsObserverTest, NetworkQualityEstimates) { |
| 351 EXPECT_CALL(mock_network_quality_provider(), GetEffectiveConnectionType()) | 319 EXPECT_CALL(mock_network_quality_provider(), GetEffectiveConnectionType()) |
| 352 .WillRepeatedly(Return(net::EFFECTIVE_CONNECTION_TYPE_3G)); | 320 .WillRepeatedly(Return(net::EFFECTIVE_CONNECTION_TYPE_3G)); |
| 353 EXPECT_CALL(mock_network_quality_provider(), GetHttpRTT()) | 321 EXPECT_CALL(mock_network_quality_provider(), GetHttpRTT()) |
| 354 .WillRepeatedly(Return(base::TimeDelta::FromMilliseconds(100))); | 322 .WillRepeatedly(Return(base::TimeDelta::FromMilliseconds(100))); |
| 355 EXPECT_CALL(mock_network_quality_provider(), GetTransportRTT()) | 323 EXPECT_CALL(mock_network_quality_provider(), GetTransportRTT()) |
| 356 .WillRepeatedly(Return(base::TimeDelta::FromMilliseconds(200))); | 324 .WillRepeatedly(Return(base::TimeDelta::FromMilliseconds(200))); |
| 357 | 325 |
| 358 NavigateAndCommit(GURL(kTestUrl1)); | 326 NavigateAndCommit(GURL(kTestUrl1)); |
| 359 | 327 |
| 360 // Simulate closing the tab. | 328 // Simulate closing the tab. |
| 361 DeleteContents(); | 329 DeleteContents(); |
| 362 | 330 |
| 363 EXPECT_EQ(1ul, ukm_source_count()); | 331 EXPECT_EQ(1ul, ukm_source_count()); |
| 364 const ukm::UkmSource* source = GetUkmSourceForUrl(kTestUrl1); | 332 const ukm::UkmSource* source = GetUkmSourceForUrl(kTestUrl1); |
| 365 EXPECT_EQ(GURL(kTestUrl1), source->url()); | 333 EXPECT_EQ(GURL(kTestUrl1), source->url()); |
| 366 | 334 |
| 367 EXPECT_GE(ukm_entry_count(), 1ul); | 335 EXPECT_GE(ukm_entry_count(), 1ul); |
| 368 ukm::Entry entry_proto = GetMergedEntryProtoForSourceID(source->id()); | 336 ukm::mojom::UkmEntryPtr entry = GetMergedEntryForSourceID(source->id()); |
| 369 EXPECT_EQ(entry_proto.source_id(), source->id()); | 337 EXPECT_EQ(entry->source_id, source->id()); |
| 370 EXPECT_EQ(entry_proto.event_hash(), | 338 EXPECT_EQ(entry->event_hash, |
| 371 base::HashMetricName(internal::kUkmPageLoadEventName)); | 339 base::HashMetricName(internal::kUkmPageLoadEventName)); |
| 372 EXPECT_FALSE(entry_proto.metrics().empty()); | 340 EXPECT_FALSE(entry->metrics.empty()); |
| 373 ExpectMetric(internal::kUkmEffectiveConnectionType, | 341 ExpectMetric(internal::kUkmEffectiveConnectionType, |
| 374 net::EFFECTIVE_CONNECTION_TYPE_3G, entry_proto.metrics()); | 342 net::EFFECTIVE_CONNECTION_TYPE_3G, entry.get()); |
| 375 ExpectMetric(internal::kUkmHttpRttEstimate, 100, entry_proto.metrics()); | 343 ExpectMetric(internal::kUkmHttpRttEstimate, 100, entry.get()); |
| 376 ExpectMetric(internal::kUkmTransportRttEstimate, 200, entry_proto.metrics()); | 344 ExpectMetric(internal::kUkmTransportRttEstimate, 200, entry.get()); |
| 377 } | 345 } |
| 378 | 346 |
| 379 TEST_F(UkmPageLoadMetricsObserverTest, PageTransitionReload) { | 347 TEST_F(UkmPageLoadMetricsObserverTest, PageTransitionReload) { |
| 380 GURL url(kTestUrl1); | 348 GURL url(kTestUrl1); |
| 381 NavigateWithPageTransitionAndCommit(GURL(kTestUrl1), | 349 NavigateWithPageTransitionAndCommit(GURL(kTestUrl1), |
| 382 ui::PAGE_TRANSITION_RELOAD); | 350 ui::PAGE_TRANSITION_RELOAD); |
| 383 | 351 |
| 384 // Simulate closing the tab. | 352 // Simulate closing the tab. |
| 385 DeleteContents(); | 353 DeleteContents(); |
| 386 | 354 |
| 387 EXPECT_EQ(1ul, ukm_source_count()); | 355 EXPECT_EQ(1ul, ukm_source_count()); |
| 388 const ukm::UkmSource* source = GetUkmSourceForUrl(kTestUrl1); | 356 const ukm::UkmSource* source = GetUkmSourceForUrl(kTestUrl1); |
| 389 EXPECT_EQ(GURL(kTestUrl1), source->url()); | 357 EXPECT_EQ(GURL(kTestUrl1), source->url()); |
| 390 | 358 |
| 391 EXPECT_GE(ukm_entry_count(), 1ul); | 359 EXPECT_GE(ukm_entry_count(), 1ul); |
| 392 ukm::Entry entry_proto = GetMergedEntryProtoForSourceID(source->id()); | 360 ukm::mojom::UkmEntryPtr entry = GetMergedEntryForSourceID(source->id()); |
| 393 EXPECT_EQ(entry_proto.source_id(), source->id()); | 361 EXPECT_EQ(entry->source_id, source->id()); |
| 394 EXPECT_EQ(entry_proto.event_hash(), | 362 EXPECT_EQ(entry->event_hash, |
| 395 base::HashMetricName(internal::kUkmPageLoadEventName)); | 363 base::HashMetricName(internal::kUkmPageLoadEventName)); |
| 396 EXPECT_FALSE(entry_proto.metrics().empty()); | 364 EXPECT_FALSE(entry->metrics.empty()); |
| 397 ExpectMetric(internal::kUkmPageTransition, ui::PAGE_TRANSITION_RELOAD, | 365 ExpectMetric(internal::kUkmPageTransition, ui::PAGE_TRANSITION_RELOAD, |
| 398 entry_proto.metrics()); | 366 entry.get()); |
| 399 } | 367 } |
| OLD | NEW |