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_scheduler.h" | |
6 | |
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" | |
12 | |
13 namespace content { | |
14 namespace { | |
15 | |
16 const int kWorkBatchSize = 2; | |
17 | |
18 class MockTask : public blink::WebThread::Task { | |
19 public: | |
20 MOCK_METHOD0(run, void()); | |
21 }; | |
22 | |
23 class MockTaskObserver : public blink::WebThread::TaskObserver { | |
24 public: | |
25 MOCK_METHOD0(willProcessTask, void()); | |
26 MOCK_METHOD0(didProcessTask, void()); | |
27 }; | |
28 } // namespace | |
29 | |
30 class WebThreadImplForSchedulerTest : public testing::Test { | |
31 public: | |
32 WebThreadImplForSchedulerTest() | |
33 : scheduler_(message_loop_.task_runner()), | |
34 default_task_runner_(scheduler_.DefaultTaskRunner()), | |
35 thread_(&scheduler_) {} | |
36 | |
37 ~WebThreadImplForSchedulerTest() override {} | |
38 | |
39 protected: | |
40 void EatDefaultTask(MockTaskObserver* observer) { | |
41 // The scheduler posts one extra DoWork() task automatically. | |
42 EXPECT_CALL(*observer, willProcessTask()); | |
43 EXPECT_CALL(*observer, didProcessTask()); | |
44 } | |
45 | |
46 base::MessageLoop message_loop_; | |
47 RendererSchedulerImpl scheduler_; | |
48 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; | |
49 WebThreadImplForScheduler thread_; | |
50 | |
51 DISALLOW_COPY_AND_ASSIGN(WebThreadImplForSchedulerTest); | |
52 }; | |
53 | |
54 TEST_F(WebThreadImplForSchedulerTest, TestTaskObserver) { | |
55 MockTaskObserver observer; | |
56 thread_.addTaskObserver(&observer); | |
57 scoped_ptr<MockTask> task(new MockTask()); | |
58 | |
59 { | |
60 testing::InSequence sequence; | |
61 EXPECT_CALL(observer, willProcessTask()); | |
62 EXPECT_CALL(*task, run()); | |
63 EXPECT_CALL(observer, didProcessTask()); | |
64 | |
65 EatDefaultTask(&observer); | |
66 } | |
67 | |
68 thread_.postTask(blink::WebTraceLocation(), task.release()); | |
69 message_loop_.RunUntilIdle(); | |
70 thread_.removeTaskObserver(&observer); | |
71 } | |
72 | |
73 TEST_F(WebThreadImplForSchedulerTest, TestWorkBatchWithOneTask) { | |
74 MockTaskObserver observer; | |
75 thread_.addTaskObserver(&observer); | |
76 scoped_ptr<MockTask> task(new MockTask()); | |
77 | |
78 scheduler_.SetWorkBatchSizeForTesting(kWorkBatchSize); | |
79 { | |
80 testing::InSequence sequence; | |
81 EXPECT_CALL(observer, willProcessTask()); | |
82 EXPECT_CALL(*task, run()); | |
83 EXPECT_CALL(observer, didProcessTask()); | |
84 | |
85 EatDefaultTask(&observer); | |
86 } | |
87 | |
88 thread_.postTask(blink::WebTraceLocation(), task.release()); | |
89 message_loop_.RunUntilIdle(); | |
90 thread_.removeTaskObserver(&observer); | |
91 } | |
92 | |
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()); | |
98 | |
99 scheduler_.SetWorkBatchSizeForTesting(kWorkBatchSize); | |
100 { | |
101 testing::InSequence sequence; | |
102 EXPECT_CALL(observer, willProcessTask()); | |
103 EXPECT_CALL(*task1, run()); | |
104 EXPECT_CALL(observer, didProcessTask()); | |
105 | |
106 EXPECT_CALL(observer, willProcessTask()); | |
107 EXPECT_CALL(*task2, run()); | |
108 EXPECT_CALL(observer, didProcessTask()); | |
109 | |
110 EatDefaultTask(&observer); | |
111 } | |
112 | |
113 thread_.postTask(blink::WebTraceLocation(), task1.release()); | |
114 thread_.postTask(blink::WebTraceLocation(), task2.release()); | |
115 message_loop_.RunUntilIdle(); | |
116 thread_.removeTaskObserver(&observer); | |
117 } | |
118 | |
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()); | |
125 | |
126 scheduler_.SetWorkBatchSizeForTesting(kWorkBatchSize); | |
127 { | |
128 testing::InSequence sequence; | |
129 EXPECT_CALL(observer, willProcessTask()); | |
130 EXPECT_CALL(*task1, run()); | |
131 EXPECT_CALL(observer, didProcessTask()); | |
132 | |
133 EXPECT_CALL(observer, willProcessTask()); | |
134 EXPECT_CALL(*task2, run()); | |
135 EXPECT_CALL(observer, didProcessTask()); | |
136 | |
137 EXPECT_CALL(observer, willProcessTask()); | |
138 EXPECT_CALL(*task3, run()); | |
139 EXPECT_CALL(observer, didProcessTask()); | |
140 | |
141 EatDefaultTask(&observer); | |
142 } | |
143 | |
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); | |
149 } | |
150 | |
151 class ExitRunLoopTask : public blink::WebThread::Task { | |
152 public: | |
153 ExitRunLoopTask(base::RunLoop* run_loop) : run_loop_(run_loop) {} | |
154 | |
155 virtual void run() { run_loop_->Quit(); } | |
156 | |
157 private: | |
158 base::RunLoop* run_loop_; | |
159 }; | |
160 | |
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); | |
167 run_loop.Run(); | |
168 } | |
169 | |
170 TEST_F(WebThreadImplForSchedulerTest, TestNestedRunLoop) { | |
171 MockTaskObserver observer; | |
172 thread_.addTaskObserver(&observer); | |
173 | |
174 { | |
175 testing::InSequence sequence; | |
176 | |
177 // One callback for EnterRunLoop. | |
178 EXPECT_CALL(observer, willProcessTask()); | |
179 | |
180 // A double pair for ExitRunLoopTask because we are in a nested message | |
181 // loop. | |
rmcilroy
2015/02/20 23:03:06
I worry that we might see test fail due to the dou
Sami
2015/02/23 15:11:02
FWIW, a form of the double calls already happens b
| |
182 EXPECT_CALL(observer, willProcessTask()); | |
183 EXPECT_CALL(observer, willProcessTask()); | |
184 EXPECT_CALL(observer, didProcessTask()); | |
185 EXPECT_CALL(observer, didProcessTask()); | |
186 | |
187 // A final callback for EnterRunLoop. | |
188 EXPECT_CALL(observer, didProcessTask()); | |
189 | |
190 EatDefaultTask(&observer); | |
191 } | |
192 | |
193 message_loop_.PostTask( | |
194 FROM_HERE, base::Bind(&EnterRunLoop, base::Unretained(&message_loop_), | |
195 base::Unretained(&thread_))); | |
196 message_loop_.RunUntilIdle(); | |
197 thread_.removeTaskObserver(&observer); | |
198 } | |
199 | |
200 } // namespace content | |
OLD | NEW |