xref: /aosp_15_r20/external/cronet/base/timer/timer_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
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 "base/timer/timer.h"
6 
7 #include <stddef.h>
8 
9 #include <memory>
10 
11 #include "base/functional/bind.h"
12 #include "base/functional/callback.h"
13 #include "base/functional/callback_helpers.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/run_loop.h"
16 #include "base/task/sequenced_task_runner.h"
17 #include "base/test/bind.h"
18 #include "base/test/mock_callback.h"
19 #include "base/test/task_environment.h"
20 #include "base/test/test_simple_task_runner.h"
21 #include "base/time/tick_clock.h"
22 #include "base/time/time.h"
23 #include "build/build_config.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 
26 namespace base {
27 
28 namespace {
29 
30 constexpr TimeDelta kTestDelay = Seconds(10);
31 constexpr TimeDelta kLongTestDelay = Minutes(10);
32 
33 // The main thread types on which each timer should be tested.
34 const test::TaskEnvironment::MainThreadType testing_main_threads[] = {
35     test::TaskEnvironment::MainThreadType::DEFAULT,
36     test::TaskEnvironment::MainThreadType::IO,
37 #if !BUILDFLAG(IS_IOS)  // iOS does not allow direct running of the UI loop.
38     test::TaskEnvironment::MainThreadType::UI,
39 #endif
40 };
41 
42 class Receiver {
43  public:
Receiver()44   Receiver() : count_(0) {}
OnCalled()45   void OnCalled() { count_++; }
WasCalled()46   bool WasCalled() { return count_ > 0; }
TimesCalled()47   int TimesCalled() { return count_; }
48 
49  private:
50   int count_;
51 };
52 
53 // Basic test with same setup as RunTest_OneShotTimers_Cancel below to confirm
54 // that |timer| would be fired in that test if it wasn't for the deletion.
RunTest_OneShotTimers(test::TaskEnvironment::MainThreadType main_thread_type)55 void RunTest_OneShotTimers(
56     test::TaskEnvironment::MainThreadType main_thread_type) {
57   test::TaskEnvironment task_environment(
58       test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
59 
60   Receiver receiver;
61   OneShotTimer timer;
62   timer.Start(FROM_HERE, kTestDelay,
63               BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
64 
65   task_environment.FastForwardBy(kTestDelay);
66   EXPECT_TRUE(receiver.WasCalled());
67   EXPECT_FALSE(timer.IsRunning());
68 }
69 
RunTest_OneShotTimers_Cancel(test::TaskEnvironment::MainThreadType main_thread_type)70 void RunTest_OneShotTimers_Cancel(
71     test::TaskEnvironment::MainThreadType main_thread_type) {
72   test::TaskEnvironment task_environment(
73       test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
74 
75   Receiver receiver;
76   auto timer = std::make_unique<OneShotTimer>();
77   auto* timer_ptr = timer.get();
78 
79   // This should run before the timer expires.
80   SequencedTaskRunner::GetCurrentDefault()->DeleteSoon(FROM_HERE,
81                                                        std::move(timer));
82 
83   timer_ptr->Start(FROM_HERE, kTestDelay,
84                    BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
85 
86   task_environment.FastForwardBy(kTestDelay);
87   EXPECT_FALSE(receiver.WasCalled());
88 }
89 
RunTest_OneShotSelfDeletingTimer(test::TaskEnvironment::MainThreadType main_thread_type)90 void RunTest_OneShotSelfDeletingTimer(
91     test::TaskEnvironment::MainThreadType main_thread_type) {
92   test::TaskEnvironment task_environment(
93       test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
94 
95   Receiver receiver;
96   auto timer = std::make_unique<OneShotTimer>();
97   auto* timer_ptr = timer.get();
98 
99   timer_ptr->Start(
100       FROM_HERE, kTestDelay,
101       BindLambdaForTesting([&receiver, timer = std::move(timer)]() mutable {
102         receiver.OnCalled();
103         EXPECT_FALSE(timer->IsRunning());
104         timer.reset();
105       }));
106 
107   task_environment.FastForwardBy(kTestDelay);
108   EXPECT_TRUE(receiver.WasCalled());
109 }
110 
RunTest_RepeatingTimer(test::TaskEnvironment::MainThreadType main_thread_type,const TimeDelta & delay)111 void RunTest_RepeatingTimer(
112     test::TaskEnvironment::MainThreadType main_thread_type,
113     const TimeDelta& delay) {
114   test::TaskEnvironment task_environment(
115       test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
116 
117   Receiver receiver;
118   RepeatingTimer timer;
119   timer.Start(FROM_HERE, kTestDelay,
120               BindRepeating(&Receiver::OnCalled, Unretained(&receiver)));
121 
122   task_environment.FastForwardBy(20 * kTestDelay);
123   EXPECT_EQ(receiver.TimesCalled(), 20);
124   EXPECT_TRUE(timer.IsRunning());
125 }
126 
RunTest_RepeatingTimer_Cancel(test::TaskEnvironment::MainThreadType main_thread_type,const TimeDelta & delay)127 void RunTest_RepeatingTimer_Cancel(
128     test::TaskEnvironment::MainThreadType main_thread_type,
129     const TimeDelta& delay) {
130   test::TaskEnvironment task_environment(
131       test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
132 
133   Receiver receiver;
134   auto timer = std::make_unique<RepeatingTimer>();
135   auto* timer_ptr = timer.get();
136 
137   // This should run before the timer expires.
138   SequencedTaskRunner::GetCurrentDefault()->DeleteSoon(FROM_HERE,
139                                                        std::move(timer));
140 
141   timer_ptr->Start(FROM_HERE, delay,
142                    BindRepeating(&Receiver::OnCalled, Unretained(&receiver)));
143 
144   task_environment.FastForwardBy(delay);
145   EXPECT_FALSE(receiver.WasCalled());
146 }
147 
RunTest_DelayTimer_NoCall(test::TaskEnvironment::MainThreadType main_thread_type)148 void RunTest_DelayTimer_NoCall(
149     test::TaskEnvironment::MainThreadType main_thread_type) {
150   test::TaskEnvironment task_environment(
151       test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
152 
153   Receiver receiver;
154   DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
155 
156   task_environment.FastForwardBy(kTestDelay);
157   EXPECT_FALSE(receiver.WasCalled());
158 }
159 
RunTest_DelayTimer_OneCall(test::TaskEnvironment::MainThreadType main_thread_type)160 void RunTest_DelayTimer_OneCall(
161     test::TaskEnvironment::MainThreadType main_thread_type) {
162   test::TaskEnvironment task_environment(
163       test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
164 
165   Receiver receiver;
166   DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
167   timer.Reset();
168 
169   task_environment.FastForwardBy(kTestDelay);
170   EXPECT_TRUE(receiver.WasCalled());
171 }
172 
RunTest_DelayTimer_Reset(test::TaskEnvironment::MainThreadType main_thread_type)173 void RunTest_DelayTimer_Reset(
174     test::TaskEnvironment::MainThreadType main_thread_type) {
175   test::TaskEnvironment task_environment(
176       test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
177 
178   Receiver receiver;
179   DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
180   timer.Reset();
181 
182   // Fast-forward by a delay smaller than the timer delay. The timer will not
183   // fire.
184   task_environment.FastForwardBy(kTestDelay / 2);
185   EXPECT_FALSE(receiver.WasCalled());
186 
187   // Postpone the fire time.
188   timer.Reset();
189 
190   // Verify that the timer does not fire at its original fire time.
191   task_environment.FastForwardBy(kTestDelay / 2);
192   EXPECT_FALSE(receiver.WasCalled());
193 
194   // Fast-forward by the timer delay. The timer will fire.
195   task_environment.FastForwardBy(kTestDelay / 2);
196   EXPECT_TRUE(receiver.WasCalled());
197 }
198 
RunTest_DelayTimer_Deleted(test::TaskEnvironment::MainThreadType main_thread_type)199 void RunTest_DelayTimer_Deleted(
200     test::TaskEnvironment::MainThreadType main_thread_type) {
201   test::TaskEnvironment task_environment(
202       test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
203 
204   Receiver receiver;
205 
206   {
207     DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
208     timer.Reset();
209   }
210 
211   // Because the timer was deleted, it will never fire.
212   task_environment.FastForwardBy(kTestDelay);
213   EXPECT_FALSE(receiver.WasCalled());
214 }
215 
216 }  // namespace
217 
218 //-----------------------------------------------------------------------------
219 // Each test is run against each type of main thread.  That way we are sure
220 // that timers work properly in all configurations.
221 
222 class TimerTestWithThreadType
223     : public testing::TestWithParam<test::TaskEnvironment::MainThreadType> {};
224 
TEST_P(TimerTestWithThreadType,OneShotTimers)225 TEST_P(TimerTestWithThreadType, OneShotTimers) {
226   RunTest_OneShotTimers(GetParam());
227 }
228 
TEST_P(TimerTestWithThreadType,OneShotTimers_Cancel)229 TEST_P(TimerTestWithThreadType, OneShotTimers_Cancel) {
230   RunTest_OneShotTimers_Cancel(GetParam());
231 }
232 
233 // If underline timer does not handle properly, we will crash or fail
234 // in full page heap environment.
TEST_P(TimerTestWithThreadType,OneShotSelfDeletingTimer)235 TEST_P(TimerTestWithThreadType, OneShotSelfDeletingTimer) {
236   RunTest_OneShotSelfDeletingTimer(GetParam());
237 }
238 
TEST(TimerTest,OneShotTimer_CustomTaskRunner)239 TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
240   auto task_runner = base::MakeRefCounted<TestSimpleTaskRunner>();
241 
242   OneShotTimer timer;
243 
244   bool task_ran = false;
245 
246   // The timer will use the TestSimpleTaskRunner to schedule its delays.
247   timer.SetTaskRunner(task_runner);
248   timer.Start(FROM_HERE, Days(1),
249               BindLambdaForTesting([&]() { task_ran = true; }));
250 
251   EXPECT_FALSE(task_ran);
252   EXPECT_TRUE(task_runner->HasPendingTask());
253 
254   task_runner->RunPendingTasks();
255 
256   EXPECT_TRUE(task_ran);
257 }
258 
TEST(TimerTest,OneShotTimerWithTickClock)259 TEST(TimerTest, OneShotTimerWithTickClock) {
260   test::TaskEnvironment task_environment(
261       test::TaskEnvironment::TimeSource::MOCK_TIME);
262   Receiver receiver;
263   OneShotTimer timer(task_environment.GetMockTickClock());
264   timer.Start(FROM_HERE, kTestDelay,
265               BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
266   task_environment.FastForwardBy(kTestDelay);
267   EXPECT_TRUE(receiver.WasCalled());
268   EXPECT_FALSE(timer.IsRunning());
269 }
270 
TEST_P(TimerTestWithThreadType,RepeatingTimer)271 TEST_P(TimerTestWithThreadType, RepeatingTimer) {
272   RunTest_RepeatingTimer(GetParam(), kTestDelay);
273 }
274 
TEST_P(TimerTestWithThreadType,RepeatingTimer_Cancel)275 TEST_P(TimerTestWithThreadType, RepeatingTimer_Cancel) {
276   RunTest_RepeatingTimer_Cancel(GetParam(), kTestDelay);
277 }
278 
TEST_P(TimerTestWithThreadType,RepeatingTimerZeroDelay)279 TEST_P(TimerTestWithThreadType, RepeatingTimerZeroDelay) {
280   RunTest_RepeatingTimer(GetParam(), Seconds(0));
281 }
282 
TEST_P(TimerTestWithThreadType,RepeatingTimerZeroDelay_Cancel)283 TEST_P(TimerTestWithThreadType, RepeatingTimerZeroDelay_Cancel) {
284   RunTest_RepeatingTimer_Cancel(GetParam(), Seconds(0));
285 }
286 
TEST(TimerTest,RepeatingTimerWithTickClock)287 TEST(TimerTest, RepeatingTimerWithTickClock) {
288   test::TaskEnvironment task_environment(
289       test::TaskEnvironment::TimeSource::MOCK_TIME);
290   Receiver receiver;
291   const int expected_times_called = 10;
292   RepeatingTimer timer(task_environment.GetMockTickClock());
293   timer.Start(FROM_HERE, kTestDelay,
294               BindRepeating(&Receiver::OnCalled, Unretained(&receiver)));
295   task_environment.FastForwardBy(expected_times_called * kTestDelay);
296   timer.Stop();
297   EXPECT_EQ(expected_times_called, receiver.TimesCalled());
298 }
299 
TEST_P(TimerTestWithThreadType,DelayTimer_NoCall)300 TEST_P(TimerTestWithThreadType, DelayTimer_NoCall) {
301   RunTest_DelayTimer_NoCall(GetParam());
302 }
303 
TEST_P(TimerTestWithThreadType,DelayTimer_OneCall)304 TEST_P(TimerTestWithThreadType, DelayTimer_OneCall) {
305   RunTest_DelayTimer_OneCall(GetParam());
306 }
307 
TEST_P(TimerTestWithThreadType,DelayTimer_Reset)308 TEST_P(TimerTestWithThreadType, DelayTimer_Reset) {
309   RunTest_DelayTimer_Reset(GetParam());
310 }
311 
TEST_P(TimerTestWithThreadType,DelayTimer_Deleted)312 TEST_P(TimerTestWithThreadType, DelayTimer_Deleted) {
313   RunTest_DelayTimer_Deleted(GetParam());
314 }
315 
TEST(TimerTest,DelayTimerWithTickClock)316 TEST(TimerTest, DelayTimerWithTickClock) {
317   test::TaskEnvironment task_environment(
318       test::TaskEnvironment::TimeSource::MOCK_TIME);
319   Receiver receiver;
320   DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled,
321                    task_environment.GetMockTickClock());
322   task_environment.FastForwardBy(kTestDelay - Microseconds(1));
323   EXPECT_FALSE(receiver.WasCalled());
324   timer.Reset();
325   task_environment.FastForwardBy(kTestDelay - Microseconds(1));
326   EXPECT_FALSE(receiver.WasCalled());
327   timer.Reset();
328   task_environment.FastForwardBy(kTestDelay);
329   EXPECT_TRUE(receiver.WasCalled());
330 }
331 
TEST(TimerTest,TaskEnvironmentShutdown)332 TEST(TimerTest, TaskEnvironmentShutdown) {
333   // This test is designed to verify that shutdown of the
334   // message loop does not cause crashes if there were pending
335   // timers not yet fired.  It may only trigger exceptions
336   // if debug heap checking is enabled.
337   Receiver receiver;
338   OneShotTimer timer;
339 
340   {
341     test::TaskEnvironment task_environment;
342     timer.Start(FROM_HERE, kTestDelay,
343                 BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
344   }  // Task environment destructs by falling out of scope.
345 
346   EXPECT_FALSE(receiver.WasCalled());
347   // Timer destruct. SHOULD NOT CRASH, of course.
348 }
349 
TEST(TimerTest,TaskEnvironmentSelfOwningTimer)350 TEST(TimerTest, TaskEnvironmentSelfOwningTimer) {
351   // This test verifies that a timer does not cause crashes if
352   // |Timer::user_task_| owns the timer. The test may only trigger exceptions if
353   // debug heap checking is enabled.
354 
355   auto timer = std::make_unique<OneShotTimer>();
356   auto* timer_ptr = timer.get();
357 
358   test::TaskEnvironment task_environment(
359       test::TaskEnvironment::TimeSource::MOCK_TIME);
360 
361   timer_ptr->Start(FROM_HERE, kTestDelay,
362                    BindLambdaForTesting([timer = std::move(timer)]() {}));
363   // |Timer::user_task_| owns sole reference to |timer|. Both will be destroyed
364   // once the task ran. SHOULD NOT CRASH.
365   task_environment.FastForwardUntilNoTasksRemain();
366 }
367 
TEST(TimerTest,TaskEnvironmentSelfOwningTimerStopped)368 TEST(TimerTest, TaskEnvironmentSelfOwningTimerStopped) {
369   // This test verifies that a timer does not cause crashes when stopped if
370   // |Timer::user_task_| owns the timer. The test may only trigger exceptions if
371   // debug heap checking is enabled.
372 
373   auto timer = std::make_unique<OneShotTimer>();
374   auto* timer_ptr = timer.get();
375 
376   test::TaskEnvironment task_environment(
377       test::TaskEnvironment::TimeSource::MOCK_TIME);
378 
379   timer_ptr->Start(FROM_HERE, kTestDelay,
380                    BindLambdaForTesting([timer = std::move(timer)]() {
381                      // Stop destroys |Timer::user_task_| which owns sole
382                      // reference to |timer|. SHOULD NOT CRASH.
383                      timer->Stop();
384                    }));
385   task_environment.FastForwardUntilNoTasksRemain();
386 }
387 
TEST(TimerTest,NonRepeatIsRunning)388 TEST(TimerTest, NonRepeatIsRunning) {
389   {
390     test::TaskEnvironment task_environment;
391     OneShotTimer timer;
392     EXPECT_FALSE(timer.IsRunning());
393     timer.Start(FROM_HERE, kTestDelay, DoNothing());
394     EXPECT_TRUE(timer.IsRunning());
395     timer.Stop();
396     EXPECT_FALSE(timer.IsRunning());
397   }
398 
399   {
400     RetainingOneShotTimer timer;
401     test::TaskEnvironment task_environment;
402     EXPECT_FALSE(timer.IsRunning());
403     timer.Start(FROM_HERE, kTestDelay, DoNothing());
404     EXPECT_TRUE(timer.IsRunning());
405     timer.Stop();
406     EXPECT_FALSE(timer.IsRunning());
407     ASSERT_FALSE(timer.user_task().is_null());
408     timer.Reset();
409     EXPECT_TRUE(timer.IsRunning());
410   }
411 }
412 
TEST(TimerTest,NonRepeatTaskEnvironmentDeath)413 TEST(TimerTest, NonRepeatTaskEnvironmentDeath) {
414   OneShotTimer timer;
415   {
416     test::TaskEnvironment task_environment;
417     EXPECT_FALSE(timer.IsRunning());
418     timer.Start(FROM_HERE, kTestDelay, DoNothing());
419     EXPECT_TRUE(timer.IsRunning());
420   }
421   EXPECT_FALSE(timer.IsRunning());
422 }
423 
TEST(TimerTest,RetainRepeatIsRunning)424 TEST(TimerTest, RetainRepeatIsRunning) {
425   test::TaskEnvironment task_environment;
426   RepeatingTimer timer(FROM_HERE, kTestDelay, DoNothing());
427   EXPECT_FALSE(timer.IsRunning());
428   timer.Reset();
429   EXPECT_TRUE(timer.IsRunning());
430   timer.Stop();
431   EXPECT_FALSE(timer.IsRunning());
432   timer.Reset();
433   EXPECT_TRUE(timer.IsRunning());
434 }
435 
TEST(TimerTest,RetainNonRepeatIsRunning)436 TEST(TimerTest, RetainNonRepeatIsRunning) {
437   test::TaskEnvironment task_environment;
438   RetainingOneShotTimer timer(FROM_HERE, kTestDelay, DoNothing());
439   EXPECT_FALSE(timer.IsRunning());
440   timer.Reset();
441   EXPECT_TRUE(timer.IsRunning());
442   timer.Stop();
443   EXPECT_FALSE(timer.IsRunning());
444   timer.Reset();
445   EXPECT_TRUE(timer.IsRunning());
446 }
447 
448 //-----------------------------------------------------------------------------
449 
TEST(TimerTest,ContinuationStopStart)450 TEST(TimerTest, ContinuationStopStart) {
451   test::TaskEnvironment task_environment(
452       test::TaskEnvironment::TimeSource::MOCK_TIME);
453 
454   Receiver receiver1;
455   Receiver receiver2;
456   OneShotTimer timer;
457   timer.Start(FROM_HERE, kTestDelay,
458               BindOnce(&Receiver::OnCalled, Unretained(&receiver1)));
459   timer.Stop();
460   timer.Start(FROM_HERE, kLongTestDelay,
461               BindOnce(&Receiver::OnCalled, Unretained(&receiver2)));
462   task_environment.FastForwardBy(kLongTestDelay);
463   EXPECT_FALSE(receiver1.WasCalled());
464   EXPECT_TRUE(receiver2.WasCalled());
465 }
466 
TEST(TimerTest,ContinuationReset)467 TEST(TimerTest, ContinuationReset) {
468   test::TaskEnvironment task_environment(
469       test::TaskEnvironment::TimeSource::MOCK_TIME);
470 
471   Receiver receiver;
472   OneShotTimer timer;
473   timer.Start(FROM_HERE, kTestDelay,
474               BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
475   timer.Reset();
476   // // Since Reset happened before task ran, the user_task must not be
477   // cleared: ASSERT_FALSE(timer.user_task().is_null());
478   task_environment.FastForwardBy(kTestDelay);
479   EXPECT_TRUE(receiver.WasCalled());
480 }
481 
TEST(TimerTest,AbandonedTaskIsCancelled)482 TEST(TimerTest, AbandonedTaskIsCancelled) {
483   test::TaskEnvironment task_environment(
484       test::TaskEnvironment::TimeSource::MOCK_TIME);
485   OneShotTimer timer;
486 
487   // Start a timer. There will be a pending task on the current sequence.
488   timer.Start(FROM_HERE, kTestDelay, base::DoNothing());
489   EXPECT_EQ(1u, task_environment.GetPendingMainThreadTaskCount());
490 
491   // After AbandonAndStop(), the task is correctly treated as cancelled.
492   timer.AbandonAndStop();
493   EXPECT_EQ(0u, task_environment.GetPendingMainThreadTaskCount());
494   EXPECT_FALSE(timer.IsRunning());
495 }
496 
TEST(TimerTest,DeadlineTimer)497 TEST(TimerTest, DeadlineTimer) {
498   test::TaskEnvironment task_environment(
499       test::TaskEnvironment::TimeSource::MOCK_TIME);
500   RunLoop run_loop;
501   DeadlineTimer timer;
502   TimeTicks start = TimeTicks::Now();
503 
504   timer.Start(FROM_HERE, start + Seconds(5), run_loop.QuitClosure());
505   run_loop.Run();
506   EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
507 }
508 
TEST(TimerTest,DeadlineTimerCancel)509 TEST(TimerTest, DeadlineTimerCancel) {
510   test::TaskEnvironment task_environment(
511       test::TaskEnvironment::TimeSource::MOCK_TIME);
512   RunLoop run_loop;
513   DeadlineTimer timer;
514   TimeTicks start = TimeTicks::Now();
515 
516   MockRepeatingCallback<void()> callback;
517   timer.Start(FROM_HERE, start + Seconds(5), callback.Get());
518 
519   EXPECT_CALL(callback, Run()).Times(0);
520   timer.Stop();
521   task_environment.FastForwardBy(Seconds(5));
522   EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
523 }
524 
TEST(TimerTest,DeadlineTimerTaskDestructed)525 TEST(TimerTest, DeadlineTimerTaskDestructed) {
526   test::TaskEnvironment task_environment(
527       test::TaskEnvironment::TimeSource::MOCK_TIME);
528   RunLoop run_loop;
529   DeadlineTimer timer;
530   TimeTicks start = TimeTicks::Now();
531 
532   MockRepeatingCallback<void()> destructed;
533   ScopedClosureRunner scoped_closure(destructed.Get());
534   timer.Start(FROM_HERE, start + Seconds(5),
535               BindOnce([](ScopedClosureRunner) {}, std::move(scoped_closure)));
536 
537   EXPECT_CALL(destructed, Run());
538   timer.Stop();
539   testing::Mock::VerifyAndClearExpectations(&destructed);
540 }
541 
TEST(TimerTest,DeadlineTimerStartTwice)542 TEST(TimerTest, DeadlineTimerStartTwice) {
543   test::TaskEnvironment task_environment(
544       test::TaskEnvironment::TimeSource::MOCK_TIME);
545   DeadlineTimer timer;
546   TimeTicks start = TimeTicks::Now();
547 
548   RunLoop run_loop;
549   timer.Start(FROM_HERE, start + Seconds(5), run_loop.QuitClosure());
550   timer.Start(FROM_HERE, start + Seconds(10), run_loop.QuitClosure());
551   run_loop.Run();
552   EXPECT_EQ(start + Seconds(10), TimeTicks::Now());
553 }
554 
TEST(TimerTest,MetronomeTimer)555 TEST(TimerTest, MetronomeTimer) {
556   test::TaskEnvironment task_environment(
557       test::TaskEnvironment::TimeSource::MOCK_TIME);
558   MetronomeTimer timer;
559   TimeTicks start = TimeTicks::Now();
560 
561   // Ensure the run_loop.Run() below doesn't straddle over multiple ticks.
562   task_environment.AdvanceClock(
563       start.SnappedToNextTick(TimeTicks(), Seconds(5)) - start);
564   start = TimeTicks::Now();
565 
566   RunLoop run_loop;
567   timer.Start(FROM_HERE, Seconds(5), run_loop.QuitClosure());
568   run_loop.Run();
569   EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
570 }
571 
TEST(TimerTest,MetronomeTimerCustomPhase)572 TEST(TimerTest, MetronomeTimerCustomPhase) {
573   test::TaskEnvironment task_environment(
574       test::TaskEnvironment::TimeSource::MOCK_TIME);
575   RunLoop run_loop;
576   MetronomeTimer timer;
577   TimeTicks start = TimeTicks::Now();
578 
579   timer.Start(FROM_HERE, Seconds(5), run_loop.QuitClosure(), start);
580   run_loop.Run();
581   EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
582 }
583 
TEST(TimerTest,MetronomeTimerReset)584 TEST(TimerTest, MetronomeTimerReset) {
585   test::TaskEnvironment task_environment(
586       test::TaskEnvironment::TimeSource::MOCK_TIME);
587   RunLoop run_loop;
588   TimeTicks start = TimeTicks::Now();
589   MetronomeTimer timer(FROM_HERE, Seconds(5), run_loop.QuitClosure(), start);
590 
591   timer.Reset();
592   run_loop.Run();
593   EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
594 }
595 
TEST(TimerTest,MetronomeTimerStartTwice)596 TEST(TimerTest, MetronomeTimerStartTwice) {
597   test::TaskEnvironment task_environment(
598       test::TaskEnvironment::TimeSource::MOCK_TIME);
599   MetronomeTimer timer;
600   TimeTicks start = TimeTicks::Now();
601 
602   {
603     RunLoop run_loop;
604     timer.Start(FROM_HERE, Seconds(4), run_loop.QuitClosure(), start);
605     run_loop.Run();
606   }
607   EXPECT_EQ(start + Seconds(4), TimeTicks::Now());
608 
609   {
610     RunLoop run_loop;
611     timer.Start(FROM_HERE, Seconds(2), run_loop.QuitClosure(), start);
612     run_loop.Run();
613   }
614   EXPECT_EQ(start + Seconds(6), TimeTicks::Now());
615 }
616 
TEST(TimerTest,MetronomeTimerMultiple)617 TEST(TimerTest, MetronomeTimerMultiple) {
618   test::TaskEnvironment task_environment(
619       test::TaskEnvironment::TimeSource::MOCK_TIME);
620   MetronomeTimer timer;
621   TimeTicks start = TimeTicks::Now();
622 
623   // Ensure the subsequent FastForwardBy() don't straddle over multiple ticks.
624   task_environment.AdvanceClock(
625       start.SnappedToNextTick(TimeTicks(), Seconds(5)) - start);
626 
627   MockRepeatingCallback<void()> callback;
628   timer.Start(FROM_HERE, Seconds(5), callback.Get());
629 
630   // The first tick is skipped because it is too close. Ticks at 5s and 10s.
631   EXPECT_CALL(callback, Run()).Times(2);
632   task_environment.FastForwardBy(Seconds(10));
633 
634   EXPECT_CALL(callback, Run()).Times(2);
635   // Ticks at 15s and 25s, while 20s is missed.
636   task_environment.AdvanceClock(Seconds(12));
637   task_environment.FastForwardBy(Seconds(3));
638 }
639 
TEST(TimerTest,MetronomeTimerCancel)640 TEST(TimerTest, MetronomeTimerCancel) {
641   test::TaskEnvironment task_environment(
642       test::TaskEnvironment::TimeSource::MOCK_TIME);
643   RunLoop run_loop;
644   MetronomeTimer timer;
645   TimeTicks start = TimeTicks::Now();
646 
647   MockRepeatingCallback<void()> callback;
648   timer.Start(FROM_HERE, Seconds(5), callback.Get());
649 
650   EXPECT_CALL(callback, Run()).Times(0);
651   timer.Stop();
652   task_environment.FastForwardBy(Seconds(5));
653   EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
654 }
655 
656 INSTANTIATE_TEST_SUITE_P(All,
657                          TimerTestWithThreadType,
658                          testing::ValuesIn(testing_main_threads));
659 
660 }  // namespace base
661