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

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

Issue 1033643004: Add a WorkerScheduler and a WebThreadImplForWorker (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Ross's suggestions 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 "cc/test/ordered_simple_task_runner.h"
9 #include "content/child/scheduler/nestable_task_runner_for_test.h"
10 #include "content/child/scheduler/scheduler_message_loop_delegate.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace content {
15
16 namespace {
17 void NopTask() {
18 }
19
20 void AppendToVectorTestTask(std::vector<std::string>* vector,
21 std::string value) {
22 vector->push_back(value);
23 }
24
25 void AppendToVectorIdleTestTask(std::vector<std::string>* vector,
26 std::string value,
27 base::TimeTicks deadline) {
28 AppendToVectorTestTask(vector, value);
29 }
30
31 void IdleTestTask(base::TimeTicks* deadline_out, base::TimeTicks deadline) {
32 *deadline_out = deadline;
33 }
34
35 void CountingIdleTestTask(int* run_count,
36 base::TimeTicks* deadline_out,
37 base::TimeTicks deadline) {
38 (*run_count)++;
39 *deadline_out = deadline;
40 }
41
42 }; // namespace
43
44 class WorkerSchedulerImplTest : public testing::Test {
45 public:
46 WorkerSchedulerImplTest()
47 : clock_(cc::TestNowSource::Create(5000)),
48 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, true)),
49 nestable_task_runner_(
50 NestableTaskRunnerForTest::Create(mock_task_runner_)),
51 scheduler_(new WorkerSchedulerImpl(nestable_task_runner_)) {
52 scheduler_->SetTimeSourceForTesting(clock_);
53 }
54
55 ~WorkerSchedulerImplTest() override {}
56
57 void TearDown() override {
58 // Check that all tests stop posting tasks.
59 while (mock_task_runner_->RunUntilIdle()) {
60 }
61 }
62
63 void Init() {
64 scheduler_->Init();
65 default_task_runner_ = scheduler_->DefaultTaskRunner();
66 idle_task_runner_ = scheduler_->IdleTaskRunner();
67 }
68
69 void RunUntilIdle() { mock_task_runner_->RunUntilIdle(); }
70
71 void InitAndPostDelayedWakeupTask() {
72 Init();
73 // WorkerSchedulerImpl::Init causes a delayed task to be posted on the
74 // after wakeup control runner. We need a task to wake the system up
75 // AFTER the delay for this has expired.
76 default_task_runner_->PostDelayedTask(
77 FROM_HERE, base::Bind(&NopTask),
78 base::TimeDelta::FromMilliseconds(100));
79 }
80
81 // Helper for posting several tasks of specific types. |task_descriptor| is a
82 // string with space delimited task identifiers. The first letter of each
83 // task identifier specifies the task type:
84 // - 'D': Default task
85 // - 'I': Idle task
86 void PostTestTasks(std::vector<std::string>* run_order,
87 const std::string& task_descriptor) {
88 std::istringstream stream(task_descriptor);
89 while (!stream.eof()) {
90 std::string task;
91 stream >> task;
92 switch (task[0]) {
93 case 'D':
94 default_task_runner_->PostTask(
95 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
96 break;
97 case 'I':
98 idle_task_runner_->PostIdleTask(
99 FROM_HERE,
100 base::Bind(&AppendToVectorIdleTestTask, run_order, task));
101 break;
102 default:
103 NOTREACHED();
104 }
105 }
106 }
107
108 static base::TimeDelta maximum_idle_period_duration() {
109 return base::TimeDelta::FromMilliseconds(
110 SchedulerHelper::kMaximumIdlePeriodMillis);
111 }
112
113 protected:
114 scoped_refptr<cc::TestNowSource> clock_;
115 // Only one of mock_task_runner_ or message_loop_ will be set.
116 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
117
118 scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_;
119 scoped_ptr<WorkerSchedulerImpl> scheduler_;
120 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
121 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
122
123 DISALLOW_COPY_AND_ASSIGN(WorkerSchedulerImplTest);
124 };
125
126 TEST_F(WorkerSchedulerImplTest, TestPostDefaultTask) {
127 InitAndPostDelayedWakeupTask();
128
129 std::vector<std::string> run_order;
130 PostTestTasks(&run_order, "D1 D2 D3 D4");
131
132 RunUntilIdle();
133 EXPECT_THAT(run_order,
134 testing::ElementsAre(std::string("D1"), std::string("D2"),
135 std::string("D3"), std::string("D4")));
136 }
137
138 TEST_F(WorkerSchedulerImplTest, TestPostIdleTask) {
139 InitAndPostDelayedWakeupTask();
140
141 std::vector<std::string> run_order;
142 PostTestTasks(&run_order, "I1");
143
144 RunUntilIdle();
145 EXPECT_THAT(run_order, testing::ElementsAre(std::string("I1")));
146 }
147
148 TEST_F(WorkerSchedulerImplTest, TestPostIdleTask_NoWakeup) {
149 Init();
150 std::vector<std::string> run_order;
151 PostTestTasks(&run_order, "I1");
152
153 RunUntilIdle();
154 EXPECT_TRUE(run_order.empty());
155 }
156
157 TEST_F(WorkerSchedulerImplTest, TestPostDefaultAndIdleTasks) {
158 InitAndPostDelayedWakeupTask();
159
160 std::vector<std::string> run_order;
161 PostTestTasks(&run_order, "I1 D2 D3 D4");
162
163 RunUntilIdle();
164 EXPECT_THAT(run_order,
165 testing::ElementsAre(std::string("D2"), std::string("D3"),
166 std::string("D4"), std::string("I1")));
167 }
168
169 TEST_F(WorkerSchedulerImplTest, TestPostIdleTaskWithWakeupNeeded_NoWakeup) {
170 InitAndPostDelayedWakeupTask();
171
172 RunUntilIdle();
173 // The delayed call to InitiateLongIdlePeriod happened and it posted a call to
174 // InitiateLongIdlePeriod on the after wakeup control queue.
175
176 std::vector<std::string> run_order;
177 PostTestTasks(&run_order, "I1");
178
179 RunUntilIdle();
180 EXPECT_TRUE(run_order.empty());
181 }
182
183 TEST_F(WorkerSchedulerImplTest, TestPostDefaultDelayedAndIdleTasks) {
184 InitAndPostDelayedWakeupTask();
185
186 std::vector<std::string> run_order;
187 PostTestTasks(&run_order, "I1 D2 D3 D4");
188
189 default_task_runner_->PostDelayedTask(
190 FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "DELAYED"),
191 base::TimeDelta::FromMilliseconds(1000));
192
193 RunUntilIdle();
194 EXPECT_THAT(run_order,
195 testing::ElementsAre(std::string("D2"), std::string("D3"),
196 std::string("D4"), std::string("I1"),
197 std::string("DELAYED")));
198 }
199
200 TEST_F(WorkerSchedulerImplTest, TestIdleDeadlineWithPendingDelayedTask) {
201 InitAndPostDelayedWakeupTask();
202
203 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(140);
204 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay);
205 base::TimeTicks deadline;
206 idle_task_runner_->PostIdleTask(FROM_HERE,
207 base::Bind(&IdleTestTask, &deadline));
208
209 base::TimeTicks expected_deadline = clock_->Now() + delay;
210 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
211
212 RunUntilIdle();
213 EXPECT_EQ(expected_deadline, deadline);
214 }
215
216 TEST_F(WorkerSchedulerImplTest,
217 TestIdleDeadlineWithPendingDelayedTaskFarInTheFuture) {
218 InitAndPostDelayedWakeupTask();
219
220 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(1000);
221 base::TimeTicks task_run_time = clock_->Now() + delay;
222 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay);
223 base::TimeTicks deadline;
224 idle_task_runner_->PostIdleTask(FROM_HERE,
225 base::Bind(&IdleTestTask, &deadline));
226
227 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
228
229 RunUntilIdle();
230 EXPECT_LT(deadline, task_run_time);
231 }
232
233 TEST_F(WorkerSchedulerImplTest,
234 TestPostIdleTaskAfterRunningUntilIdle_NoWakeUp) {
235 InitAndPostDelayedWakeupTask();
236
237 default_task_runner_->PostDelayedTask(
238 FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(1000));
239 RunUntilIdle();
240
241 // The delayed call to InitiateLongIdlePeriod happened and it posted a call to
242 // InitiateLongIdlePeriod on the after wakeup control queue. Without an other
243 // non-idle task posted, the idle tasks won't run.
244 std::vector<std::string> run_order;
245 PostTestTasks(&run_order, "I1 I2");
246
247 RunUntilIdle();
248 EXPECT_TRUE(run_order.empty());
249 }
250
251 TEST_F(WorkerSchedulerImplTest,
252 TestPostIdleTaskAfterRunningUntilIdle_WithWakeUp) {
253 InitAndPostDelayedWakeupTask();
254
255 default_task_runner_->PostDelayedTask(
256 FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(1000));
257 RunUntilIdle();
258 // The delayed call to InitiateLongIdlePeriod happened and it posted a call to
259 // InitiateLongIdlePeriod on the after wakeup control queue. Without an other
260 // non-idle task posted, the idle tasks won't run.
261
262 std::vector<std::string> run_order;
263 PostTestTasks(&run_order, "I1 I2 D3");
264
265 RunUntilIdle();
266 EXPECT_THAT(run_order,
267 testing::ElementsAre(std::string("D3"), std::string("I1"),
268 std::string("I2")));
269 }
270
271 TEST_F(WorkerSchedulerImplTest, TestLongIdlePeriodDoesNotWakeScheduler) {
272 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(false);
273 Init();
274
275 base::TimeTicks deadline_in_task;
276 int run_count = 0;
277
278 // The scheduler should not run the initiate_next_long_idle_period task if
279 // there are no idle tasks and no other task woke up the scheduler, thus
280 // the idle period deadline shouldn't update at the end of the current long
281 // idle period.
282 base::TimeTicks idle_period_deadline =
283 scheduler_->CurrentIdleTaskDeadlineForTesting();
284 clock_->AdvanceNow(maximum_idle_period_duration());
285 RunUntilIdle();
286
287 base::TimeTicks new_idle_period_deadline =
288 scheduler_->CurrentIdleTaskDeadlineForTesting();
289 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
290
291 // Posting a after-wakeup idle task also shouldn't wake the scheduler or
292 // initiate the next long idle period.
293 idle_task_runner_->PostIdleTaskAfterWakeup(
294 FROM_HERE,
295 base::Bind(&CountingIdleTestTask, &run_count, &deadline_in_task));
296 RunUntilIdle();
297 new_idle_period_deadline = scheduler_->CurrentIdleTaskDeadlineForTesting();
298 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
299 EXPECT_EQ(0, run_count);
300
301 // Running a normal task should initiate a new long idle period though.
302 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NopTask));
303 RunUntilIdle();
304 new_idle_period_deadline = scheduler_->CurrentIdleTaskDeadlineForTesting();
305 EXPECT_EQ(idle_period_deadline + maximum_idle_period_duration(),
306 new_idle_period_deadline);
307
308 EXPECT_EQ(1, run_count);
309 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
310 }
311
312 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698