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 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
)
68 : did_run_(did_run
), counter_(10) {
72 timer_
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(10), this,
73 &RepeatingTimerTester::Run
);
77 if (--counter_
== 0) {
79 base::MessageLoop::current()->QuitWhenIdle();
84 base::RepeatingTimer
<RepeatingTimerTester
> timer_
;
87 void RunTest_OneShotTimer(base::MessageLoop::Type message_loop_type
) {
88 base::MessageLoop
loop(message_loop_type
);
91 OneShotTimerTester
f(&did_run
);
94 base::MessageLoop::current()->Run();
99 void RunTest_OneShotTimer_Cancel(base::MessageLoop::Type message_loop_type
) {
100 base::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 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
108 // Now start the timer.
111 bool did_run_b
= false;
112 OneShotTimerTester
b(&did_run_b
);
115 base::MessageLoop::current()->Run();
117 EXPECT_FALSE(did_run_a
);
118 EXPECT_TRUE(did_run_b
);
121 void RunTest_OneShotSelfDeletingTimer(
122 base::MessageLoop::Type message_loop_type
) {
123 base::MessageLoop
loop(message_loop_type
);
125 bool did_run
= false;
126 OneShotSelfDeletingTimerTester
f(&did_run
);
129 base::MessageLoop::current()->Run();
131 EXPECT_TRUE(did_run
);
134 void RunTest_RepeatingTimer(base::MessageLoop::Type message_loop_type
) {
135 base::MessageLoop
loop(message_loop_type
);
137 bool did_run
= false;
138 RepeatingTimerTester
f(&did_run
);
141 base::MessageLoop::current()->Run();
143 EXPECT_TRUE(did_run
);
146 void RunTest_RepeatingTimer_Cancel(base::MessageLoop::Type message_loop_type
) {
147 base::MessageLoop
loop(message_loop_type
);
149 bool did_run_a
= false;
150 RepeatingTimerTester
* a
= new RepeatingTimerTester(&did_run_a
);
152 // This should run before the timer expires.
153 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
155 // Now start the timer.
158 bool did_run_b
= false;
159 RepeatingTimerTester
b(&did_run_b
);
162 base::MessageLoop::current()->Run();
164 EXPECT_FALSE(did_run_a
);
165 EXPECT_TRUE(did_run_b
);
168 class DelayTimerTarget
{
174 bool signaled() const { return signaled_
; }
177 ASSERT_FALSE(signaled_
);
185 void RunTest_DelayTimer_NoCall(base::MessageLoop::Type message_loop_type
) {
186 base::MessageLoop
loop(message_loop_type
);
188 // If Delay is never called, the timer shouldn't go off.
189 DelayTimerTarget target
;
190 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
191 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
193 bool did_run
= false;
194 OneShotTimerTester
tester(&did_run
);
196 base::MessageLoop::current()->Run();
198 ASSERT_FALSE(target
.signaled());
201 void RunTest_DelayTimer_OneCall(base::MessageLoop::Type message_loop_type
) {
202 base::MessageLoop
loop(message_loop_type
);
204 DelayTimerTarget target
;
205 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
206 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
209 bool did_run
= false;
210 OneShotTimerTester
tester(&did_run
, 100 /* milliseconds */);
212 base::MessageLoop::current()->Run();
214 ASSERT_TRUE(target
.signaled());
218 ResetHelper(base::DelayTimer
<DelayTimerTarget
>* timer
,
219 DelayTimerTarget
* target
)
225 ASSERT_FALSE(target_
->signaled());
230 base::DelayTimer
<DelayTimerTarget
> *const timer_
;
231 DelayTimerTarget
*const target_
;
234 void RunTest_DelayTimer_Reset(base::MessageLoop::Type message_loop_type
) {
235 base::MessageLoop
loop(message_loop_type
);
237 // If Delay is never called, the timer shouldn't go off.
238 DelayTimerTarget target
;
239 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
240 TimeDelta::FromMilliseconds(50), &target
, &DelayTimerTarget::Signal
);
243 ResetHelper
reset_helper(&timer
, &target
);
245 base::OneShotTimer
<ResetHelper
> timers
[20];
246 for (size_t i
= 0; i
< arraysize(timers
); ++i
) {
247 timers
[i
].Start(FROM_HERE
, TimeDelta::FromMilliseconds(i
* 10),
248 &reset_helper
, &ResetHelper::Reset
);
251 bool did_run
= false;
252 OneShotTimerTester
tester(&did_run
, 300);
254 base::MessageLoop::current()->Run();
256 ASSERT_TRUE(target
.signaled());
259 class DelayTimerFatalTarget
{
267 void RunTest_DelayTimer_Deleted(base::MessageLoop::Type message_loop_type
) {
268 base::MessageLoop
loop(message_loop_type
);
270 DelayTimerFatalTarget target
;
273 base::DelayTimer
<DelayTimerFatalTarget
> timer(
274 FROM_HERE
, TimeDelta::FromMilliseconds(50), &target
,
275 &DelayTimerFatalTarget::Signal
);
279 // When the timer is deleted, the DelayTimerFatalTarget should never be
281 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
286 //-----------------------------------------------------------------------------
287 // Each test is run against each type of MessageLoop. That way we are sure
288 // that timers work properly in all configurations.
290 TEST(TimerTest
, OneShotTimer
) {
291 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
292 RunTest_OneShotTimer(testing_message_loops
[i
]);
296 TEST(TimerTest
, OneShotTimer_Cancel
) {
297 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
298 RunTest_OneShotTimer_Cancel(testing_message_loops
[i
]);
302 // If underline timer does not handle properly, we will crash or fail
303 // in full page heap environment.
304 TEST(TimerTest
, OneShotSelfDeletingTimer
) {
305 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
306 RunTest_OneShotSelfDeletingTimer(testing_message_loops
[i
]);
310 TEST(TimerTest
, RepeatingTimer
) {
311 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
312 RunTest_RepeatingTimer(testing_message_loops
[i
]);
316 TEST(TimerTest
, RepeatingTimer_Cancel
) {
317 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
318 RunTest_RepeatingTimer_Cancel(testing_message_loops
[i
]);
322 TEST(TimerTest
, DelayTimer_NoCall
) {
323 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
324 RunTest_DelayTimer_NoCall(testing_message_loops
[i
]);
328 TEST(TimerTest
, DelayTimer_OneCall
) {
329 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
330 RunTest_DelayTimer_OneCall(testing_message_loops
[i
]);
334 // It's flaky on the buildbot, http://crbug.com/25038.
335 TEST(TimerTest
, DISABLED_DelayTimer_Reset
) {
336 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
337 RunTest_DelayTimer_Reset(testing_message_loops
[i
]);
341 TEST(TimerTest
, DelayTimer_Deleted
) {
342 for (int i
= 0; i
< kNumTestingMessageLoops
; i
++) {
343 RunTest_DelayTimer_Deleted(testing_message_loops
[i
]);
347 TEST(TimerTest
, MessageLoopShutdown
) {
348 // This test is designed to verify that shutdown of the
349 // message loop does not cause crashes if there were pending
350 // timers not yet fired. It may only trigger exceptions
351 // if debug heap checking is enabled.
352 bool did_run
= false;
354 OneShotTimerTester
a(&did_run
);
355 OneShotTimerTester
b(&did_run
);
356 OneShotTimerTester
c(&did_run
);
357 OneShotTimerTester
d(&did_run
);
359 base::MessageLoop
loop(base::MessageLoop::TYPE_DEFAULT
);
362 } // MessageLoop destructs by falling out of scope.
363 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
365 EXPECT_FALSE(did_run
);
368 void TimerTestCallback() {
371 TEST(TimerTest
, NonRepeatIsRunning
) {
373 base::MessageLoop
loop(base::MessageLoop::TYPE_DEFAULT
);
374 base::Timer
timer(false, false);
375 EXPECT_FALSE(timer
.IsRunning());
376 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
377 base::Bind(&TimerTestCallback
));
378 EXPECT_TRUE(timer
.IsRunning());
380 EXPECT_FALSE(timer
.IsRunning());
381 EXPECT_TRUE(timer
.user_task().is_null());
385 base::Timer
timer(true, false);
386 base::MessageLoop
loop(base::MessageLoop::TYPE_DEFAULT
);
387 EXPECT_FALSE(timer
.IsRunning());
388 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
389 base::Bind(&TimerTestCallback
));
390 EXPECT_TRUE(timer
.IsRunning());
392 EXPECT_FALSE(timer
.IsRunning());
393 ASSERT_FALSE(timer
.user_task().is_null());
395 EXPECT_TRUE(timer
.IsRunning());
399 TEST(TimerTest
, NonRepeatMessageLoopDeath
) {
400 base::Timer
timer(false, false);
402 base::MessageLoop
loop(base::MessageLoop::TYPE_DEFAULT
);
403 EXPECT_FALSE(timer
.IsRunning());
404 timer
.Start(FROM_HERE
, TimeDelta::FromDays(1),
405 base::Bind(&TimerTestCallback
));
406 EXPECT_TRUE(timer
.IsRunning());
408 EXPECT_FALSE(timer
.IsRunning());
409 EXPECT_TRUE(timer
.user_task().is_null());
412 TEST(TimerTest
, RetainRepeatIsRunning
) {
413 base::MessageLoop
loop(base::MessageLoop::TYPE_DEFAULT
);
414 base::Timer
timer(FROM_HERE
, TimeDelta::FromDays(1),
415 base::Bind(&TimerTestCallback
), true);
416 EXPECT_FALSE(timer
.IsRunning());
418 EXPECT_TRUE(timer
.IsRunning());
420 EXPECT_FALSE(timer
.IsRunning());
422 EXPECT_TRUE(timer
.IsRunning());
425 TEST(TimerTest
, RetainNonRepeatIsRunning
) {
426 base::MessageLoop
loop(base::MessageLoop::TYPE_DEFAULT
);
427 base::Timer
timer(FROM_HERE
, TimeDelta::FromDays(1),
428 base::Bind(&TimerTestCallback
), false);
429 EXPECT_FALSE(timer
.IsRunning());
431 EXPECT_TRUE(timer
.IsRunning());
433 EXPECT_FALSE(timer
.IsRunning());
435 EXPECT_TRUE(timer
.IsRunning());
440 bool g_callback_happened1
= false;
441 bool g_callback_happened2
= false;
443 void ClearAllCallbackHappened() {
444 g_callback_happened1
= false;
445 g_callback_happened2
= false;
448 void SetCallbackHappened1() {
449 g_callback_happened1
= true;
450 base::MessageLoop::current()->QuitWhenIdle();
453 void SetCallbackHappened2() {
454 g_callback_happened2
= true;
455 base::MessageLoop::current()->QuitWhenIdle();
458 TEST(TimerTest
, ContinuationStopStart
) {
460 ClearAllCallbackHappened();
461 base::MessageLoop
loop(base::MessageLoop::TYPE_DEFAULT
);
462 base::Timer
timer(false, false);
463 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(10),
464 base::Bind(&SetCallbackHappened1
));
466 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(40),
467 base::Bind(&SetCallbackHappened2
));
468 base::MessageLoop::current()->Run();
469 EXPECT_FALSE(g_callback_happened1
);
470 EXPECT_TRUE(g_callback_happened2
);
474 TEST(TimerTest
, ContinuationReset
) {
476 ClearAllCallbackHappened();
477 base::MessageLoop
loop(base::MessageLoop::TYPE_DEFAULT
);
478 base::Timer
timer(false, false);
479 timer
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(10),
480 base::Bind(&SetCallbackHappened1
));
482 // Since Reset happened before task ran, the user_task must not be cleared:
483 ASSERT_FALSE(timer
.user_task().is_null());
484 base::MessageLoop::current()->Run();
485 EXPECT_TRUE(g_callback_happened1
);