Home | History | Annotate | Download | only in timer
      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 <stddef.h>
      6 
      7 #include "base/macros.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/test/test_simple_task_runner.h"
     11 #include "base/timer/timer.h"
     12 #include "build/build_config.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 using base::TimeDelta;
     16 using base::SingleThreadTaskRunner;
     17 
     18 namespace {
     19 
     20 // The message loops on which each timer should be tested.
     21 const base::MessageLoop::Type testing_message_loops[] = {
     22   base::MessageLoop::TYPE_DEFAULT,
     23   base::MessageLoop::TYPE_IO,
     24 #if !defined(OS_IOS)  // iOS does not allow direct running of the UI loop.
     25   base::MessageLoop::TYPE_UI,
     26 #endif
     27 };
     28 
     29 const int kNumTestingMessageLoops = arraysize(testing_message_loops);
     30 
     31 class OneShotTimerTester {
     32  public:
     33   explicit OneShotTimerTester(bool* did_run, unsigned milliseconds = 10)
     34       : did_run_(did_run),
     35         delay_ms_(milliseconds),
     36         quit_message_loop_(true) {
     37   }
     38 
     39   void Start() {
     40     timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this,
     41                  &OneShotTimerTester::Run);
     42   }
     43 
     44   void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner) {
     45     quit_message_loop_ = false;
     46     timer_.SetTaskRunner(task_runner);
     47   }
     48 
     49  private:
     50   void Run() {
     51     *did_run_ = true;
     52     if (quit_message_loop_) {
     53       base::MessageLoop::current()->QuitWhenIdle();
     54     }
     55   }
     56 
     57   bool* did_run_;
     58   base::OneShotTimer timer_;
     59   const unsigned delay_ms_;
     60   bool quit_message_loop_;
     61 };
     62 
     63 class OneShotSelfDeletingTimerTester {
     64  public:
     65   explicit OneShotSelfDeletingTimerTester(bool* did_run)
     66       : did_run_(did_run), timer_(new base::OneShotTimer()) {}
     67 
     68   void Start() {
     69     timer_->Start(FROM_HERE, TimeDelta::FromMilliseconds(10), this,
     70                   &OneShotSelfDeletingTimerTester::Run);
     71   }
     72 
     73  private:
     74   void Run() {
     75     *did_run_ = true;
     76     timer_.reset();
     77     base::MessageLoop::current()->QuitWhenIdle();
     78   }
     79 
     80   bool* did_run_;
     81   scoped_ptr<base::OneShotTimer> timer_;
     82 };
     83 
     84 class RepeatingTimerTester {
     85  public:
     86   explicit RepeatingTimerTester(bool* did_run, const TimeDelta& delay)
     87       : did_run_(did_run), counter_(10), delay_(delay) {
     88   }
     89 
     90   void Start() {
     91     timer_.Start(FROM_HERE, delay_, this, &RepeatingTimerTester::Run);
     92   }
     93 
     94  private:
     95   void Run() {
     96     if (--counter_ == 0) {
     97       *did_run_ = true;
     98       timer_.Stop();
     99       base::MessageLoop::current()->QuitWhenIdle();
    100     }
    101   }
    102 
    103   bool* did_run_;
    104   int counter_;
    105   TimeDelta delay_;
    106   base::RepeatingTimer timer_;
    107 };
    108 
    109 void RunTest_OneShotTimer(base::MessageLoop::Type message_loop_type) {
    110   base::MessageLoop loop(message_loop_type);
    111 
    112   bool did_run = false;
    113   OneShotTimerTester f(&did_run);
    114   f.Start();
    115 
    116   base::MessageLoop::current()->Run();
    117 
    118   EXPECT_TRUE(did_run);
    119 }
    120 
    121 void RunTest_OneShotTimer_Cancel(base::MessageLoop::Type message_loop_type) {
    122   base::MessageLoop loop(message_loop_type);
    123 
    124   bool did_run_a = false;
    125   OneShotTimerTester* a = new OneShotTimerTester(&did_run_a);
    126 
    127   // This should run before the timer expires.
    128   base::MessageLoop::current()->DeleteSoon(FROM_HERE, a);
    129 
    130   // Now start the timer.
    131   a->Start();
    132 
    133   bool did_run_b = false;
    134   OneShotTimerTester b(&did_run_b);
    135   b.Start();
    136 
    137   base::MessageLoop::current()->Run();
    138 
    139   EXPECT_FALSE(did_run_a);
    140   EXPECT_TRUE(did_run_b);
    141 }
    142 
    143 void RunTest_OneShotSelfDeletingTimer(
    144     base::MessageLoop::Type message_loop_type) {
    145   base::MessageLoop loop(message_loop_type);
    146 
    147   bool did_run = false;
    148   OneShotSelfDeletingTimerTester f(&did_run);
    149   f.Start();
    150 
    151   base::MessageLoop::current()->Run();
    152 
    153   EXPECT_TRUE(did_run);
    154 }
    155 
    156 void RunTest_RepeatingTimer(base::MessageLoop::Type message_loop_type,
    157                             const TimeDelta& delay) {
    158   base::MessageLoop loop(message_loop_type);
    159 
    160   bool did_run = false;
    161   RepeatingTimerTester f(&did_run, delay);
    162   f.Start();
    163 
    164   base::MessageLoop::current()->Run();
    165 
    166   EXPECT_TRUE(did_run);
    167 }
    168 
    169 void RunTest_RepeatingTimer_Cancel(base::MessageLoop::Type message_loop_type,
    170                                    const TimeDelta& delay) {
    171   base::MessageLoop loop(message_loop_type);
    172 
    173   bool did_run_a = false;
    174   RepeatingTimerTester* a = new RepeatingTimerTester(&did_run_a, delay);
    175 
    176   // This should run before the timer expires.
    177   base::MessageLoop::current()->DeleteSoon(FROM_HERE, a);
    178 
    179   // Now start the timer.
    180   a->Start();
    181 
    182   bool did_run_b = false;
    183   RepeatingTimerTester b(&did_run_b, delay);
    184   b.Start();
    185 
    186   base::MessageLoop::current()->Run();
    187 
    188   EXPECT_FALSE(did_run_a);
    189   EXPECT_TRUE(did_run_b);
    190 }
    191 
    192 class DelayTimerTarget {
    193  public:
    194   bool signaled() const { return signaled_; }
    195 
    196   void Signal() {
    197     ASSERT_FALSE(signaled_);
    198     signaled_ = true;
    199   }
    200 
    201  private:
    202   bool signaled_ = false;
    203 };
    204 
    205 void RunTest_DelayTimer_NoCall(base::MessageLoop::Type message_loop_type) {
    206   base::MessageLoop loop(message_loop_type);
    207 
    208   // If Delay is never called, the timer shouldn't go off.
    209   DelayTimerTarget target;
    210   base::DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(1), &target,
    211                          &DelayTimerTarget::Signal);
    212 
    213   bool did_run = false;
    214   OneShotTimerTester tester(&did_run);
    215   tester.Start();
    216   base::MessageLoop::current()->Run();
    217 
    218   ASSERT_FALSE(target.signaled());
    219 }
    220 
    221 void RunTest_DelayTimer_OneCall(base::MessageLoop::Type message_loop_type) {
    222   base::MessageLoop loop(message_loop_type);
    223 
    224   DelayTimerTarget target;
    225   base::DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(1), &target,
    226                          &DelayTimerTarget::Signal);
    227   timer.Reset();
    228 
    229   bool did_run = false;
    230   OneShotTimerTester tester(&did_run, 100 /* milliseconds */);
    231   tester.Start();
    232   base::MessageLoop::current()->Run();
    233 
    234   ASSERT_TRUE(target.signaled());
    235 }
    236 
    237 struct ResetHelper {
    238   ResetHelper(base::DelayTimer* timer, DelayTimerTarget* target)
    239       : timer_(timer), target_(target) {}
    240 
    241   void Reset() {
    242     ASSERT_FALSE(target_->signaled());
    243     timer_->Reset();
    244   }
    245 
    246  private:
    247   base::DelayTimer* const timer_;
    248   DelayTimerTarget* const target_;
    249 };
    250 
    251 void RunTest_DelayTimer_Reset(base::MessageLoop::Type message_loop_type) {
    252   base::MessageLoop loop(message_loop_type);
    253 
    254   // If Delay is never called, the timer shouldn't go off.
    255   DelayTimerTarget target;
    256   base::DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
    257                          &DelayTimerTarget::Signal);
    258   timer.Reset();
    259 
    260   ResetHelper reset_helper(&timer, &target);
    261 
    262   base::OneShotTimer timers[20];
    263   for (size_t i = 0; i < arraysize(timers); ++i) {
    264     timers[i].Start(FROM_HERE, TimeDelta::FromMilliseconds(i * 10),
    265                     &reset_helper, &ResetHelper::Reset);
    266   }
    267 
    268   bool did_run = false;
    269   OneShotTimerTester tester(&did_run, 300);
    270   tester.Start();
    271   base::MessageLoop::current()->Run();
    272 
    273   ASSERT_TRUE(target.signaled());
    274 }
    275 
    276 class DelayTimerFatalTarget {
    277  public:
    278   void Signal() {
    279     ASSERT_TRUE(false);
    280   }
    281 };
    282 
    283 
    284 void RunTest_DelayTimer_Deleted(base::MessageLoop::Type message_loop_type) {
    285   base::MessageLoop loop(message_loop_type);
    286 
    287   DelayTimerFatalTarget target;
    288 
    289   {
    290     base::DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
    291                            &DelayTimerFatalTarget::Signal);
    292     timer.Reset();
    293   }
    294 
    295   // When the timer is deleted, the DelayTimerFatalTarget should never be
    296   // called.
    297   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
    298 }
    299 
    300 }  // namespace
    301 
    302 //-----------------------------------------------------------------------------
    303 // Each test is run against each type of MessageLoop.  That way we are sure
    304 // that timers work properly in all configurations.
    305 
    306 TEST(TimerTest, OneShotTimer) {
    307   for (int i = 0; i < kNumTestingMessageLoops; i++) {
    308     RunTest_OneShotTimer(testing_message_loops[i]);
    309   }
    310 }
    311 
    312 TEST(TimerTest, OneShotTimer_Cancel) {
    313   for (int i = 0; i < kNumTestingMessageLoops; i++) {
    314     RunTest_OneShotTimer_Cancel(testing_message_loops[i]);
    315   }
    316 }
    317 
    318 // If underline timer does not handle properly, we will crash or fail
    319 // in full page heap environment.
    320 TEST(TimerTest, OneShotSelfDeletingTimer) {
    321   for (int i = 0; i < kNumTestingMessageLoops; i++) {
    322     RunTest_OneShotSelfDeletingTimer(testing_message_loops[i]);
    323   }
    324 }
    325 
    326 TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
    327   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
    328       new base::TestSimpleTaskRunner();
    329 
    330   bool did_run = false;
    331   OneShotTimerTester f(&did_run);
    332   f.SetTaskRunner(task_runner);
    333   f.Start();
    334 
    335   EXPECT_FALSE(did_run);
    336   task_runner->RunUntilIdle();
    337   EXPECT_TRUE(did_run);
    338 }
    339 
    340 TEST(TimerTest, RepeatingTimer) {
    341   for (int i = 0; i < kNumTestingMessageLoops; i++) {
    342     RunTest_RepeatingTimer(testing_message_loops[i],
    343                            TimeDelta::FromMilliseconds(10));
    344   }
    345 }
    346 
    347 TEST(TimerTest, RepeatingTimer_Cancel) {
    348   for (int i = 0; i < kNumTestingMessageLoops; i++) {
    349     RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
    350                                   TimeDelta::FromMilliseconds(10));
    351   }
    352 }
    353 
    354 TEST(TimerTest, RepeatingTimerZeroDelay) {
    355   for (int i = 0; i < kNumTestingMessageLoops; i++) {
    356     RunTest_RepeatingTimer(testing_message_loops[i],
    357                            TimeDelta::FromMilliseconds(0));
    358   }
    359 }
    360 
    361 TEST(TimerTest, RepeatingTimerZeroDelay_Cancel) {
    362   for (int i = 0; i < kNumTestingMessageLoops; i++) {
    363     RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
    364                                   TimeDelta::FromMilliseconds(0));
    365   }
    366 }
    367 
    368 TEST(TimerTest, DelayTimer_NoCall) {
    369   for (int i = 0; i < kNumTestingMessageLoops; i++) {
    370     RunTest_DelayTimer_NoCall(testing_message_loops[i]);
    371   }
    372 }
    373 
    374 TEST(TimerTest, DelayTimer_OneCall) {
    375   for (int i = 0; i < kNumTestingMessageLoops; i++) {
    376     RunTest_DelayTimer_OneCall(testing_message_loops[i]);
    377   }
    378 }
    379 
    380 // It's flaky on the buildbot, http://crbug.com/25038.
    381 TEST(TimerTest, DISABLED_DelayTimer_Reset) {
    382   for (int i = 0; i < kNumTestingMessageLoops; i++) {
    383     RunTest_DelayTimer_Reset(testing_message_loops[i]);
    384   }
    385 }
    386 
    387 TEST(TimerTest, DelayTimer_Deleted) {
    388   for (int i = 0; i < kNumTestingMessageLoops; i++) {
    389     RunTest_DelayTimer_Deleted(testing_message_loops[i]);
    390   }
    391 }
    392 
    393 TEST(TimerTest, MessageLoopShutdown) {
    394   // This test is designed to verify that shutdown of the
    395   // message loop does not cause crashes if there were pending
    396   // timers not yet fired.  It may only trigger exceptions
    397   // if debug heap checking is enabled.
    398   bool did_run = false;
    399   {
    400     OneShotTimerTester a(&did_run);
    401     OneShotTimerTester b(&did_run);
    402     OneShotTimerTester c(&did_run);
    403     OneShotTimerTester d(&did_run);
    404     {
    405       base::MessageLoop loop;
    406       a.Start();
    407       b.Start();
    408     }  // MessageLoop destructs by falling out of scope.
    409   }  // OneShotTimers destruct.  SHOULD NOT CRASH, of course.
    410 
    411   EXPECT_FALSE(did_run);
    412 }
    413 
    414 void TimerTestCallback() {
    415 }
    416 
    417 TEST(TimerTest, NonRepeatIsRunning) {
    418   {
    419     base::MessageLoop loop;
    420     base::Timer timer(false, false);
    421     EXPECT_FALSE(timer.IsRunning());
    422     timer.Start(FROM_HERE, TimeDelta::FromDays(1),
    423                 base::Bind(&TimerTestCallback));
    424     EXPECT_TRUE(timer.IsRunning());
    425     timer.Stop();
    426     EXPECT_FALSE(timer.IsRunning());
    427     EXPECT_TRUE(timer.user_task().is_null());
    428   }
    429 
    430   {
    431     base::Timer timer(true, false);
    432     base::MessageLoop loop;
    433     EXPECT_FALSE(timer.IsRunning());
    434     timer.Start(FROM_HERE, TimeDelta::FromDays(1),
    435                 base::Bind(&TimerTestCallback));
    436     EXPECT_TRUE(timer.IsRunning());
    437     timer.Stop();
    438     EXPECT_FALSE(timer.IsRunning());
    439     ASSERT_FALSE(timer.user_task().is_null());
    440     timer.Reset();
    441     EXPECT_TRUE(timer.IsRunning());
    442   }
    443 }
    444 
    445 TEST(TimerTest, NonRepeatMessageLoopDeath) {
    446   base::Timer timer(false, false);
    447   {
    448     base::MessageLoop loop;
    449     EXPECT_FALSE(timer.IsRunning());
    450     timer.Start(FROM_HERE, TimeDelta::FromDays(1),
    451                 base::Bind(&TimerTestCallback));
    452     EXPECT_TRUE(timer.IsRunning());
    453   }
    454   EXPECT_FALSE(timer.IsRunning());
    455   EXPECT_TRUE(timer.user_task().is_null());
    456 }
    457 
    458 TEST(TimerTest, RetainRepeatIsRunning) {
    459   base::MessageLoop loop;
    460   base::Timer timer(FROM_HERE, TimeDelta::FromDays(1),
    461                     base::Bind(&TimerTestCallback), true);
    462   EXPECT_FALSE(timer.IsRunning());
    463   timer.Reset();
    464   EXPECT_TRUE(timer.IsRunning());
    465   timer.Stop();
    466   EXPECT_FALSE(timer.IsRunning());
    467   timer.Reset();
    468   EXPECT_TRUE(timer.IsRunning());
    469 }
    470 
    471 TEST(TimerTest, RetainNonRepeatIsRunning) {
    472   base::MessageLoop loop;
    473   base::Timer timer(FROM_HERE, TimeDelta::FromDays(1),
    474                     base::Bind(&TimerTestCallback), false);
    475   EXPECT_FALSE(timer.IsRunning());
    476   timer.Reset();
    477   EXPECT_TRUE(timer.IsRunning());
    478   timer.Stop();
    479   EXPECT_FALSE(timer.IsRunning());
    480   timer.Reset();
    481   EXPECT_TRUE(timer.IsRunning());
    482 }
    483 
    484 namespace {
    485 
    486 bool g_callback_happened1 = false;
    487 bool g_callback_happened2 = false;
    488 
    489 void ClearAllCallbackHappened() {
    490   g_callback_happened1 = false;
    491   g_callback_happened2 = false;
    492 }
    493 
    494 void SetCallbackHappened1() {
    495   g_callback_happened1 = true;
    496   base::MessageLoop::current()->QuitWhenIdle();
    497 }
    498 
    499 void SetCallbackHappened2() {
    500   g_callback_happened2 = true;
    501   base::MessageLoop::current()->QuitWhenIdle();
    502 }
    503 
    504 TEST(TimerTest, ContinuationStopStart) {
    505   {
    506     ClearAllCallbackHappened();
    507     base::MessageLoop loop;
    508     base::Timer timer(false, false);
    509     timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
    510                 base::Bind(&SetCallbackHappened1));
    511     timer.Stop();
    512     timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(40),
    513                 base::Bind(&SetCallbackHappened2));
    514     base::MessageLoop::current()->Run();
    515     EXPECT_FALSE(g_callback_happened1);
    516     EXPECT_TRUE(g_callback_happened2);
    517   }
    518 }
    519 
    520 TEST(TimerTest, ContinuationReset) {
    521   {
    522     ClearAllCallbackHappened();
    523     base::MessageLoop loop;
    524     base::Timer timer(false, false);
    525     timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
    526                 base::Bind(&SetCallbackHappened1));
    527     timer.Reset();
    528     // Since Reset happened before task ran, the user_task must not be cleared:
    529     ASSERT_FALSE(timer.user_task().is_null());
    530     base::MessageLoop::current()->Run();
    531     EXPECT_TRUE(g_callback_happened1);
    532   }
    533 }
    534 
    535 }  // namespace
    536