1 // Copyright (c) 2006-2008 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/message_loop.h"
6 #include "base/scoped_ptr.h"
8 #include "base/timer.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 using base::TimeDelta
;
15 class OneShotTimerTester
{
17 OneShotTimerTester(bool* did_run
, unsigned milliseconds
= 10)
19 delay_ms_(milliseconds
) {
22 timer_
.Start(TimeDelta::FromMilliseconds(delay_ms_
), this,
23 &OneShotTimerTester::Run
);
28 MessageLoop::current()->Quit();
31 base::OneShotTimer
<OneShotTimerTester
> timer_
;
32 const unsigned delay_ms_
;
35 class OneShotSelfDeletingTimerTester
{
37 explicit OneShotSelfDeletingTimerTester(bool* did_run
) :
39 timer_(new base::OneShotTimer
<OneShotSelfDeletingTimerTester
>()) {
42 timer_
->Start(TimeDelta::FromMilliseconds(10), this,
43 &OneShotSelfDeletingTimerTester::Run
);
49 MessageLoop::current()->Quit();
52 scoped_ptr
<base::OneShotTimer
<OneShotSelfDeletingTimerTester
> > timer_
;
55 class RepeatingTimerTester
{
57 explicit RepeatingTimerTester(bool* did_run
)
58 : did_run_(did_run
), counter_(10) {
62 timer_
.Start(TimeDelta::FromMilliseconds(10), this,
63 &RepeatingTimerTester::Run
);
67 if (--counter_
== 0) {
69 MessageLoop::current()->Quit();
74 base::RepeatingTimer
<RepeatingTimerTester
> timer_
;
77 void RunTest_OneShotTimer(MessageLoop::Type message_loop_type
) {
78 MessageLoop
loop(message_loop_type
);
81 OneShotTimerTester
f(&did_run
);
84 MessageLoop::current()->Run();
89 void RunTest_OneShotTimer_Cancel(MessageLoop::Type message_loop_type
) {
90 MessageLoop
loop(message_loop_type
);
92 bool did_run_a
= false;
93 OneShotTimerTester
* a
= new OneShotTimerTester(&did_run_a
);
95 // This should run before the timer expires.
96 MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
98 // Now start the timer.
101 bool did_run_b
= false;
102 OneShotTimerTester
b(&did_run_b
);
105 MessageLoop::current()->Run();
107 EXPECT_FALSE(did_run_a
);
108 EXPECT_TRUE(did_run_b
);
111 void RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type
) {
112 MessageLoop
loop(message_loop_type
);
114 bool did_run
= false;
115 OneShotSelfDeletingTimerTester
f(&did_run
);
118 MessageLoop::current()->Run();
120 EXPECT_TRUE(did_run
);
123 void RunTest_RepeatingTimer(MessageLoop::Type message_loop_type
) {
124 MessageLoop
loop(message_loop_type
);
126 bool did_run
= false;
127 RepeatingTimerTester
f(&did_run
);
130 MessageLoop::current()->Run();
132 EXPECT_TRUE(did_run
);
135 void RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type
) {
136 MessageLoop
loop(message_loop_type
);
138 bool did_run_a
= false;
139 RepeatingTimerTester
* a
= new RepeatingTimerTester(&did_run_a
);
141 // This should run before the timer expires.
142 MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
144 // Now start the timer.
147 bool did_run_b
= false;
148 RepeatingTimerTester
b(&did_run_b
);
151 MessageLoop::current()->Run();
153 EXPECT_FALSE(did_run_a
);
154 EXPECT_TRUE(did_run_b
);
157 class DelayTimerTarget
{
163 bool signaled() const { return signaled_
; }
166 ASSERT_FALSE(signaled_
);
174 void RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type
) {
175 MessageLoop
loop(message_loop_type
);
177 // If Delay is never called, the timer shouldn't go off.
178 DelayTimerTarget target
;
179 base::DelayTimer
<DelayTimerTarget
> timer(
180 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
182 bool did_run
= false;
183 OneShotTimerTester
tester(&did_run
);
185 MessageLoop::current()->Run();
187 ASSERT_FALSE(target
.signaled());
190 void RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type
) {
191 MessageLoop
loop(message_loop_type
);
193 DelayTimerTarget target
;
194 base::DelayTimer
<DelayTimerTarget
> timer(
195 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
198 bool did_run
= false;
199 OneShotTimerTester
tester(&did_run
, 100 /* milliseconds */);
201 MessageLoop::current()->Run();
203 ASSERT_TRUE(target
.signaled());
207 ResetHelper(base::DelayTimer
<DelayTimerTarget
>* timer
,
208 DelayTimerTarget
* target
)
214 ASSERT_FALSE(target_
->signaled());
219 base::DelayTimer
<DelayTimerTarget
> *const timer_
;
220 DelayTimerTarget
*const target_
;
223 void RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type
) {
224 MessageLoop
loop(message_loop_type
);
226 // If Delay is never called, the timer shouldn't go off.
227 DelayTimerTarget target
;
228 base::DelayTimer
<DelayTimerTarget
> timer(
229 TimeDelta::FromMilliseconds(50), &target
, &DelayTimerTarget::Signal
);
232 ResetHelper
reset_helper(&timer
, &target
);
234 base::OneShotTimer
<ResetHelper
> timers
[20];
235 for (size_t i
= 0; i
< arraysize(timers
); ++i
) {
236 timers
[i
].Start(TimeDelta::FromMilliseconds(i
* 10), &reset_helper
,
237 &ResetHelper::Reset
);
240 bool did_run
= false;
241 OneShotTimerTester
tester(&did_run
, 300);
243 MessageLoop::current()->Run();
245 ASSERT_TRUE(target
.signaled());
248 class DelayTimerFatalTarget
{
256 void RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type
) {
257 MessageLoop
loop(message_loop_type
);
259 DelayTimerFatalTarget target
;
262 base::DelayTimer
<DelayTimerFatalTarget
> timer(
263 TimeDelta::FromMilliseconds(50), &target
,
264 &DelayTimerFatalTarget::Signal
);
268 // When the timer is deleted, the DelayTimerFatalTarget should never be
270 PlatformThread::Sleep(100);
275 //-----------------------------------------------------------------------------
276 // Each test is run against each type of MessageLoop. That way we are sure
277 // that timers work properly in all configurations.
279 TEST(TimerTest
, OneShotTimer
) {
280 RunTest_OneShotTimer(MessageLoop::TYPE_DEFAULT
);
281 RunTest_OneShotTimer(MessageLoop::TYPE_UI
);
282 RunTest_OneShotTimer(MessageLoop::TYPE_IO
);
285 TEST(TimerTest
, OneShotTimer_Cancel
) {
286 RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_DEFAULT
);
287 RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_UI
);
288 RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_IO
);
291 // If underline timer does not handle properly, we will crash or fail
292 // in full page heap or purify environment.
293 TEST(TimerTest
, OneShotSelfDeletingTimer
) {
294 RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_DEFAULT
);
295 RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_UI
);
296 RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_IO
);
299 TEST(TimerTest
, RepeatingTimer
) {
300 RunTest_RepeatingTimer(MessageLoop::TYPE_DEFAULT
);
301 RunTest_RepeatingTimer(MessageLoop::TYPE_UI
);
302 RunTest_RepeatingTimer(MessageLoop::TYPE_IO
);
305 TEST(TimerTest
, RepeatingTimer_Cancel
) {
306 RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_DEFAULT
);
307 RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_UI
);
308 RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_IO
);
311 TEST(TimerTest
, DelayTimer_NoCall
) {
312 RunTest_DelayTimer_NoCall(MessageLoop::TYPE_DEFAULT
);
313 RunTest_DelayTimer_NoCall(MessageLoop::TYPE_UI
);
314 RunTest_DelayTimer_NoCall(MessageLoop::TYPE_IO
);
317 TEST(TimerTest
, DelayTimer_OneCall
) {
318 RunTest_DelayTimer_OneCall(MessageLoop::TYPE_DEFAULT
);
319 RunTest_DelayTimer_OneCall(MessageLoop::TYPE_UI
);
320 RunTest_DelayTimer_OneCall(MessageLoop::TYPE_IO
);
323 // It's flaky on the buildbot, http://crbug.com/25038.
324 TEST(TimerTest
, FLAKY_DelayTimer_Reset
) {
325 RunTest_DelayTimer_Reset(MessageLoop::TYPE_DEFAULT
);
326 RunTest_DelayTimer_Reset(MessageLoop::TYPE_UI
);
327 RunTest_DelayTimer_Reset(MessageLoop::TYPE_IO
);
330 TEST(TimerTest
, DelayTimer_Deleted
) {
331 RunTest_DelayTimer_Deleted(MessageLoop::TYPE_DEFAULT
);
332 RunTest_DelayTimer_Deleted(MessageLoop::TYPE_UI
);
333 RunTest_DelayTimer_Deleted(MessageLoop::TYPE_IO
);
336 TEST(TimerTest
, MessageLoopShutdown
) {
337 // This test is designed to verify that shutdown of the
338 // message loop does not cause crashes if there were pending
339 // timers not yet fired. It may only trigger exceptions
340 // if debug heap checking (or purify) is enabled.
341 bool did_run
= false;
343 OneShotTimerTester
a(&did_run
);
344 OneShotTimerTester
b(&did_run
);
345 OneShotTimerTester
c(&did_run
);
346 OneShotTimerTester
d(&did_run
);
348 MessageLoop
loop(MessageLoop::TYPE_DEFAULT
);
351 } // MessageLoop destructs by falling out of scope.
352 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
354 EXPECT_EQ(false, did_run
);