WebKit Roll 77375:77377.
[chromium-blink-merge.git] / base / timer_unittest.cc
blobc2289c8d23cbf75e0eafd5355fd9f4605fa4025f
1 // Copyright (c) 2010 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"
7 #include "base/task.h"
8 #include "base/timer.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 using base::TimeDelta;
13 namespace {
15 class OneShotTimerTester {
16 public:
17 OneShotTimerTester(bool* did_run, unsigned milliseconds = 10)
18 : did_run_(did_run),
19 delay_ms_(milliseconds) {
21 void Start() {
22 timer_.Start(TimeDelta::FromMilliseconds(delay_ms_), this,
23 &OneShotTimerTester::Run);
25 private:
26 void Run() {
27 *did_run_ = true;
28 MessageLoop::current()->Quit();
30 bool* did_run_;
31 base::OneShotTimer<OneShotTimerTester> timer_;
32 const unsigned delay_ms_;
35 class OneShotSelfDeletingTimerTester {
36 public:
37 explicit OneShotSelfDeletingTimerTester(bool* did_run) :
38 did_run_(did_run),
39 timer_(new base::OneShotTimer<OneShotSelfDeletingTimerTester>()) {
41 void Start() {
42 timer_->Start(TimeDelta::FromMilliseconds(10), this,
43 &OneShotSelfDeletingTimerTester::Run);
45 private:
46 void Run() {
47 *did_run_ = true;
48 timer_.reset();
49 MessageLoop::current()->Quit();
51 bool* did_run_;
52 scoped_ptr<base::OneShotTimer<OneShotSelfDeletingTimerTester> > timer_;
55 class RepeatingTimerTester {
56 public:
57 explicit RepeatingTimerTester(bool* did_run)
58 : did_run_(did_run), counter_(10) {
61 void Start() {
62 timer_.Start(TimeDelta::FromMilliseconds(10), this,
63 &RepeatingTimerTester::Run);
65 private:
66 void Run() {
67 if (--counter_ == 0) {
68 *did_run_ = true;
69 MessageLoop::current()->Quit();
72 bool* did_run_;
73 int counter_;
74 base::RepeatingTimer<RepeatingTimerTester> timer_;
77 void RunTest_OneShotTimer(MessageLoop::Type message_loop_type) {
78 MessageLoop loop(message_loop_type);
80 bool did_run = false;
81 OneShotTimerTester f(&did_run);
82 f.Start();
84 MessageLoop::current()->Run();
86 EXPECT_TRUE(did_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.
99 a->Start();
101 bool did_run_b = false;
102 OneShotTimerTester b(&did_run_b);
103 b.Start();
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);
116 f.Start();
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);
128 f.Start();
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.
145 a->Start();
147 bool did_run_b = false;
148 RepeatingTimerTester b(&did_run_b);
149 b.Start();
151 MessageLoop::current()->Run();
153 EXPECT_FALSE(did_run_a);
154 EXPECT_TRUE(did_run_b);
157 class DelayTimerTarget {
158 public:
159 DelayTimerTarget()
160 : signaled_(false) {
163 bool signaled() const { return signaled_; }
165 void Signal() {
166 ASSERT_FALSE(signaled_);
167 signaled_ = true;
170 private:
171 bool 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);
184 tester.Start();
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);
196 timer.Reset();
198 bool did_run = false;
199 OneShotTimerTester tester(&did_run, 100 /* milliseconds */);
200 tester.Start();
201 MessageLoop::current()->Run();
203 ASSERT_TRUE(target.signaled());
206 struct ResetHelper {
207 ResetHelper(base::DelayTimer<DelayTimerTarget>* timer,
208 DelayTimerTarget* target)
209 : timer_(timer),
210 target_(target) {
213 void Reset() {
214 ASSERT_FALSE(target_->signaled());
215 timer_->Reset();
218 private:
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);
230 timer.Reset();
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);
242 tester.Start();
243 MessageLoop::current()->Run();
245 ASSERT_TRUE(target.signaled());
248 class DelayTimerFatalTarget {
249 public:
250 void Signal() {
251 ASSERT_TRUE(false);
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);
265 timer.Reset();
268 // When the timer is deleted, the DelayTimerFatalTarget should never be
269 // called.
270 base::PlatformThread::Sleep(100);
273 } // namespace
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);
349 a.Start();
350 b.Start();
351 } // MessageLoop destructs by falling out of scope.
352 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
354 EXPECT_FALSE(did_run);