| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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. | 
|  | 4 | 
|  | 5 #include "base/bind.h" | 
|  | 6 #include "base/bind_helpers.h" | 
|  | 7 #include "base/macros.h" | 
|  | 8 #include "base/message_loop/message_loop.h" | 
|  | 9 #include "base/run_loop.h" | 
|  | 10 #include "base/threading/platform_thread.h" | 
|  | 11 #include "base/time/time.h" | 
|  | 12 #include "components/timers/alarm_timer.h" | 
|  | 13 #include "testing/gtest/include/gtest/gtest.h" | 
|  | 14 | 
|  | 15 // Most of these tests have been lifted right out of timer_unittest.cc with only | 
|  | 16 // cosmetic changes (like replacing calls to MessageLoop::current()->Run() with | 
|  | 17 // a RunLoop).  We want the AlarmTimer to be a drop-in replacement for the | 
|  | 18 // regular Timer so it should pass the same tests as the Timer class. | 
|  | 19 // | 
|  | 20 // The only new tests are the .*ConcurrentResetAndTimerFired tests, which test | 
|  | 21 // that race conditions that can come up in the AlarmTimer::Delegate are | 
|  | 22 // properly handled. | 
|  | 23 namespace timers { | 
|  | 24 namespace { | 
|  | 25 // The message loops on which each timer should be tested. | 
|  | 26 const base::MessageLoop::Type testing_message_loops[] = { | 
|  | 27   base::MessageLoop::TYPE_DEFAULT, | 
|  | 28   base::MessageLoop::TYPE_IO, | 
|  | 29 #if !defined(OS_IOS)  // iOS does not allow direct running of the UI loop. | 
|  | 30   base::MessageLoop::TYPE_UI, | 
|  | 31 #endif | 
|  | 32 }; | 
|  | 33 | 
|  | 34 const int kNumTestingMessageLoops = arraysize(testing_message_loops); | 
|  | 35 const base::TimeDelta kTenMilliseconds = base::TimeDelta::FromMilliseconds(10); | 
|  | 36 | 
|  | 37 class OneShotAlarmTimerTester { | 
|  | 38  public: | 
|  | 39   OneShotAlarmTimerTester(bool* did_run, base::TimeDelta delay) | 
|  | 40       : did_run_(did_run), | 
|  | 41         delay_(delay), | 
|  | 42         timer_(new timers::AlarmTimer(false, false)) { | 
|  | 43   } | 
|  | 44   void Start() { | 
|  | 45     timer_->Start(FROM_HERE, | 
|  | 46                   delay_, | 
|  | 47                   base::Bind(&OneShotAlarmTimerTester::Run, | 
|  | 48                              base::Unretained(this))); | 
|  | 49   } | 
|  | 50 | 
|  | 51  private: | 
|  | 52   void Run() { | 
|  | 53     *did_run_ = true; | 
|  | 54 | 
|  | 55     base::MessageLoop::current()->PostTask( | 
|  | 56         FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 
|  | 57   } | 
|  | 58 | 
|  | 59   bool* did_run_; | 
|  | 60   const base::TimeDelta delay_; | 
|  | 61   scoped_ptr<timers::AlarmTimer> timer_; | 
|  | 62 | 
|  | 63   DISALLOW_COPY_AND_ASSIGN(OneShotAlarmTimerTester); | 
|  | 64 }; | 
|  | 65 | 
|  | 66 class OneShotSelfDeletingAlarmTimerTester { | 
|  | 67  public: | 
|  | 68   OneShotSelfDeletingAlarmTimerTester(bool* did_run, base::TimeDelta delay) | 
|  | 69       : did_run_(did_run), | 
|  | 70         delay_(delay), | 
|  | 71         timer_(new timers::AlarmTimer(false, false)) { | 
|  | 72   } | 
|  | 73   void Start() { | 
|  | 74     timer_->Start(FROM_HERE, | 
|  | 75                   delay_, | 
|  | 76                   base::Bind(&OneShotSelfDeletingAlarmTimerTester::Run, | 
|  | 77                              base::Unretained(this))); | 
|  | 78   } | 
|  | 79 | 
|  | 80  private: | 
|  | 81   void Run() { | 
|  | 82     *did_run_ = true; | 
|  | 83     timer_.reset(); | 
|  | 84 | 
|  | 85     base::MessageLoop::current()->PostTask( | 
|  | 86         FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 
|  | 87   } | 
|  | 88 | 
|  | 89   bool* did_run_; | 
|  | 90   const base::TimeDelta delay_; | 
|  | 91   scoped_ptr<timers::AlarmTimer> timer_; | 
|  | 92 | 
|  | 93   DISALLOW_COPY_AND_ASSIGN(OneShotSelfDeletingAlarmTimerTester); | 
|  | 94 }; | 
|  | 95 | 
|  | 96 class RepeatingAlarmTimerTester { | 
|  | 97  public: | 
|  | 98   RepeatingAlarmTimerTester(bool* did_run, base::TimeDelta delay) | 
|  | 99       : did_run_(did_run), | 
|  | 100         delay_(delay), | 
|  | 101         counter_(10), | 
|  | 102         timer_(new timers::AlarmTimer(true, true)) { | 
|  | 103   } | 
|  | 104   void Start() { | 
|  | 105     timer_->Start(FROM_HERE, | 
|  | 106                   delay_, | 
|  | 107                   base::Bind(&RepeatingAlarmTimerTester::Run, | 
|  | 108                              base::Unretained(this))); | 
|  | 109   } | 
|  | 110 | 
|  | 111  private: | 
|  | 112   void Run() { | 
|  | 113     if (--counter_ == 0) { | 
|  | 114       *did_run_ = true; | 
|  | 115       timer_->Stop(); | 
|  | 116 | 
|  | 117       base::MessageLoop::current()->PostTask( | 
|  | 118           FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 
|  | 119     } | 
|  | 120   } | 
|  | 121 | 
|  | 122   bool* did_run_; | 
|  | 123   const base::TimeDelta delay_; | 
|  | 124   int counter_; | 
|  | 125   scoped_ptr<timers::AlarmTimer> timer_; | 
|  | 126 | 
|  | 127   DISALLOW_COPY_AND_ASSIGN(RepeatingAlarmTimerTester); | 
|  | 128 }; | 
|  | 129 | 
|  | 130 void RunTest_OneShotAlarmTimer(base::MessageLoop::Type message_loop_type) { | 
|  | 131   base::MessageLoop loop(message_loop_type); | 
|  | 132 | 
|  | 133   bool did_run = false; | 
|  | 134   OneShotAlarmTimerTester f(&did_run, kTenMilliseconds); | 
|  | 135   f.Start(); | 
|  | 136 | 
|  | 137   base::RunLoop().Run(); | 
|  | 138 | 
|  | 139   EXPECT_TRUE(did_run); | 
|  | 140 } | 
|  | 141 | 
|  | 142 void RunTest_OneShotAlarmTimer_Cancel( | 
|  | 143     base::MessageLoop::Type message_loop_type) { | 
|  | 144   base::MessageLoop loop(message_loop_type); | 
|  | 145 | 
|  | 146   bool did_run_a = false; | 
|  | 147   OneShotAlarmTimerTester* a = new OneShotAlarmTimerTester(&did_run_a, | 
|  | 148                                                            kTenMilliseconds); | 
|  | 149 | 
|  | 150   // This should run before the timer expires. | 
|  | 151   base::MessageLoop::current()->DeleteSoon(FROM_HERE, a); | 
|  | 152 | 
|  | 153   // Now start the timer. | 
|  | 154   a->Start(); | 
|  | 155 | 
|  | 156   bool did_run_b = false; | 
|  | 157   OneShotAlarmTimerTester b(&did_run_b, kTenMilliseconds); | 
|  | 158   b.Start(); | 
|  | 159 | 
|  | 160   base::RunLoop().Run(); | 
|  | 161 | 
|  | 162   EXPECT_FALSE(did_run_a); | 
|  | 163   EXPECT_TRUE(did_run_b); | 
|  | 164 } | 
|  | 165 | 
|  | 166 void RunTest_OneShotSelfDeletingAlarmTimer( | 
|  | 167     base::MessageLoop::Type message_loop_type) { | 
|  | 168   base::MessageLoop loop(message_loop_type); | 
|  | 169 | 
|  | 170   bool did_run = false; | 
|  | 171   OneShotSelfDeletingAlarmTimerTester f(&did_run, kTenMilliseconds); | 
|  | 172   f.Start(); | 
|  | 173 | 
|  | 174   base::RunLoop().Run(); | 
|  | 175 | 
|  | 176   EXPECT_TRUE(did_run); | 
|  | 177 } | 
|  | 178 | 
|  | 179 void RunTest_RepeatingAlarmTimer(base::MessageLoop::Type message_loop_type, | 
|  | 180                                  const base::TimeDelta& delay) { | 
|  | 181   base::MessageLoop loop(message_loop_type); | 
|  | 182 | 
|  | 183   bool did_run = false; | 
|  | 184   RepeatingAlarmTimerTester f(&did_run, delay); | 
|  | 185   f.Start(); | 
|  | 186 | 
|  | 187   base::RunLoop().Run(); | 
|  | 188 | 
|  | 189   EXPECT_TRUE(did_run); | 
|  | 190 } | 
|  | 191 | 
|  | 192 void RunTest_RepeatingAlarmTimer_Cancel( | 
|  | 193     base::MessageLoop::Type message_loop_type, const base::TimeDelta& delay) { | 
|  | 194   base::MessageLoop loop(message_loop_type); | 
|  | 195 | 
|  | 196   bool did_run_a = false; | 
|  | 197   RepeatingAlarmTimerTester* a = new RepeatingAlarmTimerTester(&did_run_a, | 
|  | 198                                                                delay); | 
|  | 199 | 
|  | 200   // This should run before the timer expires. | 
|  | 201   base::MessageLoop::current()->DeleteSoon(FROM_HERE, a); | 
|  | 202 | 
|  | 203   // Now start the timer. | 
|  | 204   a->Start(); | 
|  | 205 | 
|  | 206   bool did_run_b = false; | 
|  | 207   RepeatingAlarmTimerTester b(&did_run_b, delay); | 
|  | 208   b.Start(); | 
|  | 209 | 
|  | 210   base::RunLoop().Run(); | 
|  | 211 | 
|  | 212   EXPECT_FALSE(did_run_a); | 
|  | 213   EXPECT_TRUE(did_run_b); | 
|  | 214 } | 
|  | 215 | 
|  | 216 }  // namespace | 
|  | 217 | 
|  | 218 //----------------------------------------------------------------------------- | 
|  | 219 // Each test is run against each type of MessageLoop.  That way we are sure | 
|  | 220 // that timers work properly in all configurations. | 
|  | 221 | 
|  | 222 TEST(AlarmTimerTest, OneShotAlarmTimer) { | 
|  | 223   for (int i = 0; i < kNumTestingMessageLoops; i++) { | 
|  | 224     RunTest_OneShotAlarmTimer(testing_message_loops[i]); | 
|  | 225   } | 
|  | 226 } | 
|  | 227 | 
|  | 228 TEST(AlarmTimerTest, OneShotAlarmTimer_Cancel) { | 
|  | 229   for (int i = 0; i < kNumTestingMessageLoops; i++) { | 
|  | 230     RunTest_OneShotAlarmTimer_Cancel(testing_message_loops[i]); | 
|  | 231   } | 
|  | 232 } | 
|  | 233 | 
|  | 234 // If underlying timer does not handle this properly, we will crash or fail | 
|  | 235 // in full page heap environment. | 
|  | 236 TEST(AlarmTimerTest, OneShotSelfDeletingAlarmTimer) { | 
|  | 237   for (int i = 0; i < kNumTestingMessageLoops; i++) { | 
|  | 238     RunTest_OneShotSelfDeletingAlarmTimer(testing_message_loops[i]); | 
|  | 239   } | 
|  | 240 } | 
|  | 241 | 
|  | 242 TEST(AlarmTimerTest, RepeatingAlarmTimer) { | 
|  | 243   for (int i = 0; i < kNumTestingMessageLoops; i++) { | 
|  | 244     RunTest_RepeatingAlarmTimer(testing_message_loops[i], | 
|  | 245                                 kTenMilliseconds); | 
|  | 246   } | 
|  | 247 } | 
|  | 248 | 
|  | 249 TEST(AlarmTimerTest, RepeatingAlarmTimer_Cancel) { | 
|  | 250   for (int i = 0; i < kNumTestingMessageLoops; i++) { | 
|  | 251     RunTest_RepeatingAlarmTimer_Cancel(testing_message_loops[i], | 
|  | 252                                        kTenMilliseconds); | 
|  | 253   } | 
|  | 254 } | 
|  | 255 | 
|  | 256 TEST(AlarmTimerTest, RepeatingAlarmTimerZeroDelay) { | 
|  | 257   for (int i = 0; i < kNumTestingMessageLoops; i++) { | 
|  | 258     RunTest_RepeatingAlarmTimer(testing_message_loops[i], | 
|  | 259                                 base::TimeDelta::FromMilliseconds(0)); | 
|  | 260   } | 
|  | 261 } | 
|  | 262 | 
|  | 263 TEST(AlarmTimerTest, RepeatingAlarmTimerZeroDelay_Cancel) { | 
|  | 264   for (int i = 0; i < kNumTestingMessageLoops; i++) { | 
|  | 265     RunTest_RepeatingAlarmTimer_Cancel(testing_message_loops[i], | 
|  | 266                                        base::TimeDelta::FromMilliseconds(0)); | 
|  | 267   } | 
|  | 268 } | 
|  | 269 | 
|  | 270 TEST(AlarmTimerTest, MessageLoopShutdown) { | 
|  | 271   // This test is designed to verify that shutdown of the | 
|  | 272   // message loop does not cause crashes if there were pending | 
|  | 273   // timers not yet fired.  It may only trigger exceptions | 
|  | 274   // if debug heap checking is enabled. | 
|  | 275   bool did_run = false; | 
|  | 276   { | 
|  | 277     OneShotAlarmTimerTester a(&did_run, kTenMilliseconds); | 
|  | 278     OneShotAlarmTimerTester b(&did_run, kTenMilliseconds); | 
|  | 279     OneShotAlarmTimerTester c(&did_run, kTenMilliseconds); | 
|  | 280     OneShotAlarmTimerTester d(&did_run, kTenMilliseconds); | 
|  | 281     { | 
|  | 282       base::MessageLoop loop; | 
|  | 283       a.Start(); | 
|  | 284       b.Start(); | 
|  | 285     }  // MessageLoop destructs by falling out of scope. | 
|  | 286   }  // OneShotTimers destruct.  SHOULD NOT CRASH, of course. | 
|  | 287 | 
|  | 288   EXPECT_FALSE(did_run); | 
|  | 289 } | 
|  | 290 | 
|  | 291 TEST(AlarmTimerTest, NonRepeatIsRunning) { | 
|  | 292   { | 
|  | 293     base::MessageLoop loop; | 
|  | 294     timers::AlarmTimer timer(false, false); | 
|  | 295     EXPECT_FALSE(timer.IsRunning()); | 
|  | 296     timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), | 
|  | 297                 base::Bind(&base::DoNothing)); | 
|  | 298     EXPECT_TRUE(timer.IsRunning()); | 
|  | 299     timer.Stop(); | 
|  | 300     EXPECT_FALSE(timer.IsRunning()); | 
|  | 301     EXPECT_TRUE(timer.user_task().is_null()); | 
|  | 302   } | 
|  | 303 | 
|  | 304   { | 
|  | 305     timers::AlarmTimer timer(true, false); | 
|  | 306     base::MessageLoop loop; | 
|  | 307     EXPECT_FALSE(timer.IsRunning()); | 
|  | 308     timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), | 
|  | 309                 base::Bind(&base::DoNothing)); | 
|  | 310     EXPECT_TRUE(timer.IsRunning()); | 
|  | 311     timer.Stop(); | 
|  | 312     EXPECT_FALSE(timer.IsRunning()); | 
|  | 313     ASSERT_FALSE(timer.user_task().is_null()); | 
|  | 314     timer.Reset(); | 
|  | 315     EXPECT_TRUE(timer.IsRunning()); | 
|  | 316   } | 
|  | 317 } | 
|  | 318 | 
|  | 319 TEST(AlarmTimerTest, NonRepeatMessageLoopDeath) { | 
|  | 320   timers::AlarmTimer timer(false, false); | 
|  | 321   { | 
|  | 322     base::MessageLoop loop; | 
|  | 323     EXPECT_FALSE(timer.IsRunning()); | 
|  | 324     timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), | 
|  | 325                 base::Bind(&base::DoNothing)); | 
|  | 326     EXPECT_TRUE(timer.IsRunning()); | 
|  | 327   } | 
|  | 328   EXPECT_FALSE(timer.IsRunning()); | 
|  | 329   EXPECT_TRUE(timer.user_task().is_null()); | 
|  | 330 } | 
|  | 331 | 
|  | 332 TEST(AlarmTimerTest, RetainRepeatIsRunning) { | 
|  | 333   base::MessageLoop loop; | 
|  | 334   timers::AlarmTimer timer(FROM_HERE, base::TimeDelta::FromDays(1), | 
|  | 335                           base::Bind(&base::DoNothing), true); | 
|  | 336   EXPECT_FALSE(timer.IsRunning()); | 
|  | 337   timer.Reset(); | 
|  | 338   EXPECT_TRUE(timer.IsRunning()); | 
|  | 339   timer.Stop(); | 
|  | 340   EXPECT_FALSE(timer.IsRunning()); | 
|  | 341   timer.Reset(); | 
|  | 342   EXPECT_TRUE(timer.IsRunning()); | 
|  | 343 } | 
|  | 344 | 
|  | 345 TEST(AlarmTimerTest, RetainNonRepeatIsRunning) { | 
|  | 346   base::MessageLoop loop; | 
|  | 347   timers::AlarmTimer timer(FROM_HERE, base::TimeDelta::FromDays(1), | 
|  | 348                           base::Bind(&base::DoNothing), false); | 
|  | 349   EXPECT_FALSE(timer.IsRunning()); | 
|  | 350   timer.Reset(); | 
|  | 351   EXPECT_TRUE(timer.IsRunning()); | 
|  | 352   timer.Stop(); | 
|  | 353   EXPECT_FALSE(timer.IsRunning()); | 
|  | 354   timer.Reset(); | 
|  | 355   EXPECT_TRUE(timer.IsRunning()); | 
|  | 356 } | 
|  | 357 | 
|  | 358 namespace { | 
|  | 359 | 
|  | 360 bool g_callback_happened1 = false; | 
|  | 361 bool g_callback_happened2 = false; | 
|  | 362 | 
|  | 363 void ClearAllCallbackHappened() { | 
|  | 364   g_callback_happened1 = false; | 
|  | 365   g_callback_happened2 = false; | 
|  | 366 } | 
|  | 367 | 
|  | 368 void SetCallbackHappened1() { | 
|  | 369   g_callback_happened1 = true; | 
|  | 370   base::MessageLoop::current()->PostTask( | 
|  | 371       FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 
|  | 372 } | 
|  | 373 | 
|  | 374 void SetCallbackHappened2() { | 
|  | 375   g_callback_happened2 = true; | 
|  | 376   base::MessageLoop::current()->PostTask( | 
|  | 377       FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 
|  | 378 } | 
|  | 379 | 
|  | 380 TEST(AlarmTimerTest, ContinuationStopStart) { | 
|  | 381   { | 
|  | 382     ClearAllCallbackHappened(); | 
|  | 383     base::MessageLoop loop; | 
|  | 384     timers::AlarmTimer timer(false, false); | 
|  | 385     timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10), | 
|  | 386                 base::Bind(&SetCallbackHappened1)); | 
|  | 387     timer.Stop(); | 
|  | 388     timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(40), | 
|  | 389                 base::Bind(&SetCallbackHappened2)); | 
|  | 390     base::RunLoop().Run(); | 
|  | 391     EXPECT_FALSE(g_callback_happened1); | 
|  | 392     EXPECT_TRUE(g_callback_happened2); | 
|  | 393   } | 
|  | 394 } | 
|  | 395 | 
|  | 396 TEST(AlarmTimerTest, ContinuationReset) { | 
|  | 397   { | 
|  | 398     ClearAllCallbackHappened(); | 
|  | 399     base::MessageLoop loop; | 
|  | 400     timers::AlarmTimer timer(false, false); | 
|  | 401     timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10), | 
|  | 402                 base::Bind(&SetCallbackHappened1)); | 
|  | 403     timer.Reset(); | 
|  | 404     // Since Reset happened before task ran, the user_task must not be cleared: | 
|  | 405     ASSERT_FALSE(timer.user_task().is_null()); | 
|  | 406     base::RunLoop().Run(); | 
|  | 407     EXPECT_TRUE(g_callback_happened1); | 
|  | 408   } | 
|  | 409 } | 
|  | 410 | 
|  | 411 }  // namespace | 
|  | 412 | 
|  | 413 | 
|  | 414 namespace { | 
|  | 415 void TimerRanCallback(bool* did_run) { | 
|  | 416   *did_run = true; | 
|  | 417 | 
|  | 418   base::MessageLoop::current()->PostTask( | 
|  | 419       FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 
|  | 420 } | 
|  | 421 | 
|  | 422 void RunTest_OneShotTimerConcurrentResetAndTimerFired( | 
|  | 423     base::MessageLoop::Type message_loop_type) { | 
|  | 424   base::MessageLoop loop(message_loop_type); | 
|  | 425 | 
|  | 426   timers::AlarmTimer timer(false, false); | 
|  | 427   bool did_run = false; | 
|  | 428 | 
|  | 429   timer.Start( | 
|  | 430       FROM_HERE, kTenMilliseconds, base::Bind(&TimerRanCallback, &did_run)); | 
|  | 431 | 
|  | 432   // Sleep twice as long as the timer to ensure that the timer task gets queued. | 
|  | 433   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20)); | 
|  | 434 | 
|  | 435   // Now reset the timer.  This is attempting to simulate the timer firing and | 
|  | 436   // being reset at the same time.  The previously queued task should be | 
|  | 437   // removed. | 
|  | 438   timer.Reset(); | 
|  | 439 | 
|  | 440   base::RunLoop().RunUntilIdle(); | 
|  | 441   EXPECT_FALSE(did_run); | 
|  | 442 | 
|  | 443   // If the previous check failed, running the message loop again will hang the | 
|  | 444   // test so we only do it if the callback has not run yet. | 
|  | 445   if (!did_run) { | 
|  | 446     base::RunLoop().Run(); | 
|  | 447     EXPECT_TRUE(did_run); | 
|  | 448   } | 
|  | 449 } | 
|  | 450 | 
|  | 451 void RunTest_RepeatingTimerConcurrentResetAndTimerFired( | 
|  | 452     base::MessageLoop::Type message_loop_type) { | 
|  | 453   base::MessageLoop loop(message_loop_type); | 
|  | 454 | 
|  | 455   timers::AlarmTimer timer(true, true); | 
|  | 456   bool did_run = false; | 
|  | 457 | 
|  | 458   timer.Start( | 
|  | 459       FROM_HERE, kTenMilliseconds, base::Bind(&TimerRanCallback, &did_run)); | 
|  | 460 | 
|  | 461   // Sleep more that three times as long as the timer duration to ensure that | 
|  | 462   // multiple tasks get queued. | 
|  | 463   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(35)); | 
|  | 464 | 
|  | 465   // Now reset the timer.  This is attempting to simulate a very busy message | 
|  | 466   // loop where multiple tasks get queued but the timer gets reset before any of | 
|  | 467   // them have a chance to run. | 
|  | 468   timer.Reset(); | 
|  | 469 | 
|  | 470   base::RunLoop().RunUntilIdle(); | 
|  | 471   EXPECT_FALSE(did_run); | 
|  | 472 | 
|  | 473   // If the previous check failed, running the message loop again will hang the | 
|  | 474   // test so we only do it if the callback has not run yet. | 
|  | 475   if (!did_run) { | 
|  | 476     base::RunLoop().Run(); | 
|  | 477     EXPECT_TRUE(did_run); | 
|  | 478   } | 
|  | 479 } | 
|  | 480 | 
|  | 481 TEST(AlarmTimerTest, OneShotTimerConcurrentResetAndTimerFired) { | 
|  | 482   for (int i = 0; i < kNumTestingMessageLoops; i++) { | 
|  | 483     RunTest_OneShotTimerConcurrentResetAndTimerFired(testing_message_loops[i]); | 
|  | 484   } | 
|  | 485 } | 
|  | 486 | 
|  | 487 TEST(AlarmTimerTest, RepeatingTimerConcurrentResetAndTimerFired) { | 
|  | 488   for (int i = 0; i < kNumTestingMessageLoops; i++) { | 
|  | 489     RunTest_RepeatingTimerConcurrentResetAndTimerFired( | 
|  | 490         testing_message_loops[i]); | 
|  | 491   } | 
|  | 492 } | 
|  | 493 | 
|  | 494 }  // namespace | 
|  | 495 | 
|  | 496 }  // namespace timers | 
| OLD | NEW | 
|---|