OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015 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 "components/page_load_metrics/renderer/metrics_render_frame_observer.h" | |
6 | |
7 #include <memory> | |
8 #include <utility> | |
9 | |
10 #include "base/memory/ptr_util.h" | |
11 #include "base/time/time.h" | |
12 #include "base/timer/mock_timer.h" | |
13 #include "components/page_load_metrics/common/page_load_timing.h" | |
14 #include "components/page_load_metrics/renderer/fake_page_timing_metrics_ipc_sen
der.h" | |
15 #include "testing/gtest/include/gtest/gtest.h" | |
16 | |
17 namespace page_load_metrics { | |
18 | |
19 // Implementation of the MetricsRenderFrameObserver class we're testing, | |
20 // with the GetTiming() and ShouldSendMetrics() methods stubbed out to make | |
21 // the rest of the class more testable. | |
22 class TestMetricsRenderFrameObserver : public MetricsRenderFrameObserver { | |
23 public: | |
24 TestMetricsRenderFrameObserver() : MetricsRenderFrameObserver(nullptr) {} | |
25 | |
26 std::unique_ptr<base::Timer> CreateTimer() const override { | |
27 if (!mock_timer_) | |
28 ADD_FAILURE() << "CreateTimer() called, but no MockTimer available."; | |
29 return std::move(mock_timer_); | |
30 } | |
31 | |
32 // We intercept sent messages and dispatch them to our | |
33 // FakePageTimingMetricsIPCSender, which we use to verify that the expected | |
34 // IPC messages get sent. | |
35 bool Send(IPC::Message* message) override { | |
36 return fake_timing_ipc_sender_.Send(message); | |
37 } | |
38 | |
39 void set_mock_timer(std::unique_ptr<base::Timer> timer) { | |
40 ASSERT_EQ(nullptr, mock_timer_); | |
41 mock_timer_ = std::move(timer); | |
42 } | |
43 | |
44 void ExpectPageLoadTiming(const PageLoadTiming& timing) { | |
45 fake_timing_ipc_sender_.ExpectPageLoadTiming(timing); | |
46 } | |
47 | |
48 PageLoadTiming GetTiming() const override { | |
49 return fake_timing_ipc_sender_.expected_timings().empty() | |
50 ? PageLoadTiming() | |
51 : fake_timing_ipc_sender_.expected_timings().back(); | |
52 } | |
53 | |
54 void VerifyExpectedTimings() const { | |
55 fake_timing_ipc_sender_.VerifyExpectedTimings(); | |
56 } | |
57 | |
58 bool ShouldSendMetrics() const override { return true; } | |
59 bool HasNoRenderFrame() const override { return false; } | |
60 | |
61 private: | |
62 FakePageTimingMetricsIPCSender fake_timing_ipc_sender_; | |
63 mutable std::unique_ptr<base::Timer> mock_timer_; | |
64 }; | |
65 | |
66 typedef testing::Test MetricsRenderFrameObserverTest; | |
67 | |
68 TEST_F(MetricsRenderFrameObserverTest, NoMetrics) { | |
69 TestMetricsRenderFrameObserver observer; | |
70 base::MockTimer* mock_timer = new base::MockTimer(false, false); | |
71 observer.set_mock_timer(base::WrapUnique(mock_timer)); | |
72 | |
73 observer.DidChangePerformanceTiming(); | |
74 ASSERT_FALSE(mock_timer->IsRunning()); | |
75 } | |
76 | |
77 TEST_F(MetricsRenderFrameObserverTest, SingleMetric) { | |
78 base::Time nav_start = base::Time::FromDoubleT(10); | |
79 base::TimeDelta first_layout = base::TimeDelta::FromMillisecondsD(10); | |
80 | |
81 TestMetricsRenderFrameObserver observer; | |
82 base::MockTimer* mock_timer = new base::MockTimer(false, false); | |
83 observer.set_mock_timer(base::WrapUnique(mock_timer)); | |
84 | |
85 PageLoadTiming timing; | |
86 timing.navigation_start = nav_start; | |
87 observer.ExpectPageLoadTiming(timing); | |
88 observer.DidCommitProvisionalLoad(true, false); | |
89 mock_timer->Fire(); | |
90 | |
91 timing.first_layout = first_layout; | |
92 observer.ExpectPageLoadTiming(timing); | |
93 | |
94 observer.DidChangePerformanceTiming(); | |
95 mock_timer->Fire(); | |
96 } | |
97 | |
98 TEST_F(MetricsRenderFrameObserverTest, MultipleMetrics) { | |
99 base::Time nav_start = base::Time::FromDoubleT(10); | |
100 base::TimeDelta first_layout = base::TimeDelta::FromMillisecondsD(2); | |
101 base::TimeDelta dom_event = base::TimeDelta::FromMillisecondsD(2); | |
102 base::TimeDelta load_event = base::TimeDelta::FromMillisecondsD(2); | |
103 | |
104 TestMetricsRenderFrameObserver observer; | |
105 base::MockTimer* mock_timer = new base::MockTimer(false, false); | |
106 observer.set_mock_timer(base::WrapUnique(mock_timer)); | |
107 | |
108 PageLoadTiming timing; | |
109 timing.navigation_start = nav_start; | |
110 observer.ExpectPageLoadTiming(timing); | |
111 observer.DidCommitProvisionalLoad(true, false); | |
112 mock_timer->Fire(); | |
113 | |
114 timing.first_layout = first_layout; | |
115 timing.dom_content_loaded_event_start = dom_event; | |
116 observer.ExpectPageLoadTiming(timing); | |
117 | |
118 observer.DidChangePerformanceTiming(); | |
119 mock_timer->Fire(); | |
120 | |
121 // At this point, we should have triggered the generation of two metrics. | |
122 // Verify and reset the observer's expectations before moving on to the next | |
123 // part of the test. | |
124 observer.VerifyExpectedTimings(); | |
125 | |
126 timing.load_event_start = load_event; | |
127 observer.ExpectPageLoadTiming(timing); | |
128 | |
129 observer.DidChangePerformanceTiming(); | |
130 mock_timer->Fire(); | |
131 | |
132 // Verify and reset the observer's expectations before moving on to the next | |
133 // part of the test. | |
134 observer.VerifyExpectedTimings(); | |
135 | |
136 // The PageLoadTiming above includes timing information for the first layout, | |
137 // dom content, and load metrics. However, since we've already generated | |
138 // timing information for all of these metrics previously, we do not expect | |
139 // this invocation to generate any additional metrics. | |
140 observer.DidChangePerformanceTiming(); | |
141 ASSERT_FALSE(mock_timer->IsRunning()); | |
142 } | |
143 | |
144 TEST_F(MetricsRenderFrameObserverTest, MultipleNavigations) { | |
145 base::Time nav_start = base::Time::FromDoubleT(10); | |
146 base::TimeDelta first_layout = base::TimeDelta::FromMillisecondsD(2); | |
147 base::TimeDelta dom_event = base::TimeDelta::FromMillisecondsD(2); | |
148 base::TimeDelta load_event = base::TimeDelta::FromMillisecondsD(2); | |
149 | |
150 TestMetricsRenderFrameObserver observer; | |
151 base::MockTimer* mock_timer = new base::MockTimer(false, false); | |
152 observer.set_mock_timer(base::WrapUnique(mock_timer)); | |
153 | |
154 PageLoadTiming timing; | |
155 timing.navigation_start = nav_start; | |
156 observer.ExpectPageLoadTiming(timing); | |
157 observer.DidCommitProvisionalLoad(true, false); | |
158 mock_timer->Fire(); | |
159 | |
160 timing.first_layout = first_layout; | |
161 timing.dom_content_loaded_event_start = dom_event; | |
162 timing.load_event_start = load_event; | |
163 observer.ExpectPageLoadTiming(timing); | |
164 observer.DidChangePerformanceTiming(); | |
165 mock_timer->Fire(); | |
166 | |
167 // At this point, we should have triggered the generation of two metrics. | |
168 // Verify and reset the observer's expectations before moving on to the next | |
169 // part of the test. | |
170 observer.VerifyExpectedTimings(); | |
171 | |
172 base::Time nav_start_2 = base::Time::FromDoubleT(100); | |
173 base::TimeDelta first_layout_2 = base::TimeDelta::FromMillisecondsD(20); | |
174 base::TimeDelta dom_event_2 = base::TimeDelta::FromMillisecondsD(20); | |
175 base::TimeDelta load_event_2 = base::TimeDelta::FromMillisecondsD(20); | |
176 PageLoadTiming timing_2; | |
177 timing_2.navigation_start = nav_start_2; | |
178 | |
179 base::MockTimer* mock_timer2 = new base::MockTimer(false, false); | |
180 observer.set_mock_timer(base::WrapUnique(mock_timer2)); | |
181 | |
182 observer.ExpectPageLoadTiming(timing_2); | |
183 observer.DidCommitProvisionalLoad(true, false); | |
184 mock_timer2->Fire(); | |
185 | |
186 timing_2.first_layout = first_layout_2; | |
187 timing_2.dom_content_loaded_event_start = dom_event_2; | |
188 timing_2.load_event_start = load_event_2; | |
189 observer.ExpectPageLoadTiming(timing_2); | |
190 | |
191 observer.DidChangePerformanceTiming(); | |
192 mock_timer2->Fire(); | |
193 } | |
194 | |
195 } // namespace page_load_metrics | |
OLD | NEW |