Line data Source code
1 : // Copyright 2014 the V8 project 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 "src/libplatform/default-platform.h"
6 : #include "src/base/platform/semaphore.h"
7 : #include "src/base/platform/time.h"
8 : #include "testing/gmock/include/gmock/gmock.h"
9 :
10 : using testing::InSequence;
11 : using testing::StrictMock;
12 :
13 : namespace v8 {
14 : namespace platform {
15 : namespace default_platform_unittest {
16 :
17 : namespace {
18 :
19 12 : struct MockTask : public Task {
20 : // See issue v8:8185
21 36 : ~MockTask() /* override */ { Die(); }
22 18 : MOCK_METHOD0(Run, void());
23 24 : MOCK_METHOD0(Die, void());
24 : };
25 :
26 4 : struct MockIdleTask : public IdleTask {
27 : // See issue v8:8185
28 12 : ~MockIdleTask() /* override */ { Die(); }
29 8 : MOCK_METHOD1(Run, void(double deadline_in_seconds));
30 8 : MOCK_METHOD0(Die, void());
31 : };
32 :
33 8 : class DefaultPlatformWithMockTime : public DefaultPlatform {
34 : public:
35 8 : DefaultPlatformWithMockTime()
36 16 : : DefaultPlatform(IdleTaskSupport::kEnabled, nullptr) {
37 8 : mock_time_ = 0.0;
38 31 : SetTimeFunctionForTesting([]() { return mock_time_; });
39 8 : }
40 7 : void IncreaseTime(double seconds) { mock_time_ += seconds; }
41 :
42 : private:
43 : static double mock_time_;
44 : };
45 :
46 : double DefaultPlatformWithMockTime::mock_time_ = 0.0;
47 :
48 : } // namespace
49 :
50 :
51 15373 : TEST(DefaultPlatformTest, PumpMessageLoop) {
52 2 : InSequence s;
53 :
54 : int dummy;
55 : Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
56 :
57 3 : DefaultPlatform platform;
58 2 : EXPECT_FALSE(platform.PumpMessageLoop(isolate));
59 :
60 1 : StrictMock<MockTask>* task = new StrictMock<MockTask>;
61 1 : platform.CallOnForegroundThread(isolate, task);
62 2 : EXPECT_CALL(*task, Run());
63 2 : EXPECT_CALL(*task, Die());
64 2 : EXPECT_TRUE(platform.PumpMessageLoop(isolate));
65 2 : EXPECT_FALSE(platform.PumpMessageLoop(isolate));
66 1 : }
67 :
68 15373 : TEST(DefaultPlatformTest, PumpMessageLoopWithTaskRunner) {
69 2 : InSequence s;
70 :
71 : int dummy;
72 : Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
73 :
74 3 : DefaultPlatform platform;
75 : std::shared_ptr<TaskRunner> taskrunner =
76 1 : platform.GetForegroundTaskRunner(isolate);
77 2 : EXPECT_FALSE(platform.PumpMessageLoop(isolate));
78 :
79 1 : StrictMock<MockTask>* task = new StrictMock<MockTask>;
80 3 : taskrunner->PostTask(std::unique_ptr<Task>(task));
81 2 : EXPECT_CALL(*task, Run());
82 2 : EXPECT_CALL(*task, Die());
83 2 : EXPECT_TRUE(platform.PumpMessageLoop(isolate));
84 2 : EXPECT_FALSE(platform.PumpMessageLoop(isolate));
85 1 : }
86 :
87 15373 : TEST(DefaultPlatformTest, PumpMessageLoopDelayed) {
88 2 : InSequence s;
89 :
90 : int dummy;
91 : Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
92 :
93 1 : DefaultPlatformWithMockTime platform;
94 2 : EXPECT_FALSE(platform.PumpMessageLoop(isolate));
95 :
96 1 : StrictMock<MockTask>* task1 = new StrictMock<MockTask>;
97 1 : StrictMock<MockTask>* task2 = new StrictMock<MockTask>;
98 1 : platform.CallDelayedOnForegroundThread(isolate, task2, 100);
99 1 : platform.CallDelayedOnForegroundThread(isolate, task1, 10);
100 :
101 2 : EXPECT_FALSE(platform.PumpMessageLoop(isolate));
102 :
103 : platform.IncreaseTime(11);
104 2 : EXPECT_CALL(*task1, Run());
105 2 : EXPECT_CALL(*task1, Die());
106 2 : EXPECT_TRUE(platform.PumpMessageLoop(isolate));
107 :
108 2 : EXPECT_FALSE(platform.PumpMessageLoop(isolate));
109 :
110 : platform.IncreaseTime(90);
111 2 : EXPECT_CALL(*task2, Run());
112 2 : EXPECT_CALL(*task2, Die());
113 2 : EXPECT_TRUE(platform.PumpMessageLoop(isolate));
114 1 : }
115 :
116 15373 : TEST(DefaultPlatformTest, PumpMessageLoopDelayedWithTaskRunner) {
117 2 : InSequence s;
118 :
119 : int dummy;
120 : Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
121 :
122 1 : DefaultPlatformWithMockTime platform;
123 : std::shared_ptr<TaskRunner> taskrunner =
124 1 : platform.GetForegroundTaskRunner(isolate);
125 2 : EXPECT_FALSE(platform.PumpMessageLoop(isolate));
126 :
127 1 : StrictMock<MockTask>* task1 = new StrictMock<MockTask>;
128 1 : StrictMock<MockTask>* task2 = new StrictMock<MockTask>;
129 3 : taskrunner->PostDelayedTask(std::unique_ptr<Task>(task2), 100);
130 3 : taskrunner->PostDelayedTask(std::unique_ptr<Task>(task1), 10);
131 :
132 2 : EXPECT_FALSE(platform.PumpMessageLoop(isolate));
133 :
134 : platform.IncreaseTime(11);
135 2 : EXPECT_CALL(*task1, Run());
136 2 : EXPECT_CALL(*task1, Die());
137 2 : EXPECT_TRUE(platform.PumpMessageLoop(isolate));
138 :
139 2 : EXPECT_FALSE(platform.PumpMessageLoop(isolate));
140 :
141 : platform.IncreaseTime(90);
142 2 : EXPECT_CALL(*task2, Run());
143 2 : EXPECT_CALL(*task2, Die());
144 2 : EXPECT_TRUE(platform.PumpMessageLoop(isolate));
145 1 : }
146 :
147 15373 : TEST(DefaultPlatformTest, PumpMessageLoopNoStarvation) {
148 2 : InSequence s;
149 :
150 : int dummy;
151 : Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
152 :
153 1 : DefaultPlatformWithMockTime platform;
154 2 : EXPECT_FALSE(platform.PumpMessageLoop(isolate));
155 :
156 1 : StrictMock<MockTask>* task1 = new StrictMock<MockTask>;
157 1 : StrictMock<MockTask>* task2 = new StrictMock<MockTask>;
158 1 : StrictMock<MockTask>* task3 = new StrictMock<MockTask>;
159 1 : platform.CallOnForegroundThread(isolate, task1);
160 1 : platform.CallDelayedOnForegroundThread(isolate, task2, 10);
161 : platform.IncreaseTime(11);
162 :
163 2 : EXPECT_CALL(*task1, Run());
164 2 : EXPECT_CALL(*task1, Die());
165 2 : EXPECT_TRUE(platform.PumpMessageLoop(isolate));
166 :
167 1 : platform.CallOnForegroundThread(isolate, task3);
168 :
169 2 : EXPECT_CALL(*task2, Run());
170 2 : EXPECT_CALL(*task2, Die());
171 2 : EXPECT_TRUE(platform.PumpMessageLoop(isolate));
172 2 : EXPECT_CALL(*task3, Run());
173 2 : EXPECT_CALL(*task3, Die());
174 2 : EXPECT_TRUE(platform.PumpMessageLoop(isolate));
175 1 : }
176 :
177 :
178 15373 : TEST(DefaultPlatformTest, PendingDelayedTasksAreDestroyedOnShutdown) {
179 2 : InSequence s;
180 :
181 : int dummy;
182 : Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
183 :
184 : {
185 1 : DefaultPlatformWithMockTime platform;
186 1 : StrictMock<MockTask>* task = new StrictMock<MockTask>;
187 1 : platform.CallDelayedOnForegroundThread(isolate, task, 10);
188 2 : EXPECT_CALL(*task, Die());
189 : }
190 1 : }
191 :
192 15373 : TEST(DefaultPlatformTest, RunIdleTasks) {
193 2 : InSequence s;
194 :
195 : int dummy;
196 : Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
197 :
198 1 : DefaultPlatformWithMockTime platform;
199 :
200 1 : StrictMock<MockIdleTask>* task = new StrictMock<MockIdleTask>;
201 1 : platform.CallIdleOnForegroundThread(isolate, task);
202 3 : EXPECT_CALL(*task, Run(42.0 + 23.0));
203 2 : EXPECT_CALL(*task, Die());
204 : platform.IncreaseTime(23.0);
205 1 : platform.RunIdleTasks(isolate, 42.0);
206 1 : }
207 :
208 15373 : TEST(DefaultPlatformTest, RunIdleTasksWithTaskRunner) {
209 2 : InSequence s;
210 :
211 : int dummy;
212 : Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
213 :
214 1 : DefaultPlatformWithMockTime platform;
215 : std::shared_ptr<TaskRunner> taskrunner =
216 1 : platform.GetForegroundTaskRunner(isolate);
217 :
218 1 : StrictMock<MockIdleTask>* task = new StrictMock<MockIdleTask>;
219 3 : taskrunner->PostIdleTask(std::unique_ptr<IdleTask>(task));
220 3 : EXPECT_CALL(*task, Run(42.0 + 23.0));
221 2 : EXPECT_CALL(*task, Die());
222 : platform.IncreaseTime(23.0);
223 1 : platform.RunIdleTasks(isolate, 42.0);
224 1 : }
225 :
226 15373 : TEST(DefaultPlatformTest, PendingIdleTasksAreDestroyedOnShutdown) {
227 2 : InSequence s;
228 :
229 : int dummy;
230 : Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
231 :
232 : {
233 1 : DefaultPlatformWithMockTime platform;
234 1 : StrictMock<MockIdleTask>* task = new StrictMock<MockIdleTask>;
235 1 : platform.CallIdleOnForegroundThread(isolate, task);
236 2 : EXPECT_CALL(*task, Die());
237 : }
238 1 : }
239 :
240 : namespace {
241 :
242 : class TestBackgroundTask : public Task {
243 : public:
244 : explicit TestBackgroundTask(base::Semaphore* sem, bool* executed)
245 2 : : sem_(sem), executed_(executed) {}
246 :
247 3 : ~TestBackgroundTask() override { Die(); }
248 2 : MOCK_METHOD0(Die, void());
249 :
250 1 : void Run() override {
251 1 : *executed_ = true;
252 1 : sem_->Signal();
253 1 : }
254 :
255 : private:
256 : base::Semaphore* sem_;
257 : bool* executed_;
258 : };
259 :
260 : } // namespace
261 :
262 15373 : TEST(DefaultPlatformTest, RunBackgroundTask) {
263 3 : DefaultPlatform platform;
264 1 : platform.SetThreadPoolSize(1);
265 :
266 2 : base::Semaphore sem(0);
267 1 : bool task_executed = false;
268 : StrictMock<TestBackgroundTask>* task =
269 1 : new StrictMock<TestBackgroundTask>(&sem, &task_executed);
270 2 : EXPECT_CALL(*task, Die());
271 2 : platform.CallOnWorkerThread(std::unique_ptr<Task>(task));
272 2 : EXPECT_TRUE(sem.WaitFor(base::TimeDelta::FromSeconds(1)));
273 1 : EXPECT_TRUE(task_executed);
274 1 : }
275 :
276 15373 : TEST(DefaultPlatformTest, PostForegroundTaskAfterPlatformTermination) {
277 : std::shared_ptr<TaskRunner> foreground_taskrunner;
278 : {
279 1 : DefaultPlatformWithMockTime platform;
280 :
281 : int dummy;
282 : Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
283 :
284 1 : platform.SetThreadPoolSize(1);
285 2 : foreground_taskrunner = platform.GetForegroundTaskRunner(isolate);
286 : }
287 : // It should still be possible to post foreground tasks, even when the
288 : // platform does not exist anymore.
289 1 : StrictMock<MockTask>* task1 = new StrictMock<MockTask>;
290 2 : EXPECT_CALL(*task1, Die());
291 3 : foreground_taskrunner->PostTask(std::unique_ptr<Task>(task1));
292 :
293 1 : StrictMock<MockTask>* task2 = new StrictMock<MockTask>;
294 2 : EXPECT_CALL(*task2, Die());
295 3 : foreground_taskrunner->PostDelayedTask(std::unique_ptr<Task>(task2), 10);
296 :
297 1 : StrictMock<MockIdleTask>* task3 = new StrictMock<MockIdleTask>;
298 2 : EXPECT_CALL(*task3, Die());
299 3 : foreground_taskrunner->PostIdleTask(std::unique_ptr<IdleTask>(task3));
300 1 : }
301 :
302 : } // namespace default_platform_unittest
303 : } // namespace platform
304 9222 : } // namespace v8
|