Add a stat to the smoothness benchmark for avg number of missing tiles.
[chromium-blink-merge.git] / base / timer_unittest.cc
blob67bd948176aa78106ba6177f6a038c604807def0
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;
12 namespace {
14 // The message loops on which each timer should be tested.
15 const MessageLoop::Type testing_message_loops[] = {
16 MessageLoop::TYPE_DEFAULT,
17 MessageLoop::TYPE_IO,
18 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
19 MessageLoop::TYPE_UI,
20 #endif
23 const int kNumTestingMessageLoops = arraysize(testing_message_loops);
25 class OneShotTimerTester {
26 public:
27 OneShotTimerTester(bool* did_run, unsigned milliseconds = 10)
28 : did_run_(did_run),
29 delay_ms_(milliseconds) {
31 void Start() {
32 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this,
33 &OneShotTimerTester::Run);
35 private:
36 void Run() {
37 *did_run_ = true;
38 MessageLoop::current()->Quit();
40 bool* did_run_;
41 base::OneShotTimer<OneShotTimerTester> timer_;
42 const unsigned delay_ms_;
45 class OneShotSelfDeletingTimerTester {
46 public:
47 explicit OneShotSelfDeletingTimerTester(bool* did_run) :
48 did_run_(did_run),
49 timer_(new base::OneShotTimer<OneShotSelfDeletingTimerTester>()) {
51 void Start() {
52 timer_->Start(FROM_HERE, TimeDelta::FromMilliseconds(10), this,
53 &OneShotSelfDeletingTimerTester::Run);
55 private:
56 void Run() {
57 *did_run_ = true;
58 timer_.reset();
59 MessageLoop::current()->Quit();
61 bool* did_run_;
62 scoped_ptr<base::OneShotTimer<OneShotSelfDeletingTimerTester> > timer_;
65 class RepeatingTimerTester {
66 public:
67 explicit RepeatingTimerTester(bool* did_run)
68 : did_run_(did_run), counter_(10) {
71 void Start() {
72 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(10), this,
73 &RepeatingTimerTester::Run);
75 private:
76 void Run() {
77 if (--counter_ == 0) {
78 *did_run_ = true;
79 MessageLoop::current()->Quit();
82 bool* did_run_;
83 int counter_;
84 base::RepeatingTimer<RepeatingTimerTester> timer_;
87 void RunTest_OneShotTimer(MessageLoop::Type message_loop_type) {
88 MessageLoop loop(message_loop_type);
90 bool did_run = false;
91 OneShotTimerTester f(&did_run);
92 f.Start();
94 MessageLoop::current()->Run();
96 EXPECT_TRUE(did_run);
99 void RunTest_OneShotTimer_Cancel(MessageLoop::Type message_loop_type) {
100 MessageLoop loop(message_loop_type);
102 bool did_run_a = false;
103 OneShotTimerTester* a = new OneShotTimerTester(&did_run_a);
105 // This should run before the timer expires.
106 MessageLoop::current()->DeleteSoon(FROM_HERE, a);
108 // Now start the timer.
109 a->Start();
111 bool did_run_b = false;
112 OneShotTimerTester b(&did_run_b);
113 b.Start();
115 MessageLoop::current()->Run();
117 EXPECT_FALSE(did_run_a);
118 EXPECT_TRUE(did_run_b);
121 void RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type) {
122 MessageLoop loop(message_loop_type);
124 bool did_run = false;
125 OneShotSelfDeletingTimerTester f(&did_run);
126 f.Start();
128 MessageLoop::current()->Run();
130 EXPECT_TRUE(did_run);
133 void RunTest_RepeatingTimer(MessageLoop::Type message_loop_type) {
134 MessageLoop loop(message_loop_type);
136 bool did_run = false;
137 RepeatingTimerTester f(&did_run);
138 f.Start();
140 MessageLoop::current()->Run();
142 EXPECT_TRUE(did_run);
145 void RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type) {
146 MessageLoop loop(message_loop_type);
148 bool did_run_a = false;
149 RepeatingTimerTester* a = new RepeatingTimerTester(&did_run_a);
151 // This should run before the timer expires.
152 MessageLoop::current()->DeleteSoon(FROM_HERE, a);
154 // Now start the timer.
155 a->Start();
157 bool did_run_b = false;
158 RepeatingTimerTester b(&did_run_b);
159 b.Start();
161 MessageLoop::current()->Run();
163 EXPECT_FALSE(did_run_a);
164 EXPECT_TRUE(did_run_b);
167 class DelayTimerTarget {
168 public:
169 DelayTimerTarget()
170 : signaled_(false) {
173 bool signaled() const { return signaled_; }
175 void Signal() {
176 ASSERT_FALSE(signaled_);
177 signaled_ = true;
180 private:
181 bool signaled_;
184 void RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type) {
185 MessageLoop loop(message_loop_type);
187 // If Delay is never called, the timer shouldn't go off.
188 DelayTimerTarget target;
189 base::DelayTimer<DelayTimerTarget> timer(FROM_HERE,
190 TimeDelta::FromMilliseconds(1), &target, &DelayTimerTarget::Signal);
192 bool did_run = false;
193 OneShotTimerTester tester(&did_run);
194 tester.Start();
195 MessageLoop::current()->Run();
197 ASSERT_FALSE(target.signaled());
200 void RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type) {
201 MessageLoop loop(message_loop_type);
203 DelayTimerTarget target;
204 base::DelayTimer<DelayTimerTarget> timer(FROM_HERE,
205 TimeDelta::FromMilliseconds(1), &target, &DelayTimerTarget::Signal);
206 timer.Reset();
208 bool did_run = false;
209 OneShotTimerTester tester(&did_run, 100 /* milliseconds */);
210 tester.Start();
211 MessageLoop::current()->Run();
213 ASSERT_TRUE(target.signaled());
216 struct ResetHelper {
217 ResetHelper(base::DelayTimer<DelayTimerTarget>* timer,
218 DelayTimerTarget* target)
219 : timer_(timer),
220 target_(target) {
223 void Reset() {
224 ASSERT_FALSE(target_->signaled());
225 timer_->Reset();
228 private:
229 base::DelayTimer<DelayTimerTarget> *const timer_;
230 DelayTimerTarget *const target_;
233 void RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type) {
234 MessageLoop loop(message_loop_type);
236 // If Delay is never called, the timer shouldn't go off.
237 DelayTimerTarget target;
238 base::DelayTimer<DelayTimerTarget> timer(FROM_HERE,
239 TimeDelta::FromMilliseconds(50), &target, &DelayTimerTarget::Signal);
240 timer.Reset();
242 ResetHelper reset_helper(&timer, &target);
244 base::OneShotTimer<ResetHelper> timers[20];
245 for (size_t i = 0; i < arraysize(timers); ++i) {
246 timers[i].Start(FROM_HERE, TimeDelta::FromMilliseconds(i * 10),
247 &reset_helper, &ResetHelper::Reset);
250 bool did_run = false;
251 OneShotTimerTester tester(&did_run, 300);
252 tester.Start();
253 MessageLoop::current()->Run();
255 ASSERT_TRUE(target.signaled());
258 class DelayTimerFatalTarget {
259 public:
260 void Signal() {
261 ASSERT_TRUE(false);
266 void RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type) {
267 MessageLoop loop(message_loop_type);
269 DelayTimerFatalTarget target;
272 base::DelayTimer<DelayTimerFatalTarget> timer(
273 FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
274 &DelayTimerFatalTarget::Signal);
275 timer.Reset();
278 // When the timer is deleted, the DelayTimerFatalTarget should never be
279 // called.
280 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
283 } // namespace
285 //-----------------------------------------------------------------------------
286 // Each test is run against each type of MessageLoop. That way we are sure
287 // that timers work properly in all configurations.
289 TEST(TimerTest, OneShotTimer) {
290 for (int i = 0; i < kNumTestingMessageLoops; i++) {
291 RunTest_OneShotTimer(testing_message_loops[i]);
295 TEST(TimerTest, OneShotTimer_Cancel) {
296 for (int i = 0; i < kNumTestingMessageLoops; i++) {
297 RunTest_OneShotTimer_Cancel(testing_message_loops[i]);
301 // If underline timer does not handle properly, we will crash or fail
302 // in full page heap environment.
303 TEST(TimerTest, OneShotSelfDeletingTimer) {
304 for (int i = 0; i < kNumTestingMessageLoops; i++) {
305 RunTest_OneShotSelfDeletingTimer(testing_message_loops[i]);
309 TEST(TimerTest, RepeatingTimer) {
310 for (int i = 0; i < kNumTestingMessageLoops; i++) {
311 RunTest_RepeatingTimer(testing_message_loops[i]);
315 TEST(TimerTest, RepeatingTimer_Cancel) {
316 for (int i = 0; i < kNumTestingMessageLoops; i++) {
317 RunTest_RepeatingTimer_Cancel(testing_message_loops[i]);
321 TEST(TimerTest, DelayTimer_NoCall) {
322 for (int i = 0; i < kNumTestingMessageLoops; i++) {
323 RunTest_DelayTimer_NoCall(testing_message_loops[i]);
327 TEST(TimerTest, DelayTimer_OneCall) {
328 for (int i = 0; i < kNumTestingMessageLoops; i++) {
329 RunTest_DelayTimer_OneCall(testing_message_loops[i]);
333 // It's flaky on the buildbot, http://crbug.com/25038.
334 TEST(TimerTest, DISABLED_DelayTimer_Reset) {
335 for (int i = 0; i < kNumTestingMessageLoops; i++) {
336 RunTest_DelayTimer_Reset(testing_message_loops[i]);
340 TEST(TimerTest, DelayTimer_Deleted) {
341 for (int i = 0; i < kNumTestingMessageLoops; i++) {
342 RunTest_DelayTimer_Deleted(testing_message_loops[i]);
346 TEST(TimerTest, MessageLoopShutdown) {
347 // This test is designed to verify that shutdown of the
348 // message loop does not cause crashes if there were pending
349 // timers not yet fired. It may only trigger exceptions
350 // if debug heap checking is enabled.
351 bool did_run = false;
353 OneShotTimerTester a(&did_run);
354 OneShotTimerTester b(&did_run);
355 OneShotTimerTester c(&did_run);
356 OneShotTimerTester d(&did_run);
358 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
359 a.Start();
360 b.Start();
361 } // MessageLoop destructs by falling out of scope.
362 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
364 EXPECT_FALSE(did_run);
367 void TimerTestCallback() {
370 TEST(TimerTest, NonRepeatIsRunning) {
372 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
373 base::Timer timer(false, false);
374 EXPECT_FALSE(timer.IsRunning());
375 timer.Start(FROM_HERE, TimeDelta::FromDays(1),
376 base::Bind(&TimerTestCallback));
377 EXPECT_TRUE(timer.IsRunning());
378 timer.Stop();
379 EXPECT_FALSE(timer.IsRunning());
380 EXPECT_TRUE(timer.user_task().is_null());
384 base::Timer timer(true, false);
385 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
386 EXPECT_FALSE(timer.IsRunning());
387 timer.Start(FROM_HERE, TimeDelta::FromDays(1),
388 base::Bind(&TimerTestCallback));
389 EXPECT_TRUE(timer.IsRunning());
390 timer.Stop();
391 EXPECT_FALSE(timer.IsRunning());
392 ASSERT_FALSE(timer.user_task().is_null());
393 timer.Reset();
394 EXPECT_TRUE(timer.IsRunning());
398 TEST(TimerTest, NonRepeatMessageLoopDeath) {
399 base::Timer timer(false, false);
401 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
402 EXPECT_FALSE(timer.IsRunning());
403 timer.Start(FROM_HERE, TimeDelta::FromDays(1),
404 base::Bind(&TimerTestCallback));
405 EXPECT_TRUE(timer.IsRunning());
407 EXPECT_FALSE(timer.IsRunning());
408 EXPECT_TRUE(timer.user_task().is_null());
411 TEST(TimerTest, RetainRepeatIsRunning) {
412 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
413 base::Timer timer(FROM_HERE, TimeDelta::FromDays(1),
414 base::Bind(&TimerTestCallback), true);
415 EXPECT_FALSE(timer.IsRunning());
416 timer.Reset();
417 EXPECT_TRUE(timer.IsRunning());
418 timer.Stop();
419 EXPECT_FALSE(timer.IsRunning());
420 timer.Reset();
421 EXPECT_TRUE(timer.IsRunning());
424 TEST(TimerTest, RetainNonRepeatIsRunning) {
425 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
426 base::Timer timer(FROM_HERE, TimeDelta::FromDays(1),
427 base::Bind(&TimerTestCallback), false);
428 EXPECT_FALSE(timer.IsRunning());
429 timer.Reset();
430 EXPECT_TRUE(timer.IsRunning());
431 timer.Stop();
432 EXPECT_FALSE(timer.IsRunning());
433 timer.Reset();
434 EXPECT_TRUE(timer.IsRunning());
437 namespace {
439 bool g_callback_happened1 = false;
440 bool g_callback_happened2 = false;
442 void ClearAllCallbackHappened() {
443 g_callback_happened1 = false;
444 g_callback_happened2 = false;
447 void SetCallbackHappened1() {
448 g_callback_happened1 = true;
449 MessageLoop::current()->Quit();
452 void SetCallbackHappened2() {
453 g_callback_happened2 = true;
454 MessageLoop::current()->Quit();
457 TEST(TimerTest, ContinuationStopStart) {
459 ClearAllCallbackHappened();
460 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
461 base::Timer timer(false, false);
462 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
463 base::Bind(&SetCallbackHappened1));
464 timer.Stop();
465 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(40),
466 base::Bind(&SetCallbackHappened2));
467 MessageLoop::current()->Run();
468 EXPECT_FALSE(g_callback_happened1);
469 EXPECT_TRUE(g_callback_happened2);
473 TEST(TimerTest, ContinuationReset) {
475 ClearAllCallbackHappened();
476 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
477 base::Timer timer(false, false);
478 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
479 base::Bind(&SetCallbackHappened1));
480 timer.Reset();
481 // Since Reset happened before task ran, the user_task must not be cleared:
482 ASSERT_FALSE(timer.user_task().is_null());
483 MessageLoop::current()->Run();
484 EXPECT_TRUE(g_callback_happened1);
488 } // namespace