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