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

Side by Side Diff: components/scheduler/renderer/throttling_helper_unittest.cc

Issue 2118903002: scheduler: Move the Blink scheduler into Blink (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Another GYP fix Created 4 years, 5 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
OLDNEW
(Empty)
1 // Copyright 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/scheduler/renderer/throttling_helper.h"
6
7 #include <stddef.h>
8
9 #include <memory>
10
11 #include "base/callback.h"
12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/test/simple_test_tick_clock.h"
15 #include "cc/test/ordered_simple_task_runner.h"
16 #include "components/scheduler/base/test_time_source.h"
17 #include "components/scheduler/child/scheduler_tqm_delegate_for_test.h"
18 #include "components/scheduler/renderer/renderer_scheduler_impl.h"
19 #include "components/scheduler/renderer/web_frame_scheduler_impl.h"
20 #include "components/scheduler/renderer/web_view_scheduler_impl.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 using testing::ElementsAre;
25
26 namespace scheduler {
27
28 namespace {
29 void CountingTask(size_t* count, scoped_refptr<TaskQueue> timer_queue) {
30 if (++(*count) < 10) {
31 timer_queue->PostTask(FROM_HERE,
32 base::Bind(&CountingTask, count, timer_queue));
33 }
34 }
35 }
36
37 class ThrottlingHelperTest : public testing::Test {
38 public:
39 ThrottlingHelperTest() {}
40 ~ThrottlingHelperTest() override {}
41
42 void SetUp() override {
43 clock_.reset(new base::SimpleTestTickClock());
44 clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
45 mock_task_runner_ =
46 make_scoped_refptr(new cc::OrderedSimpleTaskRunner(clock_.get(), true));
47 delegate_ = SchedulerTqmDelegateForTest::Create(
48 mock_task_runner_, base::WrapUnique(new TestTimeSource(clock_.get())));
49 scheduler_.reset(new RendererSchedulerImpl(delegate_));
50 throttling_helper_ = scheduler_->throttling_helper();
51 timer_queue_ = scheduler_->NewTimerTaskRunner("test_queue");
52 }
53
54 void TearDown() override {
55 scheduler_->Shutdown();
56 scheduler_.reset();
57 }
58
59 void ExpectThrottled(scoped_refptr<TaskQueue> timer_queue) {
60 size_t count = 0;
61 timer_queue->PostTask(FROM_HERE,
62 base::Bind(&CountingTask, &count, timer_queue));
63
64 mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
65 EXPECT_LT(count, 10u);
66 mock_task_runner_->RunUntilIdle();
67 }
68
69 void ExpectUnthrottled(scoped_refptr<TaskQueue> timer_queue) {
70 size_t count = 0;
71 timer_queue->PostTask(FROM_HERE,
72 base::Bind(&CountingTask, &count, timer_queue));
73
74 mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
75 EXPECT_EQ(count, 10u);
76 mock_task_runner_->RunUntilIdle();
77 }
78
79 protected:
80 std::unique_ptr<base::SimpleTestTickClock> clock_;
81 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
82 scoped_refptr<SchedulerTqmDelegate> delegate_;
83 std::unique_ptr<RendererSchedulerImpl> scheduler_;
84 scoped_refptr<TaskQueue> timer_queue_;
85 ThrottlingHelper* throttling_helper_; // NOT OWNED
86
87 DISALLOW_COPY_AND_ASSIGN(ThrottlingHelperTest);
88 };
89
90 TEST_F(ThrottlingHelperTest, ThrottledRunTime) {
91 EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0),
92 ThrottlingHelper::ThrottledRunTime(
93 base::TimeTicks() + base::TimeDelta::FromSecondsD(0.0)));
94
95 EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0),
96 ThrottlingHelper::ThrottledRunTime(
97 base::TimeTicks() + base::TimeDelta::FromSecondsD(0.1)));
98
99 EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0),
100 ThrottlingHelper::ThrottledRunTime(
101 base::TimeTicks() + base::TimeDelta::FromSecondsD(0.2)));
102
103 EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0),
104 ThrottlingHelper::ThrottledRunTime(
105 base::TimeTicks() + base::TimeDelta::FromSecondsD(0.5)));
106
107 EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0),
108 ThrottlingHelper::ThrottledRunTime(
109 base::TimeTicks() + base::TimeDelta::FromSecondsD(0.8)));
110
111 EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0),
112 ThrottlingHelper::ThrottledRunTime(
113 base::TimeTicks() + base::TimeDelta::FromSecondsD(0.9)));
114
115 EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(2.0),
116 ThrottlingHelper::ThrottledRunTime(
117 base::TimeTicks() + base::TimeDelta::FromSecondsD(1.0)));
118
119 EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(2.0),
120 ThrottlingHelper::ThrottledRunTime(
121 base::TimeTicks() + base::TimeDelta::FromSecondsD(1.1)));
122
123 EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(9.0),
124 ThrottlingHelper::ThrottledRunTime(
125 base::TimeTicks() + base::TimeDelta::FromSecondsD(8.0)));
126
127 EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromSecondsD(9.0),
128 ThrottlingHelper::ThrottledRunTime(
129 base::TimeTicks() + base::TimeDelta::FromSecondsD(8.1)));
130 }
131
132 namespace {
133 void TestTask(std::vector<base::TimeTicks>* run_times,
134 base::SimpleTestTickClock* clock) {
135 run_times->push_back(clock->NowTicks());
136 }
137 } // namespace
138
139 TEST_F(ThrottlingHelperTest, TimerAlignment) {
140 std::vector<base::TimeTicks> run_times;
141 timer_queue_->PostDelayedTask(FROM_HERE,
142 base::Bind(&TestTask, &run_times, clock_.get()),
143 base::TimeDelta::FromMilliseconds(200.0));
144
145 timer_queue_->PostDelayedTask(FROM_HERE,
146 base::Bind(&TestTask, &run_times, clock_.get()),
147 base::TimeDelta::FromMilliseconds(800.0));
148
149 timer_queue_->PostDelayedTask(FROM_HERE,
150 base::Bind(&TestTask, &run_times, clock_.get()),
151 base::TimeDelta::FromMilliseconds(1200.0));
152
153 timer_queue_->PostDelayedTask(FROM_HERE,
154 base::Bind(&TestTask, &run_times, clock_.get()),
155 base::TimeDelta::FromMilliseconds(8300.0));
156
157 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
158
159 mock_task_runner_->RunUntilIdle();
160
161 // Times are aligned to a multipple of 1000 milliseconds.
162 EXPECT_THAT(
163 run_times,
164 ElementsAre(
165 base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000.0),
166 base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000.0),
167 base::TimeTicks() + base::TimeDelta::FromMilliseconds(2000.0),
168 base::TimeTicks() + base::TimeDelta::FromMilliseconds(9000.0)));
169 }
170
171 TEST_F(ThrottlingHelperTest, TimerAlignment_Unthrottled) {
172 std::vector<base::TimeTicks> run_times;
173 base::TimeTicks start_time = clock_->NowTicks();
174 timer_queue_->PostDelayedTask(FROM_HERE,
175 base::Bind(&TestTask, &run_times, clock_.get()),
176 base::TimeDelta::FromMilliseconds(200.0));
177
178 timer_queue_->PostDelayedTask(FROM_HERE,
179 base::Bind(&TestTask, &run_times, clock_.get()),
180 base::TimeDelta::FromMilliseconds(800.0));
181
182 timer_queue_->PostDelayedTask(FROM_HERE,
183 base::Bind(&TestTask, &run_times, clock_.get()),
184 base::TimeDelta::FromMilliseconds(1200.0));
185
186 timer_queue_->PostDelayedTask(FROM_HERE,
187 base::Bind(&TestTask, &run_times, clock_.get()),
188 base::TimeDelta::FromMilliseconds(8300.0));
189
190 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
191 throttling_helper_->DecreaseThrottleRefCount(timer_queue_.get());
192
193 mock_task_runner_->RunUntilIdle();
194
195 // Times are not aligned.
196 EXPECT_THAT(
197 run_times,
198 ElementsAre(start_time + base::TimeDelta::FromMilliseconds(200.0),
199 start_time + base::TimeDelta::FromMilliseconds(800.0),
200 start_time + base::TimeDelta::FromMilliseconds(1200.0),
201 start_time + base::TimeDelta::FromMilliseconds(8300.0)));
202 }
203
204 TEST_F(ThrottlingHelperTest, Refcount) {
205 ExpectUnthrottled(timer_queue_.get());
206
207 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
208 ExpectThrottled(timer_queue_);
209
210 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
211 ExpectThrottled(timer_queue_);
212
213 throttling_helper_->DecreaseThrottleRefCount(timer_queue_.get());
214 ExpectThrottled(timer_queue_);
215
216 throttling_helper_->DecreaseThrottleRefCount(timer_queue_.get());
217 ExpectUnthrottled(timer_queue_);
218
219 // Should be a NOP.
220 throttling_helper_->DecreaseThrottleRefCount(timer_queue_.get());
221 ExpectUnthrottled(timer_queue_);
222
223 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
224 ExpectThrottled(timer_queue_);
225 }
226
227 TEST_F(ThrottlingHelperTest,
228 ThrotlingAnEmptyQueueDoesNotPostPumpThrottledTasksLocked) {
229 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
230
231 EXPECT_TRUE(throttling_helper_->task_runner()->IsEmpty());
232 }
233
234 TEST_F(ThrottlingHelperTest, WakeUpForNonDelayedTask) {
235 std::vector<base::TimeTicks> run_times;
236
237 // Nothing is posted on timer_queue_ so PumpThrottledTasks will not tick.
238 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
239
240 // Posting a task should trigger the pump.
241 timer_queue_->PostTask(FROM_HERE,
242 base::Bind(&TestTask, &run_times, clock_.get()));
243
244 mock_task_runner_->RunUntilIdle();
245 EXPECT_THAT(run_times,
246 ElementsAre(base::TimeTicks() +
247 base::TimeDelta::FromMilliseconds(1000.0)));
248 }
249
250 TEST_F(ThrottlingHelperTest, WakeUpForDelayedTask) {
251 std::vector<base::TimeTicks> run_times;
252
253 // Nothing is posted on timer_queue_ so PumpThrottledTasks will not tick.
254 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
255
256 // Posting a task should trigger the pump.
257 timer_queue_->PostDelayedTask(FROM_HERE,
258 base::Bind(&TestTask, &run_times, clock_.get()),
259 base::TimeDelta::FromMilliseconds(1200.0));
260
261 mock_task_runner_->RunUntilIdle();
262 EXPECT_THAT(run_times,
263 ElementsAre(base::TimeTicks() +
264 base::TimeDelta::FromMilliseconds(2000.0)));
265 }
266
267 namespace {
268 bool MessageLoopTaskCounter(size_t* count) {
269 *count = *count + 1;
270 return true;
271 }
272
273 void NopTask() {}
274
275 } // namespace
276
277 TEST_F(ThrottlingHelperTest,
278 SingleThrottledTaskPumpedAndRunWithNoExtraneousMessageLoopTasks) {
279 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
280
281 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
282 timer_queue_->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay);
283
284 size_t task_count = 0;
285 mock_task_runner_->RunTasksWhile(
286 base::Bind(&MessageLoopTaskCounter, &task_count));
287
288 EXPECT_EQ(1u, task_count);
289 }
290
291 TEST_F(ThrottlingHelperTest,
292 SingleFutureThrottledTaskPumpedAndRunWithNoExtraneousMessageLoopTasks) {
293 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
294
295 base::TimeDelta delay(base::TimeDelta::FromSecondsD(15.5));
296 timer_queue_->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay);
297
298 size_t task_count = 0;
299 mock_task_runner_->RunTasksWhile(
300 base::Bind(&MessageLoopTaskCounter, &task_count));
301
302 EXPECT_EQ(1u, task_count);
303 }
304
305 TEST_F(ThrottlingHelperTest,
306 TwoFutureThrottledTaskPumpedAndRunWithNoExtraneousMessageLoopTasks) {
307 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
308 std::vector<base::TimeTicks> run_times;
309
310 base::TimeDelta delay(base::TimeDelta::FromSecondsD(15.5));
311 timer_queue_->PostDelayedTask(FROM_HERE,
312 base::Bind(&TestTask, &run_times, clock_.get()),
313 delay);
314
315 base::TimeDelta delay2(base::TimeDelta::FromSecondsD(5.5));
316 timer_queue_->PostDelayedTask(FROM_HERE,
317 base::Bind(&TestTask, &run_times, clock_.get()),
318 delay2);
319
320 size_t task_count = 0;
321 mock_task_runner_->RunTasksWhile(
322 base::Bind(&MessageLoopTaskCounter, &task_count));
323
324 EXPECT_EQ(2u, task_count); // There are two since the cancelled task runs in
325 // the same DoWork batch.
326
327 EXPECT_THAT(
328 run_times,
329 ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(6),
330 base::TimeTicks() + base::TimeDelta::FromSeconds(16)));
331 }
332
333 TEST_F(ThrottlingHelperTest, TaskDelayIsBasedOnRealTime) {
334 std::vector<base::TimeTicks> run_times;
335
336 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
337
338 // Post an initial task that should run at the first aligned time period.
339 timer_queue_->PostDelayedTask(FROM_HERE,
340 base::Bind(&TestTask, &run_times, clock_.get()),
341 base::TimeDelta::FromMilliseconds(900.0));
342
343 mock_task_runner_->RunUntilIdle();
344
345 // Advance realtime.
346 clock_->Advance(base::TimeDelta::FromMilliseconds(250));
347
348 // Post a task that due to real time + delay must run in the third aligned
349 // time period.
350 timer_queue_->PostDelayedTask(FROM_HERE,
351 base::Bind(&TestTask, &run_times, clock_.get()),
352 base::TimeDelta::FromMilliseconds(900.0));
353
354 mock_task_runner_->RunUntilIdle();
355
356 EXPECT_THAT(
357 run_times,
358 ElementsAre(
359 base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000.0),
360 base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000.0)));
361 }
362
363 TEST_F(ThrottlingHelperTest, TaskQueueDisabledTillPump) {
364 timer_queue_->PostTask(FROM_HERE, base::Bind(&NopTask));
365
366 EXPECT_TRUE(timer_queue_->IsQueueEnabled());
367 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
368 EXPECT_FALSE(timer_queue_->IsQueueEnabled());
369
370 mock_task_runner_->RunUntilIdle(); // Wait until the pump.
371 EXPECT_TRUE(timer_queue_->IsQueueEnabled());
372 }
373
374 TEST_F(ThrottlingHelperTest, TaskQueueUnthrottle_InitiallyEnabled) {
375 timer_queue_->PostTask(FROM_HERE, base::Bind(&NopTask));
376
377 timer_queue_->SetQueueEnabled(true); // NOP
378 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
379 EXPECT_FALSE(timer_queue_->IsQueueEnabled());
380
381 throttling_helper_->DecreaseThrottleRefCount(timer_queue_.get());
382 EXPECT_TRUE(timer_queue_->IsQueueEnabled());
383 }
384
385 TEST_F(ThrottlingHelperTest, TaskQueueUnthrottle_InitiallyDisabled) {
386 timer_queue_->PostTask(FROM_HERE, base::Bind(&NopTask));
387
388 timer_queue_->SetQueueEnabled(false);
389 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
390 EXPECT_FALSE(timer_queue_->IsQueueEnabled());
391
392 throttling_helper_->DecreaseThrottleRefCount(timer_queue_.get());
393 EXPECT_FALSE(timer_queue_->IsQueueEnabled());
394 }
395
396 TEST_F(ThrottlingHelperTest, SetQueueEnabled_Unthrottled) {
397 timer_queue_->PostTask(FROM_HERE, base::Bind(&NopTask));
398
399 throttling_helper_->SetQueueEnabled(timer_queue_.get(), false);
400 EXPECT_FALSE(timer_queue_->IsQueueEnabled());
401
402 throttling_helper_->SetQueueEnabled(timer_queue_.get(), true);
403 EXPECT_TRUE(timer_queue_->IsQueueEnabled());
404 }
405
406 TEST_F(ThrottlingHelperTest, SetQueueEnabled_DisabledWhileThrottled) {
407 timer_queue_->PostTask(FROM_HERE, base::Bind(&NopTask));
408
409 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
410 EXPECT_FALSE(timer_queue_->IsQueueEnabled());
411
412 throttling_helper_->SetQueueEnabled(timer_queue_.get(), false);
413 throttling_helper_->DecreaseThrottleRefCount(timer_queue_.get());
414 EXPECT_FALSE(timer_queue_->IsQueueEnabled());
415 }
416
417 TEST_F(ThrottlingHelperTest, TaskQueueDisabledTillPump_ThenManuallyDisabled) {
418 timer_queue_->PostTask(FROM_HERE, base::Bind(&NopTask));
419
420 EXPECT_TRUE(timer_queue_->IsQueueEnabled());
421 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
422 EXPECT_FALSE(timer_queue_->IsQueueEnabled());
423
424 mock_task_runner_->RunUntilIdle(); // Wait until the pump.
425 EXPECT_TRUE(timer_queue_->IsQueueEnabled());
426
427 throttling_helper_->SetQueueEnabled(timer_queue_.get(), false);
428 EXPECT_FALSE(timer_queue_->IsQueueEnabled());
429 }
430
431 TEST_F(ThrottlingHelperTest, DoubleIncrementDoubleDecrement) {
432 timer_queue_->PostTask(FROM_HERE, base::Bind(&NopTask));
433
434 EXPECT_TRUE(timer_queue_->IsQueueEnabled());
435 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
436 throttling_helper_->IncreaseThrottleRefCount(timer_queue_.get());
437 EXPECT_FALSE(timer_queue_->IsQueueEnabled());
438 throttling_helper_->DecreaseThrottleRefCount(timer_queue_.get());
439 throttling_helper_->DecreaseThrottleRefCount(timer_queue_.get());
440 EXPECT_TRUE(timer_queue_->IsQueueEnabled());
441 }
442
443 } // namespace scheduler
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698