OLD | NEW |
| (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/renderer/scheduler/webthread_impl_for_renderer_scheduler.h" | |
6 | |
7 #include "base/run_loop.h" | |
8 #include "content/child/scheduler/scheduler_message_loop_delegate.h" | |
9 #include "content/renderer/scheduler/renderer_scheduler_impl.h" | |
10 #include "testing/gmock/include/gmock/gmock.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 #include "third_party/WebKit/public/platform/WebTraceLocation.h" | |
13 | |
14 namespace content { | |
15 namespace { | |
16 | |
17 const int kWorkBatchSize = 2; | |
18 | |
19 class MockTask : public blink::WebThread::Task { | |
20 public: | |
21 MOCK_METHOD0(run, void()); | |
22 }; | |
23 | |
24 class MockTaskObserver : public blink::WebThread::TaskObserver { | |
25 public: | |
26 MOCK_METHOD0(willProcessTask, void()); | |
27 MOCK_METHOD0(didProcessTask, void()); | |
28 }; | |
29 } // namespace | |
30 | |
31 class WebThreadImplForRendererSchedulerTest : public testing::Test { | |
32 public: | |
33 WebThreadImplForRendererSchedulerTest() | |
34 : scheduler_(SchedulerMessageLoopDelegate::Create(&message_loop_)), | |
35 default_task_runner_(scheduler_.DefaultTaskRunner()), | |
36 thread_(&scheduler_) {} | |
37 | |
38 ~WebThreadImplForRendererSchedulerTest() override {} | |
39 | |
40 void SetWorkBatchSizeForTesting(size_t work_batch_size) { | |
41 scheduler_.SetWorkBatchSizeForTesting(work_batch_size); | |
42 } | |
43 | |
44 protected: | |
45 void EatDefaultTask(MockTaskObserver* observer) { | |
46 // The scheduler posts one extra DoWork() task automatically. | |
47 EXPECT_CALL(*observer, willProcessTask()); | |
48 EXPECT_CALL(*observer, didProcessTask()); | |
49 } | |
50 | |
51 base::MessageLoop message_loop_; | |
52 RendererSchedulerImpl scheduler_; | |
53 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; | |
54 WebThreadImplForRendererScheduler thread_; | |
55 | |
56 DISALLOW_COPY_AND_ASSIGN(WebThreadImplForRendererSchedulerTest); | |
57 }; | |
58 | |
59 TEST_F(WebThreadImplForRendererSchedulerTest, TestTaskObserver) { | |
60 MockTaskObserver observer; | |
61 thread_.addTaskObserver(&observer); | |
62 scoped_ptr<MockTask> task(new MockTask()); | |
63 | |
64 { | |
65 testing::InSequence sequence; | |
66 EXPECT_CALL(observer, willProcessTask()); | |
67 EXPECT_CALL(*task, run()); | |
68 EXPECT_CALL(observer, didProcessTask()); | |
69 | |
70 EatDefaultTask(&observer); | |
71 } | |
72 | |
73 thread_.postTask(blink::WebTraceLocation(), task.release()); | |
74 message_loop_.RunUntilIdle(); | |
75 thread_.removeTaskObserver(&observer); | |
76 } | |
77 | |
78 TEST_F(WebThreadImplForRendererSchedulerTest, TestWorkBatchWithOneTask) { | |
79 MockTaskObserver observer; | |
80 thread_.addTaskObserver(&observer); | |
81 scoped_ptr<MockTask> task(new MockTask()); | |
82 | |
83 scheduler_.SetWorkBatchSizeForTesting(kWorkBatchSize); | |
84 { | |
85 testing::InSequence sequence; | |
86 EXPECT_CALL(observer, willProcessTask()); | |
87 EXPECT_CALL(*task, run()); | |
88 EXPECT_CALL(observer, didProcessTask()); | |
89 | |
90 EatDefaultTask(&observer); | |
91 } | |
92 | |
93 thread_.postTask(blink::WebTraceLocation(), task.release()); | |
94 message_loop_.RunUntilIdle(); | |
95 thread_.removeTaskObserver(&observer); | |
96 } | |
97 | |
98 TEST_F(WebThreadImplForRendererSchedulerTest, TestWorkBatchWithTwoTasks) { | |
99 MockTaskObserver observer; | |
100 thread_.addTaskObserver(&observer); | |
101 scoped_ptr<MockTask> task1(new MockTask()); | |
102 scoped_ptr<MockTask> task2(new MockTask()); | |
103 | |
104 scheduler_.SetWorkBatchSizeForTesting(kWorkBatchSize); | |
105 { | |
106 testing::InSequence sequence; | |
107 EXPECT_CALL(observer, willProcessTask()); | |
108 EXPECT_CALL(*task1, run()); | |
109 EXPECT_CALL(observer, didProcessTask()); | |
110 | |
111 EXPECT_CALL(observer, willProcessTask()); | |
112 EXPECT_CALL(*task2, run()); | |
113 EXPECT_CALL(observer, didProcessTask()); | |
114 | |
115 EatDefaultTask(&observer); | |
116 } | |
117 | |
118 thread_.postTask(blink::WebTraceLocation(), task1.release()); | |
119 thread_.postTask(blink::WebTraceLocation(), task2.release()); | |
120 message_loop_.RunUntilIdle(); | |
121 thread_.removeTaskObserver(&observer); | |
122 } | |
123 | |
124 TEST_F(WebThreadImplForRendererSchedulerTest, TestWorkBatchWithThreeTasks) { | |
125 MockTaskObserver observer; | |
126 thread_.addTaskObserver(&observer); | |
127 scoped_ptr<MockTask> task1(new MockTask()); | |
128 scoped_ptr<MockTask> task2(new MockTask()); | |
129 scoped_ptr<MockTask> task3(new MockTask()); | |
130 | |
131 scheduler_.SetWorkBatchSizeForTesting(kWorkBatchSize); | |
132 { | |
133 testing::InSequence sequence; | |
134 EXPECT_CALL(observer, willProcessTask()); | |
135 EXPECT_CALL(*task1, run()); | |
136 EXPECT_CALL(observer, didProcessTask()); | |
137 | |
138 EXPECT_CALL(observer, willProcessTask()); | |
139 EXPECT_CALL(*task2, run()); | |
140 EXPECT_CALL(observer, didProcessTask()); | |
141 | |
142 EXPECT_CALL(observer, willProcessTask()); | |
143 EXPECT_CALL(*task3, run()); | |
144 EXPECT_CALL(observer, didProcessTask()); | |
145 | |
146 EatDefaultTask(&observer); | |
147 } | |
148 | |
149 thread_.postTask(blink::WebTraceLocation(), task1.release()); | |
150 thread_.postTask(blink::WebTraceLocation(), task2.release()); | |
151 thread_.postTask(blink::WebTraceLocation(), task3.release()); | |
152 message_loop_.RunUntilIdle(); | |
153 thread_.removeTaskObserver(&observer); | |
154 } | |
155 | |
156 class ExitRunLoopTask : public blink::WebThread::Task { | |
157 public: | |
158 ExitRunLoopTask(base::RunLoop* run_loop) : run_loop_(run_loop) {} | |
159 | |
160 virtual void run() { run_loop_->Quit(); } | |
161 | |
162 private: | |
163 base::RunLoop* run_loop_; | |
164 }; | |
165 | |
166 void EnterRunLoop(base::MessageLoop* message_loop, blink::WebThread* thread) { | |
167 // Note: WebThreads do not support nested run loops, which is why we use a | |
168 // run loop directly. | |
169 base::RunLoop run_loop; | |
170 thread->postTask(blink::WebTraceLocation(), new ExitRunLoopTask(&run_loop)); | |
171 message_loop->SetNestableTasksAllowed(true); | |
172 run_loop.Run(); | |
173 } | |
174 | |
175 TEST_F(WebThreadImplForRendererSchedulerTest, TestNestedRunLoop) { | |
176 MockTaskObserver observer; | |
177 thread_.addTaskObserver(&observer); | |
178 | |
179 { | |
180 testing::InSequence sequence; | |
181 | |
182 // One callback for EnterRunLoop. | |
183 EXPECT_CALL(observer, willProcessTask()); | |
184 | |
185 // A pair for ExitRunLoopTask. | |
186 EXPECT_CALL(observer, willProcessTask()); | |
187 EXPECT_CALL(observer, didProcessTask()); | |
188 | |
189 // A final callback for EnterRunLoop. | |
190 EXPECT_CALL(observer, didProcessTask()); | |
191 | |
192 EatDefaultTask(&observer); | |
193 } | |
194 | |
195 message_loop_.PostTask( | |
196 FROM_HERE, base::Bind(&EnterRunLoop, base::Unretained(&message_loop_), | |
197 base::Unretained(&thread_))); | |
198 message_loop_.RunUntilIdle(); | |
199 thread_.removeTaskObserver(&observer); | |
200 } | |
201 | |
202 } // namespace content | |
OLD | NEW |