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

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

Powered by Google App Engine
This is Rietveld 408576698