OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/timer/timer.h" | 5 #include "base/timer/timer.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
| 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" |
11 #include "base/macros.h" | 13 #include "base/macros.h" |
12 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
13 #include "base/run_loop.h" | 15 #include "base/run_loop.h" |
| 16 #include "base/test/test_mock_time_task_runner.h" |
14 #include "base/test/test_simple_task_runner.h" | 17 #include "base/test/test_simple_task_runner.h" |
15 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 19 #include "base/time/tick_clock.h" |
16 #include "build/build_config.h" | 20 #include "build/build_config.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
18 | 22 |
19 using base::TimeDelta; | 23 using base::TimeDelta; |
20 using base::SingleThreadTaskRunner; | 24 using base::SingleThreadTaskRunner; |
21 | 25 |
22 namespace { | 26 namespace { |
23 | 27 |
24 // The message loops on which each timer should be tested. | 28 // The message loops on which each timer should be tested. |
25 const base::MessageLoop::Type testing_message_loops[] = { | 29 const base::MessageLoop::Type testing_message_loops[] = { |
26 base::MessageLoop::TYPE_DEFAULT, | 30 base::MessageLoop::TYPE_DEFAULT, |
27 base::MessageLoop::TYPE_IO, | 31 base::MessageLoop::TYPE_IO, |
28 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop. | 32 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop. |
29 base::MessageLoop::TYPE_UI, | 33 base::MessageLoop::TYPE_UI, |
30 #endif | 34 #endif |
31 }; | 35 }; |
32 | 36 |
33 const int kNumTestingMessageLoops = arraysize(testing_message_loops); | 37 const int kNumTestingMessageLoops = arraysize(testing_message_loops); |
34 | 38 |
| 39 class Receiver { |
| 40 public: |
| 41 Receiver() : count_(0) {} |
| 42 void OnCalled() { count_++; } |
| 43 bool WasCalled() { return count_ > 0; } |
| 44 int TimesCalled() { return count_; } |
| 45 |
| 46 private: |
| 47 int count_; |
| 48 }; |
| 49 |
35 class OneShotTimerTester { | 50 class OneShotTimerTester { |
36 public: | 51 public: |
37 explicit OneShotTimerTester(bool* did_run, unsigned milliseconds = 10) | 52 explicit OneShotTimerTester(bool* did_run, unsigned milliseconds = 10) |
38 : did_run_(did_run), | 53 : did_run_(did_run), |
39 delay_ms_(milliseconds), | 54 delay_ms_(milliseconds), |
40 quit_message_loop_(true) { | 55 quit_message_loop_(true) { |
41 } | 56 } |
42 | 57 |
43 void Start() { | 58 void Start() { |
44 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this, | 59 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this, |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 bool did_run = false; | 349 bool did_run = false; |
335 OneShotTimerTester f(&did_run); | 350 OneShotTimerTester f(&did_run); |
336 f.SetTaskRunner(task_runner); | 351 f.SetTaskRunner(task_runner); |
337 f.Start(); | 352 f.Start(); |
338 | 353 |
339 EXPECT_FALSE(did_run); | 354 EXPECT_FALSE(did_run); |
340 task_runner->RunUntilIdle(); | 355 task_runner->RunUntilIdle(); |
341 EXPECT_TRUE(did_run); | 356 EXPECT_TRUE(did_run); |
342 } | 357 } |
343 | 358 |
| 359 TEST(TimerTest, OneShotTimerWithTickClock) { |
| 360 scoped_refptr<base::TestMockTimeTaskRunner> task_runner( |
| 361 new base::TestMockTimeTaskRunner(base::Time::Now(), |
| 362 base::TimeTicks::Now())); |
| 363 std::unique_ptr<base::TickClock> tick_clock(task_runner->GetMockTickClock()); |
| 364 base::MessageLoop message_loop; |
| 365 message_loop.SetTaskRunner(task_runner); |
| 366 Receiver receiver; |
| 367 base::OneShotTimer timer(tick_clock.get()); |
| 368 timer.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), |
| 369 base::Bind(&Receiver::OnCalled, base::Unretained(&receiver))); |
| 370 task_runner->FastForwardBy(base::TimeDelta::FromSeconds(1)); |
| 371 EXPECT_TRUE(receiver.WasCalled()); |
| 372 } |
| 373 |
344 TEST(TimerTest, RepeatingTimer) { | 374 TEST(TimerTest, RepeatingTimer) { |
345 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 375 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
346 RunTest_RepeatingTimer(testing_message_loops[i], | 376 RunTest_RepeatingTimer(testing_message_loops[i], |
347 TimeDelta::FromMilliseconds(10)); | 377 TimeDelta::FromMilliseconds(10)); |
348 } | 378 } |
349 } | 379 } |
350 | 380 |
351 TEST(TimerTest, RepeatingTimer_Cancel) { | 381 TEST(TimerTest, RepeatingTimer_Cancel) { |
352 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 382 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
353 RunTest_RepeatingTimer_Cancel(testing_message_loops[i], | 383 RunTest_RepeatingTimer_Cancel(testing_message_loops[i], |
354 TimeDelta::FromMilliseconds(10)); | 384 TimeDelta::FromMilliseconds(10)); |
355 } | 385 } |
356 } | 386 } |
357 | 387 |
358 TEST(TimerTest, RepeatingTimerZeroDelay) { | 388 TEST(TimerTest, RepeatingTimerZeroDelay) { |
359 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 389 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
360 RunTest_RepeatingTimer(testing_message_loops[i], | 390 RunTest_RepeatingTimer(testing_message_loops[i], |
361 TimeDelta::FromMilliseconds(0)); | 391 TimeDelta::FromMilliseconds(0)); |
362 } | 392 } |
363 } | 393 } |
364 | 394 |
365 TEST(TimerTest, RepeatingTimerZeroDelay_Cancel) { | 395 TEST(TimerTest, RepeatingTimerZeroDelay_Cancel) { |
366 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 396 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
367 RunTest_RepeatingTimer_Cancel(testing_message_loops[i], | 397 RunTest_RepeatingTimer_Cancel(testing_message_loops[i], |
368 TimeDelta::FromMilliseconds(0)); | 398 TimeDelta::FromMilliseconds(0)); |
369 } | 399 } |
370 } | 400 } |
371 | 401 |
| 402 TEST(TimerTest, RepeatingTimerWithTickClock) { |
| 403 scoped_refptr<base::TestMockTimeTaskRunner> task_runner( |
| 404 new base::TestMockTimeTaskRunner(base::Time::Now(), |
| 405 base::TimeTicks::Now())); |
| 406 std::unique_ptr<base::TickClock> tick_clock(task_runner->GetMockTickClock()); |
| 407 base::MessageLoop message_loop; |
| 408 message_loop.SetTaskRunner(task_runner); |
| 409 Receiver receiver; |
| 410 const int expected_times_called = 10; |
| 411 base::RepeatingTimer timer(tick_clock.get()); |
| 412 timer.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), |
| 413 base::Bind(&Receiver::OnCalled, base::Unretained(&receiver))); |
| 414 task_runner->FastForwardBy( |
| 415 base::TimeDelta::FromSeconds(expected_times_called)); |
| 416 timer.Stop(); |
| 417 EXPECT_EQ(expected_times_called, receiver.TimesCalled()); |
| 418 } |
| 419 |
372 TEST(TimerTest, DelayTimer_NoCall) { | 420 TEST(TimerTest, DelayTimer_NoCall) { |
373 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 421 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
374 RunTest_DelayTimer_NoCall(testing_message_loops[i]); | 422 RunTest_DelayTimer_NoCall(testing_message_loops[i]); |
375 } | 423 } |
376 } | 424 } |
377 | 425 |
378 TEST(TimerTest, DelayTimer_OneCall) { | 426 TEST(TimerTest, DelayTimer_OneCall) { |
379 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 427 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
380 RunTest_DelayTimer_OneCall(testing_message_loops[i]); | 428 RunTest_DelayTimer_OneCall(testing_message_loops[i]); |
381 } | 429 } |
382 } | 430 } |
383 | 431 |
384 // It's flaky on the buildbot, http://crbug.com/25038. | 432 // It's flaky on the buildbot, http://crbug.com/25038. |
385 TEST(TimerTest, DISABLED_DelayTimer_Reset) { | 433 TEST(TimerTest, DISABLED_DelayTimer_Reset) { |
386 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 434 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
387 RunTest_DelayTimer_Reset(testing_message_loops[i]); | 435 RunTest_DelayTimer_Reset(testing_message_loops[i]); |
388 } | 436 } |
389 } | 437 } |
390 | 438 |
391 TEST(TimerTest, DelayTimer_Deleted) { | 439 TEST(TimerTest, DelayTimer_Deleted) { |
392 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 440 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
393 RunTest_DelayTimer_Deleted(testing_message_loops[i]); | 441 RunTest_DelayTimer_Deleted(testing_message_loops[i]); |
394 } | 442 } |
395 } | 443 } |
396 | 444 |
| 445 TEST(TimerTest, DelayTimerWithTickClock) { |
| 446 scoped_refptr<base::TestMockTimeTaskRunner> task_runner( |
| 447 new base::TestMockTimeTaskRunner(base::Time::Now(), |
| 448 base::TimeTicks::Now())); |
| 449 std::unique_ptr<base::TickClock> tick_clock(task_runner->GetMockTickClock()); |
| 450 base::MessageLoop message_loop; |
| 451 message_loop.SetTaskRunner(task_runner); |
| 452 Receiver receiver; |
| 453 base::DelayTimer timer(FROM_HERE, base::TimeDelta::FromSeconds(1), &receiver, |
| 454 &Receiver::OnCalled, tick_clock.get()); |
| 455 task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(999)); |
| 456 EXPECT_FALSE(receiver.WasCalled()); |
| 457 timer.Reset(); |
| 458 task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(999)); |
| 459 EXPECT_FALSE(receiver.WasCalled()); |
| 460 timer.Reset(); |
| 461 task_runner->FastForwardBy(base::TimeDelta::FromSeconds(1)); |
| 462 EXPECT_TRUE(receiver.WasCalled()); |
| 463 } |
| 464 |
397 TEST(TimerTest, MessageLoopShutdown) { | 465 TEST(TimerTest, MessageLoopShutdown) { |
398 // This test is designed to verify that shutdown of the | 466 // This test is designed to verify that shutdown of the |
399 // message loop does not cause crashes if there were pending | 467 // message loop does not cause crashes if there were pending |
400 // timers not yet fired. It may only trigger exceptions | 468 // timers not yet fired. It may only trigger exceptions |
401 // if debug heap checking is enabled. | 469 // if debug heap checking is enabled. |
402 bool did_run = false; | 470 bool did_run = false; |
403 { | 471 { |
404 OneShotTimerTester a(&did_run); | 472 OneShotTimerTester a(&did_run); |
405 OneShotTimerTester b(&did_run); | 473 OneShotTimerTester b(&did_run); |
406 OneShotTimerTester c(&did_run); | 474 OneShotTimerTester c(&did_run); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 base::Bind(&SetCallbackHappened1)); | 598 base::Bind(&SetCallbackHappened1)); |
531 timer.Reset(); | 599 timer.Reset(); |
532 // Since Reset happened before task ran, the user_task must not be cleared: | 600 // Since Reset happened before task ran, the user_task must not be cleared: |
533 ASSERT_FALSE(timer.user_task().is_null()); | 601 ASSERT_FALSE(timer.user_task().is_null()); |
534 base::RunLoop().Run(); | 602 base::RunLoop().Run(); |
535 EXPECT_TRUE(g_callback_happened1); | 603 EXPECT_TRUE(g_callback_happened1); |
536 } | 604 } |
537 } | 605 } |
538 | 606 |
539 } // namespace | 607 } // namespace |
OLD | NEW |