Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetectorTest.cpp

Issue 2755873002: Improve FirstMeaningfulPaintDetectorTest's timer tests (Closed)
Patch Set: 0.001 -> 1 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 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 "core/paint/FirstMeaningfulPaintDetector.h" 5 #include "core/paint/FirstMeaningfulPaintDetector.h"
6 6
7 #include "core/paint/PaintTiming.h" 7 #include "core/paint/PaintTiming.h"
8 #include "core/testing/DummyPageHolder.h" 8 #include "core/testing/DummyPageHolder.h"
9 #include "platform/scheduler/test/fake_web_task_runner.h" 9 #include "platform/testing/TestingPlatformSupport.h"
10 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "wtf/text/StringBuilder.h" 11 #include "wtf/text/StringBuilder.h"
12 12
13 namespace blink { 13 namespace blink {
14 14
15 class FirstMeaningfulPaintDetectorTest : public testing::Test { 15 class FirstMeaningfulPaintDetectorTest : public testing::Test {
16 protected: 16 protected:
17 void SetUp() override { 17 void SetUp() override {
18 m_platform->advanceClockSeconds(1);
18 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); 19 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
19 s_timeElapsed = 0.0;
20 m_originalTimeFunction = setTimeFunctionsForTesting(returnMockTime);
21 m_taskRunner = adoptRef(new scheduler::FakeWebTaskRunner);
22 detector().m_network0QuietTimer.moveToNewTaskRunner(m_taskRunner);
23 detector().m_network2QuietTimer.moveToNewTaskRunner(m_taskRunner);
24 } 20 }
25 21
26 void TearDown() override { 22 double advanceClockAndGetTime() {
27 setTimeFunctionsForTesting(m_originalTimeFunction); 23 m_platform->advanceClockSeconds(1);
24 return monotonicallyIncreasingTime();
28 } 25 }
29 26
30 Document& document() { return m_dummyPageHolder->document(); } 27 Document& document() { return m_dummyPageHolder->document(); }
31 PaintTiming& paintTiming() { return PaintTiming::from(document()); } 28 PaintTiming& paintTiming() { return PaintTiming::from(document()); }
32 FirstMeaningfulPaintDetector& detector() { 29 FirstMeaningfulPaintDetector& detector() {
33 return paintTiming().firstMeaningfulPaintDetector(); 30 return paintTiming().firstMeaningfulPaintDetector();
34 } 31 }
35 32
36 void simulateLayoutAndPaint(int newElements) { 33 void simulateLayoutAndPaint(int newElements) {
34 m_platform->advanceClockSeconds(0.001);
37 StringBuilder builder; 35 StringBuilder builder;
38 for (int i = 0; i < newElements; i++) 36 for (int i = 0; i < newElements; i++)
39 builder.append("<span>a</span>"); 37 builder.append("<span>a</span>");
40 document().write(builder.toString()); 38 document().write(builder.toString());
41 document().updateStyleAndLayout(); 39 document().updateStyleAndLayout();
42 detector().notifyPaint(); 40 detector().notifyPaint();
43 } 41 }
44 42
45 void simulateNetworkStable() { 43 void simulateNetworkStable() {
46 document().setParsingState(Document::FinishedParsing); 44 document().setParsingState(Document::FinishedParsing);
47 detector().network0QuietTimerFired(nullptr); 45 detector().network0QuietTimerFired(nullptr);
48 detector().network2QuietTimerFired(nullptr); 46 detector().network2QuietTimerFired(nullptr);
49 } 47 }
50 48
51 void simulateNetwork0Quiet() { 49 void simulateNetwork0Quiet() {
52 document().setParsingState(Document::FinishedParsing); 50 document().setParsingState(Document::FinishedParsing);
53 detector().network0QuietTimerFired(nullptr); 51 detector().network0QuietTimerFired(nullptr);
54 } 52 }
55 53
56 void simulateNetwork2Quiet() { 54 void simulateNetwork2Quiet() {
57 document().setParsingState(Document::FinishedParsing); 55 document().setParsingState(Document::FinishedParsing);
58 detector().network2QuietTimerFired(nullptr); 56 detector().network2QuietTimerFired(nullptr);
59 } 57 }
60 58
61 void setActiveConnections(int connections) { 59 void setActiveConnections(int connections) {
62 double time0 = 0.0;
63 double time2 = 0.0;
64 m_taskRunner->setTime(returnMockTime());
65 if (isNetwork0QuietTimerActive())
66 time0 = detector().m_network0QuietTimer.nextFireInterval();
67 if (isNetwork2QuietTimerActive())
68 time2 = detector().m_network2QuietTimer.nextFireInterval();
69
70 detector().setNetworkQuietTimers(connections); 60 detector().setNetworkQuietTimers(connections);
71
72 m_0QuietTimerRestarted =
73 isNetwork0QuietTimerActive() &&
74 detector().m_network0QuietTimer.nextFireInterval() != time0;
75 m_2QuietTimerRestarted =
76 isNetwork2QuietTimerActive() &&
77 detector().m_network2QuietTimer.nextFireInterval() != time2;
78 } 61 }
79 62
80 bool isNetwork0QuietTimerActive() { 63 bool isNetwork0QuietTimerActive() {
81 return detector().m_network0QuietTimer.isActive(); 64 return detector().m_network0QuietTimer.isActive();
82 } 65 }
83 66
84 bool isNetwork2QuietTimerActive() { 67 bool isNetwork2QuietTimerActive() {
85 return detector().m_network2QuietTimer.isActive(); 68 return detector().m_network2QuietTimer.isActive();
86 } 69 }
87 70
88 bool isNetwork0QuietTimerRestarted() { return m_0QuietTimerRestarted; } 71 bool hadNetwork0Quiet() { return detector().m_network0QuietReached; }
89 bool isNetwork2QuietTimerRestarted() { return m_2QuietTimerRestarted; } 72 bool hadNetwork2Quiet() { return detector().m_network2QuietReached; }
73
74 protected:
75 ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
76 m_platform;
77
78 static constexpr double kNetwork0QuietWindowSeconds =
79 FirstMeaningfulPaintDetector::kNetwork0QuietWindowSeconds;
80 static constexpr double kNetwork2QuietWindowSeconds =
81 FirstMeaningfulPaintDetector::kNetwork2QuietWindowSeconds;
90 82
91 private: 83 private:
92 static double returnMockTime() {
93 s_timeElapsed += 1.0;
94 return s_timeElapsed;
95 }
96
97 std::unique_ptr<DummyPageHolder> m_dummyPageHolder; 84 std::unique_ptr<DummyPageHolder> m_dummyPageHolder;
98 RefPtr<scheduler::FakeWebTaskRunner> m_taskRunner;
99 TimeFunction m_originalTimeFunction;
100 bool m_0QuietTimerRestarted;
101 bool m_2QuietTimerRestarted;
102 static double s_timeElapsed;
103 }; 85 };
104 86
105 double FirstMeaningfulPaintDetectorTest::s_timeElapsed;
106
107 TEST_F(FirstMeaningfulPaintDetectorTest, NoFirstPaint) { 87 TEST_F(FirstMeaningfulPaintDetectorTest, NoFirstPaint) {
108 simulateLayoutAndPaint(1); 88 simulateLayoutAndPaint(1);
109 simulateNetworkStable(); 89 simulateNetworkStable();
110 EXPECT_EQ(paintTiming().firstMeaningfulPaint(), 0.0); 90 EXPECT_EQ(paintTiming().firstMeaningfulPaint(), 0.0);
111 } 91 }
112 92
113 TEST_F(FirstMeaningfulPaintDetectorTest, OneLayout) { 93 TEST_F(FirstMeaningfulPaintDetectorTest, OneLayout) {
114 paintTiming().markFirstContentfulPaint(); 94 paintTiming().markFirstContentfulPaint();
115 simulateLayoutAndPaint(1); 95 simulateLayoutAndPaint(1);
116 double afterPaint = monotonicallyIncreasingTime(); 96 double afterPaint = advanceClockAndGetTime();
117 EXPECT_EQ(paintTiming().firstMeaningfulPaint(), 0.0); 97 EXPECT_EQ(paintTiming().firstMeaningfulPaint(), 0.0);
118 simulateNetworkStable(); 98 simulateNetworkStable();
119 EXPECT_GT(paintTiming().firstMeaningfulPaint(), paintTiming().firstPaint()); 99 EXPECT_GT(paintTiming().firstMeaningfulPaint(), paintTiming().firstPaint());
120 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterPaint); 100 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterPaint);
121 } 101 }
122 102
123 TEST_F(FirstMeaningfulPaintDetectorTest, TwoLayoutsSignificantSecond) { 103 TEST_F(FirstMeaningfulPaintDetectorTest, TwoLayoutsSignificantSecond) {
124 paintTiming().markFirstContentfulPaint(); 104 paintTiming().markFirstContentfulPaint();
125 simulateLayoutAndPaint(1); 105 simulateLayoutAndPaint(1);
126 double afterLayout1 = monotonicallyIncreasingTime(); 106 double afterLayout1 = advanceClockAndGetTime();
127 simulateLayoutAndPaint(10); 107 simulateLayoutAndPaint(10);
128 double afterLayout2 = monotonicallyIncreasingTime(); 108 double afterLayout2 = advanceClockAndGetTime();
129 simulateNetworkStable(); 109 simulateNetworkStable();
130 EXPECT_GT(paintTiming().firstMeaningfulPaint(), afterLayout1); 110 EXPECT_GT(paintTiming().firstMeaningfulPaint(), afterLayout1);
131 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterLayout2); 111 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterLayout2);
132 } 112 }
133 113
134 TEST_F(FirstMeaningfulPaintDetectorTest, TwoLayoutsSignificantFirst) { 114 TEST_F(FirstMeaningfulPaintDetectorTest, TwoLayoutsSignificantFirst) {
135 paintTiming().markFirstContentfulPaint(); 115 paintTiming().markFirstContentfulPaint();
136 simulateLayoutAndPaint(10); 116 simulateLayoutAndPaint(10);
137 double afterLayout1 = monotonicallyIncreasingTime(); 117 double afterLayout1 = advanceClockAndGetTime();
138 simulateLayoutAndPaint(1); 118 simulateLayoutAndPaint(1);
139 simulateNetworkStable(); 119 simulateNetworkStable();
140 EXPECT_GT(paintTiming().firstMeaningfulPaint(), paintTiming().firstPaint()); 120 EXPECT_GT(paintTiming().firstMeaningfulPaint(), paintTiming().firstPaint());
141 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterLayout1); 121 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterLayout1);
142 } 122 }
143 123
144 TEST_F(FirstMeaningfulPaintDetectorTest, FirstMeaningfulPaintCandidate) { 124 TEST_F(FirstMeaningfulPaintDetectorTest, FirstMeaningfulPaintCandidate) {
145 paintTiming().markFirstContentfulPaint(); 125 paintTiming().markFirstContentfulPaint();
146 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), 0.0); 126 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), 0.0);
147 simulateLayoutAndPaint(1); 127 simulateLayoutAndPaint(1);
148 double afterPaint = monotonicallyIncreasingTime(); 128 double afterPaint = advanceClockAndGetTime();
149 // The first candidate gets ignored. 129 // The first candidate gets ignored.
150 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), 0.0); 130 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), 0.0);
151 simulateLayoutAndPaint(10); 131 simulateLayoutAndPaint(10);
152 // The second candidate gets reported. 132 // The second candidate gets reported.
153 EXPECT_GT(paintTiming().firstMeaningfulPaintCandidate(), afterPaint); 133 EXPECT_GT(paintTiming().firstMeaningfulPaintCandidate(), afterPaint);
154 double candidate = paintTiming().firstMeaningfulPaintCandidate(); 134 double candidate = paintTiming().firstMeaningfulPaintCandidate();
155 // The third candidate gets ignored since we already saw the first candidate. 135 // The third candidate gets ignored since we already saw the first candidate.
156 simulateLayoutAndPaint(10); 136 simulateLayoutAndPaint(10);
157 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), candidate); 137 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), candidate);
158 } 138 }
159 139
160 TEST_F(FirstMeaningfulPaintDetectorTest, 140 TEST_F(FirstMeaningfulPaintDetectorTest,
161 OnlyOneFirstMeaningfulPaintCandidateBeforeNetworkStable) { 141 OnlyOneFirstMeaningfulPaintCandidateBeforeNetworkStable) {
162 paintTiming().markFirstContentfulPaint(); 142 paintTiming().markFirstContentfulPaint();
163 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), 0.0); 143 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), 0.0);
164 double beforePaint = monotonicallyIncreasingTime(); 144 double beforePaint = advanceClockAndGetTime();
165 simulateLayoutAndPaint(1); 145 simulateLayoutAndPaint(1);
166 // The first candidate is initially ignored. 146 // The first candidate is initially ignored.
167 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), 0.0); 147 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), 0.0);
168 simulateNetworkStable(); 148 simulateNetworkStable();
169 // The networkStable then promotes the first candidate. 149 // The networkStable then promotes the first candidate.
170 EXPECT_GT(paintTiming().firstMeaningfulPaintCandidate(), beforePaint); 150 EXPECT_GT(paintTiming().firstMeaningfulPaintCandidate(), beforePaint);
171 double candidate = paintTiming().firstMeaningfulPaintCandidate(); 151 double candidate = paintTiming().firstMeaningfulPaintCandidate();
172 // The second candidate is then ignored. 152 // The second candidate is then ignored.
173 simulateLayoutAndPaint(10); 153 simulateLayoutAndPaint(10);
174 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), candidate); 154 EXPECT_EQ(paintTiming().firstMeaningfulPaintCandidate(), candidate);
(...skipping 17 matching lines...) Expand all
192 paintTiming().markFirstContentfulPaint(); 172 paintTiming().markFirstContentfulPaint();
193 simulateNetworkStable(); 173 simulateNetworkStable();
194 EXPECT_GE(paintTiming().firstMeaningfulPaint(), 174 EXPECT_GE(paintTiming().firstMeaningfulPaint(),
195 paintTiming().firstContentfulPaint()); 175 paintTiming().firstContentfulPaint());
196 } 176 }
197 177
198 TEST_F(FirstMeaningfulPaintDetectorTest, Network2QuietThen0Quiet) { 178 TEST_F(FirstMeaningfulPaintDetectorTest, Network2QuietThen0Quiet) {
199 paintTiming().markFirstContentfulPaint(); 179 paintTiming().markFirstContentfulPaint();
200 180
201 simulateLayoutAndPaint(1); 181 simulateLayoutAndPaint(1);
202 double afterFirstPaint = monotonicallyIncreasingTime(); 182 double afterFirstPaint = advanceClockAndGetTime();
203 simulateNetwork2Quiet(); 183 simulateNetwork2Quiet();
204 184
205 simulateLayoutAndPaint(10); 185 simulateLayoutAndPaint(10);
206 simulateNetwork0Quiet(); 186 simulateNetwork0Quiet();
207 187
208 // The first paint is FirstMeaningfulPaint. 188 // The first paint is FirstMeaningfulPaint.
209 EXPECT_GT(paintTiming().firstMeaningfulPaint(), 0.0); 189 EXPECT_GT(paintTiming().firstMeaningfulPaint(), 0.0);
210 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterFirstPaint); 190 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterFirstPaint);
211 } 191 }
212 192
213 TEST_F(FirstMeaningfulPaintDetectorTest, Network0QuietThen2Quiet) { 193 TEST_F(FirstMeaningfulPaintDetectorTest, Network0QuietThen2Quiet) {
214 paintTiming().markFirstContentfulPaint(); 194 paintTiming().markFirstContentfulPaint();
215 195
216 simulateLayoutAndPaint(1); 196 simulateLayoutAndPaint(1);
217 double afterFirstPaint = monotonicallyIncreasingTime(); 197 double afterFirstPaint = advanceClockAndGetTime();
218 simulateNetwork0Quiet(); 198 simulateNetwork0Quiet();
219 199
220 simulateLayoutAndPaint(10); 200 simulateLayoutAndPaint(10);
221 double afterSecondPaint = monotonicallyIncreasingTime(); 201 double afterSecondPaint = advanceClockAndGetTime();
222 simulateNetwork2Quiet(); 202 simulateNetwork2Quiet();
223 203
224 // The second paint is FirstMeaningfulPaint. 204 // The second paint is FirstMeaningfulPaint.
225 EXPECT_GT(paintTiming().firstMeaningfulPaint(), afterFirstPaint); 205 EXPECT_GT(paintTiming().firstMeaningfulPaint(), afterFirstPaint);
226 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterSecondPaint); 206 EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterSecondPaint);
227 } 207 }
228 208
229 TEST_F(FirstMeaningfulPaintDetectorTest, NetworkQuietTimers) { 209 TEST_F(FirstMeaningfulPaintDetectorTest, Network0QuietTimer) {
210 paintTiming().markFirstContentfulPaint();
211
212 setActiveConnections(1);
213 EXPECT_FALSE(isNetwork0QuietTimerActive());
214
215 setActiveConnections(0);
216 m_platform->runForPeriodSeconds(kNetwork0QuietWindowSeconds - 0.1);
217 EXPECT_TRUE(isNetwork0QuietTimerActive());
218 EXPECT_FALSE(hadNetwork0Quiet());
219
220 setActiveConnections(0); // This should reset the 0-quiet timer.
221 m_platform->runForPeriodSeconds(kNetwork0QuietWindowSeconds - 0.1);
222 EXPECT_TRUE(isNetwork0QuietTimerActive());
223 EXPECT_FALSE(hadNetwork0Quiet());
224
225 m_platform->runForPeriodSeconds(0.1001);
226 EXPECT_TRUE(hadNetwork0Quiet());
227 }
228
229 TEST_F(FirstMeaningfulPaintDetectorTest, Network2QuietTimer) {
230 paintTiming().markFirstContentfulPaint();
231
230 setActiveConnections(3); 232 setActiveConnections(3);
231 EXPECT_FALSE(isNetwork0QuietTimerActive());
232 EXPECT_FALSE(isNetwork2QuietTimerActive()); 233 EXPECT_FALSE(isNetwork2QuietTimerActive());
233 234
234 setActiveConnections(2); 235 setActiveConnections(2);
235 EXPECT_FALSE(isNetwork0QuietTimerActive()); 236 m_platform->runForPeriodSeconds(kNetwork2QuietWindowSeconds - 0.1);
236 EXPECT_TRUE(isNetwork2QuietTimerActive()); 237 EXPECT_TRUE(isNetwork2QuietTimerActive());
238 EXPECT_FALSE(hadNetwork2Quiet());
237 239
238 setActiveConnections(1); 240 setActiveConnections(2); // This should reset the 2-quiet timer.
239 EXPECT_FALSE(isNetwork0QuietTimerActive()); 241 m_platform->runForPeriodSeconds(kNetwork2QuietWindowSeconds - 0.1);
240 EXPECT_TRUE(isNetwork2QuietTimerActive()); 242 EXPECT_TRUE(isNetwork2QuietTimerActive());
241 EXPECT_FALSE(isNetwork2QuietTimerRestarted()); 243 EXPECT_FALSE(hadNetwork2Quiet());
242 244
243 setActiveConnections(2); 245 setActiveConnections(1); // This should not reset the 2-quiet timer.
244 EXPECT_TRUE(isNetwork2QuietTimerRestarted()); 246 m_platform->runForPeriodSeconds(0.1001);
245 247 EXPECT_TRUE(hadNetwork2Quiet());
246 setActiveConnections(0);
247 EXPECT_TRUE(isNetwork0QuietTimerActive());
248 EXPECT_TRUE(isNetwork2QuietTimerActive());
249 EXPECT_FALSE(isNetwork2QuietTimerRestarted());
250
251 setActiveConnections(0);
252 EXPECT_TRUE(isNetwork0QuietTimerActive());
253 EXPECT_TRUE(isNetwork0QuietTimerRestarted());
254 EXPECT_TRUE(isNetwork2QuietTimerActive());
255 EXPECT_FALSE(isNetwork2QuietTimerRestarted());
256 } 248 }
257 249
258 } // namespace blink 250 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698