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.h"
7 #include "base/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 MessageLoop::Type testing_message_loops
[] = {
16 MessageLoop::TYPE_DEFAULT
,
18 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
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 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 MessageLoop::current()->QuitWhenIdle();
62 scoped_ptr
<base::OneShotTimer
<OneShotSelfDeletingTimerTester
> > timer_
;
65 class RepeatingTimerTester
{
67 explicit RepeatingTimerTester(bool* did_run
)
68 : did_run_(did_run
), counter_(10) {
72 timer_
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(10), this,
73 &RepeatingTimerTester::Run
);
77 if (--counter_
== 0) {
79 MessageLoop::current()->QuitWhenIdle();
84 base::RepeatingTimer
<RepeatingTimerTester
> timer_
;
87 void RunTest_OneShotTimer(MessageLoop::Type message_loop_type
) {
88 MessageLoop
loop(message_loop_type
);
91 OneShotTimerTester
f(&did_run
);
94 MessageLoop::current()->Run();
99 void RunTest_OneShotTimer_Cancel(MessageLoop::Type message_loop_type
) {
100 MessageLoop
loop(message_loop_type
);
102 bool did_run_a
= false;
103 OneShotTimerTester
* a
= new OneShotTimerTester(&did_run_a
);
105 // This should run before the timer expires.
106 MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
108 // Now start the timer.
111 bool did_run_b
= false;
112 OneShotTimerTester
b(&did_run_b
);
115 MessageLoop::current()->Run();
117 EXPECT_FALSE(did_run_a
);
118 EXPECT_TRUE(did_run_b
);
121 void RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type
) {
122 MessageLoop
loop(message_loop_type
);
124 bool did_run
= false;
125 OneShotSelfDeletingTimerTester
f(&did_run
);
128 MessageLoop::current()->Run();
130 EXPECT_TRUE(did_run
);
133 void RunTest_RepeatingTimer(MessageLoop::Type message_loop_type
) {
134 MessageLoop
loop(message_loop_type
);
136 bool did_run
= false;
137 RepeatingTimerTester
f(&did_run
);
140 MessageLoop::current()->Run();
142 EXPECT_TRUE(did_run
);
145 void RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type
) {
146 MessageLoop
loop(message_loop_type
);
148 bool did_run_a
= false;
149 RepeatingTimerTester
* a
= new RepeatingTimerTester(&did_run_a
);
151 // This should run before the timer expires.
152 MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
154 // Now start the timer.
157 bool did_run_b
= false;
158 RepeatingTimerTester
b(&did_run_b
);
161 MessageLoop::current()->Run();
163 EXPECT_FALSE(did_run_a
);
164 EXPECT_TRUE(did_run_b
);
167 class DelayTimerTarget
{
173 bool signaled() const { return signaled_
; }
176 ASSERT_FALSE(signaled_
);
184 void RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type
) {
185 MessageLoop
loop(message_loop_type
);
187 // If Delay is never called, the timer shouldn't go off.
188 DelayTimerTarget target
;
189 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
190 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
192 bool did_run
= false;
193 OneShotTimerTester
tester(&did_run
);
195 MessageLoop::current()->Run();
197 ASSERT_FALSE(target
.signaled());
200 void RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type
) {
201 MessageLoop
loop(message_loop_type
);
203 DelayTimerTarget target
;
204 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
205 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
208 bool did_run
= false;
209 OneShotTimerTester
tester(&did_run
, 100 /* milliseconds */);
211 MessageLoop::current()->Run();
213 ASSERT_TRUE(target
.signaled());
217 ResetHelper(base::DelayTimer
<DelayTimerTarget
>* timer
,
218 DelayTimerTarget
* target
)
224 ASSERT_FALSE(target_
->signaled());
229 base::DelayTimer
<DelayTimerTarget
> *const timer_
;
230 DelayTimerTarget
*const target_
;
233 void RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type
) {
234 MessageLoop
loop(message_loop_type
);
236 // If Delay is never called, the timer shouldn't go off.
237 DelayTimerTarget target
;
238 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
239 TimeDelta::FromMilliseconds(50), &target
, &DelayTimerTarget::Signal
);
242 ResetHelper
reset_helper(&timer
, &target
);
244 base::OneShotTimer
<ResetHelper
> timers
[20];
245 for (size_t i
= 0; i
< arraysize(timers
); ++i
) {
246 timers
[i
].Start(FROM_HERE
, TimeDelta::FromMilliseconds(i
* 10),
247 &reset_helper
, &ResetHelper::Reset
);
250 bool did_run
= false;
251 OneShotTimerTester
tester(&did_run
, 300);
253 MessageLoop::current()->Run();
255 ASSERT_TRUE(target
.signaled());
258 class DelayTimerFatalTarget
{
266 void RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type
) {
267 MessageLoop
loop(message_loop_type
);
269 DelayTimerFatalTarget target
;
272 base::DelayTimer
<DelayTimerFatalTarget
> timer(
273 FROM_HERE
, TimeDelta::FromMilliseconds(50), &target
,
274 &DelayTimerFatalTarget::Signal
);
278 // When the timer is deleted, the DelayTimerFatalTarget should never be
280 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
285 //-----------------------------------------------------------------------------
286 // Each test is run against each type of MessageLoop. That way we are sure
287 // that timers work properly in all configurations.
289 TEST(TimerTest
, OneShotTimer
) {
290 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
291 RunTest_OneShotTimer(testing_message_loops
[i
]);
295 TEST(TimerTest
, OneShotTimer_Cancel
) {
296 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
297 RunTest_OneShotTimer_Cancel(testing_message_loops
[i
]);
301 // If underline timer does not handle properly, we will crash or fail
302 // in full page heap environment.
303 TEST(TimerTest
, OneShotSelfDeletingTimer
) {
304 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
305 RunTest_OneShotSelfDeletingTimer(testing_message_loops
[i
]);
309 TEST(TimerTest
, RepeatingTimer
) {
310 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
311 RunTest_RepeatingTimer(testing_message_loops
[i
]);
315 TEST(TimerTest
, RepeatingTimer_Cancel
) {
316 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
317 RunTest_RepeatingTimer_Cancel(testing_message_loops
[i
]);
321 TEST(TimerTest
, DelayTimer_NoCall
) {
322 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
323 RunTest_DelayTimer_NoCall(testing_message_loops
[i
]);
327 TEST(TimerTest
, DelayTimer_OneCall
) {
328 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
329 RunTest_DelayTimer_OneCall(testing_message_loops
[i
]);
333 // It's flaky on the buildbot, http://crbug.com/25038.
334 TEST(TimerTest
, DISABLED_DelayTimer_Reset
) {
335 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
336 RunTest_DelayTimer_Reset(testing_message_loops
[i
]);
340 TEST(TimerTest
, DelayTimer_Deleted
) {
341 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
342 RunTest_DelayTimer_Deleted(testing_message_loops
[i
]);
346 TEST(TimerTest
, MessageLoopShutdown
) {
347 // This test is designed to verify that shutdown of the
348 // message loop does not cause crashes if there were pending
349 // timers not yet fired. It may only trigger exceptions
350 // if debug heap checking is enabled.
351 bool did_run
= false;
353 OneShotTimerTester
a(&did_run
);
354 OneShotTimerTester
b(&did_run
);
355 OneShotTimerTester
c(&did_run
);
356 OneShotTimerTester
d(&did_run
);
358 MessageLoop
loop(MessageLoop::TYPE_DEFAULT
);
361 } // MessageLoop destructs by falling out of scope.
362 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
364 EXPECT_FALSE(did_run
);
367 void TimerTestCallback() {
370 TEST(TimerTest
, NonRepeatIsRunning
) {
372 MessageLoop
loop(MessageLoop::TYPE_DEFAULT
);
373 base::Timer
timer(false, false);
374 EXPECT_FALSE(timer
.IsRunning());
375 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
376 base::Bind(&TimerTestCallback
));
377 EXPECT_TRUE(timer
.IsRunning());
379 EXPECT_FALSE(timer
.IsRunning());
380 EXPECT_TRUE(timer
.user_task().is_null());
384 base::Timer
timer(true, false);
385 MessageLoop
loop(MessageLoop::TYPE_DEFAULT
);
386 EXPECT_FALSE(timer
.IsRunning());
387 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
388 base::Bind(&TimerTestCallback
));
389 EXPECT_TRUE(timer
.IsRunning());
391 EXPECT_FALSE(timer
.IsRunning());
392 ASSERT_FALSE(timer
.user_task().is_null());
394 EXPECT_TRUE(timer
.IsRunning());
398 TEST(TimerTest
, NonRepeatMessageLoopDeath
) {
399 base::Timer
timer(false, false);
401 MessageLoop
loop(MessageLoop::TYPE_DEFAULT
);
402 EXPECT_FALSE(timer
.IsRunning());
403 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
404 base::Bind(&TimerTestCallback
));
405 EXPECT_TRUE(timer
.IsRunning());
407 EXPECT_FALSE(timer
.IsRunning());
408 EXPECT_TRUE(timer
.user_task().is_null());
411 TEST(TimerTest
, RetainRepeatIsRunning
) {
412 MessageLoop
loop(MessageLoop::TYPE_DEFAULT
);
413 base::Timer
timer(FROM_HERE
, TimeDelta::FromDays(1),
414 base::Bind(&TimerTestCallback
), true);
415 EXPECT_FALSE(timer
.IsRunning());
417 EXPECT_TRUE(timer
.IsRunning());
419 EXPECT_FALSE(timer
.IsRunning());
421 EXPECT_TRUE(timer
.IsRunning());
424 TEST(TimerTest
, RetainNonRepeatIsRunning
) {
425 MessageLoop
loop(MessageLoop::TYPE_DEFAULT
);
426 base::Timer
timer(FROM_HERE
, TimeDelta::FromDays(1),
427 base::Bind(&TimerTestCallback
), false);
428 EXPECT_FALSE(timer
.IsRunning());
430 EXPECT_TRUE(timer
.IsRunning());
432 EXPECT_FALSE(timer
.IsRunning());
434 EXPECT_TRUE(timer
.IsRunning());
439 bool g_callback_happened1
= false;
440 bool g_callback_happened2
= false;
442 void ClearAllCallbackHappened() {
443 g_callback_happened1
= false;
444 g_callback_happened2
= false;
447 void SetCallbackHappened1() {
448 g_callback_happened1
= true;
449 MessageLoop::current()->QuitWhenIdle();
452 void SetCallbackHappened2() {
453 g_callback_happened2
= true;
454 MessageLoop::current()->QuitWhenIdle();
457 TEST(TimerTest
, ContinuationStopStart
) {
459 ClearAllCallbackHappened();
460 MessageLoop
loop(MessageLoop::TYPE_DEFAULT
);
461 base::Timer
timer(false, false);
462 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(10),
463 base::Bind(&SetCallbackHappened1
));
465 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(40),
466 base::Bind(&SetCallbackHappened2
));
467 MessageLoop::current()->Run();
468 EXPECT_FALSE(g_callback_happened1
);
469 EXPECT_TRUE(g_callback_happened2
);
473 TEST(TimerTest
, ContinuationReset
) {
475 ClearAllCallbackHappened();
476 MessageLoop
loop(MessageLoop::TYPE_DEFAULT
);
477 base::Timer
timer(false, false);
478 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(10),
479 base::Bind(&SetCallbackHappened1
));
481 // Since Reset happened before task ran, the user_task must not be cleared:
482 ASSERT_FALSE(timer
.user_task().is_null());
483 MessageLoop::current()->Run();
484 EXPECT_TRUE(g_callback_happened1
);