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