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: 49 Receiver() : count_(0) {} 50 void OnCalled() { count_++; } 51 bool WasCalled() { return count_ > 0; } 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. 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 70 void Start() { 71 started_time_ = TimeTicks::Now(); 72 timer_->Start(FROM_HERE, delay_, this, &OneShotTimerTesterBase::Run); 73 } 74 75 bool IsRunning() { return timer_->IsRunning(); } 76 77 TimeTicks started_time() const { return started_time_; } 78 TimeDelta delay() const { return delay_; } 79 80 protected: 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. 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 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. 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. 133 virtual void OnRun() {} 134 135 private: 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: 150 void OnRun() override { timer_.reset(); } 151 }; 152 153 constexpr int kNumRepeats = 10; 154 155 class RepeatingTimerTester { 156 public: 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 163 void Start() { 164 started_time_ = TimeTicks::Now(); 165 timer_.Start(FROM_HERE, delay_, this, &RepeatingTimerTester::Run); 166 } 167 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: 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. 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 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 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 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 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: 283 bool signaled() const { return signaled_; } 284 285 void Signal() { 286 ASSERT_FALSE(signaled_); 287 signaled_ = true; 288 } 289 290 private: 291 bool signaled_ = false; 292 }; 293 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 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 { 325 ResetHelper(DelayTimer* timer, DelayTimerTarget* target) 326 : timer_(timer), target_(target) {} 327 328 void Reset() { 329 ASSERT_FALSE(target_->signaled()); 330 timer_->Reset(); 331 } 332 333 private: 334 DelayTimer* const timer_; 335 DelayTimerTarget* const target_; 336 }; 337 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: 364 void Signal() { 365 ASSERT_TRUE(false); 366 } 367 }; 368 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 391 TEST(TimerTest, OneShotTimers) { 392 for (int i = 0; i < kNumTestingMessageLoops; i++) { 393 RunTest_OneShotTimers(testing_message_loops[i]); 394 } 395 } 396 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. 405 TEST(TimerTest, OneShotSelfDeletingTimer) { 406 for (int i = 0; i < kNumTestingMessageLoops; i++) { 407 RunTest_OneShotSelfDeletingTimer(testing_message_loops[i]); 408 } 409 } 410 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 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 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 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 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 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 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 494 TEST(TimerTest, DelayTimer_NoCall) { 495 for (int i = 0; i < kNumTestingMessageLoops; i++) { 496 RunTest_DelayTimer_NoCall(testing_message_loops[i]); 497 } 498 } 499 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. 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 513 TEST(TimerTest, DelayTimer_Deleted) { 514 for (int i = 0; i < kNumTestingMessageLoops; i++) { 515 RunTest_DelayTimer_Deleted(testing_message_loops[i]); 516 } 517 } 518 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 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 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 579 void Run() { 580 ADD_FAILURE() << "Timer unexpectedly fired."; 581 } 582 583 OneShotTimer timer_; 584 585 DISALLOW_COPY_AND_ASSIGN(OneShotSelfOwningTimerTester); 586 }; 587 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 604 void TimerTestCallback() { 605 } 606 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 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 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 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 676 void ClearAllCallbackHappened() { 677 g_callback_happened1 = false; 678 g_callback_happened2 = false; 679 } 680 681 void SetCallbackHappened1() { 682 g_callback_happened1 = true; 683 MessageLoop::current()->QuitWhenIdle(); 684 } 685 686 void SetCallbackHappened2() { 687 g_callback_happened2 = true; 688 MessageLoop::current()->QuitWhenIdle(); 689 } 690 691 } // namespace 692 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 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