Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / scheduler / child / webthread_impl_for_worker_scheduler_unittest.cc
blobdb4fd18726ed71e31877fd64aaff037b9ceb77b3
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"
14 using testing::_;
15 using testing::AnyOf;
16 using testing::ElementsAre;
17 using testing::Invoke;
19 namespace scheduler {
20 namespace {
22 class NopTask : public blink::WebTaskRunner::Task {
23 public:
24 ~NopTask() override {}
26 void run() {}
29 class MockTask : public blink::WebTaskRunner::Task {
30 public:
31 ~MockTask() override {}
33 MOCK_METHOD0(run, void());
36 class MockIdleTask : public blink::WebThread::IdleTask {
37 public:
38 ~MockIdleTask() override {}
40 MOCK_METHOD1(run, void(double deadline));
43 class TestObserver : public blink::WebThread::TaskObserver {
44 public:
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"); }
53 private:
54 std::string* calls_; // NOT OWNED
57 class TestTask : public blink::WebTaskRunner::Task {
58 public:
59 explicit TestTask(std::string* calls) : calls_(calls) {}
61 ~TestTask() override {}
63 void run() override { calls_->append(" run"); }
65 private:
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();
85 } // namespace
87 class WebThreadImplForWorkerSchedulerTest : public testing::Test {
88 public:
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(
101 from_here,
102 base::Bind(&WebThreadImplForWorkerSchedulerTest::RunOnWorkerThreadTask,
103 base::Unretained(this), task, &completion));
104 completion.Wait();
107 protected:
108 void RunOnWorkerThreadTask(const base::Closure& task,
109 base::WaitableEvent* completion) {
110 task.Run();
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());
128 completion.Wait();
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());
141 thread_.reset();
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);
157 completion.Wait();
160 TEST_F(WebThreadImplForWorkerSchedulerTest, TestTaskObserver) {
161 std::string calls;
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);
190 thread_.reset();
193 } // namespace scheduler