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.
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"
17 class TestNotifier
: public DelayedUniqueNotifier
{
19 TestNotifier(base::SequencedTaskRunner
* task_runner
,
20 const base::Closure
& closure
,
21 const base::TimeDelta
& delay
)
22 : DelayedUniqueNotifier(task_runner
, closure
, delay
) {}
23 ~TestNotifier() override
{}
25 // Overridden from DelayedUniqueNotifier:
26 base::TimeTicks
Now() const override
{ return now_
; }
28 void SetNow(base::TimeTicks now
) { now_
= now
; }
34 class DelayedUniqueNotifierTest
: public testing::Test
{
36 DelayedUniqueNotifierTest() : notification_count_(0) {}
38 void SetUp() override
{
39 notification_count_
= 0;
40 task_runner_
= make_scoped_refptr(new base::TestSimpleTaskRunner
);
43 void Notify() { ++notification_count_
; }
45 int NotificationCount() const { return notification_count_
; }
47 std::deque
<base::TestPendingTask
> TakePendingTasks() {
48 std::deque
<base::TestPendingTask
> tasks
= task_runner_
->GetPendingTasks();
49 task_runner_
->ClearPendingTasks();
54 int notification_count_
;
55 scoped_refptr
<base::TestSimpleTaskRunner
> task_runner_
;
58 TEST_F(DelayedUniqueNotifierTest
, ZeroDelay
) {
59 base::TimeDelta delay
= base::TimeDelta::FromInternalValue(0);
60 TestNotifier
notifier(
62 base::Bind(&DelayedUniqueNotifierTest::Notify
, base::Unretained(this)),
65 EXPECT_EQ(0, NotificationCount());
67 // Basic schedule for |delay| from now.
68 base::TimeTicks schedule_time
=
69 base::TimeTicks() + base::TimeDelta::FromInternalValue(10);
71 notifier
.SetNow(schedule_time
);
74 std::deque
<base::TestPendingTask
> tasks
= TakePendingTasks();
75 ASSERT_EQ(1u, tasks
.size());
76 EXPECT_EQ(base::TimeTicks() + delay
, tasks
[0].GetTimeToRun());
79 EXPECT_EQ(1, NotificationCount());
81 // 5 schedules should result in only one run.
82 for (int i
= 0; i
< 5; ++i
)
85 tasks
= TakePendingTasks();
86 ASSERT_EQ(1u, tasks
.size());
87 EXPECT_EQ(base::TimeTicks() + delay
, tasks
[0].GetTimeToRun());
90 EXPECT_EQ(2, NotificationCount());
93 TEST_F(DelayedUniqueNotifierTest
, SmallDelay
) {
94 base::TimeDelta delay
= base::TimeDelta::FromInternalValue(20);
95 TestNotifier
notifier(
97 base::Bind(&DelayedUniqueNotifierTest::Notify
, base::Unretained(this)),
100 EXPECT_EQ(0, NotificationCount());
102 // Basic schedule for |delay| from now (now: 30, run time: 50).
103 base::TimeTicks schedule_time
=
104 base::TimeTicks() + base::TimeDelta::FromInternalValue(30);
106 notifier
.SetNow(schedule_time
);
109 std::deque
<base::TestPendingTask
> tasks
= TakePendingTasks();
111 ASSERT_EQ(1u, tasks
.size());
112 EXPECT_EQ(base::TimeTicks() + delay
, tasks
[0].GetTimeToRun());
114 // It's not yet time to run, so we expect no notifications.
116 EXPECT_EQ(0, NotificationCount());
118 tasks
= TakePendingTasks();
120 ASSERT_EQ(1u, tasks
.size());
121 // Now the time should be delay minus whatever the value of now happens to be
122 // (now: 30, run time: 50).
123 base::TimeTicks scheduled_run_time
= notifier
.Now() + delay
;
124 base::TimeTicks scheduled_delay
=
125 base::TimeTicks() + (scheduled_run_time
- notifier
.Now());
126 EXPECT_EQ(scheduled_delay
, tasks
[0].GetTimeToRun());
128 // Move closer to the run time (time: 49, run time: 50).
129 notifier
.SetNow(notifier
.Now() + base::TimeDelta::FromInternalValue(19));
131 // It's not yet time to run, so we expect no notifications.
133 EXPECT_EQ(0, NotificationCount());
135 tasks
= TakePendingTasks();
136 ASSERT_EQ(1u, tasks
.size());
138 // Now the time should be delay minus whatever the value of now happens to be.
139 scheduled_delay
= base::TimeTicks() + (scheduled_run_time
- notifier
.Now());
140 EXPECT_EQ(scheduled_delay
, tasks
[0].GetTimeToRun());
142 // Move to exactly the run time (time: 50, run time: 50).
143 notifier
.SetNow(notifier
.Now() + base::TimeDelta::FromInternalValue(1));
147 EXPECT_EQ(1, NotificationCount());
149 tasks
= TakePendingTasks();
150 EXPECT_EQ(0u, tasks
.size());
153 TEST_F(DelayedUniqueNotifierTest
, RescheduleDelay
) {
154 base::TimeDelta delay
= base::TimeDelta::FromInternalValue(20);
155 TestNotifier
notifier(
157 base::Bind(&DelayedUniqueNotifierTest::Notify
, base::Unretained(this)),
160 base::TimeTicks schedule_time
;
161 // Move time 19 units forward and reschedule, expecting that we still need to
162 // run in |delay| time and we don't get a notification.
163 for (int i
= 0; i
< 10; ++i
) {
164 EXPECT_EQ(0, NotificationCount());
166 // Move time forward 19 units.
167 schedule_time
= notifier
.Now() + base::TimeDelta::FromInternalValue(19);
168 notifier
.SetNow(schedule_time
);
171 std::deque
<base::TestPendingTask
> tasks
= TakePendingTasks();
173 ASSERT_EQ(1u, tasks
.size());
174 EXPECT_EQ(base::TimeTicks() + delay
, tasks
[0].GetTimeToRun());
176 // It's not yet time to run, so we expect no notifications.
178 EXPECT_EQ(0, NotificationCount());
181 // Move time forward 20 units, expecting a notification.
182 schedule_time
= notifier
.Now() + base::TimeDelta::FromInternalValue(20);
183 notifier
.SetNow(schedule_time
);
185 std::deque
<base::TestPendingTask
> tasks
= TakePendingTasks();
187 ASSERT_EQ(1u, tasks
.size());
188 EXPECT_EQ(base::TimeTicks() + delay
, tasks
[0].GetTimeToRun());
192 EXPECT_EQ(1, NotificationCount());
195 TEST_F(DelayedUniqueNotifierTest
, CancelAndHasPendingNotification
) {
196 base::TimeDelta delay
= base::TimeDelta::FromInternalValue(20);
197 TestNotifier
notifier(
199 base::Bind(&DelayedUniqueNotifierTest::Notify
, base::Unretained(this)),
202 EXPECT_EQ(0, NotificationCount());
204 // Schedule for |delay| seconds from now.
205 base::TimeTicks schedule_time
=
206 notifier
.Now() + base::TimeDelta::FromInternalValue(10);
207 notifier
.SetNow(schedule_time
);
209 EXPECT_TRUE(notifier
.HasPendingNotification());
213 EXPECT_FALSE(notifier
.HasPendingNotification());
215 std::deque
<base::TestPendingTask
> tasks
= TakePendingTasks();
217 ASSERT_EQ(1u, tasks
.size());
218 EXPECT_EQ(base::TimeTicks() + delay
, tasks
[0].GetTimeToRun());
220 // Time to run, but a canceled task!
222 EXPECT_EQ(0, NotificationCount());
223 EXPECT_FALSE(notifier
.HasPendingNotification());
225 tasks
= TakePendingTasks();
226 EXPECT_EQ(0u, tasks
.size());
229 EXPECT_TRUE(notifier
.HasPendingNotification());
230 tasks
= TakePendingTasks();
232 ASSERT_EQ(1u, tasks
.size());
233 EXPECT_EQ(base::TimeTicks() + delay
, tasks
[0].GetTimeToRun());
236 notifier
.SetNow(notifier
.Now() + delay
);
238 // This should run since it wasn't canceled.
240 EXPECT_EQ(1, NotificationCount());
241 EXPECT_FALSE(notifier
.HasPendingNotification());
243 for (int i
= 0; i
< 10; ++i
) {
245 EXPECT_TRUE(notifier
.HasPendingNotification());
247 EXPECT_FALSE(notifier
.HasPendingNotification());
250 tasks
= TakePendingTasks();
252 ASSERT_EQ(1u, tasks
.size());
253 EXPECT_EQ(base::TimeTicks() + delay
, tasks
[0].GetTimeToRun());
255 // Time to run, but a canceled task!
256 notifier
.SetNow(notifier
.Now() + delay
);
258 EXPECT_EQ(1, NotificationCount());
260 tasks
= TakePendingTasks();
261 EXPECT_EQ(0u, tasks
.size());
262 EXPECT_FALSE(notifier
.HasPendingNotification());
265 TEST_F(DelayedUniqueNotifierTest
, ShutdownWithScheduledTask
) {
266 base::TimeDelta delay
= base::TimeDelta::FromInternalValue(20);
267 TestNotifier
notifier(
269 base::Bind(&DelayedUniqueNotifierTest::Notify
, base::Unretained(this)),
272 EXPECT_EQ(0, NotificationCount());
274 // Schedule for |delay| seconds from now.
275 base::TimeTicks schedule_time
=
276 notifier
.Now() + base::TimeDelta::FromInternalValue(10);
277 notifier
.SetNow(schedule_time
);
279 EXPECT_TRUE(notifier
.HasPendingNotification());
281 // Shutdown the notifier.
284 // The task is still there, but...
285 std::deque
<base::TestPendingTask
> tasks
= TakePendingTasks();
286 ASSERT_EQ(1u, tasks
.size());
288 // Running the task after shutdown does nothing since it's cancelled.
290 EXPECT_EQ(0, NotificationCount());
292 tasks
= TakePendingTasks();
293 EXPECT_EQ(0u, tasks
.size());
295 // We are no longer able to schedule tasks.
297 tasks
= TakePendingTasks();
298 ASSERT_EQ(0u, tasks
.size());
300 // Verify after the scheduled time happens there is still no task.
301 notifier
.SetNow(notifier
.Now() + delay
);
302 tasks
= TakePendingTasks();
303 ASSERT_EQ(0u, tasks
.size());
306 TEST_F(DelayedUniqueNotifierTest
, ShutdownPreventsSchedule
) {
307 base::TimeDelta delay
= base::TimeDelta::FromInternalValue(20);
308 TestNotifier
notifier(
310 base::Bind(&DelayedUniqueNotifierTest::Notify
, base::Unretained(this)),
313 EXPECT_EQ(0, NotificationCount());
315 // Schedule for |delay| seconds from now.
316 base::TimeTicks schedule_time
=
317 notifier
.Now() + base::TimeDelta::FromInternalValue(10);
318 notifier
.SetNow(schedule_time
);
320 // Shutdown the notifier.
323 // Scheduling a task no longer does anything.
325 std::deque
<base::TestPendingTask
> tasks
= TakePendingTasks();
326 ASSERT_EQ(0u, tasks
.size());
328 // Verify after the scheduled time happens there is still no task.
329 notifier
.SetNow(notifier
.Now() + delay
);
330 tasks
= TakePendingTasks();
331 ASSERT_EQ(0u, tasks
.size());