blob: 79d3a4e65ec3f3dc1f6a09e8408850b09cbacf90 [file] [log] [blame]
[email protected]3b63f8f42011-03-28 01:54:151// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
[email protected]3b63f8f42011-03-28 01:54:155#include "base/memory/scoped_ptr.h"
initial.commitd7cae122008-07-26 21:49:386#include "base/message_loop.h"
[email protected]542bdfe2010-11-30 03:55:477#include "base/task.h"
initial.commitd7cae122008-07-26 21:49:388#include "base/timer.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
[email protected]e1acf6f2008-10-27 20:43:3311using base::TimeDelta;
12
[email protected]aeab57ea2008-08-28 20:50:1213namespace {
14
15class OneShotTimerTester {
16 public:
[email protected]e68e62fa2009-02-20 02:00:0417 OneShotTimerTester(bool* did_run, unsigned milliseconds = 10)
18 : did_run_(did_run),
19 delay_ms_(milliseconds) {
[email protected]aeab57ea2008-08-28 20:50:1220 }
21 void Start() {
[email protected]e68e62fa2009-02-20 02:00:0422 timer_.Start(TimeDelta::FromMilliseconds(delay_ms_), this,
[email protected]aeab57ea2008-08-28 20:50:1223 &OneShotTimerTester::Run);
24 }
25 private:
26 void Run() {
27 *did_run_ = true;
28 MessageLoop::current()->Quit();
29 }
30 bool* did_run_;
31 base::OneShotTimer<OneShotTimerTester> timer_;
[email protected]e68e62fa2009-02-20 02:00:0432 const unsigned delay_ms_;
[email protected]aeab57ea2008-08-28 20:50:1233};
34
[email protected]95284322009-02-07 00:37:0135class OneShotSelfDeletingTimerTester {
36 public:
[email protected]2fdc86a2010-01-26 23:08:0237 explicit OneShotSelfDeletingTimerTester(bool* did_run) :
[email protected]95284322009-02-07 00:37:0138 did_run_(did_run),
39 timer_(new base::OneShotTimer<OneShotSelfDeletingTimerTester>()) {
40 }
41 void Start() {
42 timer_->Start(TimeDelta::FromMilliseconds(10), this,
43 &OneShotSelfDeletingTimerTester::Run);
44 }
45 private:
46 void Run() {
47 *did_run_ = true;
48 timer_.reset();
49 MessageLoop::current()->Quit();
50 }
51 bool* did_run_;
52 scoped_ptr<base::OneShotTimer<OneShotSelfDeletingTimerTester> > timer_;
53};
54
[email protected]aeab57ea2008-08-28 20:50:1255class RepeatingTimerTester {
56 public:
[email protected]2fdc86a2010-01-26 23:08:0257 explicit RepeatingTimerTester(bool* did_run)
58 : did_run_(did_run), counter_(10) {
[email protected]aeab57ea2008-08-28 20:50:1259 }
[email protected]2fdc86a2010-01-26 23:08:0260
[email protected]aeab57ea2008-08-28 20:50:1261 void Start() {
62 timer_.Start(TimeDelta::FromMilliseconds(10), this,
63 &RepeatingTimerTester::Run);
64 }
65 private:
66 void Run() {
67 if (--counter_ == 0) {
68 *did_run_ = true;
69 MessageLoop::current()->Quit();
70 }
71 }
72 bool* did_run_;
73 int counter_;
74 base::RepeatingTimer<RepeatingTimerTester> timer_;
75};
76
[email protected]aeab57ea2008-08-28 20:50:1277void RunTest_OneShotTimer(MessageLoop::Type message_loop_type) {
78 MessageLoop loop(message_loop_type);
79
80 bool did_run = false;
81 OneShotTimerTester f(&did_run);
82 f.Start();
83
84 MessageLoop::current()->Run();
85
86 EXPECT_TRUE(did_run);
87}
88
89void RunTest_OneShotTimer_Cancel(MessageLoop::Type message_loop_type) {
90 MessageLoop loop(message_loop_type);
91
92 bool did_run_a = false;
93 OneShotTimerTester* a = new OneShotTimerTester(&did_run_a);
94
95 // This should run before the timer expires.
96 MessageLoop::current()->DeleteSoon(FROM_HERE, a);
97
98 // Now start the timer.
99 a->Start();
[email protected]52a261f2009-03-03 15:01:12100
[email protected]aeab57ea2008-08-28 20:50:12101 bool did_run_b = false;
102 OneShotTimerTester b(&did_run_b);
103 b.Start();
104
105 MessageLoop::current()->Run();
106
107 EXPECT_FALSE(did_run_a);
108 EXPECT_TRUE(did_run_b);
109}
110
[email protected]95284322009-02-07 00:37:01111void RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type) {
112 MessageLoop loop(message_loop_type);
113
114 bool did_run = false;
115 OneShotSelfDeletingTimerTester f(&did_run);
116 f.Start();
117
118 MessageLoop::current()->Run();
119
120 EXPECT_TRUE(did_run);
121}
122
[email protected]aeab57ea2008-08-28 20:50:12123void RunTest_RepeatingTimer(MessageLoop::Type message_loop_type) {
124 MessageLoop loop(message_loop_type);
125
126 bool did_run = false;
127 RepeatingTimerTester f(&did_run);
128 f.Start();
129
130 MessageLoop::current()->Run();
131
132 EXPECT_TRUE(did_run);
133}
134
135void RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type) {
136 MessageLoop loop(message_loop_type);
137
138 bool did_run_a = false;
139 RepeatingTimerTester* a = new RepeatingTimerTester(&did_run_a);
140
141 // This should run before the timer expires.
142 MessageLoop::current()->DeleteSoon(FROM_HERE, a);
143
144 // Now start the timer.
145 a->Start();
[email protected]e68e62fa2009-02-20 02:00:04146
[email protected]aeab57ea2008-08-28 20:50:12147 bool did_run_b = false;
148 RepeatingTimerTester b(&did_run_b);
149 b.Start();
150
151 MessageLoop::current()->Run();
152
153 EXPECT_FALSE(did_run_a);
154 EXPECT_TRUE(did_run_b);
155}
156
[email protected]e68e62fa2009-02-20 02:00:04157class DelayTimerTarget {
158 public:
159 DelayTimerTarget()
160 : signaled_(false) {
161 }
162
163 bool signaled() const { return signaled_; }
164
165 void Signal() {
166 ASSERT_FALSE(signaled_);
167 signaled_ = true;
168 }
169
170 private:
171 bool signaled_;
172};
173
174void RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type) {
175 MessageLoop loop(message_loop_type);
176
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);
181
182 bool did_run = false;
183 OneShotTimerTester tester(&did_run);
184 tester.Start();
185 MessageLoop::current()->Run();
186
187 ASSERT_FALSE(target.signaled());
188}
189
190void RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type) {
191 MessageLoop loop(message_loop_type);
192
193 DelayTimerTarget target;
194 base::DelayTimer<DelayTimerTarget> timer(
195 TimeDelta::FromMilliseconds(1), &target, &DelayTimerTarget::Signal);
196 timer.Reset();
197
198 bool did_run = false;
199 OneShotTimerTester tester(&did_run, 100 /* milliseconds */);
200 tester.Start();
201 MessageLoop::current()->Run();
202
203 ASSERT_TRUE(target.signaled());
204}
205
206struct ResetHelper {
207 ResetHelper(base::DelayTimer<DelayTimerTarget>* timer,
208 DelayTimerTarget* target)
209 : timer_(timer),
210 target_(target) {
211 }
212
213 void Reset() {
214 ASSERT_FALSE(target_->signaled());
215 timer_->Reset();
216 }
217
218 private:
219 base::DelayTimer<DelayTimerTarget> *const timer_;
220 DelayTimerTarget *const target_;
221};
222
223void RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type) {
224 MessageLoop loop(message_loop_type);
225
226 // If Delay is never called, the timer shouldn't go off.
227 DelayTimerTarget target;
228 base::DelayTimer<DelayTimerTarget> timer(
[email protected]b69e1af2009-02-20 02:11:59229 TimeDelta::FromMilliseconds(50), &target, &DelayTimerTarget::Signal);
[email protected]e68e62fa2009-02-20 02:00:04230 timer.Reset();
231
232 ResetHelper reset_helper(&timer, &target);
233
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);
238 }
239
240 bool did_run = false;
241 OneShotTimerTester tester(&did_run, 300);
242 tester.Start();
243 MessageLoop::current()->Run();
244
245 ASSERT_TRUE(target.signaled());
246}
247
[email protected]02bf7f272009-02-26 23:17:56248class DelayTimerFatalTarget {
249 public:
250 void Signal() {
251 ASSERT_TRUE(false);
252 }
253};
254
255
256void RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type) {
257 MessageLoop loop(message_loop_type);
258
259 DelayTimerFatalTarget target;
260
261 {
262 base::DelayTimer<DelayTimerFatalTarget> timer(
263 TimeDelta::FromMilliseconds(50), &target,
264 &DelayTimerFatalTarget::Signal);
265 timer.Reset();
266 }
267
268 // When the timer is deleted, the DelayTimerFatalTarget should never be
269 // called.
[email protected]ce072a72010-12-31 20:02:16270 base::PlatformThread::Sleep(100);
[email protected]02bf7f272009-02-26 23:17:56271}
272
[email protected]4d9bdfaf2008-08-26 05:53:57273} // namespace
274
275//-----------------------------------------------------------------------------
276// Each test is run against each type of MessageLoop. That way we are sure
277// that timers work properly in all configurations.
278
[email protected]aeab57ea2008-08-28 20:50:12279TEST(TimerTest, OneShotTimer) {
280 RunTest_OneShotTimer(MessageLoop::TYPE_DEFAULT);
281 RunTest_OneShotTimer(MessageLoop::TYPE_UI);
282 RunTest_OneShotTimer(MessageLoop::TYPE_IO);
283}
284
285TEST(TimerTest, OneShotTimer_Cancel) {
286 RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_DEFAULT);
287 RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_UI);
288 RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_IO);
289}
290
[email protected]95284322009-02-07 00:37:01291// If underline timer does not handle properly, we will crash or fail
292// in full page heap or purify environment.
293TEST(TimerTest, OneShotSelfDeletingTimer) {
294 RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_DEFAULT);
295 RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_UI);
296 RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_IO);
297}
298
[email protected]aeab57ea2008-08-28 20:50:12299TEST(TimerTest, RepeatingTimer) {
300 RunTest_RepeatingTimer(MessageLoop::TYPE_DEFAULT);
301 RunTest_RepeatingTimer(MessageLoop::TYPE_UI);
302 RunTest_RepeatingTimer(MessageLoop::TYPE_IO);
303}
304
305TEST(TimerTest, RepeatingTimer_Cancel) {
306 RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_DEFAULT);
307 RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_UI);
308 RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_IO);
309}
[email protected]a0287cbd2008-12-02 23:16:55310
[email protected]e68e62fa2009-02-20 02:00:04311TEST(TimerTest, DelayTimer_NoCall) {
312 RunTest_DelayTimer_NoCall(MessageLoop::TYPE_DEFAULT);
313 RunTest_DelayTimer_NoCall(MessageLoop::TYPE_UI);
314 RunTest_DelayTimer_NoCall(MessageLoop::TYPE_IO);
315}
316
317TEST(TimerTest, DelayTimer_OneCall) {
318 RunTest_DelayTimer_OneCall(MessageLoop::TYPE_DEFAULT);
319 RunTest_DelayTimer_OneCall(MessageLoop::TYPE_UI);
320 RunTest_DelayTimer_OneCall(MessageLoop::TYPE_IO);
321}
322
[email protected]471d7d62009-10-16 15:26:16323// It's flaky on the buildbot, http://crbug.com/25038.
324TEST(TimerTest, FLAKY_DelayTimer_Reset) {
[email protected]e68e62fa2009-02-20 02:00:04325 RunTest_DelayTimer_Reset(MessageLoop::TYPE_DEFAULT);
326 RunTest_DelayTimer_Reset(MessageLoop::TYPE_UI);
327 RunTest_DelayTimer_Reset(MessageLoop::TYPE_IO);
328}
329
[email protected]02bf7f272009-02-26 23:17:56330TEST(TimerTest, DelayTimer_Deleted) {
331 RunTest_DelayTimer_Deleted(MessageLoop::TYPE_DEFAULT);
332 RunTest_DelayTimer_Deleted(MessageLoop::TYPE_UI);
333 RunTest_DelayTimer_Deleted(MessageLoop::TYPE_IO);
334}
335
[email protected]a0287cbd2008-12-02 23:16:55336TEST(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;
342 {
343 OneShotTimerTester a(&did_run);
344 OneShotTimerTester b(&did_run);
345 OneShotTimerTester c(&did_run);
346 OneShotTimerTester d(&did_run);
347 {
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.
353
[email protected]74e3af72010-10-03 21:44:39354 EXPECT_FALSE(did_run);
[email protected]a0287cbd2008-12-02 23:16:55355}