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

Side by Side Diff: content/child/scheduler/worker_scheduler_impl_unittest.cc

Issue 1088933002: Revert of Add a WorkerScheduler and a WebThreadImplForWorker (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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 "content/child/scheduler/worker_scheduler_impl.h"
6
7 #include "base/callback.h"
8 #include "base/strings/stringprintf.h"
9 #include "cc/test/ordered_simple_task_runner.h"
10 #include "content/child/scheduler/nestable_task_runner_for_test.h"
11 #include "content/child/scheduler/scheduler_message_loop_delegate.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 using testing::ElementsAreArray;
16
17 namespace content {
18
19 namespace {
20 void NopTask() {
21 }
22
23 int TimeTicksToIntMs(const base::TimeTicks& time) {
24 return static_cast<int>((time - base::TimeTicks()).InMilliseconds());
25 }
26
27 void WakeUpTask(std::vector<std::string>* timeline, cc::TestNowSource* clock) {
28 if (timeline) {
29 timeline->push_back(base::StringPrintf(
30 "run WakeUpTask @ %d", TimeTicksToIntMs(clock->Now())));
31 }
32 }
33
34 void RecordTimelineTask(std::vector<std::string>* timeline,
35 cc::TestNowSource* clock) {
36 timeline->push_back(base::StringPrintf(
37 "run RecordTimelineTask @ %d", TimeTicksToIntMs(clock->Now())));
38 }
39
40 void AppendToVectorTestTask(std::vector<std::string>* vector,
41 std::string value) {
42 vector->push_back(value);
43 }
44
45 void AppendToVectorIdleTestTask(std::vector<std::string>* vector,
46 std::string value,
47 base::TimeTicks deadline) {
48 AppendToVectorTestTask(vector, value);
49 }
50
51 void TimelineIdleTestTask(std::vector<std::string>* timeline,
52 base::TimeTicks deadline) {
53 timeline->push_back(base::StringPrintf("run TimelineIdleTestTask deadline %d",
54 TimeTicksToIntMs(deadline)));
55 }
56
57 }; // namespace
58
59 class WorkerSchedulerImplForTest : public WorkerSchedulerImpl {
60 public:
61 WorkerSchedulerImplForTest(
62 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
63 scoped_refptr<cc::TestNowSource> clock_)
64 : WorkerSchedulerImpl(main_task_runner),
65 clock_(clock_),
66 timeline_(nullptr) {}
67
68 void RecordTimelineEvents(std::vector<std::string>* timeline) {
69 timeline_ = timeline;
70 }
71
72 private:
73 bool CanEnterLongIdlePeriod(
74 base::TimeTicks now,
75 base::TimeDelta* next_long_idle_period_delay_out) override {
76 if (timeline_) {
77 timeline_->push_back(base::StringPrintf("CanEnterLongIdlePeriod @ %d",
78 TimeTicksToIntMs(now)));
79 }
80 return WorkerSchedulerImpl::CanEnterLongIdlePeriod(
81 now, next_long_idle_period_delay_out);
82 }
83
84 void IsNotQuiescent() override {
85 if (timeline_) {
86 timeline_->push_back(base::StringPrintf("IsNotQuiescent @ %d",
87 TimeTicksToIntMs(clock_->Now())));
88 }
89 WorkerSchedulerImpl::IsNotQuiescent();
90 }
91
92 scoped_refptr<cc::TestNowSource> clock_;
93 std::vector<std::string>* timeline_; // NOT OWNED
94 };
95
96 class WorkerSchedulerImplTest : public testing::Test {
97 public:
98 WorkerSchedulerImplTest()
99 : clock_(cc::TestNowSource::Create(5000)),
100 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, true)),
101 nestable_task_runner_(
102 NestableTaskRunnerForTest::Create(mock_task_runner_)),
103 scheduler_(
104 new WorkerSchedulerImplForTest(nestable_task_runner_, clock_)),
105 timeline_(nullptr) {
106 scheduler_->SetTimeSourceForTesting(clock_);
107 }
108
109 ~WorkerSchedulerImplTest() override {}
110
111 void TearDown() override {
112 // Check that all tests stop posting tasks.
113 while (mock_task_runner_->RunUntilIdle()) {
114 }
115 }
116
117 void Init() {
118 scheduler_->Init();
119 default_task_runner_ = scheduler_->DefaultTaskRunner();
120 idle_task_runner_ = scheduler_->IdleTaskRunner();
121 timeline_ = nullptr;
122 }
123
124 void RecordTimelineEvents(std::vector<std::string>* timeline) {
125 timeline_ = timeline;
126 scheduler_->RecordTimelineEvents(timeline);
127 }
128
129 void RunUntilIdle() {
130 if (timeline_) {
131 timeline_->push_back(base::StringPrintf("RunUntilIdle begin @ %d",
132 TimeTicksToIntMs(clock_->Now())));
133 }
134 mock_task_runner_->RunUntilIdle();
135 if (timeline_) {
136 timeline_->push_back(base::StringPrintf("RunUntilIdle end @ %d",
137 TimeTicksToIntMs(clock_->Now())));
138 }
139 }
140
141 void InitAndPostDelayedWakeupTask() {
142 Init();
143 // WorkerSchedulerImpl::Init causes a delayed task to be posted on the
144 // after wakeup control runner. We need a task to wake the system up
145 // AFTER the delay for this has expired.
146 default_task_runner_->PostDelayedTask(
147 FROM_HERE, base::Bind(&WakeUpTask, base::Unretained(timeline_),
148 base::Unretained(clock_.get())),
149 base::TimeDelta::FromMilliseconds(100));
150 }
151
152 // Helper for posting several tasks of specific types. |task_descriptor| is a
153 // string with space delimited task identifiers. The first letter of each
154 // task identifier specifies the task type:
155 // - 'D': Default task
156 // - 'I': Idle task
157 void PostTestTasks(std::vector<std::string>* run_order,
158 const std::string& task_descriptor) {
159 std::istringstream stream(task_descriptor);
160 while (!stream.eof()) {
161 std::string task;
162 stream >> task;
163 switch (task[0]) {
164 case 'D':
165 default_task_runner_->PostTask(
166 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
167 break;
168 case 'I':
169 idle_task_runner_->PostIdleTask(
170 FROM_HERE,
171 base::Bind(&AppendToVectorIdleTestTask, run_order, task));
172 break;
173 default:
174 NOTREACHED();
175 }
176 }
177 }
178
179 static base::TimeDelta maximum_idle_period_duration() {
180 return base::TimeDelta::FromMilliseconds(
181 SchedulerHelper::kMaximumIdlePeriodMillis);
182 }
183
184 protected:
185 scoped_refptr<cc::TestNowSource> clock_;
186 // Only one of mock_task_runner_ or message_loop_ will be set.
187 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
188
189 scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_;
190 scoped_ptr<WorkerSchedulerImplForTest> scheduler_;
191 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
192 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
193 std::vector<std::string>* timeline_; // NOT OWNED
194
195 DISALLOW_COPY_AND_ASSIGN(WorkerSchedulerImplTest);
196 };
197
198 TEST_F(WorkerSchedulerImplTest, TestPostDefaultTask) {
199 InitAndPostDelayedWakeupTask();
200
201 std::vector<std::string> run_order;
202 PostTestTasks(&run_order, "D1 D2 D3 D4");
203
204 RunUntilIdle();
205 EXPECT_THAT(run_order,
206 testing::ElementsAre(std::string("D1"), std::string("D2"),
207 std::string("D3"), std::string("D4")));
208 }
209
210 TEST_F(WorkerSchedulerImplTest, TestPostIdleTask) {
211 InitAndPostDelayedWakeupTask();
212
213 std::vector<std::string> run_order;
214 PostTestTasks(&run_order, "I1");
215
216 RunUntilIdle();
217 EXPECT_THAT(run_order, testing::ElementsAre(std::string("I1")));
218 }
219
220 TEST_F(WorkerSchedulerImplTest, TestPostIdleTask_NoWakeup) {
221 Init();
222 std::vector<std::string> run_order;
223 PostTestTasks(&run_order, "I1");
224
225 RunUntilIdle();
226 EXPECT_TRUE(run_order.empty());
227 }
228
229 TEST_F(WorkerSchedulerImplTest, TestPostDefaultAndIdleTasks) {
230 InitAndPostDelayedWakeupTask();
231
232 std::vector<std::string> run_order;
233 PostTestTasks(&run_order, "I1 D2 D3 D4");
234
235 RunUntilIdle();
236 EXPECT_THAT(run_order,
237 testing::ElementsAre(std::string("D2"), std::string("D3"),
238 std::string("D4"), std::string("I1")));
239 }
240
241 TEST_F(WorkerSchedulerImplTest, TestPostIdleTaskWithWakeupNeeded_NoWakeup) {
242 InitAndPostDelayedWakeupTask();
243
244 RunUntilIdle();
245 // The delayed call to EnableLongIdlePeriod happened and it posted a call to
246 // EnableLongIdlePeriod on the after wakeup control queue.
247
248 std::vector<std::string> run_order;
249 PostTestTasks(&run_order, "I1");
250
251 RunUntilIdle();
252 EXPECT_TRUE(run_order.empty());
253 }
254
255 TEST_F(WorkerSchedulerImplTest, TestPostDefaultDelayedAndIdleTasks) {
256 InitAndPostDelayedWakeupTask();
257
258 std::vector<std::string> run_order;
259 PostTestTasks(&run_order, "I1 D2 D3 D4");
260
261 default_task_runner_->PostDelayedTask(
262 FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "DELAYED"),
263 base::TimeDelta::FromMilliseconds(1000));
264
265 RunUntilIdle();
266 EXPECT_THAT(run_order,
267 testing::ElementsAre(std::string("D2"), std::string("D3"),
268 std::string("D4"), std::string("I1"),
269 std::string("DELAYED")));
270 }
271
272 TEST_F(WorkerSchedulerImplTest, TestIdleDeadlineWithPendingDelayedTask) {
273 std::vector<std::string> timeline;
274 RecordTimelineEvents(&timeline);
275 InitAndPostDelayedWakeupTask();
276
277 timeline.push_back("Post delayed and idle tasks");
278 // Post a delayed task timed to occur mid way during the long idle period.
279 default_task_runner_->PostDelayedTask(
280 FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline),
281 base::Unretained(clock_.get())),
282 base::TimeDelta::FromMilliseconds(420));
283 idle_task_runner_->PostIdleTask(FROM_HERE,
284 base::Bind(&TimelineIdleTestTask, &timeline));
285
286 RunUntilIdle();
287
288 std::string expected_timeline[] = {
289 "CanEnterLongIdlePeriod @ 5",
290 "Post delayed and idle tasks",
291 "IsNotQuiescent @ 105",
292 "CanEnterLongIdlePeriod @ 405",
293 "run TimelineIdleTestTask deadline 425", // Note the short 20ms deadline.
294 "CanEnterLongIdlePeriod @ 425",
295 "run RecordTimelineTask @ 425"};
296
297 EXPECT_THAT(timeline, ElementsAreArray(expected_timeline));
298 }
299
300 TEST_F(WorkerSchedulerImplTest,
301 TestIdleDeadlineWithPendingDelayedTaskFarInTheFuture) {
302 std::vector<std::string> timeline;
303 RecordTimelineEvents(&timeline);
304 InitAndPostDelayedWakeupTask();
305
306 timeline.push_back("Post delayed and idle tasks");
307 // Post a delayed task timed to occur well after the long idle period.
308 default_task_runner_->PostDelayedTask(
309 FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline),
310 base::Unretained(clock_.get())),
311 base::TimeDelta::FromMilliseconds(1000));
312 idle_task_runner_->PostIdleTask(FROM_HERE,
313 base::Bind(&TimelineIdleTestTask, &timeline));
314
315 RunUntilIdle();
316
317 std::string expected_timeline[] = {
318 "CanEnterLongIdlePeriod @ 5",
319 "Post delayed and idle tasks",
320 "IsNotQuiescent @ 105",
321 "CanEnterLongIdlePeriod @ 405",
322 "run TimelineIdleTestTask deadline 455", // Note the full 50ms deadline.
323 "CanEnterLongIdlePeriod @ 455",
324 "run RecordTimelineTask @ 1005"};
325
326 EXPECT_THAT(timeline, ElementsAreArray(expected_timeline));
327 }
328
329 TEST_F(WorkerSchedulerImplTest,
330 TestPostIdleTaskAfterRunningUntilIdle_NoWakeUp) {
331 InitAndPostDelayedWakeupTask();
332
333 default_task_runner_->PostDelayedTask(
334 FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(1000));
335 RunUntilIdle();
336
337 // The delayed call to EnableLongIdlePeriod happened and it posted a call to
338 // EnableLongIdlePeriod on the after wakeup control queue. Without an other
339 // non-idle task posted, the idle tasks won't run.
340 std::vector<std::string> run_order;
341 PostTestTasks(&run_order, "I1 I2");
342
343 RunUntilIdle();
344 EXPECT_TRUE(run_order.empty());
345 }
346
347 TEST_F(WorkerSchedulerImplTest,
348 TestPostIdleTaskAfterRunningUntilIdle_WithWakeUp) {
349 InitAndPostDelayedWakeupTask();
350
351 default_task_runner_->PostDelayedTask(
352 FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(1000));
353 RunUntilIdle();
354 // The delayed call to EnableLongIdlePeriod happened and it posted a call to
355 // EnableLongIdlePeriod on the after wakeup control queue. Without an other
356 // non-idle task posted, the idle tasks won't run.
357
358 std::vector<std::string> run_order;
359 PostTestTasks(&run_order, "I1 I2 D3");
360
361 RunUntilIdle();
362 EXPECT_THAT(run_order,
363 testing::ElementsAre(std::string("D3"), std::string("I1"),
364 std::string("I2")));
365 }
366
367 TEST_F(WorkerSchedulerImplTest, TestLongIdlePeriodTimeline) {
368 Init();
369
370 std::vector<std::string> timeline;
371 RecordTimelineEvents(&timeline);
372
373 // The scheduler should not run the initiate_next_long_idle_period task if
374 // there are no idle tasks and no other task woke up the scheduler, thus
375 // the idle period deadline shouldn't update at the end of the current long
376 // idle period.
377 base::TimeTicks idle_period_deadline =
378 scheduler_->CurrentIdleTaskDeadlineForTesting();
379 clock_->AdvanceNow(maximum_idle_period_duration());
380 RunUntilIdle();
381
382 base::TimeTicks new_idle_period_deadline =
383 scheduler_->CurrentIdleTaskDeadlineForTesting();
384 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
385
386 // Posting a after-wakeup idle task also shouldn't wake the scheduler or
387 // initiate the next long idle period.
388 timeline.push_back("PostIdleTaskAfterWakeup");
389 idle_task_runner_->PostIdleTaskAfterWakeup(
390 FROM_HERE, base::Bind(&TimelineIdleTestTask, &timeline));
391 RunUntilIdle();
392 new_idle_period_deadline = scheduler_->CurrentIdleTaskDeadlineForTesting();
393
394 // Running a normal task should initiate a new long idle period after waiting
395 // 300ms for quiescence.
396 timeline.push_back("Post RecordTimelineTask");
397 default_task_runner_->PostTask(
398 FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline),
399 base::Unretained(clock_.get())));
400 RunUntilIdle();
401
402 std::string expected_timeline[] = {
403 "RunUntilIdle begin @ 55",
404 "RunUntilIdle end @ 55",
405 "PostIdleTaskAfterWakeup",
406 "RunUntilIdle begin @ 55", // NOTE idle task doesn't run till later.
407 "RunUntilIdle end @ 55",
408 "Post RecordTimelineTask",
409 "RunUntilIdle begin @ 55",
410 "run RecordTimelineTask @ 55",
411 "IsNotQuiescent @ 55", // NOTE we have to wait for quiescence.
412 "CanEnterLongIdlePeriod @ 355",
413 "run TimelineIdleTestTask deadline 405",
414 "CanEnterLongIdlePeriod @ 405",
415 "RunUntilIdle end @ 455"};
416
417 EXPECT_THAT(timeline, ElementsAreArray(expected_timeline));
418 }
419
420 } // namespace content
OLDNEW
« no previous file with comments | « content/child/scheduler/worker_scheduler_impl.cc ('k') | content/child/threaded_data_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698