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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.h"
6
7 #include <memory>
8
9 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
10 #include "components/page_load_metrics/browser/page_load_tracker.h"
11 #include "components/page_load_metrics/browser/protocol_util.h"
12 #include "components/page_load_metrics/common/test/page_load_metrics_test_util.h"
13
14 class ProtocolPageLoadMetricsObserverTest
15 : public page_load_metrics::PageLoadMetricsObserverTestHarness {
16 protected:
RegisterObservers(page_load_metrics::PageLoadTracker * tracker)17 void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override {
18 std::unique_ptr<ProtocolPageLoadMetricsObserver> observer =
19 std::make_unique<ProtocolPageLoadMetricsObserver>();
20 observer_ = observer.get();
21 tracker->AddObserver(std::move(observer));
22 }
23
InitializeTestPageLoadTiming(page_load_metrics::mojom::PageLoadTiming * timing)24 void InitializeTestPageLoadTiming(
25 page_load_metrics::mojom::PageLoadTiming* timing) {
26 page_load_metrics::InitPageLoadTimingForTest(timing);
27 timing->navigation_start = base::Time::FromDoubleT(1);
28 timing->parse_timing->parse_start = base::TimeDelta::FromMilliseconds(100);
29 timing->paint_timing->first_paint = base::TimeDelta::FromMilliseconds(200);
30 timing->paint_timing->first_contentful_paint =
31 base::TimeDelta::FromMilliseconds(300);
32 timing->paint_timing->first_meaningful_paint =
33 base::TimeDelta::FromMilliseconds(400);
34 timing->document_timing->dom_content_loaded_event_start =
35 base::TimeDelta::FromMilliseconds(600);
36 timing->document_timing->load_event_start =
37 base::TimeDelta::FromMilliseconds(1000);
38 PopulateRequiredTimingFields(timing);
39 }
40
SimulateNavigation(net::HttpResponseInfo::ConnectionInfo connection_info)41 void SimulateNavigation(
42 net::HttpResponseInfo::ConnectionInfo connection_info) {
43 NavigateAndCommit(GURL("http://google.com"));
44
45 // Force the ConnectionInfo that the observer received from the
46 // NavigationHandle.
47 observer_->protocol_ =
48 page_load_metrics::GetNetworkProtocol(connection_info);
49
50 page_load_metrics::mojom::PageLoadTiming timing;
51 InitializeTestPageLoadTiming(&timing);
52 tester()->SimulateTimingUpdate(timing);
53
54 // Navigate again to force OnComplete, which happens when a new navigation
55 // occurs.
56 NavigateAndCommit(GURL("http://example.com"));
57 }
58
CountTotalProtocolMetricsRecorded()59 int CountTotalProtocolMetricsRecorded() {
60 int count = 0;
61
62 base::HistogramTester::CountsMap counts_map =
63 tester()->histogram_tester().GetTotalCountsForPrefix(
64 "PageLoad.Clients.Protocol.");
65 for (const auto& entry : counts_map)
66 count += entry.second;
67 return count;
68 }
69
CheckHistograms(int expected_count,const std::string & protocol)70 void CheckHistograms(int expected_count, const std::string& protocol) {
71 EXPECT_EQ(expected_count, CountTotalProtocolMetricsRecorded());
72 if (expected_count == 0)
73 return;
74
75 std::string prefix = "PageLoad.Clients.Protocol.";
76 prefix += protocol;
77
78 tester()->histogram_tester().ExpectTotalCount(
79 prefix + ".ParseTiming.NavigationToParseStart", 1);
80 tester()->histogram_tester().ExpectTotalCount(
81 prefix + ".PaintTiming.ParseStartToFirstContentfulPaint", 1);
82 tester()->histogram_tester().ExpectTotalCount(
83 prefix + ".PaintTiming.NavigationToFirstContentfulPaint", 1);
84 tester()->histogram_tester().ExpectTotalCount(
85 prefix + ".Experimental.PaintTiming.ParseStartToFirstMeaningfulPaint",
86 1);
87 tester()->histogram_tester().ExpectTotalCount(
88 prefix + ".Experimental.PaintTiming.NavigationToFirstMeaningfulPaint",
89 1);
90 tester()->histogram_tester().ExpectTotalCount(
91 prefix + ".DocumentTiming.NavigationToDOMContentLoadedEventFired", 1);
92 tester()->histogram_tester().ExpectTotalCount(
93 prefix + ".DocumentTiming.NavigationToLoadEventFired", 1);
94 }
95
96 ProtocolPageLoadMetricsObserver* observer_;
97 };
98
TEST_F(ProtocolPageLoadMetricsObserverTest,H11Navigation)99 TEST_F(ProtocolPageLoadMetricsObserverTest, H11Navigation) {
100 SimulateNavigation(net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1);
101 CheckHistograms(7, "H11");
102 }
103
TEST_F(ProtocolPageLoadMetricsObserverTest,H10Navigation)104 TEST_F(ProtocolPageLoadMetricsObserverTest, H10Navigation) {
105 SimulateNavigation(net::HttpResponseInfo::CONNECTION_INFO_HTTP1_0);
106 CheckHistograms(0, "");
107 }
108
TEST_F(ProtocolPageLoadMetricsObserverTest,H09Navigation)109 TEST_F(ProtocolPageLoadMetricsObserverTest, H09Navigation) {
110 SimulateNavigation(net::HttpResponseInfo::CONNECTION_INFO_HTTP0_9);
111 CheckHistograms(0, "");
112 }
113
TEST_F(ProtocolPageLoadMetricsObserverTest,H2Navigation)114 TEST_F(ProtocolPageLoadMetricsObserverTest, H2Navigation) {
115 SimulateNavigation(net::HttpResponseInfo::CONNECTION_INFO_HTTP2);
116 CheckHistograms(7, "H2");
117 }
118
TEST_F(ProtocolPageLoadMetricsObserverTest,QuicNavigation)119 TEST_F(ProtocolPageLoadMetricsObserverTest, QuicNavigation) {
120 SimulateNavigation(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
121 CheckHistograms(7, "QUIC");
122 }
123
TEST_F(ProtocolPageLoadMetricsObserverTest,UnknownNavigation)124 TEST_F(ProtocolPageLoadMetricsObserverTest, UnknownNavigation) {
125 SimulateNavigation(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN);
126 CheckHistograms(0, "");
127 }
128