blob: bc1dfc4dd6e71fc6cebe344b11c709b7dd1554d7 [file] [log] [blame]
[email protected]afb84fc2014-05-29 01:47:531// 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 <deque>
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/test/test_pending_task.h"
10#include "base/test/test_simple_task_runner.h"
11#include "cc/base/delayed_unique_notifier.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14namespace cc {
15namespace {
16
17class TestNotifier : public DelayedUniqueNotifier {
18 public:
19 TestNotifier(base::SequencedTaskRunner* task_runner,
20 const base::Closure& closure,
21 const base::TimeDelta& delay)
22 : DelayedUniqueNotifier(task_runner, closure, delay) {}
dcheng716bedf2014-10-21 09:51:0823 ~TestNotifier() override {}
[email protected]afb84fc2014-05-29 01:47:5324
25 // Overridden from DelayedUniqueNotifier:
dcheng716bedf2014-10-21 09:51:0826 base::TimeTicks Now() const override { return now_; }
[email protected]afb84fc2014-05-29 01:47:5327
28 void SetNow(base::TimeTicks now) { now_ = now; }
29
30 private:
31 base::TimeTicks now_;
32};
33
34class DelayedUniqueNotifierTest : public testing::Test {
35 public:
36 DelayedUniqueNotifierTest() : notification_count_(0) {}
37
danakjaeb95062014-11-14 01:35:3638 void SetUp() override {
[email protected]afb84fc2014-05-29 01:47:5339 notification_count_ = 0;
kylechar96f3eba2017-09-25 20:23:5640 task_runner_ = base::MakeRefCounted<base::TestSimpleTaskRunner>();
[email protected]afb84fc2014-05-29 01:47:5341 }
42
43 void Notify() { ++notification_count_; }
44
45 int NotificationCount() const { return notification_count_; }
46
47 std::deque<base::TestPendingTask> TakePendingTasks() {
tzik2d1f91c2016-10-04 03:58:0548 return task_runner_->TakePendingTasks();
[email protected]afb84fc2014-05-29 01:47:5349 }
50
51 protected:
52 int notification_count_;
53 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
54};
55
56TEST_F(DelayedUniqueNotifierTest, ZeroDelay) {
Yuri Wiitalad0611762017-07-22 02:33:2157 base::TimeDelta delay; // Zero delay.
[email protected]afb84fc2014-05-29 01:47:5358 TestNotifier notifier(
dcheng80bc5e3c2014-08-26 03:54:1859 task_runner_.get(),
[email protected]afb84fc2014-05-29 01:47:5360 base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
61 delay);
62
63 EXPECT_EQ(0, NotificationCount());
64
65 // Basic schedule for |delay| from now.
66 base::TimeTicks schedule_time =
Yuri Wiitalad0611762017-07-22 02:33:2167 base::TimeTicks() + base::TimeDelta::FromMicroseconds(10);
[email protected]afb84fc2014-05-29 01:47:5368
69 notifier.SetNow(schedule_time);
70 notifier.Schedule();
71
72 std::deque<base::TestPendingTask> tasks = TakePendingTasks();
73 ASSERT_EQ(1u, tasks.size());
74 EXPECT_EQ(base::TimeTicks() + delay, tasks[0].GetTimeToRun());
75
tzika6f0007a2017-01-27 04:01:1176 std::move(tasks[0].task).Run();
[email protected]afb84fc2014-05-29 01:47:5377 EXPECT_EQ(1, NotificationCount());
78
79 // 5 schedules should result in only one run.
80 for (int i = 0; i < 5; ++i)
81 notifier.Schedule();
82
83 tasks = TakePendingTasks();
84 ASSERT_EQ(1u, tasks.size());
85 EXPECT_EQ(base::TimeTicks() + delay, tasks[0].GetTimeToRun());
86
tzika6f0007a2017-01-27 04:01:1187 std::move(tasks[0].task).Run();
[email protected]afb84fc2014-05-29 01:47:5388 EXPECT_EQ(2, NotificationCount());
89}
90
91TEST_F(DelayedUniqueNotifierTest, SmallDelay) {
Yuri Wiitalad0611762017-07-22 02:33:2192 base::TimeDelta delay = base::TimeDelta::FromMicroseconds(20);
[email protected]afb84fc2014-05-29 01:47:5393 TestNotifier notifier(
dcheng80bc5e3c2014-08-26 03:54:1894 task_runner_.get(),
[email protected]afb84fc2014-05-29 01:47:5395 base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
96 delay);
97
98 EXPECT_EQ(0, NotificationCount());
99
100 // Basic schedule for |delay| from now (now: 30, run time: 50).
101 base::TimeTicks schedule_time =
Yuri Wiitalad0611762017-07-22 02:33:21102 base::TimeTicks() + base::TimeDelta::FromMicroseconds(30);
[email protected]afb84fc2014-05-29 01:47:53103
104 notifier.SetNow(schedule_time);
105 notifier.Schedule();
106
107 std::deque<base::TestPendingTask> tasks = TakePendingTasks();
108
109 ASSERT_EQ(1u, tasks.size());
110 EXPECT_EQ(base::TimeTicks() + delay, tasks[0].GetTimeToRun());
111
112 // It's not yet time to run, so we expect no notifications.
tzika6f0007a2017-01-27 04:01:11113 std::move(tasks[0].task).Run();
[email protected]afb84fc2014-05-29 01:47:53114 EXPECT_EQ(0, NotificationCount());
115
116 tasks = TakePendingTasks();
117
118 ASSERT_EQ(1u, tasks.size());
119 // Now the time should be delay minus whatever the value of now happens to be
120 // (now: 30, run time: 50).
121 base::TimeTicks scheduled_run_time = notifier.Now() + delay;
122 base::TimeTicks scheduled_delay =
123 base::TimeTicks() + (scheduled_run_time - notifier.Now());
124 EXPECT_EQ(scheduled_delay, tasks[0].GetTimeToRun());
125
126 // Move closer to the run time (time: 49, run time: 50).
Yuri Wiitalad0611762017-07-22 02:33:21127 notifier.SetNow(notifier.Now() + base::TimeDelta::FromMicroseconds(19));
[email protected]afb84fc2014-05-29 01:47:53128
129 // It's not yet time to run, so we expect no notifications.
tzika6f0007a2017-01-27 04:01:11130 std::move(tasks[0].task).Run();
[email protected]afb84fc2014-05-29 01:47:53131 EXPECT_EQ(0, NotificationCount());
132
133 tasks = TakePendingTasks();
134 ASSERT_EQ(1u, tasks.size());
135
136 // Now the time should be delay minus whatever the value of now happens to be.
137 scheduled_delay = base::TimeTicks() + (scheduled_run_time - notifier.Now());
138 EXPECT_EQ(scheduled_delay, tasks[0].GetTimeToRun());
139
140 // Move to exactly the run time (time: 50, run time: 50).
Yuri Wiitalad0611762017-07-22 02:33:21141 notifier.SetNow(notifier.Now() + base::TimeDelta::FromMicroseconds(1));
[email protected]afb84fc2014-05-29 01:47:53142
143 // It's time to run!
tzika6f0007a2017-01-27 04:01:11144 std::move(tasks[0].task).Run();
[email protected]afb84fc2014-05-29 01:47:53145 EXPECT_EQ(1, NotificationCount());
146
147 tasks = TakePendingTasks();
148 EXPECT_EQ(0u, tasks.size());
149}
150
151TEST_F(DelayedUniqueNotifierTest, RescheduleDelay) {
Yuri Wiitalad0611762017-07-22 02:33:21152 base::TimeDelta delay = base::TimeDelta::FromMicroseconds(20);
[email protected]afb84fc2014-05-29 01:47:53153 TestNotifier notifier(
dcheng80bc5e3c2014-08-26 03:54:18154 task_runner_.get(),
[email protected]afb84fc2014-05-29 01:47:53155 base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
156 delay);
157
158 base::TimeTicks schedule_time;
159 // Move time 19 units forward and reschedule, expecting that we still need to
160 // run in |delay| time and we don't get a notification.
161 for (int i = 0; i < 10; ++i) {
162 EXPECT_EQ(0, NotificationCount());
163
164 // Move time forward 19 units.
Yuri Wiitalad0611762017-07-22 02:33:21165 schedule_time = notifier.Now() + base::TimeDelta::FromMicroseconds(19);
[email protected]afb84fc2014-05-29 01:47:53166 notifier.SetNow(schedule_time);
167 notifier.Schedule();
168
169 std::deque<base::TestPendingTask> tasks = TakePendingTasks();
170
171 ASSERT_EQ(1u, tasks.size());
172 EXPECT_EQ(base::TimeTicks() + delay, tasks[0].GetTimeToRun());
173
174 // It's not yet time to run, so we expect no notifications.
tzika6f0007a2017-01-27 04:01:11175 std::move(tasks[0].task).Run();
[email protected]afb84fc2014-05-29 01:47:53176 EXPECT_EQ(0, NotificationCount());
177 }
178
179 // Move time forward 20 units, expecting a notification.
Yuri Wiitalad0611762017-07-22 02:33:21180 schedule_time = notifier.Now() + base::TimeDelta::FromMicroseconds(20);
[email protected]afb84fc2014-05-29 01:47:53181 notifier.SetNow(schedule_time);
182
183 std::deque<base::TestPendingTask> tasks = TakePendingTasks();
184
185 ASSERT_EQ(1u, tasks.size());
186 EXPECT_EQ(base::TimeTicks() + delay, tasks[0].GetTimeToRun());
187
188 // Time to run!
tzika6f0007a2017-01-27 04:01:11189 std::move(tasks[0].task).Run();
[email protected]afb84fc2014-05-29 01:47:53190 EXPECT_EQ(1, NotificationCount());
191}
192
[email protected]0a1028722014-05-30 10:08:03193TEST_F(DelayedUniqueNotifierTest, CancelAndHasPendingNotification) {
Yuri Wiitalad0611762017-07-22 02:33:21194 base::TimeDelta delay = base::TimeDelta::FromMicroseconds(20);
[email protected]afb84fc2014-05-29 01:47:53195 TestNotifier notifier(
dcheng80bc5e3c2014-08-26 03:54:18196 task_runner_.get(),
[email protected]afb84fc2014-05-29 01:47:53197 base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
198 delay);
199
200 EXPECT_EQ(0, NotificationCount());
201
202 // Schedule for |delay| seconds from now.
203 base::TimeTicks schedule_time =
Yuri Wiitalad0611762017-07-22 02:33:21204 notifier.Now() + base::TimeDelta::FromMicroseconds(10);
[email protected]afb84fc2014-05-29 01:47:53205 notifier.SetNow(schedule_time);
206 notifier.Schedule();
[email protected]0a1028722014-05-30 10:08:03207 EXPECT_TRUE(notifier.HasPendingNotification());
[email protected]afb84fc2014-05-29 01:47:53208
209 // Cancel the run.
210 notifier.Cancel();
[email protected]0a1028722014-05-30 10:08:03211 EXPECT_FALSE(notifier.HasPendingNotification());
[email protected]afb84fc2014-05-29 01:47:53212
213 std::deque<base::TestPendingTask> tasks = TakePendingTasks();
214
215 ASSERT_EQ(1u, tasks.size());
216 EXPECT_EQ(base::TimeTicks() + delay, tasks[0].GetTimeToRun());
217
218 // Time to run, but a canceled task!
tzika6f0007a2017-01-27 04:01:11219 std::move(tasks[0].task).Run();
[email protected]afb84fc2014-05-29 01:47:53220 EXPECT_EQ(0, NotificationCount());
[email protected]0a1028722014-05-30 10:08:03221 EXPECT_FALSE(notifier.HasPendingNotification());
[email protected]afb84fc2014-05-29 01:47:53222
223 tasks = TakePendingTasks();
224 EXPECT_EQ(0u, tasks.size());
225
226 notifier.Schedule();
[email protected]0a1028722014-05-30 10:08:03227 EXPECT_TRUE(notifier.HasPendingNotification());
[email protected]afb84fc2014-05-29 01:47:53228 tasks = TakePendingTasks();
229
230 ASSERT_EQ(1u, tasks.size());
231 EXPECT_EQ(base::TimeTicks() + delay, tasks[0].GetTimeToRun());
232
233 // Advance the time.
234 notifier.SetNow(notifier.Now() + delay);
235
[email protected]0a1028722014-05-30 10:08:03236 // This should run since it wasn't canceled.
tzika6f0007a2017-01-27 04:01:11237 std::move(tasks[0].task).Run();
[email protected]afb84fc2014-05-29 01:47:53238 EXPECT_EQ(1, NotificationCount());
[email protected]0a1028722014-05-30 10:08:03239 EXPECT_FALSE(notifier.HasPendingNotification());
[email protected]afb84fc2014-05-29 01:47:53240
[email protected]0a1028722014-05-30 10:08:03241 for (int i = 0; i < 10; ++i) {
[email protected]afb84fc2014-05-29 01:47:53242 notifier.Schedule();
[email protected]0a1028722014-05-30 10:08:03243 EXPECT_TRUE(notifier.HasPendingNotification());
244 notifier.Cancel();
245 EXPECT_FALSE(notifier.HasPendingNotification());
246 }
[email protected]afb84fc2014-05-29 01:47:53247
[email protected]afb84fc2014-05-29 01:47:53248 tasks = TakePendingTasks();
249
250 ASSERT_EQ(1u, tasks.size());
251 EXPECT_EQ(base::TimeTicks() + delay, tasks[0].GetTimeToRun());
252
253 // Time to run, but a canceled task!
254 notifier.SetNow(notifier.Now() + delay);
tzika6f0007a2017-01-27 04:01:11255 std::move(tasks[0].task).Run();
[email protected]afb84fc2014-05-29 01:47:53256 EXPECT_EQ(1, NotificationCount());
257
258 tasks = TakePendingTasks();
259 EXPECT_EQ(0u, tasks.size());
[email protected]0a1028722014-05-30 10:08:03260 EXPECT_FALSE(notifier.HasPendingNotification());
[email protected]afb84fc2014-05-29 01:47:53261}
262
danakj1a3c3172014-10-29 18:24:49263TEST_F(DelayedUniqueNotifierTest, ShutdownWithScheduledTask) {
Yuri Wiitalad0611762017-07-22 02:33:21264 base::TimeDelta delay = base::TimeDelta::FromMicroseconds(20);
danakj1a3c3172014-10-29 18:24:49265 TestNotifier notifier(
266 task_runner_.get(),
267 base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
268 delay);
269
270 EXPECT_EQ(0, NotificationCount());
271
272 // Schedule for |delay| seconds from now.
273 base::TimeTicks schedule_time =
Yuri Wiitalad0611762017-07-22 02:33:21274 notifier.Now() + base::TimeDelta::FromMicroseconds(10);
danakj1a3c3172014-10-29 18:24:49275 notifier.SetNow(schedule_time);
276 notifier.Schedule();
277 EXPECT_TRUE(notifier.HasPendingNotification());
278
279 // Shutdown the notifier.
280 notifier.Shutdown();
281
282 // The task is still there, but...
283 std::deque<base::TestPendingTask> tasks = TakePendingTasks();
284 ASSERT_EQ(1u, tasks.size());
285
286 // Running the task after shutdown does nothing since it's cancelled.
tzika6f0007a2017-01-27 04:01:11287 std::move(tasks[0].task).Run();
danakj1a3c3172014-10-29 18:24:49288 EXPECT_EQ(0, NotificationCount());
289
290 tasks = TakePendingTasks();
291 EXPECT_EQ(0u, tasks.size());
292
293 // We are no longer able to schedule tasks.
294 notifier.Schedule();
295 tasks = TakePendingTasks();
296 ASSERT_EQ(0u, tasks.size());
297
298 // Verify after the scheduled time happens there is still no task.
299 notifier.SetNow(notifier.Now() + delay);
300 tasks = TakePendingTasks();
301 ASSERT_EQ(0u, tasks.size());
302}
303
304TEST_F(DelayedUniqueNotifierTest, ShutdownPreventsSchedule) {
Yuri Wiitalad0611762017-07-22 02:33:21305 base::TimeDelta delay = base::TimeDelta::FromMicroseconds(20);
danakj1a3c3172014-10-29 18:24:49306 TestNotifier notifier(
307 task_runner_.get(),
308 base::Bind(&DelayedUniqueNotifierTest::Notify, base::Unretained(this)),
309 delay);
310
311 EXPECT_EQ(0, NotificationCount());
312
313 // Schedule for |delay| seconds from now.
314 base::TimeTicks schedule_time =
Yuri Wiitalad0611762017-07-22 02:33:21315 notifier.Now() + base::TimeDelta::FromMicroseconds(10);
danakj1a3c3172014-10-29 18:24:49316 notifier.SetNow(schedule_time);
317
318 // Shutdown the notifier.
319 notifier.Shutdown();
320
321 // Scheduling a task no longer does anything.
322 notifier.Schedule();
323 std::deque<base::TestPendingTask> tasks = TakePendingTasks();
324 ASSERT_EQ(0u, tasks.size());
325
326 // Verify after the scheduled time happens there is still no task.
327 notifier.SetNow(notifier.Now() + delay);
328 tasks = TakePendingTasks();
329 ASSERT_EQ(0u, tasks.size());
330}
331
[email protected]afb84fc2014-05-29 01:47:53332} // namespace
333} // namespace cc