Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / scheduler / SchedulerTest.cpp
1 // Copyright 2014 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 "config.h"
6 #include "platform/scheduler/Scheduler.h"
7
8 #include "platform/TestingPlatformSupport.h"
9 #include "platform/TraceLocation.h"
10 #include "public/platform/Platform.h"
11 #include "public/platform/WebThread.h"
12
13 #include <gmock/gmock.h>
14 #include <gtest/gtest.h>
15 #include <string>
16 #include <vector>
17
18 using blink::Scheduler;
19 using namespace std;
20
21 namespace {
22
23 class TestMainThread : public blink::WebThread {
24 public:
25     // blink::WebThread implementation.
26     virtual void postTask(Task* task) OVERRIDE
27     {
28         m_pendingTasks.append(adoptPtr(task));
29     }
30
31     virtual void postDelayedTask(Task* task, long long delayMs) OVERRIDE
32     {
33         ASSERT_NOT_REACHED();
34     }
35
36     virtual bool isCurrentThread() const OVERRIDE
37     {
38         return true;
39     }
40
41     virtual void enterRunLoop() OVERRIDE
42     {
43         ASSERT_NOT_REACHED();
44     }
45
46     virtual void exitRunLoop() OVERRIDE
47     {
48         ASSERT_NOT_REACHED();
49     }
50
51     void runPendingTasks()
52     {
53         while (!m_pendingTasks.isEmpty())
54             m_pendingTasks.takeFirst()->run();
55     }
56
57 private:
58     WTF::Deque<OwnPtr<Task> > m_pendingTasks;
59 };
60
61 class SchedulerTestingPlatformSupport : blink::TestingPlatformSupport {
62 public:
63     SchedulerTestingPlatformSupport()
64         : TestingPlatformSupport(TestingPlatformSupport::Config())
65         , m_sharedTimerFunction(nullptr)
66         , m_sharedTimerRunning(false)
67         , m_sharedTimerFireInterval(0)
68     {
69     }
70
71     // blink::Platform implementation.
72     virtual blink::WebThread* currentThread() OVERRIDE
73     {
74         return &m_mainThread;
75     }
76
77     virtual void setSharedTimerFiredFunction(SharedTimerFunction timerFunction) OVERRIDE
78     {
79         m_sharedTimerFunction = timerFunction;
80     }
81
82     virtual void setSharedTimerFireInterval(double)
83     {
84         m_sharedTimerFireInterval = 0;
85         m_sharedTimerRunning = true;
86     }
87
88     virtual void stopSharedTimer()
89     {
90         m_sharedTimerRunning = false;
91     }
92
93     void runPendingTasks()
94     {
95         m_mainThread.runPendingTasks();
96     }
97
98     bool sharedTimerRunning() const
99     {
100         return m_sharedTimerRunning;
101     }
102
103     double sharedTimerFireInterval() const
104     {
105         return m_sharedTimerFireInterval;
106     }
107
108     void triggerSharedTimer()
109     {
110         m_sharedTimerFunction();
111     }
112
113 private:
114     TestMainThread m_mainThread;
115     SharedTimerFunction m_sharedTimerFunction;
116     bool m_sharedTimerRunning;
117     double m_sharedTimerFireInterval;
118 };
119
120 class SchedulerTest : public testing::Test {
121 public:
122     SchedulerTest()
123         : m_reentrantCount(0)
124         , m_maxRecursion(4)
125     {
126         Scheduler::initializeOnMainThread();
127         m_scheduler = Scheduler::shared();
128     }
129
130     ~SchedulerTest()
131     {
132         Scheduler::shutdown();
133     }
134
135     void runPendingTasks()
136     {
137         m_platformSupport.runPendingTasks();
138     }
139
140     void appendToVector(string value)
141     {
142         m_order.push_back(value);
143     }
144
145     void appendToVectorReentrantTask()
146     {
147         m_reentrantOrder.push_back(m_reentrantCount++);
148
149         if (m_reentrantCount > m_maxRecursion)
150             return;
151         Scheduler::shared()->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVectorReentrantTask, this));
152     }
153
154     void appendToVectorReentrantInputTask()
155     {
156         m_reentrantOrder.push_back(m_reentrantCount++);
157
158         if (m_reentrantCount > m_maxRecursion)
159             return;
160         m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVectorReentrantInputTask, this));
161     }
162
163     void appendToVectorReentrantCompositorTask()
164     {
165         m_reentrantOrder.push_back(m_reentrantCount++);
166
167         if (m_reentrantCount > m_maxRecursion)
168             return;
169         m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVectorReentrantCompositorTask, this));
170     }
171
172 protected:
173     SchedulerTestingPlatformSupport m_platformSupport;
174     Scheduler* m_scheduler;
175     std::vector<string> m_order;
176     std::vector<int> m_reentrantOrder;
177     int m_reentrantCount;
178     int m_maxRecursion;
179 };
180
181 void orderedTestTask(int value, int* result)
182 {
183     *result = (*result << 4) | value;
184 }
185
186 void unorderedTestTask(int value, int* result)
187 {
188     *result += value;
189 }
190
191 void idleTestTask(int value, int* result, double allottedTime)
192 {
193     *result += value;
194 }
195
196 TEST_F(SchedulerTest, TestPostTask)
197 {
198     int result = 0;
199     m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 1, &result));
200     m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 2, &result));
201     m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 3, &result));
202     m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 4, &result));
203     runPendingTasks();
204     EXPECT_EQ(0x1234, result);
205 }
206
207 TEST_F(SchedulerTest, TestPostMixedTaskTypes)
208 {
209     int result = 0;
210     m_scheduler->postTask(FROM_HERE, WTF::bind(&unorderedTestTask, 1, &result));
211     m_scheduler->postInputTask(FROM_HERE, WTF::bind(&unorderedTestTask, 2, &result));
212     m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&unorderedTestTask, 4, &result));
213     m_scheduler->postTask(FROM_HERE, WTF::bind(&unorderedTestTask, 8, &result));
214     runPendingTasks();
215     EXPECT_EQ(15, result);
216 }
217
218 int s_sharedTimerTickCount;
219 void sharedTimerFunction()
220 {
221     s_sharedTimerTickCount++;
222 }
223
224 TEST_F(SchedulerTest, TestSharedTimer)
225 {
226     s_sharedTimerTickCount = 0;
227     m_scheduler->setSharedTimerFiredFunction(&sharedTimerFunction);
228     EXPECT_FALSE(m_platformSupport.sharedTimerRunning());
229     m_scheduler->setSharedTimerFireInterval(0);
230     EXPECT_TRUE(m_platformSupport.sharedTimerRunning());
231
232     m_platformSupport.triggerSharedTimer();
233     EXPECT_EQ(1, s_sharedTimerTickCount);
234
235     m_scheduler->stopSharedTimer();
236     EXPECT_FALSE(m_platformSupport.sharedTimerRunning());
237
238     m_scheduler->setSharedTimerFiredFunction(nullptr);
239     EXPECT_FALSE(m_platformSupport.sharedTimerRunning());
240 }
241
242 TEST_F(SchedulerTest, TestIdleTask)
243 {
244     // TODO: Check task allottedTime when implemented in the scheduler.
245     int result = 0;
246     m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &result));
247     m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &result));
248     m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &result));
249     m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &result));
250     runPendingTasks();
251     EXPECT_EQ(4, result);
252 }
253
254 TEST_F(SchedulerTest, TestTaskPrioritization)
255 {
256     m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, string("L1")));
257     m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, string("L2")));
258     m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, string("I1")));
259     m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, string("I2")));
260     m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, string("C1")));
261     m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, string("C2")));
262
263     runPendingTasks();
264     EXPECT_THAT(m_order, testing::ElementsAre(
265         string("I1"), string("I2"), string("C1"), string("C2"), string("L1"), string("L2")));
266 }
267
268 TEST_F(SchedulerTest, TestRentrantTask)
269 {
270     m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVectorReentrantTask, this));
271     runPendingTasks();
272
273     EXPECT_THAT(m_reentrantOrder, testing::ElementsAre(0, 1, 2, 3, 4));
274 }
275
276
277 TEST_F(SchedulerTest, TestRentrantInputTaskDuringShutdown)
278 {
279     m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVectorReentrantInputTask, this));
280     Scheduler::shutdown();
281
282     EXPECT_THAT(m_reentrantOrder, testing::ElementsAre(0, 1, 2, 3, 4));
283 }
284
285 TEST_F(SchedulerTest, TestRentrantCompositorTaskDuringShutdown)
286 {
287     m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVectorReentrantCompositorTask, this));
288     Scheduler::shutdown();
289
290     EXPECT_THAT(m_reentrantOrder, testing::ElementsAre(0, 1, 2, 3, 4));
291 }
292
293 } // namespace