Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: base/timer/timer_unittest.cc

Issue 1647803004: Move base to DEPS (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/timer/timer.cc ('k') | base/tools_sanity_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 bool signaled() const { return signaled_; }
193
194 void Signal() {
195 ASSERT_FALSE(signaled_);
196 signaled_ = true;
197 }
198
199 private:
200 bool signaled_ = false;
201 };
202
203 void RunTest_DelayTimer_NoCall(base::MessageLoop::Type message_loop_type) {
204 base::MessageLoop loop(message_loop_type);
205
206 // If Delay is never called, the timer shouldn't go off.
207 DelayTimerTarget target;
208 base::DelayTimer<DelayTimerTarget> timer(FROM_HERE,
209 TimeDelta::FromMilliseconds(1), &target, &DelayTimerTarget::Signal);
210
211 bool did_run = false;
212 OneShotTimerTester tester(&did_run);
213 tester.Start();
214 base::MessageLoop::current()->Run();
215
216 ASSERT_FALSE(target.signaled());
217 }
218
219 void RunTest_DelayTimer_OneCall(base::MessageLoop::Type message_loop_type) {
220 base::MessageLoop loop(message_loop_type);
221
222 DelayTimerTarget target;
223 base::DelayTimer<DelayTimerTarget> timer(FROM_HERE,
224 TimeDelta::FromMilliseconds(1), &target, &DelayTimerTarget::Signal);
225 timer.Reset();
226
227 bool did_run = false;
228 OneShotTimerTester tester(&did_run, 100 /* milliseconds */);
229 tester.Start();
230 base::MessageLoop::current()->Run();
231
232 ASSERT_TRUE(target.signaled());
233 }
234
235 struct ResetHelper {
236 ResetHelper(base::DelayTimer<DelayTimerTarget>* timer,
237 DelayTimerTarget* target)
238 : timer_(timer),
239 target_(target) {
240 }
241
242 void Reset() {
243 ASSERT_FALSE(target_->signaled());
244 timer_->Reset();
245 }
246
247 private:
248 base::DelayTimer<DelayTimerTarget> *const timer_;
249 DelayTimerTarget *const target_;
250 };
251
252 void RunTest_DelayTimer_Reset(base::MessageLoop::Type message_loop_type) {
253 base::MessageLoop loop(message_loop_type);
254
255 // If Delay is never called, the timer shouldn't go off.
256 DelayTimerTarget target;
257 base::DelayTimer<DelayTimerTarget> timer(FROM_HERE,
258 TimeDelta::FromMilliseconds(50), &target, &DelayTimerTarget::Signal);
259 timer.Reset();
260
261 ResetHelper reset_helper(&timer, &target);
262
263 base::OneShotTimer<ResetHelper> timers[20];
264 for (size_t i = 0; i < arraysize(timers); ++i) {
265 timers[i].Start(FROM_HERE, TimeDelta::FromMilliseconds(i * 10),
266 &reset_helper, &ResetHelper::Reset);
267 }
268
269 bool did_run = false;
270 OneShotTimerTester tester(&did_run, 300);
271 tester.Start();
272 base::MessageLoop::current()->Run();
273
274 ASSERT_TRUE(target.signaled());
275 }
276
277 class DelayTimerFatalTarget {
278 public:
279 void Signal() {
280 ASSERT_TRUE(false);
281 }
282 };
283
284
285 void RunTest_DelayTimer_Deleted(base::MessageLoop::Type message_loop_type) {
286 base::MessageLoop loop(message_loop_type);
287
288 DelayTimerFatalTarget target;
289
290 {
291 base::DelayTimer<DelayTimerFatalTarget> timer(
292 FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
293 &DelayTimerFatalTarget::Signal);
294 timer.Reset();
295 }
296
297 // When the timer is deleted, the DelayTimerFatalTarget should never be
298 // called.
299 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
300 }
301
302 } // namespace
303
304 //-----------------------------------------------------------------------------
305 // Each test is run against each type of MessageLoop. That way we are sure
306 // that timers work properly in all configurations.
307
308 TEST(TimerTest, OneShotTimer) {
309 for (int i = 0; i < kNumTestingMessageLoops; i++) {
310 RunTest_OneShotTimer(testing_message_loops[i]);
311 }
312 }
313
314 TEST(TimerTest, OneShotTimer_Cancel) {
315 for (int i = 0; i < kNumTestingMessageLoops; i++) {
316 RunTest_OneShotTimer_Cancel(testing_message_loops[i]);
317 }
318 }
319
320 // If underline timer does not handle properly, we will crash or fail
321 // in full page heap environment.
322 TEST(TimerTest, OneShotSelfDeletingTimer) {
323 for (int i = 0; i < kNumTestingMessageLoops; i++) {
324 RunTest_OneShotSelfDeletingTimer(testing_message_loops[i]);
325 }
326 }
327
328 TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
329 scoped_refptr<base::TestSimpleTaskRunner> task_runner =
330 new base::TestSimpleTaskRunner();
331
332 bool did_run = false;
333 OneShotTimerTester f(&did_run);
334 f.SetTaskRunner(task_runner);
335 f.Start();
336
337 EXPECT_FALSE(did_run);
338 task_runner->RunUntilIdle();
339 EXPECT_TRUE(did_run);
340 }
341
342 TEST(TimerTest, RepeatingTimer) {
343 for (int i = 0; i < kNumTestingMessageLoops; i++) {
344 RunTest_RepeatingTimer(testing_message_loops[i],
345 TimeDelta::FromMilliseconds(10));
346 }
347 }
348
349 TEST(TimerTest, RepeatingTimer_Cancel) {
350 for (int i = 0; i < kNumTestingMessageLoops; i++) {
351 RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
352 TimeDelta::FromMilliseconds(10));
353 }
354 }
355
356 TEST(TimerTest, RepeatingTimerZeroDelay) {
357 for (int i = 0; i < kNumTestingMessageLoops; i++) {
358 RunTest_RepeatingTimer(testing_message_loops[i],
359 TimeDelta::FromMilliseconds(0));
360 }
361 }
362
363 TEST(TimerTest, RepeatingTimerZeroDelay_Cancel) {
364 for (int i = 0; i < kNumTestingMessageLoops; i++) {
365 RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
366 TimeDelta::FromMilliseconds(0));
367 }
368 }
369
370 TEST(TimerTest, DelayTimer_NoCall) {
371 for (int i = 0; i < kNumTestingMessageLoops; i++) {
372 RunTest_DelayTimer_NoCall(testing_message_loops[i]);
373 }
374 }
375
376 TEST(TimerTest, DelayTimer_OneCall) {
377 for (int i = 0; i < kNumTestingMessageLoops; i++) {
378 RunTest_DelayTimer_OneCall(testing_message_loops[i]);
379 }
380 }
381
382 // It's flaky on the buildbot, http://crbug.com/25038.
383 TEST(TimerTest, DISABLED_DelayTimer_Reset) {
384 for (int i = 0; i < kNumTestingMessageLoops; i++) {
385 RunTest_DelayTimer_Reset(testing_message_loops[i]);
386 }
387 }
388
389 TEST(TimerTest, DelayTimer_Deleted) {
390 for (int i = 0; i < kNumTestingMessageLoops; i++) {
391 RunTest_DelayTimer_Deleted(testing_message_loops[i]);
392 }
393 }
394
395 TEST(TimerTest, MessageLoopShutdown) {
396 // This test is designed to verify that shutdown of the
397 // message loop does not cause crashes if there were pending
398 // timers not yet fired. It may only trigger exceptions
399 // if debug heap checking is enabled.
400 bool did_run = false;
401 {
402 OneShotTimerTester a(&did_run);
403 OneShotTimerTester b(&did_run);
404 OneShotTimerTester c(&did_run);
405 OneShotTimerTester d(&did_run);
406 {
407 base::MessageLoop loop;
408 a.Start();
409 b.Start();
410 } // MessageLoop destructs by falling out of scope.
411 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
412
413 EXPECT_FALSE(did_run);
414 }
415
416 void TimerTestCallback() {
417 }
418
419 TEST(TimerTest, NonRepeatIsRunning) {
420 {
421 base::MessageLoop loop;
422 base::Timer timer(false, false);
423 EXPECT_FALSE(timer.IsRunning());
424 timer.Start(FROM_HERE, TimeDelta::FromDays(1),
425 base::Bind(&TimerTestCallback));
426 EXPECT_TRUE(timer.IsRunning());
427 timer.Stop();
428 EXPECT_FALSE(timer.IsRunning());
429 EXPECT_TRUE(timer.user_task().is_null());
430 }
431
432 {
433 base::Timer timer(true, false);
434 base::MessageLoop loop;
435 EXPECT_FALSE(timer.IsRunning());
436 timer.Start(FROM_HERE, TimeDelta::FromDays(1),
437 base::Bind(&TimerTestCallback));
438 EXPECT_TRUE(timer.IsRunning());
439 timer.Stop();
440 EXPECT_FALSE(timer.IsRunning());
441 ASSERT_FALSE(timer.user_task().is_null());
442 timer.Reset();
443 EXPECT_TRUE(timer.IsRunning());
444 }
445 }
446
447 TEST(TimerTest, NonRepeatMessageLoopDeath) {
448 base::Timer timer(false, false);
449 {
450 base::MessageLoop loop;
451 EXPECT_FALSE(timer.IsRunning());
452 timer.Start(FROM_HERE, TimeDelta::FromDays(1),
453 base::Bind(&TimerTestCallback));
454 EXPECT_TRUE(timer.IsRunning());
455 }
456 EXPECT_FALSE(timer.IsRunning());
457 EXPECT_TRUE(timer.user_task().is_null());
458 }
459
460 TEST(TimerTest, RetainRepeatIsRunning) {
461 base::MessageLoop loop;
462 base::Timer timer(FROM_HERE, TimeDelta::FromDays(1),
463 base::Bind(&TimerTestCallback), true);
464 EXPECT_FALSE(timer.IsRunning());
465 timer.Reset();
466 EXPECT_TRUE(timer.IsRunning());
467 timer.Stop();
468 EXPECT_FALSE(timer.IsRunning());
469 timer.Reset();
470 EXPECT_TRUE(timer.IsRunning());
471 }
472
473 TEST(TimerTest, RetainNonRepeatIsRunning) {
474 base::MessageLoop loop;
475 base::Timer timer(FROM_HERE, TimeDelta::FromDays(1),
476 base::Bind(&TimerTestCallback), false);
477 EXPECT_FALSE(timer.IsRunning());
478 timer.Reset();
479 EXPECT_TRUE(timer.IsRunning());
480 timer.Stop();
481 EXPECT_FALSE(timer.IsRunning());
482 timer.Reset();
483 EXPECT_TRUE(timer.IsRunning());
484 }
485
486 namespace {
487
488 bool g_callback_happened1 = false;
489 bool g_callback_happened2 = false;
490
491 void ClearAllCallbackHappened() {
492 g_callback_happened1 = false;
493 g_callback_happened2 = false;
494 }
495
496 void SetCallbackHappened1() {
497 g_callback_happened1 = true;
498 base::MessageLoop::current()->QuitWhenIdle();
499 }
500
501 void SetCallbackHappened2() {
502 g_callback_happened2 = true;
503 base::MessageLoop::current()->QuitWhenIdle();
504 }
505
506 TEST(TimerTest, ContinuationStopStart) {
507 {
508 ClearAllCallbackHappened();
509 base::MessageLoop loop;
510 base::Timer timer(false, false);
511 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
512 base::Bind(&SetCallbackHappened1));
513 timer.Stop();
514 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(40),
515 base::Bind(&SetCallbackHappened2));
516 base::MessageLoop::current()->Run();
517 EXPECT_FALSE(g_callback_happened1);
518 EXPECT_TRUE(g_callback_happened2);
519 }
520 }
521
522 TEST(TimerTest, ContinuationReset) {
523 {
524 ClearAllCallbackHappened();
525 base::MessageLoop loop;
526 base::Timer timer(false, false);
527 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
528 base::Bind(&SetCallbackHappened1));
529 timer.Reset();
530 // Since Reset happened before task ran, the user_task must not be cleared:
531 ASSERT_FALSE(timer.user_task().is_null());
532 base::MessageLoop::current()->Run();
533 EXPECT_TRUE(g_callback_happened1);
534 }
535 }
536
537 } // namespace
OLDNEW
« no previous file with comments | « base/timer/timer.cc ('k') | base/tools_sanity_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698