GN + Android: extract android_standalone_library rule.
[chromium-blink-merge.git] / base / timer / timer_unittest.cc
blob1cbccd1626d558d912a267212325856aa3eff86c
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/message_loop.h"
7 #include "base/test/test_simple_task_runner.h"
8 #include "base/timer/timer.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 using base::TimeDelta;
12 using base::SingleThreadTaskRunner;
14 namespace {
16 // The message loops on which each timer should be tested.
17 const base::MessageLoop::Type testing_message_loops[] = {
18 base::MessageLoop::TYPE_DEFAULT,
19 base::MessageLoop::TYPE_IO,
20 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
21 base::MessageLoop::TYPE_UI,
22 #endif
25 const int kNumTestingMessageLoops = arraysize(testing_message_loops);
27 class OneShotTimerTester {
28 public:
29 explicit OneShotTimerTester(bool* did_run, unsigned milliseconds = 10)
30 : did_run_(did_run),
31 delay_ms_(milliseconds),
32 quit_message_loop_(true) {
35 void Start() {
36 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this,
37 &OneShotTimerTester::Run);
40 void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner) {
41 quit_message_loop_ = false;
42 timer_.SetTaskRunner(task_runner);
45 private:
46 void Run() {
47 *did_run_ = true;
48 if (quit_message_loop_) {
49 base::MessageLoop::current()->QuitWhenIdle();
53 bool* did_run_;
54 base::OneShotTimer<OneShotTimerTester> timer_;
55 const unsigned delay_ms_;
56 bool quit_message_loop_;
59 class OneShotSelfDeletingTimerTester {
60 public:
61 explicit OneShotSelfDeletingTimerTester(bool* did_run) :
62 did_run_(did_run),
63 timer_(new base::OneShotTimer<OneShotSelfDeletingTimerTester>()) {
66 void Start() {
67 timer_->Start(FROM_HERE, TimeDelta::FromMilliseconds(10), this,
68 &OneShotSelfDeletingTimerTester::Run);
71 private:
72 void Run() {
73 *did_run_ = true;
74 timer_.reset();
75 base::MessageLoop::current()->QuitWhenIdle();
78 bool* did_run_;
79 scoped_ptr<base::OneShotTimer<OneShotSelfDeletingTimerTester> > timer_;
82 class RepeatingTimerTester {
83 public:
84 explicit RepeatingTimerTester(bool* did_run, const TimeDelta& delay)
85 : did_run_(did_run), counter_(10), delay_(delay) {
88 void Start() {
89 timer_.Start(FROM_HERE, delay_, this, &RepeatingTimerTester::Run);
92 private:
93 void Run() {
94 if (--counter_ == 0) {
95 *did_run_ = true;
96 timer_.Stop();
97 base::MessageLoop::current()->QuitWhenIdle();
101 bool* did_run_;
102 int counter_;
103 TimeDelta delay_;
104 base::RepeatingTimer<RepeatingTimerTester> timer_;
107 void RunTest_OneShotTimer(base::MessageLoop::Type message_loop_type) {
108 base::MessageLoop loop(message_loop_type);
110 bool did_run = false;
111 OneShotTimerTester f(&did_run);
112 f.Start();
114 base::MessageLoop::current()->Run();
116 EXPECT_TRUE(did_run);
119 void RunTest_OneShotTimer_Cancel(base::MessageLoop::Type message_loop_type) {
120 base::MessageLoop loop(message_loop_type);
122 bool did_run_a = false;
123 OneShotTimerTester* a = new OneShotTimerTester(&did_run_a);
125 // This should run before the timer expires.
126 base::MessageLoop::current()->DeleteSoon(FROM_HERE, a);
128 // Now start the timer.
129 a->Start();
131 bool did_run_b = false;
132 OneShotTimerTester b(&did_run_b);
133 b.Start();
135 base::MessageLoop::current()->Run();
137 EXPECT_FALSE(did_run_a);
138 EXPECT_TRUE(did_run_b);
141 void RunTest_OneShotSelfDeletingTimer(
142 base::MessageLoop::Type message_loop_type) {
143 base::MessageLoop loop(message_loop_type);
145 bool did_run = false;
146 OneShotSelfDeletingTimerTester f(&did_run);
147 f.Start();
149 base::MessageLoop::current()->Run();
151 EXPECT_TRUE(did_run);
154 void RunTest_RepeatingTimer(base::MessageLoop::Type message_loop_type,
155 const TimeDelta& delay) {
156 base::MessageLoop loop(message_loop_type);
158 bool did_run = false;
159 RepeatingTimerTester f(&did_run, delay);
160 f.Start();
162 base::MessageLoop::current()->Run();
164 EXPECT_TRUE(did_run);
167 void RunTest_RepeatingTimer_Cancel(base::MessageLoop::Type message_loop_type,
168 const TimeDelta& delay) {
169 base::MessageLoop loop(message_loop_type);
171 bool did_run_a = false;
172 RepeatingTimerTester* a = new RepeatingTimerTester(&did_run_a, delay);
174 // This should run before the timer expires.
175 base::MessageLoop::current()->DeleteSoon(FROM_HERE, a);
177 // Now start the timer.
178 a->Start();
180 bool did_run_b = false;
181 RepeatingTimerTester b(&did_run_b, delay);
182 b.Start();
184 base::MessageLoop::current()->Run();
186 EXPECT_FALSE(did_run_a);
187 EXPECT_TRUE(did_run_b);
190 class DelayTimerTarget {
191 public:
192 DelayTimerTarget()
193 : signaled_(false) {
196 bool signaled() const { return signaled_; }
198 void Signal() {
199 ASSERT_FALSE(signaled_);
200 signaled_ = true;
203 private:
204 bool signaled_;
207 void RunTest_DelayTimer_NoCall(base::MessageLoop::Type message_loop_type) {
208 base::MessageLoop loop(message_loop_type);
210 // If Delay is never called, the timer shouldn't go off.
211 DelayTimerTarget target;
212 base::DelayTimer<DelayTimerTarget> timer(FROM_HERE,
213 TimeDelta::FromMilliseconds(1), &target, &DelayTimerTarget::Signal);
215 bool did_run = false;
216 OneShotTimerTester tester(&did_run);
217 tester.Start();
218 base::MessageLoop::current()->Run();
220 ASSERT_FALSE(target.signaled());
223 void RunTest_DelayTimer_OneCall(base::MessageLoop::Type message_loop_type) {
224 base::MessageLoop loop(message_loop_type);
226 DelayTimerTarget target;
227 base::DelayTimer<DelayTimerTarget> timer(FROM_HERE,
228 TimeDelta::FromMilliseconds(1), &target, &DelayTimerTarget::Signal);
229 timer.Reset();
231 bool did_run = false;
232 OneShotTimerTester tester(&did_run, 100 /* milliseconds */);
233 tester.Start();
234 base::MessageLoop::current()->Run();
236 ASSERT_TRUE(target.signaled());
239 struct ResetHelper {
240 ResetHelper(base::DelayTimer<DelayTimerTarget>* timer,
241 DelayTimerTarget* target)
242 : timer_(timer),
243 target_(target) {
246 void Reset() {
247 ASSERT_FALSE(target_->signaled());
248 timer_->Reset();
251 private:
252 base::DelayTimer<DelayTimerTarget> *const timer_;
253 DelayTimerTarget *const target_;
256 void RunTest_DelayTimer_Reset(base::MessageLoop::Type message_loop_type) {
257 base::MessageLoop loop(message_loop_type);
259 // If Delay is never called, the timer shouldn't go off.
260 DelayTimerTarget target;
261 base::DelayTimer<DelayTimerTarget> timer(FROM_HERE,
262 TimeDelta::FromMilliseconds(50), &target, &DelayTimerTarget::Signal);
263 timer.Reset();
265 ResetHelper reset_helper(&timer, &target);
267 base::OneShotTimer<ResetHelper> timers[20];
268 for (size_t i = 0; i < arraysize(timers); ++i) {
269 timers[i].Start(FROM_HERE, TimeDelta::FromMilliseconds(i * 10),
270 &reset_helper, &ResetHelper::Reset);
273 bool did_run = false;
274 OneShotTimerTester tester(&did_run, 300);
275 tester.Start();
276 base::MessageLoop::current()->Run();
278 ASSERT_TRUE(target.signaled());
281 class DelayTimerFatalTarget {
282 public:
283 void Signal() {
284 ASSERT_TRUE(false);
289 void RunTest_DelayTimer_Deleted(base::MessageLoop::Type message_loop_type) {
290 base::MessageLoop loop(message_loop_type);
292 DelayTimerFatalTarget target;
295 base::DelayTimer<DelayTimerFatalTarget> timer(
296 FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
297 &DelayTimerFatalTarget::Signal);
298 timer.Reset();
301 // When the timer is deleted, the DelayTimerFatalTarget should never be
302 // called.
303 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
306 } // namespace
308 //-----------------------------------------------------------------------------
309 // Each test is run against each type of MessageLoop. That way we are sure
310 // that timers work properly in all configurations.
312 TEST(TimerTest, OneShotTimer) {
313 for (int i = 0; i < kNumTestingMessageLoops; i++) {
314 RunTest_OneShotTimer(testing_message_loops[i]);
318 TEST(TimerTest, OneShotTimer_Cancel) {
319 for (int i = 0; i < kNumTestingMessageLoops; i++) {
320 RunTest_OneShotTimer_Cancel(testing_message_loops[i]);
324 // If underline timer does not handle properly, we will crash or fail
325 // in full page heap environment.
326 TEST(TimerTest, OneShotSelfDeletingTimer) {
327 for (int i = 0; i < kNumTestingMessageLoops; i++) {
328 RunTest_OneShotSelfDeletingTimer(testing_message_loops[i]);
332 TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
333 scoped_refptr<base::TestSimpleTaskRunner> task_runner =
334 new base::TestSimpleTaskRunner();
336 bool did_run = false;
337 OneShotTimerTester f(&did_run);
338 f.SetTaskRunner(task_runner);
339 f.Start();
341 EXPECT_FALSE(did_run);
342 task_runner->RunUntilIdle();
343 EXPECT_TRUE(did_run);
346 TEST(TimerTest, RepeatingTimer) {
347 for (int i = 0; i < kNumTestingMessageLoops; i++) {
348 RunTest_RepeatingTimer(testing_message_loops[i],
349 TimeDelta::FromMilliseconds(10));
353 TEST(TimerTest, RepeatingTimer_Cancel) {
354 for (int i = 0; i < kNumTestingMessageLoops; i++) {
355 RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
356 TimeDelta::FromMilliseconds(10));
360 TEST(TimerTest, RepeatingTimerZeroDelay) {
361 for (int i = 0; i < kNumTestingMessageLoops; i++) {
362 RunTest_RepeatingTimer(testing_message_loops[i],
363 TimeDelta::FromMilliseconds(0));
367 TEST(TimerTest, RepeatingTimerZeroDelay_Cancel) {
368 for (int i = 0; i < kNumTestingMessageLoops; i++) {
369 RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
370 TimeDelta::FromMilliseconds(0));
374 TEST(TimerTest, DelayTimer_NoCall) {
375 for (int i = 0; i < kNumTestingMessageLoops; i++) {
376 RunTest_DelayTimer_NoCall(testing_message_loops[i]);
380 TEST(TimerTest, DelayTimer_OneCall) {
381 for (int i = 0; i < kNumTestingMessageLoops; i++) {
382 RunTest_DelayTimer_OneCall(testing_message_loops[i]);
386 // It's flaky on the buildbot, http://crbug.com/25038.
387 TEST(TimerTest, DISABLED_DelayTimer_Reset) {
388 for (int i = 0; i < kNumTestingMessageLoops; i++) {
389 RunTest_DelayTimer_Reset(testing_message_loops[i]);
393 TEST(TimerTest, DelayTimer_Deleted) {
394 for (int i = 0; i < kNumTestingMessageLoops; i++) {
395 RunTest_DelayTimer_Deleted(testing_message_loops[i]);
399 TEST(TimerTest, MessageLoopShutdown) {
400 // This test is designed to verify that shutdown of the
401 // message loop does not cause crashes if there were pending
402 // timers not yet fired. It may only trigger exceptions
403 // if debug heap checking is enabled.
404 bool did_run = false;
406 OneShotTimerTester a(&did_run);
407 OneShotTimerTester b(&did_run);
408 OneShotTimerTester c(&did_run);
409 OneShotTimerTester d(&did_run);
411 base::MessageLoop loop;
412 a.Start();
413 b.Start();
414 } // MessageLoop destructs by falling out of scope.
415 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
417 EXPECT_FALSE(did_run);
420 void TimerTestCallback() {
423 TEST(TimerTest, NonRepeatIsRunning) {
425 base::MessageLoop loop;
426 base::Timer timer(false, false);
427 EXPECT_FALSE(timer.IsRunning());
428 timer.Start(FROM_HERE, TimeDelta::FromDays(1),
429 base::Bind(&TimerTestCallback));
430 EXPECT_TRUE(timer.IsRunning());
431 timer.Stop();
432 EXPECT_FALSE(timer.IsRunning());
433 EXPECT_TRUE(timer.user_task().is_null());
437 base::Timer timer(true, false);
438 base::MessageLoop loop;
439 EXPECT_FALSE(timer.IsRunning());
440 timer.Start(FROM_HERE, TimeDelta::FromDays(1),
441 base::Bind(&TimerTestCallback));
442 EXPECT_TRUE(timer.IsRunning());
443 timer.Stop();
444 EXPECT_FALSE(timer.IsRunning());
445 ASSERT_FALSE(timer.user_task().is_null());
446 timer.Reset();
447 EXPECT_TRUE(timer.IsRunning());
451 TEST(TimerTest, NonRepeatMessageLoopDeath) {
452 base::Timer timer(false, false);
454 base::MessageLoop loop;
455 EXPECT_FALSE(timer.IsRunning());
456 timer.Start(FROM_HERE, TimeDelta::FromDays(1),
457 base::Bind(&TimerTestCallback));
458 EXPECT_TRUE(timer.IsRunning());
460 EXPECT_FALSE(timer.IsRunning());
461 EXPECT_TRUE(timer.user_task().is_null());
464 TEST(TimerTest, RetainRepeatIsRunning) {
465 base::MessageLoop loop;
466 base::Timer timer(FROM_HERE, TimeDelta::FromDays(1),
467 base::Bind(&TimerTestCallback), true);
468 EXPECT_FALSE(timer.IsRunning());
469 timer.Reset();
470 EXPECT_TRUE(timer.IsRunning());
471 timer.Stop();
472 EXPECT_FALSE(timer.IsRunning());
473 timer.Reset();
474 EXPECT_TRUE(timer.IsRunning());
477 TEST(TimerTest, RetainNonRepeatIsRunning) {
478 base::MessageLoop loop;
479 base::Timer timer(FROM_HERE, TimeDelta::FromDays(1),
480 base::Bind(&TimerTestCallback), false);
481 EXPECT_FALSE(timer.IsRunning());
482 timer.Reset();
483 EXPECT_TRUE(timer.IsRunning());
484 timer.Stop();
485 EXPECT_FALSE(timer.IsRunning());
486 timer.Reset();
487 EXPECT_TRUE(timer.IsRunning());
490 namespace {
492 bool g_callback_happened1 = false;
493 bool g_callback_happened2 = false;
495 void ClearAllCallbackHappened() {
496 g_callback_happened1 = false;
497 g_callback_happened2 = false;
500 void SetCallbackHappened1() {
501 g_callback_happened1 = true;
502 base::MessageLoop::current()->QuitWhenIdle();
505 void SetCallbackHappened2() {
506 g_callback_happened2 = true;
507 base::MessageLoop::current()->QuitWhenIdle();
510 TEST(TimerTest, ContinuationStopStart) {
512 ClearAllCallbackHappened();
513 base::MessageLoop loop;
514 base::Timer timer(false, false);
515 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
516 base::Bind(&SetCallbackHappened1));
517 timer.Stop();
518 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(40),
519 base::Bind(&SetCallbackHappened2));
520 base::MessageLoop::current()->Run();
521 EXPECT_FALSE(g_callback_happened1);
522 EXPECT_TRUE(g_callback_happened2);
526 TEST(TimerTest, ContinuationReset) {
528 ClearAllCallbackHappened();
529 base::MessageLoop loop;
530 base::Timer timer(false, false);
531 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
532 base::Bind(&SetCallbackHappened1));
533 timer.Reset();
534 // Since Reset happened before task ran, the user_task must not be cleared:
535 ASSERT_FALSE(timer.user_task().is_null());
536 base::MessageLoop::current()->Run();
537 EXPECT_TRUE(g_callback_happened1);
541 } // namespace