• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 "base/timer/timer.h"
6 
7 #include <stddef.h>
8 
9 #include <memory>
10 
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/callback.h"
14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/message_loop/message_loop.h"
18 #include "base/run_loop.h"
19 #include "base/sequenced_task_runner.h"
20 #include "base/single_thread_task_runner.h"
21 #include "base/synchronization/waitable_event.h"
22 #include "base/test/sequenced_worker_pool_owner.h"
23 #include "base/test/test_mock_time_task_runner.h"
24 #include "base/threading/platform_thread.h"
25 #include "base/threading/sequenced_task_runner_handle.h"
26 #include "base/threading/thread.h"
27 #include "base/threading/thread_task_runner_handle.h"
28 #include "base/time/tick_clock.h"
29 #include "base/time/time.h"
30 #include "build/build_config.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 
33 namespace base {
34 
35 namespace {
36 
37 // The message loops on which each timer should be tested.
38 const MessageLoop::Type testing_message_loops[] = {
39     MessageLoop::TYPE_DEFAULT, MessageLoop::TYPE_IO,
40 #if !defined(OS_IOS)  // iOS does not allow direct running of the UI loop.
41     MessageLoop::TYPE_UI,
42 #endif
43 };
44 
45 const int kNumTestingMessageLoops = arraysize(testing_message_loops);
46 
47 class Receiver {
48  public:
Receiver()49   Receiver() : count_(0) {}
OnCalled()50   void OnCalled() { count_++; }
WasCalled()51   bool WasCalled() { return count_ > 0; }
TimesCalled()52   int TimesCalled() { return count_; }
53 
54  private:
55   int count_;
56 };
57 
58 // A basic helper class that can start a one-shot timer and signal a
59 // WaitableEvent when this timer fires.
60 class OneShotTimerTesterBase {
61  public:
62   // |did_run|, if provided, will be signaled when Run() fires.
OneShotTimerTesterBase(WaitableEvent * did_run=nullptr,const TimeDelta & delay=TimeDelta::FromMilliseconds (10))63   explicit OneShotTimerTesterBase(
64       WaitableEvent* did_run = nullptr,
65       const TimeDelta& delay = TimeDelta::FromMilliseconds(10))
66       : did_run_(did_run), delay_(delay) {}
67 
68   virtual ~OneShotTimerTesterBase() = default;
69 
Start()70   void Start() {
71     started_time_ = TimeTicks::Now();
72     timer_->Start(FROM_HERE, delay_, this, &OneShotTimerTesterBase::Run);
73   }
74 
IsRunning()75   bool IsRunning() { return timer_->IsRunning(); }
76 
started_time() const77   TimeTicks started_time() const { return started_time_; }
delay() const78   TimeDelta delay() const { return delay_; }
79 
80  protected:
Run()81   virtual void Run() {
82     if (did_run_) {
83       EXPECT_FALSE(did_run_->IsSignaled());
84       did_run_->Signal();
85     }
86   }
87 
88   std::unique_ptr<OneShotTimer> timer_ = MakeUnique<OneShotTimer>();
89 
90  private:
91   WaitableEvent* const did_run_;
92   const TimeDelta delay_;
93   TimeTicks started_time_;
94 
95   DISALLOW_COPY_AND_ASSIGN(OneShotTimerTesterBase);
96 };
97 
98 // Extends functionality of OneShotTimerTesterBase with the abilities to wait
99 // until the timer fires and to change task runner for the timer.
100 class OneShotTimerTester : public OneShotTimerTesterBase {
101  public:
102   // |did_run|, if provided, will be signaled when Run() fires.
OneShotTimerTester(WaitableEvent * did_run=nullptr,const TimeDelta & delay=TimeDelta::FromMilliseconds (10))103   explicit OneShotTimerTester(
104       WaitableEvent* did_run = nullptr,
105       const TimeDelta& delay = TimeDelta::FromMilliseconds(10))
106       : OneShotTimerTesterBase(did_run, delay),
107         quit_closure_(run_loop_.QuitClosure()) {}
108 
109   ~OneShotTimerTester() override = default;
110 
SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner)111   void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner) {
112     timer_->SetTaskRunner(std::move(task_runner));
113 
114     // Run() will be invoked on |task_runner| but |run_loop_|'s QuitClosure
115     // needs to run on this thread (where the MessageLoop lives).
116     quit_closure_ =
117         Bind(IgnoreResult(&SingleThreadTaskRunner::PostTask),
118              ThreadTaskRunnerHandle::Get(), FROM_HERE, run_loop_.QuitClosure());
119   }
120 
121   // Blocks until Run() executes and confirms that Run() didn't fire before
122   // |delay_| expired.
WaitAndConfirmTimerFiredAfterDelay()123   void WaitAndConfirmTimerFiredAfterDelay() {
124     run_loop_.Run();
125 
126     EXPECT_NE(TimeTicks(), started_time());
127     EXPECT_GE(TimeTicks::Now() - started_time(), delay());
128   }
129 
130  protected:
131   // Overridable method to do things on Run() before signaling events/closures
132   // managed by this helper.
OnRun()133   virtual void OnRun() {}
134 
135  private:
Run()136   void Run() override {
137     OnRun();
138     OneShotTimerTesterBase::Run();
139     quit_closure_.Run();
140   }
141 
142   RunLoop run_loop_;
143   Closure quit_closure_;
144 
145   DISALLOW_COPY_AND_ASSIGN(OneShotTimerTester);
146 };
147 
148 class OneShotSelfDeletingTimerTester : public OneShotTimerTester {
149  protected:
OnRun()150   void OnRun() override { timer_.reset(); }
151 };
152 
153 constexpr int kNumRepeats = 10;
154 
155 class RepeatingTimerTester {
156  public:
RepeatingTimerTester(WaitableEvent * did_run,const TimeDelta & delay)157   explicit RepeatingTimerTester(WaitableEvent* did_run, const TimeDelta& delay)
158       : counter_(kNumRepeats),
159         quit_closure_(run_loop_.QuitClosure()),
160         did_run_(did_run),
161         delay_(delay) {}
162 
Start()163   void Start() {
164     started_time_ = TimeTicks::Now();
165     timer_.Start(FROM_HERE, delay_, this, &RepeatingTimerTester::Run);
166   }
167 
WaitAndConfirmTimerFiredRepeatedlyAfterDelay()168   void WaitAndConfirmTimerFiredRepeatedlyAfterDelay() {
169     run_loop_.Run();
170 
171     EXPECT_NE(TimeTicks(), started_time_);
172     EXPECT_GE(TimeTicks::Now() - started_time_, kNumRepeats * delay_);
173   }
174 
175  private:
Run()176   void Run() {
177     if (--counter_ == 0) {
178       if (did_run_) {
179         EXPECT_FALSE(did_run_->IsSignaled());
180         did_run_->Signal();
181       }
182       timer_.Stop();
183       quit_closure_.Run();
184     }
185   }
186 
187   RepeatingTimer timer_;
188   int counter_;
189 
190   RunLoop run_loop_;
191   Closure quit_closure_;
192   WaitableEvent* const did_run_;
193 
194   const TimeDelta delay_;
195   TimeTicks started_time_;
196 
197   DISALLOW_COPY_AND_ASSIGN(RepeatingTimerTester);
198 };
199 
200 // Basic test with same setup as RunTest_OneShotTimers_Cancel below to confirm
201 // that |did_run_a| would be signaled in that test if it wasn't for the
202 // deletion.
RunTest_OneShotTimers(MessageLoop::Type message_loop_type)203 void RunTest_OneShotTimers(MessageLoop::Type message_loop_type) {
204   MessageLoop loop(message_loop_type);
205 
206   WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
207                           WaitableEvent::InitialState::NOT_SIGNALED);
208   OneShotTimerTester a(&did_run_a);
209   a.Start();
210 
211   OneShotTimerTester b;
212   b.Start();
213 
214   b.WaitAndConfirmTimerFiredAfterDelay();
215 
216   EXPECT_TRUE(did_run_a.IsSignaled());
217 }
218 
RunTest_OneShotTimers_Cancel(MessageLoop::Type message_loop_type)219 void RunTest_OneShotTimers_Cancel(MessageLoop::Type message_loop_type) {
220   MessageLoop loop(message_loop_type);
221 
222   WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
223                           WaitableEvent::InitialState::NOT_SIGNALED);
224   OneShotTimerTester* a = new OneShotTimerTester(&did_run_a);
225 
226   // This should run before the timer expires.
227   SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
228 
229   // Now start the timer.
230   a->Start();
231 
232   OneShotTimerTester b;
233   b.Start();
234 
235   b.WaitAndConfirmTimerFiredAfterDelay();
236 
237   EXPECT_FALSE(did_run_a.IsSignaled());
238 }
239 
RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type)240 void RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type) {
241   MessageLoop loop(message_loop_type);
242 
243   OneShotSelfDeletingTimerTester f;
244   f.Start();
245   f.WaitAndConfirmTimerFiredAfterDelay();
246 }
247 
RunTest_RepeatingTimer(MessageLoop::Type message_loop_type,const TimeDelta & delay)248 void RunTest_RepeatingTimer(MessageLoop::Type message_loop_type,
249                             const TimeDelta& delay) {
250   MessageLoop loop(message_loop_type);
251 
252   RepeatingTimerTester f(nullptr, delay);
253   f.Start();
254   f.WaitAndConfirmTimerFiredRepeatedlyAfterDelay();
255 }
256 
RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type,const TimeDelta & delay)257 void RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type,
258                                    const TimeDelta& delay) {
259   MessageLoop loop(message_loop_type);
260 
261   WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
262                           WaitableEvent::InitialState::NOT_SIGNALED);
263   RepeatingTimerTester* a = new RepeatingTimerTester(&did_run_a, delay);
264 
265   // This should run before the timer expires.
266   SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
267 
268   // Now start the timer.
269   a->Start();
270 
271   RepeatingTimerTester b(nullptr, delay);
272   b.Start();
273 
274   b.WaitAndConfirmTimerFiredRepeatedlyAfterDelay();
275 
276   // |a| should not have fired despite |b| starting after it on the same
277   // sequence and being complete by now.
278   EXPECT_FALSE(did_run_a.IsSignaled());
279 }
280 
281 class DelayTimerTarget {
282  public:
signaled() const283   bool signaled() const { return signaled_; }
284 
Signal()285   void Signal() {
286     ASSERT_FALSE(signaled_);
287     signaled_ = true;
288   }
289 
290  private:
291   bool signaled_ = false;
292 };
293 
RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type)294 void RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type) {
295   MessageLoop loop(message_loop_type);
296 
297   // If Delay is never called, the timer shouldn't go off.
298   DelayTimerTarget target;
299   DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(1), &target,
300                    &DelayTimerTarget::Signal);
301 
302   OneShotTimerTester tester;
303   tester.Start();
304   tester.WaitAndConfirmTimerFiredAfterDelay();
305 
306   ASSERT_FALSE(target.signaled());
307 }
308 
RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type)309 void RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type) {
310   MessageLoop loop(message_loop_type);
311 
312   DelayTimerTarget target;
313   DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(1), &target,
314                    &DelayTimerTarget::Signal);
315   timer.Reset();
316 
317   OneShotTimerTester tester(nullptr, TimeDelta::FromMilliseconds(100));
318   tester.Start();
319   tester.WaitAndConfirmTimerFiredAfterDelay();
320 
321   ASSERT_TRUE(target.signaled());
322 }
323 
324 struct ResetHelper {
ResetHelperbase::__anon38a4be600111::ResetHelper325   ResetHelper(DelayTimer* timer, DelayTimerTarget* target)
326       : timer_(timer), target_(target) {}
327 
Resetbase::__anon38a4be600111::ResetHelper328   void Reset() {
329     ASSERT_FALSE(target_->signaled());
330     timer_->Reset();
331   }
332 
333  private:
334   DelayTimer* const timer_;
335   DelayTimerTarget* const target_;
336 };
337 
RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type)338 void RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type) {
339   MessageLoop loop(message_loop_type);
340 
341   // If Delay is never called, the timer shouldn't go off.
342   DelayTimerTarget target;
343   DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
344                    &DelayTimerTarget::Signal);
345   timer.Reset();
346 
347   ResetHelper reset_helper(&timer, &target);
348 
349   OneShotTimer timers[20];
350   for (size_t i = 0; i < arraysize(timers); ++i) {
351     timers[i].Start(FROM_HERE, TimeDelta::FromMilliseconds(i * 10),
352                     &reset_helper, &ResetHelper::Reset);
353   }
354 
355   OneShotTimerTester tester(nullptr, TimeDelta::FromMilliseconds(300));
356   tester.Start();
357   tester.WaitAndConfirmTimerFiredAfterDelay();
358 
359   ASSERT_TRUE(target.signaled());
360 }
361 
362 class DelayTimerFatalTarget {
363  public:
Signal()364   void Signal() {
365     ASSERT_TRUE(false);
366   }
367 };
368 
RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type)369 void RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type) {
370   MessageLoop loop(message_loop_type);
371 
372   DelayTimerFatalTarget target;
373 
374   {
375     DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
376                      &DelayTimerFatalTarget::Signal);
377     timer.Reset();
378   }
379 
380   // When the timer is deleted, the DelayTimerFatalTarget should never be
381   // called.
382   PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
383 }
384 
385 }  // namespace
386 
387 //-----------------------------------------------------------------------------
388 // Each test is run against each type of MessageLoop.  That way we are sure
389 // that timers work properly in all configurations.
390 
TEST(TimerTest,OneShotTimers)391 TEST(TimerTest, OneShotTimers) {
392   for (int i = 0; i < kNumTestingMessageLoops; i++) {
393     RunTest_OneShotTimers(testing_message_loops[i]);
394   }
395 }
396 
TEST(TimerTest,OneShotTimers_Cancel)397 TEST(TimerTest, OneShotTimers_Cancel) {
398   for (int i = 0; i < kNumTestingMessageLoops; i++) {
399     RunTest_OneShotTimers_Cancel(testing_message_loops[i]);
400   }
401 }
402 
403 // If underline timer does not handle properly, we will crash or fail
404 // in full page heap environment.
TEST(TimerTest,OneShotSelfDeletingTimer)405 TEST(TimerTest, OneShotSelfDeletingTimer) {
406   for (int i = 0; i < kNumTestingMessageLoops; i++) {
407     RunTest_OneShotSelfDeletingTimer(testing_message_loops[i]);
408   }
409 }
410 
TEST(TimerTest,OneShotTimer_CustomTaskRunner)411 TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
412   // A MessageLoop is required for the timer events on the other thread to
413   // communicate back to the Timer under test.
414   MessageLoop loop;
415 
416   Thread other_thread("OneShotTimer_CustomTaskRunner");
417   other_thread.Start();
418 
419   WaitableEvent did_run(WaitableEvent::ResetPolicy::MANUAL,
420                         WaitableEvent::InitialState::NOT_SIGNALED);
421   OneShotTimerTester f(&did_run);
422   f.SetTaskRunner(other_thread.task_runner());
423   f.Start();
424   EXPECT_TRUE(f.IsRunning());
425 
426   f.WaitAndConfirmTimerFiredAfterDelay();
427   EXPECT_TRUE(did_run.IsSignaled());
428 
429   // |f| should already have communicated back to this |loop| before invoking
430   // Run() and as such this thread should already be aware that |f| is no longer
431   // running.
432   EXPECT_TRUE(loop.IsIdleForTesting());
433   EXPECT_FALSE(f.IsRunning());
434 }
435 
TEST(TimerTest,OneShotTimerWithTickClock)436 TEST(TimerTest, OneShotTimerWithTickClock) {
437   scoped_refptr<TestMockTimeTaskRunner> task_runner(
438       new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
439   std::unique_ptr<TickClock> tick_clock(task_runner->GetMockTickClock());
440   MessageLoop message_loop;
441   message_loop.SetTaskRunner(task_runner);
442   Receiver receiver;
443   OneShotTimer timer(tick_clock.get());
444   timer.Start(FROM_HERE, TimeDelta::FromSeconds(1),
445               Bind(&Receiver::OnCalled, Unretained(&receiver)));
446   task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
447   EXPECT_TRUE(receiver.WasCalled());
448 }
449 
TEST(TimerTest,RepeatingTimer)450 TEST(TimerTest, RepeatingTimer) {
451   for (int i = 0; i < kNumTestingMessageLoops; i++) {
452     RunTest_RepeatingTimer(testing_message_loops[i],
453                            TimeDelta::FromMilliseconds(10));
454   }
455 }
456 
TEST(TimerTest,RepeatingTimer_Cancel)457 TEST(TimerTest, RepeatingTimer_Cancel) {
458   for (int i = 0; i < kNumTestingMessageLoops; i++) {
459     RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
460                                   TimeDelta::FromMilliseconds(10));
461   }
462 }
463 
TEST(TimerTest,RepeatingTimerZeroDelay)464 TEST(TimerTest, RepeatingTimerZeroDelay) {
465   for (int i = 0; i < kNumTestingMessageLoops; i++) {
466     RunTest_RepeatingTimer(testing_message_loops[i],
467                            TimeDelta::FromMilliseconds(0));
468   }
469 }
470 
TEST(TimerTest,RepeatingTimerZeroDelay_Cancel)471 TEST(TimerTest, RepeatingTimerZeroDelay_Cancel) {
472   for (int i = 0; i < kNumTestingMessageLoops; i++) {
473     RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
474                                   TimeDelta::FromMilliseconds(0));
475   }
476 }
477 
TEST(TimerTest,RepeatingTimerWithTickClock)478 TEST(TimerTest, RepeatingTimerWithTickClock) {
479   scoped_refptr<TestMockTimeTaskRunner> task_runner(
480       new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
481   std::unique_ptr<TickClock> tick_clock(task_runner->GetMockTickClock());
482   MessageLoop message_loop;
483   message_loop.SetTaskRunner(task_runner);
484   Receiver receiver;
485   const int expected_times_called = 10;
486   RepeatingTimer timer(tick_clock.get());
487   timer.Start(FROM_HERE, TimeDelta::FromSeconds(1),
488               Bind(&Receiver::OnCalled, Unretained(&receiver)));
489   task_runner->FastForwardBy(TimeDelta::FromSeconds(expected_times_called));
490   timer.Stop();
491   EXPECT_EQ(expected_times_called, receiver.TimesCalled());
492 }
493 
TEST(TimerTest,DelayTimer_NoCall)494 TEST(TimerTest, DelayTimer_NoCall) {
495   for (int i = 0; i < kNumTestingMessageLoops; i++) {
496     RunTest_DelayTimer_NoCall(testing_message_loops[i]);
497   }
498 }
499 
TEST(TimerTest,DelayTimer_OneCall)500 TEST(TimerTest, DelayTimer_OneCall) {
501   for (int i = 0; i < kNumTestingMessageLoops; i++) {
502     RunTest_DelayTimer_OneCall(testing_message_loops[i]);
503   }
504 }
505 
506 // It's flaky on the buildbot, http://crbug.com/25038.
TEST(TimerTest,DISABLED_DelayTimer_Reset)507 TEST(TimerTest, DISABLED_DelayTimer_Reset) {
508   for (int i = 0; i < kNumTestingMessageLoops; i++) {
509     RunTest_DelayTimer_Reset(testing_message_loops[i]);
510   }
511 }
512 
TEST(TimerTest,DelayTimer_Deleted)513 TEST(TimerTest, DelayTimer_Deleted) {
514   for (int i = 0; i < kNumTestingMessageLoops; i++) {
515     RunTest_DelayTimer_Deleted(testing_message_loops[i]);
516   }
517 }
518 
TEST(TimerTest,DelayTimerWithTickClock)519 TEST(TimerTest, DelayTimerWithTickClock) {
520   scoped_refptr<TestMockTimeTaskRunner> task_runner(
521       new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
522   std::unique_ptr<TickClock> tick_clock(task_runner->GetMockTickClock());
523   MessageLoop message_loop;
524   message_loop.SetTaskRunner(task_runner);
525   Receiver receiver;
526   DelayTimer timer(FROM_HERE, TimeDelta::FromSeconds(1), &receiver,
527                    &Receiver::OnCalled, tick_clock.get());
528   task_runner->FastForwardBy(TimeDelta::FromMilliseconds(999));
529   EXPECT_FALSE(receiver.WasCalled());
530   timer.Reset();
531   task_runner->FastForwardBy(TimeDelta::FromMilliseconds(999));
532   EXPECT_FALSE(receiver.WasCalled());
533   timer.Reset();
534   task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
535   EXPECT_TRUE(receiver.WasCalled());
536 }
537 
TEST(TimerTest,MessageLoopShutdown)538 TEST(TimerTest, MessageLoopShutdown) {
539   // This test is designed to verify that shutdown of the
540   // message loop does not cause crashes if there were pending
541   // timers not yet fired.  It may only trigger exceptions
542   // if debug heap checking is enabled.
543   WaitableEvent did_run(WaitableEvent::ResetPolicy::MANUAL,
544                         WaitableEvent::InitialState::NOT_SIGNALED);
545   {
546     OneShotTimerTesterBase a(&did_run);
547     OneShotTimerTesterBase b(&did_run);
548     OneShotTimerTesterBase c(&did_run);
549     OneShotTimerTesterBase d(&did_run);
550     {
551       MessageLoop loop;
552       a.Start();
553       b.Start();
554     }  // MessageLoop destructs by falling out of scope.
555   }  // OneShotTimers destruct.  SHOULD NOT CRASH, of course.
556 
557   EXPECT_FALSE(did_run.IsSignaled());
558 }
559 
560 // Ref counted class which owns a Timer. The class passes a reference to itself
561 // via the |user_task| parameter in Timer::Start(). |Timer::user_task_| might
562 // end up holding the last reference to the class.
563 class OneShotSelfOwningTimerTester
564     : public RefCounted<OneShotSelfOwningTimerTester> {
565  public:
566   OneShotSelfOwningTimerTester() = default;
567 
StartTimer()568   void StartTimer() {
569     // Start timer with long delay in order to test the timer getting destroyed
570     // while a timer task is still pending.
571     timer_.Start(FROM_HERE, TimeDelta::FromDays(1),
572                  base::Bind(&OneShotSelfOwningTimerTester::Run, this));
573   }
574 
575  private:
576   friend class RefCounted<OneShotSelfOwningTimerTester>;
577   ~OneShotSelfOwningTimerTester() = default;
578 
Run()579   void Run() {
580     ADD_FAILURE() << "Timer unexpectedly fired.";
581   }
582 
583   OneShotTimer timer_;
584 
585   DISALLOW_COPY_AND_ASSIGN(OneShotSelfOwningTimerTester);
586 };
587 
TEST(TimerTest,MessageLoopShutdownSelfOwningTimer)588 TEST(TimerTest, MessageLoopShutdownSelfOwningTimer) {
589   // This test verifies that shutdown of the message loop does not cause crashes
590   // if there is a pending timer not yet fired and |Timer::user_task_| owns the
591   // timer. The test may only trigger exceptions if debug heap checking is
592   // enabled.
593 
594   MessageLoop loop;
595   scoped_refptr<OneShotSelfOwningTimerTester> tester =
596       new OneShotSelfOwningTimerTester();
597 
598   std::move(tester)->StartTimer();
599   // |Timer::user_task_| owns sole reference to |tester|.
600 
601   // MessageLoop destructs by falling out of scope. SHOULD NOT CRASH.
602 }
603 
TimerTestCallback()604 void TimerTestCallback() {
605 }
606 
TEST(TimerTest,NonRepeatIsRunning)607 TEST(TimerTest, NonRepeatIsRunning) {
608   {
609     MessageLoop loop;
610     Timer timer(false, false);
611     EXPECT_FALSE(timer.IsRunning());
612     timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
613     EXPECT_TRUE(timer.IsRunning());
614     timer.Stop();
615     EXPECT_FALSE(timer.IsRunning());
616     EXPECT_TRUE(timer.user_task().is_null());
617   }
618 
619   {
620     Timer timer(true, false);
621     MessageLoop loop;
622     EXPECT_FALSE(timer.IsRunning());
623     timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
624     EXPECT_TRUE(timer.IsRunning());
625     timer.Stop();
626     EXPECT_FALSE(timer.IsRunning());
627     ASSERT_FALSE(timer.user_task().is_null());
628     timer.Reset();
629     EXPECT_TRUE(timer.IsRunning());
630   }
631 }
632 
TEST(TimerTest,NonRepeatMessageLoopDeath)633 TEST(TimerTest, NonRepeatMessageLoopDeath) {
634   Timer timer(false, false);
635   {
636     MessageLoop loop;
637     EXPECT_FALSE(timer.IsRunning());
638     timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
639     EXPECT_TRUE(timer.IsRunning());
640   }
641   EXPECT_FALSE(timer.IsRunning());
642   EXPECT_TRUE(timer.user_task().is_null());
643 }
644 
TEST(TimerTest,RetainRepeatIsRunning)645 TEST(TimerTest, RetainRepeatIsRunning) {
646   MessageLoop loop;
647   Timer timer(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback),
648               true);
649   EXPECT_FALSE(timer.IsRunning());
650   timer.Reset();
651   EXPECT_TRUE(timer.IsRunning());
652   timer.Stop();
653   EXPECT_FALSE(timer.IsRunning());
654   timer.Reset();
655   EXPECT_TRUE(timer.IsRunning());
656 }
657 
TEST(TimerTest,RetainNonRepeatIsRunning)658 TEST(TimerTest, RetainNonRepeatIsRunning) {
659   MessageLoop loop;
660   Timer timer(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback),
661               false);
662   EXPECT_FALSE(timer.IsRunning());
663   timer.Reset();
664   EXPECT_TRUE(timer.IsRunning());
665   timer.Stop();
666   EXPECT_FALSE(timer.IsRunning());
667   timer.Reset();
668   EXPECT_TRUE(timer.IsRunning());
669 }
670 
671 namespace {
672 
673 bool g_callback_happened1 = false;
674 bool g_callback_happened2 = false;
675 
ClearAllCallbackHappened()676 void ClearAllCallbackHappened() {
677   g_callback_happened1 = false;
678   g_callback_happened2 = false;
679 }
680 
SetCallbackHappened1()681 void SetCallbackHappened1() {
682   g_callback_happened1 = true;
683   MessageLoop::current()->QuitWhenIdle();
684 }
685 
SetCallbackHappened2()686 void SetCallbackHappened2() {
687   g_callback_happened2 = true;
688   MessageLoop::current()->QuitWhenIdle();
689 }
690 
691 }  // namespace
692 
TEST(TimerTest,ContinuationStopStart)693 TEST(TimerTest, ContinuationStopStart) {
694   {
695     ClearAllCallbackHappened();
696     MessageLoop loop;
697     Timer timer(false, false);
698     timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
699                 Bind(&SetCallbackHappened1));
700     timer.Stop();
701     timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(40),
702                 Bind(&SetCallbackHappened2));
703     RunLoop().Run();
704     EXPECT_FALSE(g_callback_happened1);
705     EXPECT_TRUE(g_callback_happened2);
706   }
707 }
708 
TEST(TimerTest,ContinuationReset)709 TEST(TimerTest, ContinuationReset) {
710   {
711     ClearAllCallbackHappened();
712     MessageLoop loop;
713     Timer timer(false, false);
714     timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
715                 Bind(&SetCallbackHappened1));
716     timer.Reset();
717     // Since Reset happened before task ran, the user_task must not be cleared:
718     ASSERT_FALSE(timer.user_task().is_null());
719     RunLoop().Run();
720     EXPECT_TRUE(g_callback_happened1);
721   }
722 }
723 
724 }  // namespace base
725