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 class OneShotTimerTester
{
16 OneShotTimerTester(bool* did_run
, unsigned milliseconds
= 10)
18 delay_ms_(milliseconds
) {
21 timer_
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(delay_ms_
), this,
22 &OneShotTimerTester::Run
);
27 MessageLoop::current()->Quit();
30 base::OneShotTimer
<OneShotTimerTester
> timer_
;
31 const unsigned delay_ms_
;
34 class OneShotSelfDeletingTimerTester
{
36 explicit OneShotSelfDeletingTimerTester(bool* did_run
) :
38 timer_(new base::OneShotTimer
<OneShotSelfDeletingTimerTester
>()) {
41 timer_
->Start(FROM_HERE
, TimeDelta::FromMilliseconds(10), this,
42 &OneShotSelfDeletingTimerTester::Run
);
48 MessageLoop::current()->Quit();
51 scoped_ptr
<base::OneShotTimer
<OneShotSelfDeletingTimerTester
> > timer_
;
54 class RepeatingTimerTester
{
56 explicit RepeatingTimerTester(bool* did_run
)
57 : did_run_(did_run
), counter_(10) {
61 timer_
.Start(FROM_HERE
, TimeDelta::FromMilliseconds(10), this,
62 &RepeatingTimerTester::Run
);
66 if (--counter_
== 0) {
68 MessageLoop::current()->Quit();
73 base::RepeatingTimer
<RepeatingTimerTester
> timer_
;
76 void RunTest_OneShotTimer(MessageLoop::Type message_loop_type
) {
77 MessageLoop
loop(message_loop_type
);
80 OneShotTimerTester
f(&did_run
);
83 MessageLoop::current()->Run();
88 void RunTest_OneShotTimer_Cancel(MessageLoop::Type message_loop_type
) {
89 MessageLoop
loop(message_loop_type
);
91 bool did_run_a
= false;
92 OneShotTimerTester
* a
= new OneShotTimerTester(&did_run_a
);
94 // This should run before the timer expires.
95 MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
97 // Now start the timer.
100 bool did_run_b
= false;
101 OneShotTimerTester
b(&did_run_b
);
104 MessageLoop::current()->Run();
106 EXPECT_FALSE(did_run_a
);
107 EXPECT_TRUE(did_run_b
);
110 void RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type
) {
111 MessageLoop
loop(message_loop_type
);
113 bool did_run
= false;
114 OneShotSelfDeletingTimerTester
f(&did_run
);
117 MessageLoop::current()->Run();
119 EXPECT_TRUE(did_run
);
122 void RunTest_RepeatingTimer(MessageLoop::Type message_loop_type
) {
123 MessageLoop
loop(message_loop_type
);
125 bool did_run
= false;
126 RepeatingTimerTester
f(&did_run
);
129 MessageLoop::current()->Run();
131 EXPECT_TRUE(did_run
);
134 void RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type
) {
135 MessageLoop
loop(message_loop_type
);
137 bool did_run_a
= false;
138 RepeatingTimerTester
* a
= new RepeatingTimerTester(&did_run_a
);
140 // This should run before the timer expires.
141 MessageLoop::current()->DeleteSoon(FROM_HERE
, a
);
143 // Now start the timer.
146 bool did_run_b
= false;
147 RepeatingTimerTester
b(&did_run_b
);
150 MessageLoop::current()->Run();
152 EXPECT_FALSE(did_run_a
);
153 EXPECT_TRUE(did_run_b
);
156 class DelayTimerTarget
{
162 bool signaled() const { return signaled_
; }
165 ASSERT_FALSE(signaled_
);
173 void RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type
) {
174 MessageLoop
loop(message_loop_type
);
176 // If Delay is never called, the timer shouldn't go off.
177 DelayTimerTarget target
;
178 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
179 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
181 bool did_run
= false;
182 OneShotTimerTester
tester(&did_run
);
184 MessageLoop::current()->Run();
186 ASSERT_FALSE(target
.signaled());
189 void RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type
) {
190 MessageLoop
loop(message_loop_type
);
192 DelayTimerTarget target
;
193 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
194 TimeDelta::FromMilliseconds(1), &target
, &DelayTimerTarget::Signal
);
197 bool did_run
= false;
198 OneShotTimerTester
tester(&did_run
, 100 /* milliseconds */);
200 MessageLoop::current()->Run();
202 ASSERT_TRUE(target
.signaled());
206 ResetHelper(base::DelayTimer
<DelayTimerTarget
>* timer
,
207 DelayTimerTarget
* target
)
213 ASSERT_FALSE(target_
->signaled());
218 base::DelayTimer
<DelayTimerTarget
> *const timer_
;
219 DelayTimerTarget
*const target_
;
222 void RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type
) {
223 MessageLoop
loop(message_loop_type
);
225 // If Delay is never called, the timer shouldn't go off.
226 DelayTimerTarget target
;
227 base::DelayTimer
<DelayTimerTarget
> timer(FROM_HERE
,
228 TimeDelta::FromMilliseconds(50), &target
, &DelayTimerTarget::Signal
);
231 ResetHelper
reset_helper(&timer
, &target
);
233 base::OneShotTimer
<ResetHelper
> timers
[20];
234 for (size_t i
= 0; i
< arraysize(timers
); ++i
) {
235 timers
[i
].Start(FROM_HERE
, TimeDelta::FromMilliseconds(i
* 10),
236 &reset_helper
, &ResetHelper::Reset
);
239 bool did_run
= false;
240 OneShotTimerTester
tester(&did_run
, 300);
242 MessageLoop::current()->Run();
244 ASSERT_TRUE(target
.signaled());
247 class DelayTimerFatalTarget
{
255 void RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type
) {
256 MessageLoop
loop(message_loop_type
);
258 DelayTimerFatalTarget target
;
261 base::DelayTimer
<DelayTimerFatalTarget
> timer(
262 FROM_HERE
, TimeDelta::FromMilliseconds(50), &target
,
263 &DelayTimerFatalTarget::Signal
);
267 // When the timer is deleted, the DelayTimerFatalTarget should never be
269 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
274 //-----------------------------------------------------------------------------
275 // Each test is run against each type of MessageLoop. That way we are sure
276 // that timers work properly in all configurations.
278 TEST(TimerTest
, OneShotTimer
) {
279 RunTest_OneShotTimer(MessageLoop::TYPE_DEFAULT
);
280 RunTest_OneShotTimer(MessageLoop::TYPE_UI
);
281 RunTest_OneShotTimer(MessageLoop::TYPE_IO
);
284 TEST(TimerTest
, OneShotTimer_Cancel
) {
285 RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_DEFAULT
);
286 RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_UI
);
287 RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_IO
);
290 // If underline timer does not handle properly, we will crash or fail
291 // in full page heap environment.
292 TEST(TimerTest
, OneShotSelfDeletingTimer
) {
293 RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_DEFAULT
);
294 RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_UI
);
295 RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_IO
);
298 TEST(TimerTest
, RepeatingTimer
) {
299 RunTest_RepeatingTimer(MessageLoop::TYPE_DEFAULT
);
300 RunTest_RepeatingTimer(MessageLoop::TYPE_UI
);
301 RunTest_RepeatingTimer(MessageLoop::TYPE_IO
);
304 TEST(TimerTest
, RepeatingTimer_Cancel
) {
305 RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_DEFAULT
);
306 RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_UI
);
307 RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_IO
);
310 TEST(TimerTest
, DelayTimer_NoCall
) {
311 RunTest_DelayTimer_NoCall(MessageLoop::TYPE_DEFAULT
);
312 RunTest_DelayTimer_NoCall(MessageLoop::TYPE_UI
);
313 RunTest_DelayTimer_NoCall(MessageLoop::TYPE_IO
);
316 TEST(TimerTest
, DelayTimer_OneCall
) {
317 RunTest_DelayTimer_OneCall(MessageLoop::TYPE_DEFAULT
);
318 RunTest_DelayTimer_OneCall(MessageLoop::TYPE_UI
);
319 RunTest_DelayTimer_OneCall(MessageLoop::TYPE_IO
);
322 // It's flaky on the buildbot, http://crbug.com/25038.
323 TEST(TimerTest
, DISABLED_DelayTimer_Reset
) {
324 RunTest_DelayTimer_Reset(MessageLoop::TYPE_DEFAULT
);
325 RunTest_DelayTimer_Reset(MessageLoop::TYPE_UI
);
326 RunTest_DelayTimer_Reset(MessageLoop::TYPE_IO
);
329 TEST(TimerTest
, DelayTimer_Deleted
) {
330 RunTest_DelayTimer_Deleted(MessageLoop::TYPE_DEFAULT
);
331 RunTest_DelayTimer_Deleted(MessageLoop::TYPE_UI
);
332 RunTest_DelayTimer_Deleted(MessageLoop::TYPE_IO
);
335 TEST(TimerTest
, MessageLoopShutdown
) {
336 // This test is designed to verify that shutdown of the
337 // message loop does not cause crashes if there were pending
338 // timers not yet fired. It may only trigger exceptions
339 // if debug heap checking is enabled.
340 bool did_run
= false;
342 OneShotTimerTester
a(&did_run
);
343 OneShotTimerTester
b(&did_run
);
344 OneShotTimerTester
c(&did_run
);
345 OneShotTimerTester
d(&did_run
);
347 MessageLoop
loop(MessageLoop::TYPE_DEFAULT
);
350 } // MessageLoop destructs by falling out of scope.
351 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
353 EXPECT_FALSE(did_run
);