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/timer/timer.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 using base::TimeDelta
;
14 // The message loops on which each timer should be tested.
15 const base::MessageLoop::Type testing_message_loops
[] = {
16 base::MessageLoop::TYPE_DEFAULT
,
17 base::MessageLoop::TYPE_IO
,
18 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
19 base::MessageLoop::TYPE_UI
,
23 const int kNumTestingMessageLoops
= arraysize(testing_message_loops
);
25 class OneShotTimerTester
{
27 explicit OneShotTimerTester(bool* did_run
, unsigned milliseconds
= 10)
29 delay_ms_(milliseconds
) {
32 timer_
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(delay_ms_
), this,
33 &OneShotTimerTester::Run
);
38 base::MessageLoop::current()->QuitWhenIdle();
41 base::OneShotTimer
<OneShotTimerTester
> timer_
;
42 const unsigned delay_ms_
;
45 class OneShotSelfDeletingTimerTester
{
47 explicit OneShotSelfDeletingTimerTester(bool* did_run
) :
49 timer_(new base::OneShotTimer
<OneShotSelfDeletingTimerTester
>()) {
52 timer_
->Start(FROM_HERE
, TimeDelta::FromMilliseconds(10), this,
53 &OneShotSelfDeletingTimerTester::Run
);
59 base::MessageLoop::current()->QuitWhenIdle();
62 scoped_ptr
<base::OneShotTimer
<OneShotSelfDeletingTimerTester
> > timer_
;
65 class RepeatingTimerTester
{
67 explicit RepeatingTimerTester(bool* did_run
, const TimeDelta
& delay
)
68 : did_run_(did_run
), counter_(10), delay_(delay
) {
72 timer_
.Start(FROM_HERE
, delay_
, this, &RepeatingTimerTester::Run
);
76 if (--counter_
== 0) {
79 base::MessageLoop::current()->QuitWhenIdle();
85 base::RepeatingTimer
<RepeatingTimerTester
> timer_
;
88 void RunTest_OneShotTimer(base::MessageLoop::Type message_loop_type
) {
89 base::MessageLoop
loop(message_loop_type
);
92 OneShotTimerTester
f(&did_run
);
95 base::MessageLoop::current()->Run();
100 void RunTest_OneShotTimer_Cancel(base::MessageLoop::Type message_loop_type
) {
101 base::MessageLoop
loop(message_loop_type
);
103 bool did_run_a
= false;
104 OneShotTimerTester
* a
= new OneShotTimerTester(&did_run_a
);
106 // This should run before the timer expires.
107 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
109 // Now start the timer.
112 bool did_run_b
= false;
113 OneShotTimerTester
b(&did_run_b
);
116 base::MessageLoop::current()->Run();
118 EXPECT_FALSE(did_run_a
);
119 EXPECT_TRUE(did_run_b
);
122 void RunTest_OneShotSelfDeletingTimer(
123 base::MessageLoop::Type message_loop_type
) {
124 base::MessageLoop
loop(message_loop_type
);
126 bool did_run
= false;
127 OneShotSelfDeletingTimerTester
f(&did_run
);
130 base::MessageLoop::current()->Run();
132 EXPECT_TRUE(did_run
);
135 void RunTest_RepeatingTimer(base::MessageLoop::Type message_loop_type
,
136 const TimeDelta
& delay
) {
137 base::MessageLoop
loop(message_loop_type
);
139 bool did_run
= false;
140 RepeatingTimerTester
f(&did_run
, delay
);
143 base::MessageLoop::current()->Run();
145 EXPECT_TRUE(did_run
);
148 void RunTest_RepeatingTimer_Cancel(base::MessageLoop::Type message_loop_type
,
149 const TimeDelta
& delay
) {
150 base::MessageLoop
loop(message_loop_type
);
152 bool did_run_a
= false;
153 RepeatingTimerTester
* a
= new RepeatingTimerTester(&did_run_a
, delay
);
155 // This should run before the timer expires.
156 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
158 // Now start the timer.
161 bool did_run_b
= false;
162 RepeatingTimerTester
b(&did_run_b
, delay
);
165 base::MessageLoop::current()->Run();
167 EXPECT_FALSE(did_run_a
);
168 EXPECT_TRUE(did_run_b
);
171 class DelayTimerTarget
{
177 bool signaled() const { return signaled_
; }
180 ASSERT_FALSE(signaled_
);
188 void RunTest_DelayTimer_NoCall(base::MessageLoop::Type message_loop_type
) {
189 base::MessageLoop
loop(message_loop_type
);
191 // If Delay is never called, the timer shouldn't go off.
192 DelayTimerTarget target
;
193 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
194 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
196 bool did_run
= false;
197 OneShotTimerTester
tester(&did_run
);
199 base::MessageLoop::current()->Run();
201 ASSERT_FALSE(target
.signaled());
204 void RunTest_DelayTimer_OneCall(base::MessageLoop::Type message_loop_type
) {
205 base::MessageLoop
loop(message_loop_type
);
207 DelayTimerTarget target
;
208 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
209 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
212 bool did_run
= false;
213 OneShotTimerTester
tester(&did_run
, 100 /* milliseconds */);
215 base::MessageLoop::current()->Run();
217 ASSERT_TRUE(target
.signaled());
221 ResetHelper(base::DelayTimer
<DelayTimerTarget
>* timer
,
222 DelayTimerTarget
* target
)
228 ASSERT_FALSE(target_
->signaled());
233 base::DelayTimer
<DelayTimerTarget
> *const timer_
;
234 DelayTimerTarget
*const target_
;
237 void RunTest_DelayTimer_Reset(base::MessageLoop::Type message_loop_type
) {
238 base::MessageLoop
loop(message_loop_type
);
240 // If Delay is never called, the timer shouldn't go off.
241 DelayTimerTarget target
;
242 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
243 TimeDelta::FromMilliseconds(50), &target
, &DelayTimerTarget::Signal
);
246 ResetHelper
reset_helper(&timer
, &target
);
248 base::OneShotTimer
<ResetHelper
> timers
[20];
249 for (size_t i
= 0; i
< arraysize(timers
); ++i
) {
250 timers
[i
].Start(FROM_HERE
, TimeDelta::FromMilliseconds(i
* 10),
251 &reset_helper
, &ResetHelper::Reset
);
254 bool did_run
= false;
255 OneShotTimerTester
tester(&did_run
, 300);
257 base::MessageLoop::current()->Run();
259 ASSERT_TRUE(target
.signaled());
262 class DelayTimerFatalTarget
{
270 void RunTest_DelayTimer_Deleted(base::MessageLoop::Type message_loop_type
) {
271 base::MessageLoop
loop(message_loop_type
);
273 DelayTimerFatalTarget target
;
276 base::DelayTimer
<DelayTimerFatalTarget
> timer(
277 FROM_HERE
, TimeDelta::FromMilliseconds(50), &target
,
278 &DelayTimerFatalTarget::Signal
);
282 // When the timer is deleted, the DelayTimerFatalTarget should never be
284 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
289 //-----------------------------------------------------------------------------
290 // Each test is run against each type of MessageLoop. That way we are sure
291 // that timers work properly in all configurations.
293 TEST(TimerTest
, OneShotTimer
) {
294 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
295 RunTest_OneShotTimer(testing_message_loops
[i
]);
299 TEST(TimerTest
, OneShotTimer_Cancel
) {
300 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
301 RunTest_OneShotTimer_Cancel(testing_message_loops
[i
]);
305 // If underline timer does not handle properly, we will crash or fail
306 // in full page heap environment.
307 TEST(TimerTest
, OneShotSelfDeletingTimer
) {
308 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
309 RunTest_OneShotSelfDeletingTimer(testing_message_loops
[i
]);
313 TEST(TimerTest
, RepeatingTimer
) {
314 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
315 RunTest_RepeatingTimer(testing_message_loops
[i
],
316 TimeDelta::FromMilliseconds(10));
320 TEST(TimerTest
, RepeatingTimer_Cancel
) {
321 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
322 RunTest_RepeatingTimer_Cancel(testing_message_loops
[i
],
323 TimeDelta::FromMilliseconds(10));
327 TEST(TimerTest
, RepeatingTimerZeroDelay
) {
328 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
329 RunTest_RepeatingTimer(testing_message_loops
[i
],
330 TimeDelta::FromMilliseconds(0));
334 TEST(TimerTest
, RepeatingTimerZeroDelay_Cancel
) {
335 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
336 RunTest_RepeatingTimer_Cancel(testing_message_loops
[i
],
337 TimeDelta::FromMilliseconds(0));
341 TEST(TimerTest
, DelayTimer_NoCall
) {
342 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
343 RunTest_DelayTimer_NoCall(testing_message_loops
[i
]);
347 TEST(TimerTest
, DelayTimer_OneCall
) {
348 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
349 RunTest_DelayTimer_OneCall(testing_message_loops
[i
]);
353 // It's flaky on the buildbot, http://crbug.com/25038.
354 TEST(TimerTest
, DISABLED_DelayTimer_Reset
) {
355 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
356 RunTest_DelayTimer_Reset(testing_message_loops
[i
]);
360 TEST(TimerTest
, DelayTimer_Deleted
) {
361 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
362 RunTest_DelayTimer_Deleted(testing_message_loops
[i
]);
366 TEST(TimerTest
, MessageLoopShutdown
) {
367 // This test is designed to verify that shutdown of the
368 // message loop does not cause crashes if there were pending
369 // timers not yet fired. It may only trigger exceptions
370 // if debug heap checking is enabled.
371 bool did_run
= false;
373 OneShotTimerTester
a(&did_run
);
374 OneShotTimerTester
b(&did_run
);
375 OneShotTimerTester
c(&did_run
);
376 OneShotTimerTester
d(&did_run
);
378 base::MessageLoop loop
;
381 } // MessageLoop destructs by falling out of scope.
382 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
384 EXPECT_FALSE(did_run
);
387 void TimerTestCallback() {
390 TEST(TimerTest
, NonRepeatIsRunning
) {
392 base::MessageLoop loop
;
393 base::Timer
timer(false, false);
394 EXPECT_FALSE(timer
.IsRunning());
395 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
396 base::Bind(&TimerTestCallback
));
397 EXPECT_TRUE(timer
.IsRunning());
399 EXPECT_FALSE(timer
.IsRunning());
400 EXPECT_TRUE(timer
.user_task().is_null());
404 base::Timer
timer(true, false);
405 base::MessageLoop loop
;
406 EXPECT_FALSE(timer
.IsRunning());
407 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
408 base::Bind(&TimerTestCallback
));
409 EXPECT_TRUE(timer
.IsRunning());
411 EXPECT_FALSE(timer
.IsRunning());
412 ASSERT_FALSE(timer
.user_task().is_null());
414 EXPECT_TRUE(timer
.IsRunning());
418 TEST(TimerTest
, NonRepeatMessageLoopDeath
) {
419 base::Timer
timer(false, false);
421 base::MessageLoop loop
;
422 EXPECT_FALSE(timer
.IsRunning());
423 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
424 base::Bind(&TimerTestCallback
));
425 EXPECT_TRUE(timer
.IsRunning());
427 EXPECT_FALSE(timer
.IsRunning());
428 EXPECT_TRUE(timer
.user_task().is_null());
431 TEST(TimerTest
, RetainRepeatIsRunning
) {
432 base::MessageLoop loop
;
433 base::Timer
timer(FROM_HERE
, TimeDelta::FromDays(1),
434 base::Bind(&TimerTestCallback
), true);
435 EXPECT_FALSE(timer
.IsRunning());
437 EXPECT_TRUE(timer
.IsRunning());
439 EXPECT_FALSE(timer
.IsRunning());
441 EXPECT_TRUE(timer
.IsRunning());
444 TEST(TimerTest
, RetainNonRepeatIsRunning
) {
445 base::MessageLoop loop
;
446 base::Timer
timer(FROM_HERE
, TimeDelta::FromDays(1),
447 base::Bind(&TimerTestCallback
), false);
448 EXPECT_FALSE(timer
.IsRunning());
450 EXPECT_TRUE(timer
.IsRunning());
452 EXPECT_FALSE(timer
.IsRunning());
454 EXPECT_TRUE(timer
.IsRunning());
459 bool g_callback_happened1
= false;
460 bool g_callback_happened2
= false;
462 void ClearAllCallbackHappened() {
463 g_callback_happened1
= false;
464 g_callback_happened2
= false;
467 void SetCallbackHappened1() {
468 g_callback_happened1
= true;
469 base::MessageLoop::current()->QuitWhenIdle();
472 void SetCallbackHappened2() {
473 g_callback_happened2
= true;
474 base::MessageLoop::current()->QuitWhenIdle();
477 TEST(TimerTest
, ContinuationStopStart
) {
479 ClearAllCallbackHappened();
480 base::MessageLoop loop
;
481 base::Timer
timer(false, false);
482 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(10),
483 base::Bind(&SetCallbackHappened1
));
485 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(40),
486 base::Bind(&SetCallbackHappened2
));
487 base::MessageLoop::current()->Run();
488 EXPECT_FALSE(g_callback_happened1
);
489 EXPECT_TRUE(g_callback_happened2
);
493 TEST(TimerTest
, ContinuationReset
) {
495 ClearAllCallbackHappened();
496 base::MessageLoop loop
;
497 base::Timer
timer(false, false);
498 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(10),
499 base::Bind(&SetCallbackHappened1
));
501 // Since Reset happened before task ran, the user_task must not be cleared:
502 ASSERT_FALSE(timer
.user_task().is_null());
503 base::MessageLoop::current()->Run();
504 EXPECT_TRUE(g_callback_happened1
);