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.
5 #include "content/renderer/scheduler/webthread_impl_for_scheduler.h"
7 #include "base/run_loop.h"
8 #include "content/renderer/scheduler/renderer_scheduler_impl.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/WebKit/public/platform/WebTraceLocation.h"
16 const int kWorkBatchSize
= 2;
18 class MockTask
: public blink::WebThread::Task
{
20 MOCK_METHOD0(run
, void());
23 class MockTaskObserver
: public blink::WebThread::TaskObserver
{
25 MOCK_METHOD0(willProcessTask
, void());
26 MOCK_METHOD0(didProcessTask
, void());
30 class WebThreadImplForSchedulerTest
: public testing::Test
{
32 WebThreadImplForSchedulerTest()
33 : scheduler_(message_loop_
.task_runner()),
34 default_task_runner_(scheduler_
.DefaultTaskRunner()),
35 thread_(&scheduler_
) {}
37 ~WebThreadImplForSchedulerTest() override
{}
40 void EatDefaultTask(MockTaskObserver
* observer
) {
41 // The scheduler posts one extra DoWork() task automatically.
42 EXPECT_CALL(*observer
, willProcessTask());
43 EXPECT_CALL(*observer
, didProcessTask());
46 base::MessageLoop message_loop_
;
47 RendererSchedulerImpl scheduler_
;
48 scoped_refptr
<base::SingleThreadTaskRunner
> default_task_runner_
;
49 WebThreadImplForScheduler thread_
;
51 DISALLOW_COPY_AND_ASSIGN(WebThreadImplForSchedulerTest
);
54 TEST_F(WebThreadImplForSchedulerTest
, TestTaskObserver
) {
55 MockTaskObserver observer
;
56 thread_
.addTaskObserver(&observer
);
57 scoped_ptr
<MockTask
> task(new MockTask());
60 testing::InSequence sequence
;
61 EXPECT_CALL(observer
, willProcessTask());
62 EXPECT_CALL(*task
, run());
63 EXPECT_CALL(observer
, didProcessTask());
65 EatDefaultTask(&observer
);
68 thread_
.postTask(blink::WebTraceLocation(), task
.release());
69 message_loop_
.RunUntilIdle();
70 thread_
.removeTaskObserver(&observer
);
73 TEST_F(WebThreadImplForSchedulerTest
, TestWorkBatchWithOneTask
) {
74 MockTaskObserver observer
;
75 thread_
.addTaskObserver(&observer
);
76 scoped_ptr
<MockTask
> task(new MockTask());
78 scheduler_
.SetWorkBatchSizeForTesting(kWorkBatchSize
);
80 testing::InSequence sequence
;
81 EXPECT_CALL(observer
, willProcessTask());
82 EXPECT_CALL(*task
, run());
83 EXPECT_CALL(observer
, didProcessTask());
85 EatDefaultTask(&observer
);
88 thread_
.postTask(blink::WebTraceLocation(), task
.release());
89 message_loop_
.RunUntilIdle();
90 thread_
.removeTaskObserver(&observer
);
93 TEST_F(WebThreadImplForSchedulerTest
, TestWorkBatchWithTwoTasks
) {
94 MockTaskObserver observer
;
95 thread_
.addTaskObserver(&observer
);
96 scoped_ptr
<MockTask
> task1(new MockTask());
97 scoped_ptr
<MockTask
> task2(new MockTask());
99 scheduler_
.SetWorkBatchSizeForTesting(kWorkBatchSize
);
101 testing::InSequence sequence
;
102 EXPECT_CALL(observer
, willProcessTask());
103 EXPECT_CALL(*task1
, run());
104 EXPECT_CALL(observer
, didProcessTask());
106 EXPECT_CALL(observer
, willProcessTask());
107 EXPECT_CALL(*task2
, run());
108 EXPECT_CALL(observer
, didProcessTask());
110 EatDefaultTask(&observer
);
113 thread_
.postTask(blink::WebTraceLocation(), task1
.release());
114 thread_
.postTask(blink::WebTraceLocation(), task2
.release());
115 message_loop_
.RunUntilIdle();
116 thread_
.removeTaskObserver(&observer
);
119 TEST_F(WebThreadImplForSchedulerTest
, TestWorkBatchWithThreeTasks
) {
120 MockTaskObserver observer
;
121 thread_
.addTaskObserver(&observer
);
122 scoped_ptr
<MockTask
> task1(new MockTask());
123 scoped_ptr
<MockTask
> task2(new MockTask());
124 scoped_ptr
<MockTask
> task3(new MockTask());
126 scheduler_
.SetWorkBatchSizeForTesting(kWorkBatchSize
);
128 testing::InSequence sequence
;
129 EXPECT_CALL(observer
, willProcessTask());
130 EXPECT_CALL(*task1
, run());
131 EXPECT_CALL(observer
, didProcessTask());
133 EXPECT_CALL(observer
, willProcessTask());
134 EXPECT_CALL(*task2
, run());
135 EXPECT_CALL(observer
, didProcessTask());
137 EXPECT_CALL(observer
, willProcessTask());
138 EXPECT_CALL(*task3
, run());
139 EXPECT_CALL(observer
, didProcessTask());
141 EatDefaultTask(&observer
);
144 thread_
.postTask(blink::WebTraceLocation(), task1
.release());
145 thread_
.postTask(blink::WebTraceLocation(), task2
.release());
146 thread_
.postTask(blink::WebTraceLocation(), task3
.release());
147 message_loop_
.RunUntilIdle();
148 thread_
.removeTaskObserver(&observer
);
151 class ExitRunLoopTask
: public blink::WebThread::Task
{
153 ExitRunLoopTask(base::RunLoop
* run_loop
) : run_loop_(run_loop
) {}
155 virtual void run() { run_loop_
->Quit(); }
158 base::RunLoop
* run_loop_
;
161 void EnterRunLoop(base::MessageLoop
* message_loop
, blink::WebThread
* thread
) {
162 // Note: WebThreads do not support nested run loops, which is why we use a
163 // run loop directly.
164 base::RunLoop run_loop
;
165 thread
->postTask(blink::WebTraceLocation(), new ExitRunLoopTask(&run_loop
));
166 message_loop
->SetNestableTasksAllowed(true);
170 TEST_F(WebThreadImplForSchedulerTest
, TestNestedRunLoop
) {
171 MockTaskObserver observer
;
172 thread_
.addTaskObserver(&observer
);
175 testing::InSequence sequence
;
177 // One callback for EnterRunLoop.
178 EXPECT_CALL(observer
, willProcessTask());
180 // A pair for ExitRunLoopTask.
181 EXPECT_CALL(observer
, willProcessTask());
182 EXPECT_CALL(observer
, didProcessTask());
184 // A final callback for EnterRunLoop.
185 EXPECT_CALL(observer
, didProcessTask());
187 EatDefaultTask(&observer
);
190 message_loop_
.PostTask(
191 FROM_HERE
, base::Bind(&EnterRunLoop
, base::Unretained(&message_loop_
),
192 base::Unretained(&thread_
)));
193 message_loop_
.RunUntilIdle();
194 thread_
.removeTaskObserver(&observer
);
197 } // namespace content