Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / base / timer / timer_unittest.cc
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.
4
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"
10
11 using base::TimeDelta;
12 using base::SingleThreadTaskRunner;
13
14 namespace {
15
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
23 };
24
25 const int kNumTestingMessageLoops = arraysize(testing_message_loops);
26
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) {
33   }
34
35   void Start() {
36     timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this,
37                  &OneShotTimerTester::Run);
38   }
39
40   void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner) {
41     quit_message_loop_ = false;
42     timer_.SetTaskRunner(task_runner);
43   }
44
45  private:
46   void Run() {
47     *did_run_ = true;
48     if (quit_message_loop_) {
49       base::MessageLoop::current()->QuitWhenIdle();
50     }
51   }
52
53   bool* did_run_;
54   base::OneShotTimer<OneShotTimerTester> timer_;
55   const unsigned delay_ms_;
56   bool quit_message_loop_;
57 };
58
59 class OneShotSelfDeletingTimerTester {
60  public:
61   explicit OneShotSelfDeletingTimerTester(bool* did_run) :
62       did_run_(did_run),
63       timer_(new base::OneShotTimer<OneShotSelfDeletingTimerTester>()) {
64   }
65
66   void Start() {
67     timer_->Start(FROM_HERE, TimeDelta::FromMilliseconds(10), this,
68                   &OneShotSelfDeletingTimerTester::Run);
69   }
70
71  private:
72   void Run() {
73     *did_run_ = true;
74     timer_.reset();
75     base::MessageLoop::current()->QuitWhenIdle();
76   }
77
78   bool* did_run_;
79   scoped_ptr<base::OneShotTimer<OneShotSelfDeletingTimerTester> > timer_;
80 };
81
82 class RepeatingTimerTester {
83  public:
84   explicit RepeatingTimerTester(bool* did_run, const TimeDelta& delay)
85       : did_run_(did_run), counter_(10), delay_(delay) {
86   }
87
88   void Start() {
89     timer_.Start(FROM_HERE, delay_, this, &RepeatingTimerTester::Run);
90   }
91
92  private:
93   void Run() {
94     if (--counter_ == 0) {
95       *did_run_ = true;
96       timer_.Stop();
97       base::MessageLoop::current()->QuitWhenIdle();
98     }
99   }
100
101   bool* did_run_;
102   int counter_;
103   TimeDelta delay_;
104   base::RepeatingTimer<RepeatingTimerTester> timer_;
105 };
106
107 void RunTest_OneShotTimer(base::MessageLoop::Type message_loop_type) {
108   base::MessageLoop loop(message_loop_type);
109
110   bool did_run = false;
111   OneShotTimerTester f(&did_run);
112   f.Start();
113
114   base::MessageLoop::current()->Run();
115
116   EXPECT_TRUE(did_run);
117 }
118
119 void RunTest_OneShotTimer_Cancel(base::MessageLoop::Type message_loop_type) {
120   base::MessageLoop loop(message_loop_type);
121
122   bool did_run_a = false;
123   OneShotTimerTester* a = new OneShotTimerTester(&did_run_a);
124
125   // This should run before the timer expires.
126   base::MessageLoop::current()->DeleteSoon(FROM_HERE, a);
127
128   // Now start the timer.
129   a->Start();
130
131   bool did_run_b = false;
132   OneShotTimerTester b(&did_run_b);
133   b.Start();
134
135   base::MessageLoop::current()->Run();
136
137   EXPECT_FALSE(did_run_a);
138   EXPECT_TRUE(did_run_b);
139 }
140
141 void RunTest_OneShotSelfDeletingTimer(
142     base::MessageLoop::Type message_loop_type) {
143   base::MessageLoop loop(message_loop_type);
144
145   bool did_run = false;
146   OneShotSelfDeletingTimerTester f(&did_run);
147   f.Start();
148
149   base::MessageLoop::current()->Run();
150
151   EXPECT_TRUE(did_run);
152 }
153
154 void RunTest_RepeatingTimer(base::MessageLoop::Type message_loop_type,
155                             const TimeDelta& delay) {
156   base::MessageLoop loop(message_loop_type);
157
158   bool did_run = false;
159   RepeatingTimerTester f(&did_run, delay);
160   f.Start();
161
162   base::MessageLoop::current()->Run();
163
164   EXPECT_TRUE(did_run);
165 }
166
167 void RunTest_RepeatingTimer_Cancel(base::MessageLoop::Type message_loop_type,
168                                    const TimeDelta& delay) {
169   base::MessageLoop loop(message_loop_type);
170
171   bool did_run_a = false;
172   RepeatingTimerTester* a = new RepeatingTimerTester(&did_run_a, delay);
173
174   // This should run before the timer expires.
175   base::MessageLoop::current()->DeleteSoon(FROM_HERE, a);
176
177   // Now start the timer.
178   a->Start();
179
180   bool did_run_b = false;
181   RepeatingTimerTester b(&did_run_b, delay);
182   b.Start();
183
184   base::MessageLoop::current()->Run();
185
186   EXPECT_FALSE(did_run_a);
187   EXPECT_TRUE(did_run_b);
188 }
189
190 class DelayTimerTarget {
191  public:
192   DelayTimerTarget()
193       : signaled_(false) {
194   }
195
196   bool signaled() const { return signaled_; }
197
198   void Signal() {
199     ASSERT_FALSE(signaled_);
200     signaled_ = true;
201   }
202
203  private:
204   bool signaled_;
205 };
206
207 void RunTest_DelayTimer_NoCall(base::MessageLoop::Type message_loop_type) {
208   base::MessageLoop loop(message_loop_type);
209
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);
214
215   bool did_run = false;
216   OneShotTimerTester tester(&did_run);
217   tester.Start();
218   base::MessageLoop::current()->Run();
219
220   ASSERT_FALSE(target.signaled());
221 }
222
223 void RunTest_DelayTimer_OneCall(base::MessageLoop::Type message_loop_type) {
224   base::MessageLoop loop(message_loop_type);
225
226   DelayTimerTarget target;
227   base::DelayTimer<DelayTimerTarget> timer(FROM_HERE,
228       TimeDelta::FromMilliseconds(1), &target, &DelayTimerTarget::Signal);
229   timer.Reset();
230
231   bool did_run = false;
232   OneShotTimerTester tester(&did_run, 100 /* milliseconds */);
233   tester.Start();
234   base::MessageLoop::current()->Run();
235
236   ASSERT_TRUE(target.signaled());
237 }
238
239 struct ResetHelper {
240   ResetHelper(base::DelayTimer<DelayTimerTarget>* timer,
241               DelayTimerTarget* target)
242       : timer_(timer),
243         target_(target) {
244   }
245
246   void Reset() {
247     ASSERT_FALSE(target_->signaled());
248     timer_->Reset();
249   }
250
251  private:
252   base::DelayTimer<DelayTimerTarget> *const timer_;
253   DelayTimerTarget *const target_;
254 };
255
256 void RunTest_DelayTimer_Reset(base::MessageLoop::Type message_loop_type) {
257   base::MessageLoop loop(message_loop_type);
258
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();
264
265   ResetHelper reset_helper(&timer, &target);
266
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);
271   }
272
273   bool did_run = false;
274   OneShotTimerTester tester(&did_run, 300);
275   tester.Start();
276   base::MessageLoop::current()->Run();
277
278   ASSERT_TRUE(target.signaled());
279 }
280
281 class DelayTimerFatalTarget {
282  public:
283   void Signal() {
284     ASSERT_TRUE(false);
285   }
286 };
287
288
289 void RunTest_DelayTimer_Deleted(base::MessageLoop::Type message_loop_type) {
290   base::MessageLoop loop(message_loop_type);
291
292   DelayTimerFatalTarget target;
293
294   {
295     base::DelayTimer<DelayTimerFatalTarget> timer(
296         FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
297         &DelayTimerFatalTarget::Signal);
298     timer.Reset();
299   }
300
301   // When the timer is deleted, the DelayTimerFatalTarget should never be
302   // called.
303   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
304 }
305
306 }  // namespace
307
308 //-----------------------------------------------------------------------------
309 // Each test is run against each type of MessageLoop.  That way we are sure
310 // that timers work properly in all configurations.
311
312 TEST(TimerTest, OneShotTimer) {
313   for (int i = 0; i < kNumTestingMessageLoops; i++) {
314     RunTest_OneShotTimer(testing_message_loops[i]);
315   }
316 }
317
318 TEST(TimerTest, OneShotTimer_Cancel) {
319   for (int i = 0; i < kNumTestingMessageLoops; i++) {
320     RunTest_OneShotTimer_Cancel(testing_message_loops[i]);
321   }
322 }
323
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]);
329   }
330 }
331
332 TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
333   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
334       new base::TestSimpleTaskRunner();
335
336   bool did_run = false;
337   OneShotTimerTester f(&did_run);
338   f.SetTaskRunner(task_runner);
339   f.Start();
340
341   EXPECT_FALSE(did_run);
342   task_runner->RunUntilIdle();
343   EXPECT_TRUE(did_run);
344 }
345
346 TEST(TimerTest, RepeatingTimer) {
347   for (int i = 0; i < kNumTestingMessageLoops; i++) {
348     RunTest_RepeatingTimer(testing_message_loops[i],
349                            TimeDelta::FromMilliseconds(10));
350   }
351 }
352
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));
357   }
358 }
359
360 TEST(TimerTest, RepeatingTimerZeroDelay) {
361   for (int i = 0; i < kNumTestingMessageLoops; i++) {
362     RunTest_RepeatingTimer(testing_message_loops[i],
363                            TimeDelta::FromMilliseconds(0));
364   }
365 }
366
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));
371   }
372 }
373
374 TEST(TimerTest, DelayTimer_NoCall) {
375   for (int i = 0; i < kNumTestingMessageLoops; i++) {
376     RunTest_DelayTimer_NoCall(testing_message_loops[i]);
377   }
378 }
379
380 TEST(TimerTest, DelayTimer_OneCall) {
381   for (int i = 0; i < kNumTestingMessageLoops; i++) {
382     RunTest_DelayTimer_OneCall(testing_message_loops[i]);
383   }
384 }
385
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]);
390   }
391 }
392
393 TEST(TimerTest, DelayTimer_Deleted) {
394   for (int i = 0; i < kNumTestingMessageLoops; i++) {
395     RunTest_DelayTimer_Deleted(testing_message_loops[i]);
396   }
397 }
398
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;
405   {
406     OneShotTimerTester a(&did_run);
407     OneShotTimerTester b(&did_run);
408     OneShotTimerTester c(&did_run);
409     OneShotTimerTester d(&did_run);
410     {
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.
416
417   EXPECT_FALSE(did_run);
418 }
419
420 void TimerTestCallback() {
421 }
422
423 TEST(TimerTest, NonRepeatIsRunning) {
424   {
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());
434   }
435
436   {
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());
448   }
449 }
450
451 TEST(TimerTest, NonRepeatMessageLoopDeath) {
452   base::Timer timer(false, false);
453   {
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());
459   }
460   EXPECT_FALSE(timer.IsRunning());
461   EXPECT_TRUE(timer.user_task().is_null());
462 }
463
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());
475 }
476
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());
488 }
489
490 namespace {
491
492 bool g_callback_happened1 = false;
493 bool g_callback_happened2 = false;
494
495 void ClearAllCallbackHappened() {
496   g_callback_happened1 = false;
497   g_callback_happened2 = false;
498 }
499
500 void SetCallbackHappened1() {
501   g_callback_happened1 = true;
502   base::MessageLoop::current()->QuitWhenIdle();
503 }
504
505 void SetCallbackHappened2() {
506   g_callback_happened2 = true;
507   base::MessageLoop::current()->QuitWhenIdle();
508 }
509
510 TEST(TimerTest, ContinuationStopStart) {
511   {
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);
523   }
524 }
525
526 TEST(TimerTest, ContinuationReset) {
527   {
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);
538   }
539 }
540
541 }  // namespace