1 // Copyright 2017 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 "chromecast/base/alarm_manager.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/test/simple_test_clock.h"
12 #include "base/test/task_environment.h"
13 #include "base/threading/thread_task_runner_handle.h"
14 #include "base/time/clock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace chromecast {
18
19 class AlarmManagerTest : public ::testing::Test {
20 protected:
21 class WallClockDependantTask {
22 public:
WallClockDependantTask()23 WallClockDependantTask() : fired_(false), weak_factory_(this) {}
GetWeakPtr()24 base::WeakPtr<WallClockDependantTask> GetWeakPtr() {
25 return weak_factory_.GetWeakPtr();
26 }
OnAlarmFire()27 void OnAlarmFire() { fired_ = true; }
28 bool fired_;
29 base::WeakPtrFactory<WallClockDependantTask> weak_factory_;
30 };
31
32 base::test::SingleThreadTaskEnvironment task_environment_{
33 base::test::TaskEnvironment::TimeSource::MOCK_TIME};
34 };
35
TEST_F(AlarmManagerTest,AlarmNotFire)36 TEST_F(AlarmManagerTest, AlarmNotFire) {
37 WallClockDependantTask task;
38 ASSERT_FALSE(task.fired_);
39
40 // Create the AlarmManager.
41 base::Time now = base::Time::Now();
42 std::unique_ptr<base::SimpleTestClock> test_clock =
43 std::make_unique<base::SimpleTestClock>();
44 test_clock->SetNow(now);
45 base::SimpleTestClock* clock = test_clock.get();
46 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
47 clock, base::ThreadTaskRunnerHandle::Get());
48
49 base::Time alarm_time = now + base::TimeDelta::FromMinutes(10);
50 std::unique_ptr<AlarmHandle> handle(manager->PostAlarmTask(
51 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task.GetWeakPtr()),
52 alarm_time));
53 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(9));
54 clock->Advance(base::TimeDelta::FromMinutes(9));
55 task_environment_.RunUntilIdle();
56 ASSERT_FALSE(task.fired_);
57 }
58
TEST_F(AlarmManagerTest,AlarmFire)59 TEST_F(AlarmManagerTest, AlarmFire) {
60 WallClockDependantTask task;
61 ASSERT_FALSE(task.fired_);
62
63 // Create the AlarmManager.
64 base::Time now = base::Time::Now();
65 std::unique_ptr<base::SimpleTestClock> test_clock =
66 std::make_unique<base::SimpleTestClock>();
67 test_clock->SetNow(now);
68 base::SimpleTestClock* clock = test_clock.get();
69 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
70 clock, base::ThreadTaskRunnerHandle::Get());
71
72 // Add an alarm.
73 base::Time alarm_time = now + base::TimeDelta::FromMinutes(10);
74 std::unique_ptr<AlarmHandle> handle(manager->PostAlarmTask(
75 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task.GetWeakPtr()),
76 alarm_time));
77 clock->Advance(base::TimeDelta::FromMinutes(10));
78 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
79 task_environment_.RunUntilIdle();
80 ASSERT_TRUE(task.fired_);
81
82 // Fires only once.
83 task.fired_ = false;
84 clock->Advance(base::TimeDelta::FromMinutes(10));
85 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
86 task_environment_.RunUntilIdle();
87 ASSERT_FALSE(task.fired_);
88 }
89
TEST_F(AlarmManagerTest,AlarmPast)90 TEST_F(AlarmManagerTest, AlarmPast) {
91 WallClockDependantTask task;
92 ASSERT_FALSE(task.fired_);
93
94 // Create the AlarmManager.
95 base::Time now = base::Time::Now();
96 std::unique_ptr<base::SimpleTestClock> test_clock =
97 std::make_unique<base::SimpleTestClock>();
98 test_clock->SetNow(now);
99 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
100 test_clock.get(), base::ThreadTaskRunnerHandle::Get());
101
102 // Add an alarm in the past. Should fire right away.
103 base::Time alarm_time = base::Time::Now() - base::TimeDelta::FromMinutes(10);
104 std::unique_ptr<AlarmHandle> handle(manager->PostAlarmTask(
105 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task.GetWeakPtr()),
106 alarm_time));
107 task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(10));
108 task_environment_.RunUntilIdle();
109 ASSERT_TRUE(task.fired_);
110 }
111
TEST_F(AlarmManagerTest,AlarmTimeJump)112 TEST_F(AlarmManagerTest, AlarmTimeJump) {
113 WallClockDependantTask task;
114 ASSERT_FALSE(task.fired_);
115
116 // Create the AlarmManager.
117 base::Time now = base::Time::Now();
118 std::unique_ptr<base::SimpleTestClock> test_clock =
119 std::make_unique<base::SimpleTestClock>();
120 test_clock->SetNow(now);
121 base::SimpleTestClock* clock = test_clock.get();
122 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
123 clock, base::ThreadTaskRunnerHandle::Get());
124
125 // Add an alarm. The time jumps to the future.
126 base::Time alarm_time = now + base::TimeDelta::FromMinutes(10);
127 std::unique_ptr<AlarmHandle> handle(manager->PostAlarmTask(
128 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task.GetWeakPtr()),
129 alarm_time));
130 clock->Advance(base::TimeDelta::FromMinutes(10));
131 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
132 task_environment_.RunUntilIdle();
133 ASSERT_TRUE(task.fired_);
134 }
135
TEST_F(AlarmManagerTest,AlarmJumpFuture)136 TEST_F(AlarmManagerTest, AlarmJumpFuture) {
137 WallClockDependantTask task;
138 ASSERT_FALSE(task.fired_);
139
140 // Create the AlarmManager.
141 base::Time now = base::Time::Now();
142 std::unique_ptr<base::SimpleTestClock> test_clock =
143 std::make_unique<base::SimpleTestClock>();
144 test_clock->SetNow(now);
145 base::SimpleTestClock* clock = test_clock.get();
146 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
147 clock, base::ThreadTaskRunnerHandle::Get());
148
149 // Add an alarm. The time jumps far into the future.
150 base::Time alarm_time = now + base::TimeDelta::FromMinutes(10);
151 std::unique_ptr<AlarmHandle> handle(manager->PostAlarmTask(
152 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task.GetWeakPtr()),
153 alarm_time));
154 clock->Advance(base::TimeDelta::FromMinutes(60));
155 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
156 task_environment_.RunUntilIdle();
157 ASSERT_TRUE(task.fired_);
158 }
159
TEST_F(AlarmManagerTest,AlarmMultiple)160 TEST_F(AlarmManagerTest, AlarmMultiple) {
161 WallClockDependantTask task1;
162 WallClockDependantTask task2;
163 ASSERT_FALSE(task1.fired_);
164 ASSERT_FALSE(task2.fired_);
165
166 // Create the AlarmManager.
167 base::Time now = base::Time::Now();
168 std::unique_ptr<base::SimpleTestClock> test_clock =
169 std::make_unique<base::SimpleTestClock>();
170 test_clock->SetNow(now);
171 base::SimpleTestClock* clock = test_clock.get();
172 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
173 clock, base::ThreadTaskRunnerHandle::Get());
174
175 // Add first task.
176 base::Time alarm_time = now + base::TimeDelta::FromMinutes(10);
177 std::unique_ptr<AlarmHandle> handle1(manager->PostAlarmTask(
178 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task1.GetWeakPtr()),
179 alarm_time));
180
181 // Add second task.
182 alarm_time = now + base::TimeDelta::FromMinutes(12);
183 std::unique_ptr<AlarmHandle> handle2(manager->PostAlarmTask(
184 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task2.GetWeakPtr()),
185 alarm_time));
186
187 // First task should fire.
188 clock->Advance(base::TimeDelta::FromMinutes(10));
189 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
190 task_environment_.RunUntilIdle();
191 ASSERT_TRUE(task1.fired_);
192 ASSERT_FALSE(task2.fired_);
193
194 // Reset state;
195 task1.fired_ = false;
196 task2.fired_ = false;
197
198 // Second task should fire.
199 clock->Advance(base::TimeDelta::FromMinutes(2));
200 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
201 task_environment_.RunUntilIdle();
202 ASSERT_FALSE(task1.fired_);
203 ASSERT_TRUE(task2.fired_);
204 }
205
TEST_F(AlarmManagerTest,AlarmMultipleReverseOrder)206 TEST_F(AlarmManagerTest, AlarmMultipleReverseOrder) {
207 WallClockDependantTask task1;
208 WallClockDependantTask task2;
209 ASSERT_FALSE(task1.fired_);
210 ASSERT_FALSE(task2.fired_);
211
212 // Create the AlarmManager.
213 base::Time now = base::Time::Now();
214 std::unique_ptr<base::SimpleTestClock> test_clock =
215 std::make_unique<base::SimpleTestClock>();
216 test_clock->SetNow(now);
217 base::SimpleTestClock* clock = test_clock.get();
218 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
219 clock, base::ThreadTaskRunnerHandle::Get());
220
221 // Add first task.
222 base::Time alarm_time = now + base::TimeDelta::FromMinutes(12);
223 std::unique_ptr<AlarmHandle> handle1(manager->PostAlarmTask(
224 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task1.GetWeakPtr()),
225 alarm_time));
226
227 // Add second task.
228 alarm_time = now + base::TimeDelta::FromMinutes(10);
229 std::unique_ptr<AlarmHandle> handle2(manager->PostAlarmTask(
230 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task2.GetWeakPtr()),
231 alarm_time));
232
233 // Second task should fire.
234 clock->Advance(base::TimeDelta::FromMinutes(10));
235 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
236 task_environment_.RunUntilIdle();
237 ASSERT_FALSE(task1.fired_);
238 ASSERT_TRUE(task2.fired_);
239
240 // Reset state;
241 task1.fired_ = false;
242 task2.fired_ = false;
243
244 // First task should fire.
245 clock->Advance(base::TimeDelta::FromMinutes(2));
246 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
247 task_environment_.RunUntilIdle();
248 ASSERT_TRUE(task1.fired_);
249 ASSERT_FALSE(task2.fired_);
250 }
251
TEST_F(AlarmManagerTest,AlarmMultipleSameTime)252 TEST_F(AlarmManagerTest, AlarmMultipleSameTime) {
253 WallClockDependantTask task1;
254 WallClockDependantTask task2;
255 WallClockDependantTask task3;
256 ASSERT_FALSE(task1.fired_);
257 ASSERT_FALSE(task2.fired_);
258 ASSERT_FALSE(task3.fired_);
259
260 // Create the AlarmManager.
261 base::Time now = base::Time::Now();
262 std::unique_ptr<base::SimpleTestClock> test_clock =
263 std::make_unique<base::SimpleTestClock>();
264 test_clock->SetNow(now);
265 base::SimpleTestClock* clock = test_clock.get();
266 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
267 clock, base::ThreadTaskRunnerHandle::Get());
268
269 // Add first task.
270 base::Time alarm_time = now + base::TimeDelta::FromMinutes(12);
271 std::unique_ptr<AlarmHandle> handle1(manager->PostAlarmTask(
272 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task1.GetWeakPtr()),
273 alarm_time));
274
275 // Add second task.
276 alarm_time = now + base::TimeDelta::FromMinutes(16);
277 std::unique_ptr<AlarmHandle> handle2(manager->PostAlarmTask(
278 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task2.GetWeakPtr()),
279 alarm_time));
280
281 // Add third task.
282 alarm_time = now + base::TimeDelta::FromMinutes(12);
283 std::unique_ptr<AlarmHandle> handle3(manager->PostAlarmTask(
284 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task3.GetWeakPtr()),
285 alarm_time));
286
287 // First and third task should fire.
288 clock->Advance(base::TimeDelta::FromMinutes(12));
289 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
290 task_environment_.RunUntilIdle();
291 ASSERT_TRUE(task1.fired_);
292 ASSERT_FALSE(task2.fired_);
293 ASSERT_TRUE(task3.fired_);
294 }
295
TEST_F(AlarmManagerTest,AlarmMultipleShuffle)296 TEST_F(AlarmManagerTest, AlarmMultipleShuffle) {
297 WallClockDependantTask task1;
298 WallClockDependantTask task2;
299 WallClockDependantTask task3;
300 ASSERT_FALSE(task1.fired_);
301 ASSERT_FALSE(task2.fired_);
302 ASSERT_FALSE(task3.fired_);
303
304 // Create the AlarmManager.
305 base::Time now = base::Time::Now();
306 std::unique_ptr<base::SimpleTestClock> test_clock =
307 std::make_unique<base::SimpleTestClock>();
308 test_clock->SetNow(now);
309 base::SimpleTestClock* clock = test_clock.get();
310 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
311 clock, base::ThreadTaskRunnerHandle::Get());
312
313 // Add first task.
314 base::Time alarm_time = now + base::TimeDelta::FromMinutes(15);
315 std::unique_ptr<AlarmHandle> handle1(manager->PostAlarmTask(
316 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task1.GetWeakPtr()),
317 alarm_time));
318
319 // Add second task.
320 alarm_time = now + base::TimeDelta::FromMinutes(16);
321 std::unique_ptr<AlarmHandle> handle2(manager->PostAlarmTask(
322 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task2.GetWeakPtr()),
323 alarm_time));
324
325 // Add third task.
326 alarm_time = now + base::TimeDelta::FromMinutes(11);
327 std::unique_ptr<AlarmHandle> handle3(manager->PostAlarmTask(
328 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task3.GetWeakPtr()),
329 alarm_time));
330
331 // Third task should fire.
332 clock->Advance(base::TimeDelta::FromMinutes(12));
333 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
334 task_environment_.RunUntilIdle();
335 ASSERT_FALSE(task1.fired_);
336 ASSERT_FALSE(task2.fired_);
337 ASSERT_TRUE(task3.fired_);
338
339 clock->Advance(base::TimeDelta::FromMinutes(3));
340 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
341 task_environment_.RunUntilIdle();
342 ASSERT_TRUE(task1.fired_);
343 ASSERT_FALSE(task2.fired_);
344 ASSERT_TRUE(task3.fired_);
345 }
346
TEST_F(AlarmManagerTest,AlarmTwice)347 TEST_F(AlarmManagerTest, AlarmTwice) {
348 WallClockDependantTask task1;
349 WallClockDependantTask task2;
350 ASSERT_FALSE(task1.fired_);
351 ASSERT_FALSE(task2.fired_);
352
353 // Create the AlarmManager.
354 base::Time now = base::Time::Now();
355 std::unique_ptr<base::SimpleTestClock> test_clock =
356 std::make_unique<base::SimpleTestClock>();
357 test_clock->SetNow(now);
358 base::SimpleTestClock* clock = test_clock.get();
359 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
360 clock, base::ThreadTaskRunnerHandle::Get());
361
362 // Add first task.
363 base::Time alarm_time = now + base::TimeDelta::FromMinutes(15);
364 std::unique_ptr<AlarmHandle> handle1(manager->PostAlarmTask(
365 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task1.GetWeakPtr()),
366 alarm_time));
367
368 // Add it again with less time.
369 alarm_time = now + base::TimeDelta::FromMinutes(1);
370 std::unique_ptr<AlarmHandle> handle2(manager->PostAlarmTask(
371 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task1.GetWeakPtr()),
372 alarm_time));
373
374 // Add second task.
375 alarm_time = now + base::TimeDelta::FromMinutes(16);
376 std::unique_ptr<AlarmHandle> handle3(manager->PostAlarmTask(
377 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task2.GetWeakPtr()),
378 alarm_time));
379
380 // First task should fire.
381 clock->Advance(base::TimeDelta::FromMinutes(1));
382 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
383 task_environment_.RunUntilIdle();
384 ASSERT_TRUE(task1.fired_);
385 ASSERT_FALSE(task2.fired_);
386
387 task1.fired_ = false;
388 task2.fired_ = false;
389
390 // First task should fire again because it was added twice.
391 clock->Advance(base::TimeDelta::FromMinutes(14));
392 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
393 task_environment_.RunUntilIdle();
394 ASSERT_TRUE(task1.fired_);
395 ASSERT_FALSE(task2.fired_);
396 }
397
TEST_F(AlarmManagerTest,AlarmCancel)398 TEST_F(AlarmManagerTest, AlarmCancel) {
399 std::unique_ptr<WallClockDependantTask> task1 =
400 std::make_unique<WallClockDependantTask>();
401 std::unique_ptr<WallClockDependantTask> task2 =
402 std::make_unique<WallClockDependantTask>();
403 std::unique_ptr<WallClockDependantTask> task3 =
404 std::make_unique<WallClockDependantTask>();
405 ASSERT_FALSE(task1->fired_);
406 ASSERT_FALSE(task2->fired_);
407 ASSERT_FALSE(task3->fired_);
408
409 // Create the AlarmManager.
410 base::Time now = base::Time::Now();
411 std::unique_ptr<base::SimpleTestClock> test_clock =
412 std::make_unique<base::SimpleTestClock>();
413 test_clock->SetNow(now);
414 base::SimpleTestClock* clock = test_clock.get();
415 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
416 clock, base::ThreadTaskRunnerHandle::Get());
417
418 // Add first task.
419 base::Time alarm_time = now + base::TimeDelta::FromMinutes(12);
420 std::unique_ptr<AlarmHandle> handle1(manager->PostAlarmTask(
421 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task1->GetWeakPtr()),
422 alarm_time));
423
424 // Add second task.
425 alarm_time = now + base::TimeDelta::FromMinutes(16);
426 std::unique_ptr<AlarmHandle> handle2(manager->PostAlarmTask(
427 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task2->GetWeakPtr()),
428 alarm_time));
429
430 // Add third task.
431 alarm_time = now + base::TimeDelta::FromMinutes(12);
432 std::unique_ptr<AlarmHandle> handle3(manager->PostAlarmTask(
433 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task3->GetWeakPtr()),
434 alarm_time));
435
436 // Remove the first task.
437 task1.reset(nullptr);
438
439 // Third task should fire.
440 clock->Advance(base::TimeDelta::FromMinutes(15));
441 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
442 task_environment_.RunUntilIdle();
443 ASSERT_FALSE(task2->fired_);
444 ASSERT_TRUE(task3->fired_);
445 }
446
TEST_F(AlarmManagerTest,AlarmDeleteHandle)447 TEST_F(AlarmManagerTest, AlarmDeleteHandle) {
448 std::unique_ptr<WallClockDependantTask> task1 =
449 std::make_unique<WallClockDependantTask>();
450 std::unique_ptr<WallClockDependantTask> task2 =
451 std::make_unique<WallClockDependantTask>();
452 std::unique_ptr<WallClockDependantTask> task3 =
453 std::make_unique<WallClockDependantTask>();
454 ASSERT_FALSE(task1->fired_);
455 ASSERT_FALSE(task2->fired_);
456 ASSERT_FALSE(task3->fired_);
457
458 // Create the AlarmManager.
459 base::Time now = base::Time::Now();
460 std::unique_ptr<base::SimpleTestClock> test_clock =
461 std::make_unique<base::SimpleTestClock>();
462 test_clock->SetNow(now);
463 base::SimpleTestClock* clock = test_clock.get();
464 std::unique_ptr<AlarmManager> manager = std::make_unique<AlarmManager>(
465 clock, base::ThreadTaskRunnerHandle::Get());
466
467 // Add first task.
468 base::Time alarm_time = now + base::TimeDelta::FromMinutes(12);
469 std::unique_ptr<AlarmHandle> handle1(manager->PostAlarmTask(
470 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task1->GetWeakPtr()),
471 alarm_time));
472
473 // Add second task.
474 alarm_time = now + base::TimeDelta::FromMinutes(16);
475 std::unique_ptr<AlarmHandle> handle2(manager->PostAlarmTask(
476 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task2->GetWeakPtr()),
477 alarm_time));
478
479 // Add third task.
480 alarm_time = now + base::TimeDelta::FromMinutes(12);
481 std::unique_ptr<AlarmHandle> handle3(manager->PostAlarmTask(
482 base::BindOnce(&WallClockDependantTask::OnAlarmFire, task3->GetWeakPtr()),
483 alarm_time));
484
485 // Delete the first task's handle.
486 handle1.reset();
487
488 // Third task should fire.
489 clock->Advance(base::TimeDelta::FromMinutes(15));
490 task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
491 task_environment_.RunUntilIdle();
492 ASSERT_FALSE(task1->fired_);
493 ASSERT_FALSE(task2->fired_);
494 ASSERT_TRUE(task3->fired_);
495 }
496
497 } // namespace chromecast
498