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 "components/scheduler/child/webthread_impl_for_worker_scheduler.h"
7 #include "base/synchronization/waitable_event.h"
8 #include "components/scheduler/child/web_scheduler_impl.h"
9 #include "components/scheduler/child/worker_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"
16 using testing::ElementsAre
;
17 using testing::Invoke
;
22 class NopTask
: public blink::WebTaskRunner::Task
{
24 ~NopTask() override
{}
29 class MockTask
: public blink::WebTaskRunner::Task
{
31 ~MockTask() override
{}
33 MOCK_METHOD0(run
, void());
36 class MockIdleTask
: public blink::WebThread::IdleTask
{
38 ~MockIdleTask() override
{}
40 MOCK_METHOD1(run
, void(double deadline
));
43 class TestObserver
: public blink::WebThread::TaskObserver
{
45 explicit TestObserver(std::string
* calls
) : calls_(calls
) {}
47 ~TestObserver() override
{}
49 void willProcessTask() override
{ calls_
->append(" willProcessTask"); }
51 void didProcessTask() override
{ calls_
->append(" didProcessTask"); }
54 std::string
* calls_
; // NOT OWNED
57 class TestTask
: public blink::WebTaskRunner::Task
{
59 explicit TestTask(std::string
* calls
) : calls_(calls
) {}
61 ~TestTask() override
{}
63 void run() override
{ calls_
->append(" run"); }
66 std::string
* calls_
; // NOT OWNED
69 void addTaskObserver(WebThreadImplForWorkerScheduler
* thread
,
70 TestObserver
* observer
) {
71 thread
->addTaskObserver(observer
);
74 void removeTaskObserver(WebThreadImplForWorkerScheduler
* thread
,
75 TestObserver
* observer
) {
76 thread
->removeTaskObserver(observer
);
79 void shutdownOnThread(WebThreadImplForWorkerScheduler
* thread
) {
80 WebSchedulerImpl
* web_scheduler_impl
=
81 static_cast<WebSchedulerImpl
*>(thread
->scheduler());
82 web_scheduler_impl
->shutdown();
87 class WebThreadImplForWorkerSchedulerTest
: public testing::Test
{
89 WebThreadImplForWorkerSchedulerTest() {}
91 ~WebThreadImplForWorkerSchedulerTest() override
{}
93 void SetUp() override
{
94 thread_
.reset(new WebThreadImplForWorkerScheduler("test thread"));
97 void RunOnWorkerThread(const tracked_objects::Location
& from_here
,
98 const base::Closure
& task
) {
99 base::WaitableEvent
completion(false, false);
100 thread_
->TaskRunner()->PostTask(
102 base::Bind(&WebThreadImplForWorkerSchedulerTest::RunOnWorkerThreadTask
,
103 base::Unretained(this), task
, &completion
));
108 void RunOnWorkerThreadTask(const base::Closure
& task
,
109 base::WaitableEvent
* completion
) {
111 completion
->Signal();
114 scoped_ptr
<WebThreadImplForWorkerScheduler
> thread_
;
116 DISALLOW_COPY_AND_ASSIGN(WebThreadImplForWorkerSchedulerTest
);
119 TEST_F(WebThreadImplForWorkerSchedulerTest
, TestDefaultTask
) {
120 scoped_ptr
<MockTask
> task(new MockTask());
121 base::WaitableEvent
completion(false, false);
123 EXPECT_CALL(*task
, run());
124 ON_CALL(*task
, run())
125 .WillByDefault(Invoke([&completion
]() { completion
.Signal(); }));
127 thread_
->taskRunner()->postTask(blink::WebTraceLocation(), task
.release());
131 TEST_F(WebThreadImplForWorkerSchedulerTest
,
132 TestTaskExecutedBeforeThreadDeletion
) {
133 scoped_ptr
<MockTask
> task(new MockTask());
134 base::WaitableEvent
completion(false, false);
136 EXPECT_CALL(*task
, run());
137 ON_CALL(*task
, run())
138 .WillByDefault(Invoke([&completion
]() { completion
.Signal(); }));
140 thread_
->taskRunner()->postTask(blink::WebTraceLocation(), task
.release());
144 TEST_F(WebThreadImplForWorkerSchedulerTest
, TestIdleTask
) {
145 scoped_ptr
<MockIdleTask
> task(new MockIdleTask());
146 base::WaitableEvent
completion(false, false);
148 EXPECT_CALL(*task
, run(_
));
149 ON_CALL(*task
, run(_
))
150 .WillByDefault(Invoke([&completion
](double) { completion
.Signal(); }));
152 thread_
->postIdleTask(blink::WebTraceLocation(), task
.release());
153 // We need to post a wakeup task or idle work will never happen.
154 thread_
->taskRunner()->postDelayedTask(blink::WebTraceLocation(),
155 new NopTask(), 50ll);
160 TEST_F(WebThreadImplForWorkerSchedulerTest
, TestTaskObserver
) {
162 TestObserver
observer(&calls
);
164 RunOnWorkerThread(FROM_HERE
,
165 base::Bind(&addTaskObserver
, thread_
.get(), &observer
));
166 thread_
->taskRunner()->postTask(blink::WebTraceLocation(),
167 new TestTask(&calls
));
168 RunOnWorkerThread(FROM_HERE
,
169 base::Bind(&removeTaskObserver
, thread_
.get(), &observer
));
171 // We need to be careful what we test here. We want to make sure the
172 // observers are un in the expected order before and after the task.
173 // Sometimes we get an internal scheduler task running before or after
174 // TestTask as well. This is not a bug, and we need to make sure the test
175 // doesn't fail when that happens.
176 EXPECT_THAT(calls
, testing::HasSubstr("willProcessTask run didProcessTask"));
179 TEST_F(WebThreadImplForWorkerSchedulerTest
, TestShutdown
) {
180 scoped_ptr
<MockTask
> task(new MockTask());
181 scoped_ptr
<MockTask
> delayed_task(new MockTask());
183 EXPECT_CALL(*task
, run()).Times(0);
184 EXPECT_CALL(*delayed_task
, run()).Times(0);
186 RunOnWorkerThread(FROM_HERE
, base::Bind(&shutdownOnThread
, thread_
.get()));
187 thread_
->taskRunner()->postTask(blink::WebTraceLocation(), task
.release());
188 thread_
->taskRunner()->postDelayedTask(blink::WebTraceLocation(),
189 task
.release(), 50ll);
193 } // namespace scheduler