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.
5 #include "base/memory/scoped_ptr.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/test/test_simple_task_runner.h"
8 #include "base/timer/timer.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 using base::TimeDelta
;
12 using base::SingleThreadTaskRunner
;
16 // The message loops on which each timer should be tested.
17 const base::MessageLoop::Type testing_message_loops
[] = {
18 base::MessageLoop::TYPE_DEFAULT
,
19 base::MessageLoop::TYPE_IO
,
20 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
21 base::MessageLoop::TYPE_UI
,
25 const int kNumTestingMessageLoops
= arraysize(testing_message_loops
);
27 class OneShotTimerTester
{
29 explicit OneShotTimerTester(bool* did_run
, unsigned milliseconds
= 10)
31 delay_ms_(milliseconds
),
32 quit_message_loop_(true) {
36 timer_
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(delay_ms_
), this,
37 &OneShotTimerTester::Run
);
40 void SetTaskRunner(scoped_refptr
<SingleThreadTaskRunner
> task_runner
) {
41 quit_message_loop_
= false;
42 timer_
.SetTaskRunner(task_runner
);
48 if (quit_message_loop_
) {
49 base::MessageLoop::current()->QuitWhenIdle();
54 base::OneShotTimer
<OneShotTimerTester
> timer_
;
55 const unsigned delay_ms_
;
56 bool quit_message_loop_
;
59 class OneShotSelfDeletingTimerTester
{
61 explicit OneShotSelfDeletingTimerTester(bool* did_run
) :
63 timer_(new base::OneShotTimer
<OneShotSelfDeletingTimerTester
>()) {
67 timer_
->Start(FROM_HERE
, TimeDelta::FromMilliseconds(10), this,
68 &OneShotSelfDeletingTimerTester::Run
);
75 base::MessageLoop::current()->QuitWhenIdle();
79 scoped_ptr
<base::OneShotTimer
<OneShotSelfDeletingTimerTester
> > timer_
;
82 class RepeatingTimerTester
{
84 explicit RepeatingTimerTester(bool* did_run
, const TimeDelta
& delay
)
85 : did_run_(did_run
), counter_(10), delay_(delay
) {
89 timer_
.Start(FROM_HERE
, delay_
, this, &RepeatingTimerTester::Run
);
94 if (--counter_
== 0) {
97 base::MessageLoop::current()->QuitWhenIdle();
104 base::RepeatingTimer
<RepeatingTimerTester
> timer_
;
107 void RunTest_OneShotTimer(base::MessageLoop::Type message_loop_type
) {
108 base::MessageLoop
loop(message_loop_type
);
110 bool did_run
= false;
111 OneShotTimerTester
f(&did_run
);
114 base::MessageLoop::current()->Run();
116 EXPECT_TRUE(did_run
);
119 void RunTest_OneShotTimer_Cancel(base::MessageLoop::Type message_loop_type
) {
120 base::MessageLoop
loop(message_loop_type
);
122 bool did_run_a
= false;
123 OneShotTimerTester
* a
= new OneShotTimerTester(&did_run_a
);
125 // This should run before the timer expires.
126 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
128 // Now start the timer.
131 bool did_run_b
= false;
132 OneShotTimerTester
b(&did_run_b
);
135 base::MessageLoop::current()->Run();
137 EXPECT_FALSE(did_run_a
);
138 EXPECT_TRUE(did_run_b
);
141 void RunTest_OneShotSelfDeletingTimer(
142 base::MessageLoop::Type message_loop_type
) {
143 base::MessageLoop
loop(message_loop_type
);
145 bool did_run
= false;
146 OneShotSelfDeletingTimerTester
f(&did_run
);
149 base::MessageLoop::current()->Run();
151 EXPECT_TRUE(did_run
);
154 void RunTest_RepeatingTimer(base::MessageLoop::Type message_loop_type
,
155 const TimeDelta
& delay
) {
156 base::MessageLoop
loop(message_loop_type
);
158 bool did_run
= false;
159 RepeatingTimerTester
f(&did_run
, delay
);
162 base::MessageLoop::current()->Run();
164 EXPECT_TRUE(did_run
);
167 void RunTest_RepeatingTimer_Cancel(base::MessageLoop::Type message_loop_type
,
168 const TimeDelta
& delay
) {
169 base::MessageLoop
loop(message_loop_type
);
171 bool did_run_a
= false;
172 RepeatingTimerTester
* a
= new RepeatingTimerTester(&did_run_a
, delay
);
174 // This should run before the timer expires.
175 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
177 // Now start the timer.
180 bool did_run_b
= false;
181 RepeatingTimerTester
b(&did_run_b
, delay
);
184 base::MessageLoop::current()->Run();
186 EXPECT_FALSE(did_run_a
);
187 EXPECT_TRUE(did_run_b
);
190 class DelayTimerTarget
{
192 bool signaled() const { return signaled_
; }
195 ASSERT_FALSE(signaled_
);
200 bool signaled_
= false;
203 void RunTest_DelayTimer_NoCall(base::MessageLoop::Type message_loop_type
) {
204 base::MessageLoop
loop(message_loop_type
);
206 // If Delay is never called, the timer shouldn't go off.
207 DelayTimerTarget target
;
208 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
209 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
211 bool did_run
= false;
212 OneShotTimerTester
tester(&did_run
);
214 base::MessageLoop::current()->Run();
216 ASSERT_FALSE(target
.signaled());
219 void RunTest_DelayTimer_OneCall(base::MessageLoop::Type message_loop_type
) {
220 base::MessageLoop
loop(message_loop_type
);
222 DelayTimerTarget target
;
223 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
224 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
227 bool did_run
= false;
228 OneShotTimerTester
tester(&did_run
, 100 /* milliseconds */);
230 base::MessageLoop::current()->Run();
232 ASSERT_TRUE(target
.signaled());
236 ResetHelper(base::DelayTimer
<DelayTimerTarget
>* timer
,
237 DelayTimerTarget
* target
)
243 ASSERT_FALSE(target_
->signaled());
248 base::DelayTimer
<DelayTimerTarget
> *const timer_
;
249 DelayTimerTarget
*const target_
;
252 void RunTest_DelayTimer_Reset(base::MessageLoop::Type message_loop_type
) {
253 base::MessageLoop
loop(message_loop_type
);
255 // If Delay is never called, the timer shouldn't go off.
256 DelayTimerTarget target
;
257 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
258 TimeDelta::FromMilliseconds(50), &target
, &DelayTimerTarget::Signal
);
261 ResetHelper
reset_helper(&timer
, &target
);
263 base::OneShotTimer
<ResetHelper
> timers
[20];
264 for (size_t i
= 0; i
< arraysize(timers
); ++i
) {
265 timers
[i
].Start(FROM_HERE
, TimeDelta::FromMilliseconds(i
* 10),
266 &reset_helper
, &ResetHelper::Reset
);
269 bool did_run
= false;
270 OneShotTimerTester
tester(&did_run
, 300);
272 base::MessageLoop::current()->Run();
274 ASSERT_TRUE(target
.signaled());
277 class DelayTimerFatalTarget
{
285 void RunTest_DelayTimer_Deleted(base::MessageLoop::Type message_loop_type
) {
286 base::MessageLoop
loop(message_loop_type
);
288 DelayTimerFatalTarget target
;
291 base::DelayTimer
<DelayTimerFatalTarget
> timer(
292 FROM_HERE
, TimeDelta::FromMilliseconds(50), &target
,
293 &DelayTimerFatalTarget::Signal
);
297 // When the timer is deleted, the DelayTimerFatalTarget should never be
299 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
304 //-----------------------------------------------------------------------------
305 // Each test is run against each type of MessageLoop. That way we are sure
306 // that timers work properly in all configurations.
308 TEST(TimerTest
, OneShotTimer
) {
309 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
310 RunTest_OneShotTimer(testing_message_loops
[i
]);
314 TEST(TimerTest
, OneShotTimer_Cancel
) {
315 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
316 RunTest_OneShotTimer_Cancel(testing_message_loops
[i
]);
320 // If underline timer does not handle properly, we will crash or fail
321 // in full page heap environment.
322 TEST(TimerTest
, OneShotSelfDeletingTimer
) {
323 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
324 RunTest_OneShotSelfDeletingTimer(testing_message_loops
[i
]);
328 TEST(TimerTest
, OneShotTimer_CustomTaskRunner
) {
329 scoped_refptr
<base::TestSimpleTaskRunner
> task_runner
=
330 new base::TestSimpleTaskRunner();
332 bool did_run
= false;
333 OneShotTimerTester
f(&did_run
);
334 f
.SetTaskRunner(task_runner
);
337 EXPECT_FALSE(did_run
);
338 task_runner
->RunUntilIdle();
339 EXPECT_TRUE(did_run
);
342 TEST(TimerTest
, RepeatingTimer
) {
343 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
344 RunTest_RepeatingTimer(testing_message_loops
[i
],
345 TimeDelta::FromMilliseconds(10));
349 TEST(TimerTest
, RepeatingTimer_Cancel
) {
350 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
351 RunTest_RepeatingTimer_Cancel(testing_message_loops
[i
],
352 TimeDelta::FromMilliseconds(10));
356 TEST(TimerTest
, RepeatingTimerZeroDelay
) {
357 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
358 RunTest_RepeatingTimer(testing_message_loops
[i
],
359 TimeDelta::FromMilliseconds(0));
363 TEST(TimerTest
, RepeatingTimerZeroDelay_Cancel
) {
364 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
365 RunTest_RepeatingTimer_Cancel(testing_message_loops
[i
],
366 TimeDelta::FromMilliseconds(0));
370 TEST(TimerTest
, DelayTimer_NoCall
) {
371 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
372 RunTest_DelayTimer_NoCall(testing_message_loops
[i
]);
376 TEST(TimerTest
, DelayTimer_OneCall
) {
377 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
378 RunTest_DelayTimer_OneCall(testing_message_loops
[i
]);
382 // It's flaky on the buildbot, http://crbug.com/25038.
383 TEST(TimerTest
, DISABLED_DelayTimer_Reset
) {
384 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
385 RunTest_DelayTimer_Reset(testing_message_loops
[i
]);
389 TEST(TimerTest
, DelayTimer_Deleted
) {
390 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
391 RunTest_DelayTimer_Deleted(testing_message_loops
[i
]);
395 TEST(TimerTest
, MessageLoopShutdown
) {
396 // This test is designed to verify that shutdown of the
397 // message loop does not cause crashes if there were pending
398 // timers not yet fired. It may only trigger exceptions
399 // if debug heap checking is enabled.
400 bool did_run
= false;
402 OneShotTimerTester
a(&did_run
);
403 OneShotTimerTester
b(&did_run
);
404 OneShotTimerTester
c(&did_run
);
405 OneShotTimerTester
d(&did_run
);
407 base::MessageLoop loop
;
410 } // MessageLoop destructs by falling out of scope.
411 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
413 EXPECT_FALSE(did_run
);
416 void TimerTestCallback() {
419 TEST(TimerTest
, NonRepeatIsRunning
) {
421 base::MessageLoop loop
;
422 base::Timer
timer(false, false);
423 EXPECT_FALSE(timer
.IsRunning());
424 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
425 base::Bind(&TimerTestCallback
));
426 EXPECT_TRUE(timer
.IsRunning());
428 EXPECT_FALSE(timer
.IsRunning());
429 EXPECT_TRUE(timer
.user_task().is_null());
433 base::Timer
timer(true, false);
434 base::MessageLoop loop
;
435 EXPECT_FALSE(timer
.IsRunning());
436 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
437 base::Bind(&TimerTestCallback
));
438 EXPECT_TRUE(timer
.IsRunning());
440 EXPECT_FALSE(timer
.IsRunning());
441 ASSERT_FALSE(timer
.user_task().is_null());
443 EXPECT_TRUE(timer
.IsRunning());
447 TEST(TimerTest
, NonRepeatMessageLoopDeath
) {
448 base::Timer
timer(false, false);
450 base::MessageLoop loop
;
451 EXPECT_FALSE(timer
.IsRunning());
452 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
453 base::Bind(&TimerTestCallback
));
454 EXPECT_TRUE(timer
.IsRunning());
456 EXPECT_FALSE(timer
.IsRunning());
457 EXPECT_TRUE(timer
.user_task().is_null());
460 TEST(TimerTest
, RetainRepeatIsRunning
) {
461 base::MessageLoop loop
;
462 base::Timer
timer(FROM_HERE
, TimeDelta::FromDays(1),
463 base::Bind(&TimerTestCallback
), true);
464 EXPECT_FALSE(timer
.IsRunning());
466 EXPECT_TRUE(timer
.IsRunning());
468 EXPECT_FALSE(timer
.IsRunning());
470 EXPECT_TRUE(timer
.IsRunning());
473 TEST(TimerTest
, RetainNonRepeatIsRunning
) {
474 base::MessageLoop loop
;
475 base::Timer
timer(FROM_HERE
, TimeDelta::FromDays(1),
476 base::Bind(&TimerTestCallback
), false);
477 EXPECT_FALSE(timer
.IsRunning());
479 EXPECT_TRUE(timer
.IsRunning());
481 EXPECT_FALSE(timer
.IsRunning());
483 EXPECT_TRUE(timer
.IsRunning());
488 bool g_callback_happened1
= false;
489 bool g_callback_happened2
= false;
491 void ClearAllCallbackHappened() {
492 g_callback_happened1
= false;
493 g_callback_happened2
= false;
496 void SetCallbackHappened1() {
497 g_callback_happened1
= true;
498 base::MessageLoop::current()->QuitWhenIdle();
501 void SetCallbackHappened2() {
502 g_callback_happened2
= true;
503 base::MessageLoop::current()->QuitWhenIdle();
506 TEST(TimerTest
, ContinuationStopStart
) {
508 ClearAllCallbackHappened();
509 base::MessageLoop loop
;
510 base::Timer
timer(false, false);
511 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(10),
512 base::Bind(&SetCallbackHappened1
));
514 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(40),
515 base::Bind(&SetCallbackHappened2
));
516 base::MessageLoop::current()->Run();
517 EXPECT_FALSE(g_callback_happened1
);
518 EXPECT_TRUE(g_callback_happened2
);
522 TEST(TimerTest
, ContinuationReset
) {
524 ClearAllCallbackHappened();
525 base::MessageLoop loop
;
526 base::Timer
timer(false, false);
527 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(10),
528 base::Bind(&SetCallbackHappened1
));
530 // Since Reset happened before task ran, the user_task must not be cleared:
531 ASSERT_FALSE(timer
.user_task().is_null());
532 base::MessageLoop::current()->Run();
533 EXPECT_TRUE(g_callback_happened1
);