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/timer/timer.h"
6
7 #include <stddef.h>
8
9 #include <memory>
10
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/callback.h"
14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/message_loop/message_loop.h"
18 #include "base/run_loop.h"
19 #include "base/sequenced_task_runner.h"
20 #include "base/synchronization/waitable_event.h"
21 #include "base/task_scheduler/post_task.h"
22 #include "base/test/scoped_task_environment.h"
23 #include "base/test/test_mock_time_task_runner.h"
24 #include "base/threading/platform_thread.h"
25 #include "base/threading/sequenced_task_runner_handle.h"
26 #include "base/threading/thread.h"
27 #include "base/time/tick_clock.h"
28 #include "base/time/time.h"
29 #include "build/build_config.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31
32 namespace base {
33
34 namespace {
35
36 // The message loops on which each timer should be tested.
37 const MessageLoop::Type testing_message_loops[] = {
38 MessageLoop::TYPE_DEFAULT, MessageLoop::TYPE_IO,
39 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
40 MessageLoop::TYPE_UI,
41 #endif
42 };
43
44 const int kNumTestingMessageLoops = arraysize(testing_message_loops);
45
46 class Receiver {
47 public:
Receiver()48 Receiver() : count_(0) {}
OnCalled()49 void OnCalled() { count_++; }
WasCalled()50 bool WasCalled() { return count_ > 0; }
TimesCalled()51 int TimesCalled() { return count_; }
52
53 private:
54 int count_;
55 };
56
57 // A basic helper class that can start a one-shot timer and signal a
58 // WaitableEvent when this timer fires.
59 class OneShotTimerTesterBase {
60 public:
61 // |did_run|, if provided, will be signaled when Run() fires.
OneShotTimerTesterBase(WaitableEvent * did_run=nullptr,const TimeDelta & delay=TimeDelta::FromMilliseconds (10))62 explicit OneShotTimerTesterBase(
63 WaitableEvent* did_run = nullptr,
64 const TimeDelta& delay = TimeDelta::FromMilliseconds(10))
65 : did_run_(did_run), delay_(delay) {}
66
67 virtual ~OneShotTimerTesterBase() = default;
68
Start()69 void Start() {
70 started_time_ = TimeTicks::Now();
71 timer_->Start(FROM_HERE, delay_, this, &OneShotTimerTesterBase::Run);
72 }
73
IsRunning()74 bool IsRunning() { return timer_->IsRunning(); }
75
started_time() const76 TimeTicks started_time() const { return started_time_; }
delay() const77 TimeDelta delay() const { return delay_; }
78
79 protected:
Run()80 virtual void Run() {
81 if (did_run_) {
82 EXPECT_FALSE(did_run_->IsSignaled());
83 did_run_->Signal();
84 }
85 }
86
87 std::unique_ptr<OneShotTimer> timer_ = std::make_unique<OneShotTimer>();
88
89 private:
90 WaitableEvent* const did_run_;
91 const TimeDelta delay_;
92 TimeTicks started_time_;
93
94 DISALLOW_COPY_AND_ASSIGN(OneShotTimerTesterBase);
95 };
96
97 // Extends functionality of OneShotTimerTesterBase with the abilities to wait
98 // until the timer fires and to change task runner for the timer.
99 class OneShotTimerTester : public OneShotTimerTesterBase {
100 public:
101 // |did_run|, if provided, will be signaled when Run() fires.
OneShotTimerTester(WaitableEvent * did_run=nullptr,const TimeDelta & delay=TimeDelta::FromMilliseconds (10))102 explicit OneShotTimerTester(
103 WaitableEvent* did_run = nullptr,
104 const TimeDelta& delay = TimeDelta::FromMilliseconds(10))
105 : OneShotTimerTesterBase(did_run, delay),
106 quit_closure_(run_loop_.QuitClosure()) {}
107
108 ~OneShotTimerTester() override = default;
109
SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner)110 void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) {
111 timer_->SetTaskRunner(std::move(task_runner));
112
113 // Run() will be invoked on |task_runner| but |run_loop_|'s QuitClosure
114 // needs to run on this thread (where the MessageLoop lives).
115 quit_closure_ = Bind(IgnoreResult(&SequencedTaskRunner::PostTask),
116 SequencedTaskRunnerHandle::Get(), FROM_HERE,
117 run_loop_.QuitClosure());
118 }
119
120 // Blocks until Run() executes and confirms that Run() didn't fire before
121 // |delay_| expired.
WaitAndConfirmTimerFiredAfterDelay()122 void WaitAndConfirmTimerFiredAfterDelay() {
123 run_loop_.Run();
124
125 EXPECT_NE(TimeTicks(), started_time());
126 EXPECT_GE(TimeTicks::Now() - started_time(), delay());
127 }
128
129 protected:
130 // Overridable method to do things on Run() before signaling events/closures
131 // managed by this helper.
OnRun()132 virtual void OnRun() {}
133
134 private:
Run()135 void Run() override {
136 OnRun();
137 OneShotTimerTesterBase::Run();
138 quit_closure_.Run();
139 }
140
141 RunLoop run_loop_;
142 Closure quit_closure_;
143
144 DISALLOW_COPY_AND_ASSIGN(OneShotTimerTester);
145 };
146
147 class OneShotSelfDeletingTimerTester : public OneShotTimerTester {
148 protected:
OnRun()149 void OnRun() override { timer_.reset(); }
150 };
151
152 constexpr int kNumRepeats = 10;
153
154 class RepeatingTimerTester {
155 public:
RepeatingTimerTester(WaitableEvent * did_run,const TimeDelta & delay)156 explicit RepeatingTimerTester(WaitableEvent* did_run, const TimeDelta& delay)
157 : counter_(kNumRepeats),
158 quit_closure_(run_loop_.QuitClosure()),
159 did_run_(did_run),
160 delay_(delay) {}
161
Start()162 void Start() {
163 started_time_ = TimeTicks::Now();
164 timer_.Start(FROM_HERE, delay_, this, &RepeatingTimerTester::Run);
165 }
166
WaitAndConfirmTimerFiredRepeatedlyAfterDelay()167 void WaitAndConfirmTimerFiredRepeatedlyAfterDelay() {
168 run_loop_.Run();
169
170 EXPECT_NE(TimeTicks(), started_time_);
171 EXPECT_GE(TimeTicks::Now() - started_time_, kNumRepeats * delay_);
172 }
173
174 private:
Run()175 void Run() {
176 if (--counter_ == 0) {
177 if (did_run_) {
178 EXPECT_FALSE(did_run_->IsSignaled());
179 did_run_->Signal();
180 }
181 timer_.Stop();
182 quit_closure_.Run();
183 }
184 }
185
186 RepeatingTimer timer_;
187 int counter_;
188
189 RunLoop run_loop_;
190 Closure quit_closure_;
191 WaitableEvent* const did_run_;
192
193 const TimeDelta delay_;
194 TimeTicks started_time_;
195
196 DISALLOW_COPY_AND_ASSIGN(RepeatingTimerTester);
197 };
198
199 // Basic test with same setup as RunTest_OneShotTimers_Cancel below to confirm
200 // that |did_run_a| would be signaled in that test if it wasn't for the
201 // deletion.
RunTest_OneShotTimers(MessageLoop::Type message_loop_type)202 void RunTest_OneShotTimers(MessageLoop::Type message_loop_type) {
203 MessageLoop loop(message_loop_type);
204
205 WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
206 WaitableEvent::InitialState::NOT_SIGNALED);
207 OneShotTimerTester a(&did_run_a);
208 a.Start();
209
210 OneShotTimerTester b;
211 b.Start();
212
213 b.WaitAndConfirmTimerFiredAfterDelay();
214
215 EXPECT_TRUE(did_run_a.IsSignaled());
216 }
217
RunTest_OneShotTimers_Cancel(MessageLoop::Type message_loop_type)218 void RunTest_OneShotTimers_Cancel(MessageLoop::Type message_loop_type) {
219 MessageLoop loop(message_loop_type);
220
221 WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
222 WaitableEvent::InitialState::NOT_SIGNALED);
223 OneShotTimerTester* a = new OneShotTimerTester(&did_run_a);
224
225 // This should run before the timer expires.
226 SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
227
228 // Now start the timer.
229 a->Start();
230
231 OneShotTimerTester b;
232 b.Start();
233
234 b.WaitAndConfirmTimerFiredAfterDelay();
235
236 EXPECT_FALSE(did_run_a.IsSignaled());
237 }
238
RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type)239 void RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type) {
240 MessageLoop loop(message_loop_type);
241
242 OneShotSelfDeletingTimerTester f;
243 f.Start();
244 f.WaitAndConfirmTimerFiredAfterDelay();
245 }
246
RunTest_RepeatingTimer(MessageLoop::Type message_loop_type,const TimeDelta & delay)247 void RunTest_RepeatingTimer(MessageLoop::Type message_loop_type,
248 const TimeDelta& delay) {
249 MessageLoop loop(message_loop_type);
250
251 RepeatingTimerTester f(nullptr, delay);
252 f.Start();
253 f.WaitAndConfirmTimerFiredRepeatedlyAfterDelay();
254 }
255
RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type,const TimeDelta & delay)256 void RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type,
257 const TimeDelta& delay) {
258 MessageLoop loop(message_loop_type);
259
260 WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
261 WaitableEvent::InitialState::NOT_SIGNALED);
262 RepeatingTimerTester* a = new RepeatingTimerTester(&did_run_a, delay);
263
264 // This should run before the timer expires.
265 SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
266
267 // Now start the timer.
268 a->Start();
269
270 RepeatingTimerTester b(nullptr, delay);
271 b.Start();
272
273 b.WaitAndConfirmTimerFiredRepeatedlyAfterDelay();
274
275 // |a| should not have fired despite |b| starting after it on the same
276 // sequence and being complete by now.
277 EXPECT_FALSE(did_run_a.IsSignaled());
278 }
279
280 class DelayTimerTarget {
281 public:
signaled() const282 bool signaled() const { return signaled_; }
283
Signal()284 void Signal() {
285 ASSERT_FALSE(signaled_);
286 signaled_ = true;
287 }
288
289 private:
290 bool signaled_ = false;
291 };
292
RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type)293 void RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type) {
294 MessageLoop loop(message_loop_type);
295
296 // If Delay is never called, the timer shouldn't go off.
297 DelayTimerTarget target;
298 DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(1), &target,
299 &DelayTimerTarget::Signal);
300
301 OneShotTimerTester tester;
302 tester.Start();
303 tester.WaitAndConfirmTimerFiredAfterDelay();
304
305 ASSERT_FALSE(target.signaled());
306 }
307
RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type)308 void RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type) {
309 MessageLoop loop(message_loop_type);
310
311 DelayTimerTarget target;
312 DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(1), &target,
313 &DelayTimerTarget::Signal);
314 timer.Reset();
315
316 OneShotTimerTester tester(nullptr, TimeDelta::FromMilliseconds(100));
317 tester.Start();
318 tester.WaitAndConfirmTimerFiredAfterDelay();
319
320 ASSERT_TRUE(target.signaled());
321 }
322
323 struct ResetHelper {
ResetHelperbase::__anon4ee860b90111::ResetHelper324 ResetHelper(DelayTimer* timer, DelayTimerTarget* target)
325 : timer_(timer), target_(target) {}
326
Resetbase::__anon4ee860b90111::ResetHelper327 void Reset() {
328 ASSERT_FALSE(target_->signaled());
329 timer_->Reset();
330 }
331
332 private:
333 DelayTimer* const timer_;
334 DelayTimerTarget* const target_;
335 };
336
RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type)337 void RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type) {
338 MessageLoop loop(message_loop_type);
339
340 // If Delay is never called, the timer shouldn't go off.
341 DelayTimerTarget target;
342 DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
343 &DelayTimerTarget::Signal);
344 timer.Reset();
345
346 ResetHelper reset_helper(&timer, &target);
347
348 OneShotTimer timers[20];
349 for (size_t i = 0; i < arraysize(timers); ++i) {
350 timers[i].Start(FROM_HERE, TimeDelta::FromMilliseconds(i * 10),
351 &reset_helper, &ResetHelper::Reset);
352 }
353
354 OneShotTimerTester tester(nullptr, TimeDelta::FromMilliseconds(300));
355 tester.Start();
356 tester.WaitAndConfirmTimerFiredAfterDelay();
357
358 ASSERT_TRUE(target.signaled());
359 }
360
361 class DelayTimerFatalTarget {
362 public:
Signal()363 void Signal() {
364 ASSERT_TRUE(false);
365 }
366 };
367
RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type)368 void RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type) {
369 MessageLoop loop(message_loop_type);
370
371 DelayTimerFatalTarget target;
372
373 {
374 DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
375 &DelayTimerFatalTarget::Signal);
376 timer.Reset();
377 }
378
379 // When the timer is deleted, the DelayTimerFatalTarget should never be
380 // called.
381 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
382 }
383
384 } // namespace
385
386 //-----------------------------------------------------------------------------
387 // Each test is run against each type of MessageLoop. That way we are sure
388 // that timers work properly in all configurations.
389
TEST(TimerTest,OneShotTimers)390 TEST(TimerTest, OneShotTimers) {
391 for (int i = 0; i < kNumTestingMessageLoops; i++) {
392 RunTest_OneShotTimers(testing_message_loops[i]);
393 }
394 }
395
TEST(TimerTest,OneShotTimers_Cancel)396 TEST(TimerTest, OneShotTimers_Cancel) {
397 for (int i = 0; i < kNumTestingMessageLoops; i++) {
398 RunTest_OneShotTimers_Cancel(testing_message_loops[i]);
399 }
400 }
401
402 // If underline timer does not handle properly, we will crash or fail
403 // in full page heap environment.
TEST(TimerTest,OneShotSelfDeletingTimer)404 TEST(TimerTest, OneShotSelfDeletingTimer) {
405 for (int i = 0; i < kNumTestingMessageLoops; i++) {
406 RunTest_OneShotSelfDeletingTimer(testing_message_loops[i]);
407 }
408 }
409
TEST(TimerTest,OneShotTimer_CustomTaskRunner)410 TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
411 // A MessageLoop is required for the timer events on the other thread to
412 // communicate back to the Timer under test.
413 MessageLoop loop;
414
415 Thread other_thread("OneShotTimer_CustomTaskRunner");
416 other_thread.Start();
417
418 WaitableEvent did_run(WaitableEvent::ResetPolicy::MANUAL,
419 WaitableEvent::InitialState::NOT_SIGNALED);
420 OneShotTimerTester f(&did_run);
421 f.SetTaskRunner(other_thread.task_runner());
422 f.Start();
423 EXPECT_TRUE(f.IsRunning() || did_run.IsSignaled());
424
425 f.WaitAndConfirmTimerFiredAfterDelay();
426 EXPECT_TRUE(did_run.IsSignaled());
427
428 // |f| should already have communicated back to this |loop| before invoking
429 // Run() and as such this thread should already be aware that |f| is no longer
430 // running.
431 EXPECT_TRUE(loop.IsIdleForTesting());
432 EXPECT_FALSE(f.IsRunning());
433 }
434
TEST(TimerTest,OneShotTimerWithTickClock)435 TEST(TimerTest, OneShotTimerWithTickClock) {
436 scoped_refptr<TestMockTimeTaskRunner> task_runner(
437 new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
438 MessageLoop message_loop;
439 message_loop.SetTaskRunner(task_runner);
440 Receiver receiver;
441 OneShotTimer timer(task_runner->GetMockTickClock());
442 timer.Start(FROM_HERE, TimeDelta::FromSeconds(1),
443 Bind(&Receiver::OnCalled, Unretained(&receiver)));
444 task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
445 EXPECT_TRUE(receiver.WasCalled());
446 }
447
TEST(TimerTest,RepeatingTimer)448 TEST(TimerTest, RepeatingTimer) {
449 for (int i = 0; i < kNumTestingMessageLoops; i++) {
450 RunTest_RepeatingTimer(testing_message_loops[i],
451 TimeDelta::FromMilliseconds(10));
452 }
453 }
454
TEST(TimerTest,RepeatingTimer_Cancel)455 TEST(TimerTest, RepeatingTimer_Cancel) {
456 for (int i = 0; i < kNumTestingMessageLoops; i++) {
457 RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
458 TimeDelta::FromMilliseconds(10));
459 }
460 }
461
TEST(TimerTest,RepeatingTimerZeroDelay)462 TEST(TimerTest, RepeatingTimerZeroDelay) {
463 for (int i = 0; i < kNumTestingMessageLoops; i++) {
464 RunTest_RepeatingTimer(testing_message_loops[i],
465 TimeDelta::FromMilliseconds(0));
466 }
467 }
468
TEST(TimerTest,RepeatingTimerZeroDelay_Cancel)469 TEST(TimerTest, RepeatingTimerZeroDelay_Cancel) {
470 for (int i = 0; i < kNumTestingMessageLoops; i++) {
471 RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
472 TimeDelta::FromMilliseconds(0));
473 }
474 }
475
TEST(TimerTest,RepeatingTimerWithTickClock)476 TEST(TimerTest, RepeatingTimerWithTickClock) {
477 scoped_refptr<TestMockTimeTaskRunner> task_runner(
478 new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
479 MessageLoop message_loop;
480 message_loop.SetTaskRunner(task_runner);
481 Receiver receiver;
482 const int expected_times_called = 10;
483 RepeatingTimer timer(task_runner->GetMockTickClock());
484 timer.Start(FROM_HERE, TimeDelta::FromSeconds(1),
485 Bind(&Receiver::OnCalled, Unretained(&receiver)));
486 task_runner->FastForwardBy(TimeDelta::FromSeconds(expected_times_called));
487 timer.Stop();
488 EXPECT_EQ(expected_times_called, receiver.TimesCalled());
489 }
490
TEST(TimerTest,DelayTimer_NoCall)491 TEST(TimerTest, DelayTimer_NoCall) {
492 for (int i = 0; i < kNumTestingMessageLoops; i++) {
493 RunTest_DelayTimer_NoCall(testing_message_loops[i]);
494 }
495 }
496
TEST(TimerTest,DelayTimer_OneCall)497 TEST(TimerTest, DelayTimer_OneCall) {
498 for (int i = 0; i < kNumTestingMessageLoops; i++) {
499 RunTest_DelayTimer_OneCall(testing_message_loops[i]);
500 }
501 }
502
503 // It's flaky on the buildbot, http://crbug.com/25038.
TEST(TimerTest,DISABLED_DelayTimer_Reset)504 TEST(TimerTest, DISABLED_DelayTimer_Reset) {
505 for (int i = 0; i < kNumTestingMessageLoops; i++) {
506 RunTest_DelayTimer_Reset(testing_message_loops[i]);
507 }
508 }
509
TEST(TimerTest,DelayTimer_Deleted)510 TEST(TimerTest, DelayTimer_Deleted) {
511 for (int i = 0; i < kNumTestingMessageLoops; i++) {
512 RunTest_DelayTimer_Deleted(testing_message_loops[i]);
513 }
514 }
515
TEST(TimerTest,DelayTimerWithTickClock)516 TEST(TimerTest, DelayTimerWithTickClock) {
517 scoped_refptr<TestMockTimeTaskRunner> task_runner(
518 new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
519 MessageLoop message_loop;
520 message_loop.SetTaskRunner(task_runner);
521 Receiver receiver;
522 DelayTimer timer(FROM_HERE, TimeDelta::FromSeconds(1), &receiver,
523 &Receiver::OnCalled, task_runner->GetMockTickClock());
524 task_runner->FastForwardBy(TimeDelta::FromMilliseconds(999));
525 EXPECT_FALSE(receiver.WasCalled());
526 timer.Reset();
527 task_runner->FastForwardBy(TimeDelta::FromMilliseconds(999));
528 EXPECT_FALSE(receiver.WasCalled());
529 timer.Reset();
530 task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
531 EXPECT_TRUE(receiver.WasCalled());
532 }
533
TEST(TimerTest,MessageLoopShutdown)534 TEST(TimerTest, MessageLoopShutdown) {
535 // This test is designed to verify that shutdown of the
536 // message loop does not cause crashes if there were pending
537 // timers not yet fired. It may only trigger exceptions
538 // if debug heap checking is enabled.
539 WaitableEvent did_run(WaitableEvent::ResetPolicy::MANUAL,
540 WaitableEvent::InitialState::NOT_SIGNALED);
541 {
542 OneShotTimerTesterBase a(&did_run);
543 OneShotTimerTesterBase b(&did_run);
544 OneShotTimerTesterBase c(&did_run);
545 OneShotTimerTesterBase d(&did_run);
546 {
547 MessageLoop loop;
548 a.Start();
549 b.Start();
550 } // MessageLoop destructs by falling out of scope.
551 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
552
553 EXPECT_FALSE(did_run.IsSignaled());
554 }
555
556 // Ref counted class which owns a Timer. The class passes a reference to itself
557 // via the |user_task| parameter in Timer::Start(). |Timer::user_task_| might
558 // end up holding the last reference to the class.
559 class OneShotSelfOwningTimerTester
560 : public RefCounted<OneShotSelfOwningTimerTester> {
561 public:
562 OneShotSelfOwningTimerTester() = default;
563
StartTimer()564 void StartTimer() {
565 // Start timer with long delay in order to test the timer getting destroyed
566 // while a timer task is still pending.
567 timer_.Start(FROM_HERE, TimeDelta::FromDays(1),
568 base::Bind(&OneShotSelfOwningTimerTester::Run, this));
569 }
570
571 private:
572 friend class RefCounted<OneShotSelfOwningTimerTester>;
573 ~OneShotSelfOwningTimerTester() = default;
574
Run()575 void Run() {
576 ADD_FAILURE() << "Timer unexpectedly fired.";
577 }
578
579 OneShotTimer timer_;
580
581 DISALLOW_COPY_AND_ASSIGN(OneShotSelfOwningTimerTester);
582 };
583
TEST(TimerTest,MessageLoopShutdownSelfOwningTimer)584 TEST(TimerTest, MessageLoopShutdownSelfOwningTimer) {
585 // This test verifies that shutdown of the message loop does not cause crashes
586 // if there is a pending timer not yet fired and |Timer::user_task_| owns the
587 // timer. The test may only trigger exceptions if debug heap checking is
588 // enabled.
589
590 MessageLoop loop;
591 scoped_refptr<OneShotSelfOwningTimerTester> tester =
592 new OneShotSelfOwningTimerTester();
593
594 std::move(tester)->StartTimer();
595 // |Timer::user_task_| owns sole reference to |tester|.
596
597 // MessageLoop destructs by falling out of scope. SHOULD NOT CRASH.
598 }
599
TimerTestCallback()600 void TimerTestCallback() {
601 }
602
TEST(TimerTest,NonRepeatIsRunning)603 TEST(TimerTest, NonRepeatIsRunning) {
604 {
605 MessageLoop loop;
606 Timer timer(false, false);
607 EXPECT_FALSE(timer.IsRunning());
608 timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
609 EXPECT_TRUE(timer.IsRunning());
610 timer.Stop();
611 EXPECT_FALSE(timer.IsRunning());
612 EXPECT_TRUE(timer.user_task().is_null());
613 }
614
615 {
616 Timer timer(true, false);
617 MessageLoop loop;
618 EXPECT_FALSE(timer.IsRunning());
619 timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
620 EXPECT_TRUE(timer.IsRunning());
621 timer.Stop();
622 EXPECT_FALSE(timer.IsRunning());
623 ASSERT_FALSE(timer.user_task().is_null());
624 timer.Reset();
625 EXPECT_TRUE(timer.IsRunning());
626 }
627 }
628
TEST(TimerTest,NonRepeatMessageLoopDeath)629 TEST(TimerTest, NonRepeatMessageLoopDeath) {
630 Timer timer(false, false);
631 {
632 MessageLoop loop;
633 EXPECT_FALSE(timer.IsRunning());
634 timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
635 EXPECT_TRUE(timer.IsRunning());
636 }
637 EXPECT_FALSE(timer.IsRunning());
638 EXPECT_TRUE(timer.user_task().is_null());
639 }
640
TEST(TimerTest,RetainRepeatIsRunning)641 TEST(TimerTest, RetainRepeatIsRunning) {
642 MessageLoop loop;
643 Timer timer(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback),
644 true);
645 EXPECT_FALSE(timer.IsRunning());
646 timer.Reset();
647 EXPECT_TRUE(timer.IsRunning());
648 timer.Stop();
649 EXPECT_FALSE(timer.IsRunning());
650 timer.Reset();
651 EXPECT_TRUE(timer.IsRunning());
652 }
653
TEST(TimerTest,RetainNonRepeatIsRunning)654 TEST(TimerTest, RetainNonRepeatIsRunning) {
655 MessageLoop loop;
656 Timer timer(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback),
657 false);
658 EXPECT_FALSE(timer.IsRunning());
659 timer.Reset();
660 EXPECT_TRUE(timer.IsRunning());
661 timer.Stop();
662 EXPECT_FALSE(timer.IsRunning());
663 timer.Reset();
664 EXPECT_TRUE(timer.IsRunning());
665 }
666
667 //-----------------------------------------------------------------------------
668
669 namespace {
670
671 bool g_callback_happened1 = false;
672 bool g_callback_happened2 = false;
673
ClearAllCallbackHappened()674 void ClearAllCallbackHappened() {
675 g_callback_happened1 = false;
676 g_callback_happened2 = false;
677 }
678
SetCallbackHappened1()679 void SetCallbackHappened1() {
680 g_callback_happened1 = true;
681 RunLoop::QuitCurrentWhenIdleDeprecated();
682 }
683
SetCallbackHappened2()684 void SetCallbackHappened2() {
685 g_callback_happened2 = true;
686 RunLoop::QuitCurrentWhenIdleDeprecated();
687 }
688
689 } // namespace
690
TEST(TimerTest,ContinuationStopStart)691 TEST(TimerTest, ContinuationStopStart) {
692 {
693 ClearAllCallbackHappened();
694 MessageLoop loop;
695 Timer timer(false, false);
696 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
697 Bind(&SetCallbackHappened1));
698 timer.Stop();
699 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(40),
700 Bind(&SetCallbackHappened2));
701 RunLoop().Run();
702 EXPECT_FALSE(g_callback_happened1);
703 EXPECT_TRUE(g_callback_happened2);
704 }
705 }
706
TEST(TimerTest,ContinuationReset)707 TEST(TimerTest, ContinuationReset) {
708 {
709 ClearAllCallbackHappened();
710 MessageLoop loop;
711 Timer timer(false, false);
712 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
713 Bind(&SetCallbackHappened1));
714 timer.Reset();
715 // Since Reset happened before task ran, the user_task must not be cleared:
716 ASSERT_FALSE(timer.user_task().is_null());
717 RunLoop().Run();
718 EXPECT_TRUE(g_callback_happened1);
719 }
720 }
721
722 namespace {
723
724 // Fixture for tests requiring ScopedTaskEnvironment. Includes a WaitableEvent
725 // so that cases may Wait() on one thread and Signal() (explicitly, or
726 // implicitly via helper methods) on another.
727 class TimerSequenceTest : public testing::Test {
728 public:
TimerSequenceTest()729 TimerSequenceTest()
730 : event_(WaitableEvent::ResetPolicy::AUTOMATIC,
731 WaitableEvent::InitialState::NOT_SIGNALED) {}
732
733 // Block until Signal() is called on another thread.
Wait()734 void Wait() { event_.Wait(); }
735
Signal()736 void Signal() { event_.Signal(); }
737
738 // Helper to augment a task with a subsequent call to Signal().
TaskWithSignal(const Closure & task)739 Closure TaskWithSignal(const Closure& task) {
740 return Bind(&TimerSequenceTest::RunTaskAndSignal, Unretained(this), task);
741 }
742
743 // Create the timer.
CreateTimer()744 void CreateTimer() { timer_.reset(new OneShotTimer); }
745
746 // Schedule an event on the timer.
StartTimer(TimeDelta delay,const Closure & task)747 void StartTimer(TimeDelta delay, const Closure& task) {
748 timer_->Start(FROM_HERE, delay, task);
749 }
750
SetTaskRunnerForTimer(scoped_refptr<SequencedTaskRunner> task_runner)751 void SetTaskRunnerForTimer(scoped_refptr<SequencedTaskRunner> task_runner) {
752 timer_->SetTaskRunner(std::move(task_runner));
753 }
754
755 // Tell the timer to abandon the task.
AbandonTask()756 void AbandonTask() {
757 EXPECT_TRUE(timer_->IsRunning());
758 // Reset() to call Timer::AbandonScheduledTask()
759 timer_->Reset();
760 EXPECT_TRUE(timer_->IsRunning());
761 timer_->Stop();
762 EXPECT_FALSE(timer_->IsRunning());
763 }
764
VerifyAffinity(const SequencedTaskRunner * task_runner)765 static void VerifyAffinity(const SequencedTaskRunner* task_runner) {
766 EXPECT_TRUE(task_runner->RunsTasksInCurrentSequence());
767 }
768
769 // Delete the timer.
DeleteTimer()770 void DeleteTimer() { timer_.reset(); }
771
772 private:
RunTaskAndSignal(const Closure & task)773 void RunTaskAndSignal(const Closure& task) {
774 task.Run();
775 Signal();
776 }
777
778 base::test::ScopedTaskEnvironment scoped_task_environment_;
779 WaitableEvent event_;
780 std::unique_ptr<OneShotTimer> timer_;
781
782 DISALLOW_COPY_AND_ASSIGN(TimerSequenceTest);
783 };
784
785 } // namespace
786
TEST_F(TimerSequenceTest,OneShotTimerTaskOnPoolSequence)787 TEST_F(TimerSequenceTest, OneShotTimerTaskOnPoolSequence) {
788 scoped_refptr<SequencedTaskRunner> task_runner =
789 base::CreateSequencedTaskRunnerWithTraits({});
790
791 base::RunLoop run_loop_;
792
793 // Timer is created on this thread.
794 CreateTimer();
795
796 // Task will execute on a pool thread.
797 SetTaskRunnerForTimer(task_runner);
798 StartTimer(TimeDelta::FromMilliseconds(1),
799 Bind(IgnoreResult(&SequencedTaskRunner::PostTask),
800 SequencedTaskRunnerHandle::Get(), FROM_HERE,
801 run_loop_.QuitClosure()));
802
803 // Spin the loop so that the delayed task fires on it, which will forward it
804 // to |task_runner|. And since the Timer's task is one that posts back to this
805 // MessageLoop to quit, we finally unblock.
806 run_loop_.Run();
807
808 // Timer will be destroyed on this thread.
809 DeleteTimer();
810 }
811
TEST_F(TimerSequenceTest,OneShotTimerUsedOnPoolSequence)812 TEST_F(TimerSequenceTest, OneShotTimerUsedOnPoolSequence) {
813 scoped_refptr<SequencedTaskRunner> task_runner =
814 base::CreateSequencedTaskRunnerWithTraits({});
815
816 // Timer is created on this thread.
817 CreateTimer();
818
819 // Task will be scheduled from a pool thread.
820 task_runner->PostTask(
821 FROM_HERE, BindOnce(&TimerSequenceTest::StartTimer, Unretained(this),
822 TimeDelta::FromMilliseconds(1),
823 Bind(&TimerSequenceTest::Signal, Unretained(this))));
824 Wait();
825
826 // Timer must be destroyed on pool thread, too.
827 task_runner->PostTask(
828 FROM_HERE,
829 TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
830 Wait();
831 }
832
TEST_F(TimerSequenceTest,OneShotTimerTwoSequencesAbandonTask)833 TEST_F(TimerSequenceTest, OneShotTimerTwoSequencesAbandonTask) {
834 scoped_refptr<SequencedTaskRunner> task_runner1 =
835 base::CreateSequencedTaskRunnerWithTraits({});
836 scoped_refptr<SequencedTaskRunner> task_runner2 =
837 base::CreateSequencedTaskRunnerWithTraits({});
838
839 // Create timer on sequence #1.
840 task_runner1->PostTask(
841 FROM_HERE,
842 TaskWithSignal(Bind(&TimerSequenceTest::CreateTimer, Unretained(this))));
843 Wait();
844
845 // And tell it to execute on a different sequence (#2).
846 task_runner1->PostTask(
847 FROM_HERE, TaskWithSignal(Bind(&TimerSequenceTest::SetTaskRunnerForTimer,
848 Unretained(this), task_runner2)));
849 Wait();
850
851 // Task will be scheduled from sequence #1.
852 task_runner1->PostTask(
853 FROM_HERE, BindOnce(&TimerSequenceTest::StartTimer, Unretained(this),
854 TimeDelta::FromHours(1), DoNothing()));
855
856 // Abandon task - must be called from scheduling sequence (#1).
857 task_runner1->PostTask(
858 FROM_HERE,
859 TaskWithSignal(Bind(&TimerSequenceTest::AbandonTask, Unretained(this))));
860 Wait();
861
862 // Timer must be destroyed on the sequence it was scheduled from (#1).
863 task_runner1->PostTask(
864 FROM_HERE,
865 TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
866 Wait();
867 }
868
TEST_F(TimerSequenceTest,OneShotTimerUsedAndTaskedOnDifferentSequences)869 TEST_F(TimerSequenceTest, OneShotTimerUsedAndTaskedOnDifferentSequences) {
870 scoped_refptr<SequencedTaskRunner> task_runner1 =
871 base::CreateSequencedTaskRunnerWithTraits({});
872 scoped_refptr<SequencedTaskRunner> task_runner2 =
873 base::CreateSequencedTaskRunnerWithTraits({});
874
875 // Create timer on sequence #1.
876 task_runner1->PostTask(
877 FROM_HERE,
878 TaskWithSignal(Bind(&TimerSequenceTest::CreateTimer, Unretained(this))));
879 Wait();
880
881 // And tell it to execute on a different sequence (#2).
882 task_runner1->PostTask(
883 FROM_HERE, TaskWithSignal(Bind(&TimerSequenceTest::SetTaskRunnerForTimer,
884 Unretained(this), task_runner2)));
885 Wait();
886
887 // Task will be scheduled from sequence #1.
888 task_runner1->PostTask(
889 FROM_HERE,
890 BindOnce(&TimerSequenceTest::StartTimer, Unretained(this),
891 TimeDelta::FromMilliseconds(1),
892 TaskWithSignal(Bind(&TimerSequenceTest::VerifyAffinity,
893 Unretained(task_runner2.get())))));
894
895 Wait();
896
897 // Timer must be destroyed on the sequence it was scheduled from (#1).
898 task_runner1->PostTask(
899 FROM_HERE,
900 TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
901 Wait();
902 }
903
904 } // namespace base
905