blob: 3de79291a9ff74a68435197eea9f4440651f6fbe [file] [log] [blame]
[email protected]a67fc9e12012-02-14 00:29:141// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
dcheng093de9b2016-04-04 21:25:515#include "base/timer/timer.h"
6
avi9b6f42932015-12-26 22:15:147#include <stddef.h>
8
dcheng093de9b2016-04-04 21:25:519#include <memory>
10
jameswest6e0c8d22016-11-15 05:19:5411#include "base/bind.h"
gab175490c12016-11-28 23:01:3312#include "base/callback.h"
danakjdb9ae7942020-11-11 16:01:3513#include "base/callback_helpers.h"
Lei Zhangb7f26222021-06-15 18:45:4714#include "base/cxx17_backports.h"
avi9b6f42932015-12-26 22:15:1415#include "base/macros.h"
gab175490c12016-11-28 23:01:3316#include "base/memory/ptr_util.h"
pkotwicz4a286ed2017-01-17 20:45:2617#include "base/memory/ref_counted.h"
fdoray10224582016-06-30 18:17:3918#include "base/run_loop.h"
gab175490c12016-11-28 23:01:3319#include "base/sequenced_task_runner.h"
gab175490c12016-11-28 23:01:3320#include "base/synchronization/waitable_event.h"
Gabriel Charette44db1422018-08-06 11:19:3321#include "base/task/post_task.h"
Guido Urdanetaef4e91942020-11-09 15:06:2422#include "base/test/bind.h"
Gabriel Charettec7108742019-08-23 03:31:4023#include "base/test/task_environment.h"
jameswest6e0c8d22016-11-15 05:19:5424#include "base/test/test_mock_time_task_runner.h"
Gabriel Charettee92ccc02019-01-19 14:13:0525#include "base/test/test_simple_task_runner.h"
gab175490c12016-11-28 23:01:3326#include "base/threading/platform_thread.h"
27#include "base/threading/sequenced_task_runner_handle.h"
28#include "base/threading/thread.h"
jameswest6e0c8d22016-11-15 05:19:5429#include "base/time/tick_clock.h"
gab175490c12016-11-28 23:01:3330#include "base/time/time.h"
avi9b6f42932015-12-26 22:15:1431#include "build/build_config.h"
initial.commitd7cae122008-07-26 21:49:3832#include "testing/gtest/include/gtest/gtest.h"
33
gab175490c12016-11-28 23:01:3334namespace base {
[email protected]e1acf6f2008-10-27 20:43:3335
[email protected]aeab57ea2008-08-28 20:50:1236namespace {
37
Sami Kyostila3f49cb572018-11-19 13:01:0938// The main thread types on which each timer should be tested.
Gabriel Charette694c3c332019-08-19 14:53:0539const test::TaskEnvironment::MainThreadType testing_main_threads[] = {
40 test::TaskEnvironment::MainThreadType::DEFAULT,
41 test::TaskEnvironment::MainThreadType::IO,
[email protected]835332b2012-07-17 11:22:5942#if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
Gabriel Charette694c3c332019-08-19 14:53:0543 test::TaskEnvironment::MainThreadType::UI,
[email protected]835332b2012-07-17 11:22:5944#endif
45};
46
jameswest6e0c8d22016-11-15 05:19:5447class Receiver {
48 public:
49 Receiver() : count_(0) {}
50 void OnCalled() { count_++; }
51 bool WasCalled() { return count_ > 0; }
52 int TimesCalled() { return count_; }
53
54 private:
55 int count_;
56};
57
ahest68c9f102016-12-13 11:34:3858// A basic helper class that can start a one-shot timer and signal a
59// WaitableEvent when this timer fires.
60class OneShotTimerTesterBase {
61 public:
62 // |did_run|, if provided, will be signaled when Run() fires.
Peter Kasting53fd6ee2021-10-05 20:40:4863 explicit OneShotTimerTesterBase(WaitableEvent* did_run = nullptr,
64 const TimeDelta& delay = Milliseconds(10))
ahest68c9f102016-12-13 11:34:3865 : did_run_(did_run), delay_(delay) {}
66
Peter Boström7319bbd2021-09-15 22:59:3867 OneShotTimerTesterBase(const OneShotTimerTesterBase&) = delete;
68 OneShotTimerTesterBase& operator=(const OneShotTimerTesterBase&) = delete;
69
ahest68c9f102016-12-13 11:34:3870 virtual ~OneShotTimerTesterBase() = default;
71
72 void Start() {
73 started_time_ = TimeTicks::Now();
74 timer_->Start(FROM_HERE, delay_, this, &OneShotTimerTesterBase::Run);
75 }
76
77 bool IsRunning() { return timer_->IsRunning(); }
78
79 TimeTicks started_time() const { return started_time_; }
80 TimeDelta delay() const { return delay_; }
81
82 protected:
83 virtual void Run() {
84 if (did_run_) {
85 EXPECT_FALSE(did_run_->IsSignaled());
86 did_run_->Signal();
87 }
88 }
89
Jeremy Roman9532f252017-08-16 23:27:2490 std::unique_ptr<OneShotTimer> timer_ = std::make_unique<OneShotTimer>();
ahest68c9f102016-12-13 11:34:3891
92 private:
93 WaitableEvent* const did_run_;
94 const TimeDelta delay_;
95 TimeTicks started_time_;
ahest68c9f102016-12-13 11:34:3896};
97
98// Extends functionality of OneShotTimerTesterBase with the abilities to wait
99// until the timer fires and to change task runner for the timer.
100class OneShotTimerTester : public OneShotTimerTesterBase {
[email protected]aeab57ea2008-08-28 20:50:12101 public:
gab175490c12016-11-28 23:01:33102 // |did_run|, if provided, will be signaled when Run() fires.
Peter Kasting53fd6ee2021-10-05 20:40:48103 explicit OneShotTimerTester(WaitableEvent* did_run = nullptr,
104 const TimeDelta& delay = Milliseconds(10))
ahest68c9f102016-12-13 11:34:38105 : OneShotTimerTesterBase(did_run, delay),
106 quit_closure_(run_loop_.QuitClosure()) {}
petrcermak7652da6d2014-11-06 02:17:57107
Peter Boström7319bbd2021-09-15 22:59:38108 OneShotTimerTester(const OneShotTimerTester&) = delete;
109 OneShotTimerTester& operator=(const OneShotTimerTester&) = delete;
110
ahest68c9f102016-12-13 11:34:38111 ~OneShotTimerTester() override = default;
petrcermak7652da6d2014-11-06 02:17:57112
gab4e844bb2017-06-01 16:23:36113 void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) {
gab175490c12016-11-28 23:01:33114 timer_->SetTaskRunner(std::move(task_runner));
115
116 // Run() will be invoked on |task_runner| but |run_loop_|'s QuitClosure
Sami Kyostila3f49cb572018-11-19 13:01:09117 // needs to run on this thread (where the task environment lives).
tzikf3336c92018-07-25 03:15:50118 quit_closure_ = BindOnce(IgnoreResult(&SequencedTaskRunner::PostTask),
119 SequencedTaskRunnerHandle::Get(), FROM_HERE,
120 run_loop_.QuitClosure());
petrcermak7652da6d2014-11-06 02:17:57121 }
122
gab175490c12016-11-28 23:01:33123 // Blocks until Run() executes and confirms that Run() didn't fire before
124 // |delay_| expired.
125 void WaitAndConfirmTimerFiredAfterDelay() {
126 run_loop_.Run();
127
ahest68c9f102016-12-13 11:34:38128 EXPECT_NE(TimeTicks(), started_time());
129 EXPECT_GE(TimeTicks::Now() - started_time(), delay());
gab175490c12016-11-28 23:01:33130 }
131
gab175490c12016-11-28 23:01:33132 protected:
133 // Overridable method to do things on Run() before signaling events/closures
134 // managed by this helper.
135 virtual void OnRun() {}
136
[email protected]95284322009-02-07 00:37:01137 private:
ahest68c9f102016-12-13 11:34:38138 void Run() override {
gab175490c12016-11-28 23:01:33139 OnRun();
ahest68c9f102016-12-13 11:34:38140 OneShotTimerTesterBase::Run();
tzikf3336c92018-07-25 03:15:50141 std::move(quit_closure_).Run();
[email protected]95284322009-02-07 00:37:01142 }
petrcermak7652da6d2014-11-06 02:17:57143
gab175490c12016-11-28 23:01:33144 RunLoop run_loop_;
tzikf3336c92018-07-25 03:15:50145 OnceClosure quit_closure_;
[email protected]95284322009-02-07 00:37:01146};
147
gab175490c12016-11-28 23:01:33148class OneShotSelfDeletingTimerTester : public OneShotTimerTester {
149 protected:
150 void OnRun() override { timer_.reset(); }
151};
152
153constexpr int kNumRepeats = 10;
154
[email protected]aeab57ea2008-08-28 20:50:12155class RepeatingTimerTester {
156 public:
gab175490c12016-11-28 23:01:33157 explicit RepeatingTimerTester(WaitableEvent* did_run, const TimeDelta& delay)
158 : counter_(kNumRepeats),
159 quit_closure_(run_loop_.QuitClosure()),
160 did_run_(did_run),
161 delay_(delay) {}
[email protected]2fdc86a2010-01-26 23:08:02162
Peter Boström75cd3c02021-09-28 15:23:18163 RepeatingTimerTester(const RepeatingTimerTester&) = delete;
164 RepeatingTimerTester& operator=(const RepeatingTimerTester&) = delete;
165
[email protected]aeab57ea2008-08-28 20:50:12166 void Start() {
gab175490c12016-11-28 23:01:33167 started_time_ = TimeTicks::Now();
[email protected]e495c532013-12-06 15:22:35168 timer_.Start(FROM_HERE, delay_, this, &RepeatingTimerTester::Run);
[email protected]aeab57ea2008-08-28 20:50:12169 }
petrcermak7652da6d2014-11-06 02:17:57170
gab175490c12016-11-28 23:01:33171 void WaitAndConfirmTimerFiredRepeatedlyAfterDelay() {
172 run_loop_.Run();
173
174 EXPECT_NE(TimeTicks(), started_time_);
175 EXPECT_GE(TimeTicks::Now() - started_time_, kNumRepeats * delay_);
176 }
177
[email protected]aeab57ea2008-08-28 20:50:12178 private:
179 void Run() {
180 if (--counter_ == 0) {
gab175490c12016-11-28 23:01:33181 if (did_run_) {
182 EXPECT_FALSE(did_run_->IsSignaled());
183 did_run_->Signal();
184 }
[email protected]e495c532013-12-06 15:22:35185 timer_.Stop();
gab175490c12016-11-28 23:01:33186 quit_closure_.Run();
[email protected]aeab57ea2008-08-28 20:50:12187 }
188 }
petrcermak7652da6d2014-11-06 02:17:57189
gab175490c12016-11-28 23:01:33190 RepeatingTimer timer_;
[email protected]aeab57ea2008-08-28 20:50:12191 int counter_;
gab175490c12016-11-28 23:01:33192
193 RunLoop run_loop_;
kylechar83fb51e52019-03-14 15:30:43194 RepeatingClosure quit_closure_;
gab175490c12016-11-28 23:01:33195 WaitableEvent* const did_run_;
196
197 const TimeDelta delay_;
198 TimeTicks started_time_;
[email protected]aeab57ea2008-08-28 20:50:12199};
200
gab175490c12016-11-28 23:01:33201// Basic test with same setup as RunTest_OneShotTimers_Cancel below to confirm
202// that |did_run_a| would be signaled in that test if it wasn't for the
203// deletion.
Sami Kyostila3f49cb572018-11-19 13:01:09204void RunTest_OneShotTimers(
Gabriel Charette694c3c332019-08-19 14:53:05205 test::TaskEnvironment::MainThreadType main_thread_type) {
206 test::TaskEnvironment task_environment(main_thread_type);
[email protected]aeab57ea2008-08-28 20:50:12207
gab175490c12016-11-28 23:01:33208 WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
209 WaitableEvent::InitialState::NOT_SIGNALED);
210 OneShotTimerTester a(&did_run_a);
211 a.Start();
[email protected]aeab57ea2008-08-28 20:50:12212
gab175490c12016-11-28 23:01:33213 OneShotTimerTester b;
214 b.Start();
[email protected]aeab57ea2008-08-28 20:50:12215
gab175490c12016-11-28 23:01:33216 b.WaitAndConfirmTimerFiredAfterDelay();
217
218 EXPECT_TRUE(did_run_a.IsSignaled());
[email protected]aeab57ea2008-08-28 20:50:12219}
220
Sami Kyostila3f49cb572018-11-19 13:01:09221void RunTest_OneShotTimers_Cancel(
Gabriel Charette694c3c332019-08-19 14:53:05222 test::TaskEnvironment::MainThreadType main_thread_type) {
223 test::TaskEnvironment task_environment(main_thread_type);
[email protected]aeab57ea2008-08-28 20:50:12224
gab175490c12016-11-28 23:01:33225 WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
226 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]aeab57ea2008-08-28 20:50:12227 OneShotTimerTester* a = new OneShotTimerTester(&did_run_a);
228
229 // This should run before the timer expires.
gab175490c12016-11-28 23:01:33230 SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
[email protected]aeab57ea2008-08-28 20:50:12231
232 // Now start the timer.
233 a->Start();
[email protected]52a261f2009-03-03 15:01:12234
gab175490c12016-11-28 23:01:33235 OneShotTimerTester b;
[email protected]aeab57ea2008-08-28 20:50:12236 b.Start();
237
gab175490c12016-11-28 23:01:33238 b.WaitAndConfirmTimerFiredAfterDelay();
[email protected]aeab57ea2008-08-28 20:50:12239
gab175490c12016-11-28 23:01:33240 EXPECT_FALSE(did_run_a.IsSignaled());
[email protected]aeab57ea2008-08-28 20:50:12241}
242
Sami Kyostila3f49cb572018-11-19 13:01:09243void RunTest_OneShotSelfDeletingTimer(
Gabriel Charette694c3c332019-08-19 14:53:05244 test::TaskEnvironment::MainThreadType main_thread_type) {
245 test::TaskEnvironment task_environment(main_thread_type);
[email protected]95284322009-02-07 00:37:01246
gab175490c12016-11-28 23:01:33247 OneShotSelfDeletingTimerTester f;
[email protected]95284322009-02-07 00:37:01248 f.Start();
gab175490c12016-11-28 23:01:33249 f.WaitAndConfirmTimerFiredAfterDelay();
[email protected]95284322009-02-07 00:37:01250}
251
Sami Kyostila3f49cb572018-11-19 13:01:09252void RunTest_RepeatingTimer(
Gabriel Charette694c3c332019-08-19 14:53:05253 test::TaskEnvironment::MainThreadType main_thread_type,
Sami Kyostila3f49cb572018-11-19 13:01:09254 const TimeDelta& delay) {
Gabriel Charette694c3c332019-08-19 14:53:05255 test::TaskEnvironment task_environment(main_thread_type);
[email protected]aeab57ea2008-08-28 20:50:12256
gab175490c12016-11-28 23:01:33257 RepeatingTimerTester f(nullptr, delay);
[email protected]aeab57ea2008-08-28 20:50:12258 f.Start();
gab175490c12016-11-28 23:01:33259 f.WaitAndConfirmTimerFiredRepeatedlyAfterDelay();
[email protected]aeab57ea2008-08-28 20:50:12260}
261
Sami Kyostila3f49cb572018-11-19 13:01:09262void RunTest_RepeatingTimer_Cancel(
Gabriel Charette694c3c332019-08-19 14:53:05263 test::TaskEnvironment::MainThreadType main_thread_type,
Sami Kyostila3f49cb572018-11-19 13:01:09264 const TimeDelta& delay) {
Gabriel Charette694c3c332019-08-19 14:53:05265 test::TaskEnvironment task_environment(main_thread_type);
[email protected]aeab57ea2008-08-28 20:50:12266
gab175490c12016-11-28 23:01:33267 WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
268 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]e495c532013-12-06 15:22:35269 RepeatingTimerTester* a = new RepeatingTimerTester(&did_run_a, delay);
[email protected]aeab57ea2008-08-28 20:50:12270
271 // This should run before the timer expires.
gab175490c12016-11-28 23:01:33272 SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
[email protected]aeab57ea2008-08-28 20:50:12273
274 // Now start the timer.
275 a->Start();
[email protected]e68e62fa2009-02-20 02:00:04276
gab175490c12016-11-28 23:01:33277 RepeatingTimerTester b(nullptr, delay);
[email protected]aeab57ea2008-08-28 20:50:12278 b.Start();
279
gab175490c12016-11-28 23:01:33280 b.WaitAndConfirmTimerFiredRepeatedlyAfterDelay();
[email protected]aeab57ea2008-08-28 20:50:12281
gab175490c12016-11-28 23:01:33282 // |a| should not have fired despite |b| starting after it on the same
283 // sequence and being complete by now.
284 EXPECT_FALSE(did_run_a.IsSignaled());
[email protected]aeab57ea2008-08-28 20:50:12285}
286
[email protected]e68e62fa2009-02-20 02:00:04287class DelayTimerTarget {
288 public:
[email protected]e68e62fa2009-02-20 02:00:04289 bool signaled() const { return signaled_; }
290
291 void Signal() {
292 ASSERT_FALSE(signaled_);
293 signaled_ = true;
294 }
295
296 private:
hashimoto42a14e862015-01-22 15:21:41297 bool signaled_ = false;
[email protected]e68e62fa2009-02-20 02:00:04298};
299
Sami Kyostila3f49cb572018-11-19 13:01:09300void RunTest_DelayTimer_NoCall(
Gabriel Charette694c3c332019-08-19 14:53:05301 test::TaskEnvironment::MainThreadType main_thread_type) {
302 test::TaskEnvironment task_environment(main_thread_type);
[email protected]e68e62fa2009-02-20 02:00:04303
304 // If Delay is never called, the timer shouldn't go off.
305 DelayTimerTarget target;
Peter Kasting53fd6ee2021-10-05 20:40:48306 DelayTimer timer(FROM_HERE, Milliseconds(1), &target,
gab175490c12016-11-28 23:01:33307 &DelayTimerTarget::Signal);
[email protected]e68e62fa2009-02-20 02:00:04308
gab175490c12016-11-28 23:01:33309 OneShotTimerTester tester;
[email protected]e68e62fa2009-02-20 02:00:04310 tester.Start();
gab175490c12016-11-28 23:01:33311 tester.WaitAndConfirmTimerFiredAfterDelay();
[email protected]e68e62fa2009-02-20 02:00:04312
313 ASSERT_FALSE(target.signaled());
314}
315
Sami Kyostila3f49cb572018-11-19 13:01:09316void RunTest_DelayTimer_OneCall(
Gabriel Charette694c3c332019-08-19 14:53:05317 test::TaskEnvironment::MainThreadType main_thread_type) {
318 test::TaskEnvironment task_environment(main_thread_type);
[email protected]e68e62fa2009-02-20 02:00:04319
320 DelayTimerTarget target;
Peter Kasting53fd6ee2021-10-05 20:40:48321 DelayTimer timer(FROM_HERE, Milliseconds(1), &target,
gab175490c12016-11-28 23:01:33322 &DelayTimerTarget::Signal);
[email protected]e68e62fa2009-02-20 02:00:04323 timer.Reset();
324
Peter Kasting53fd6ee2021-10-05 20:40:48325 OneShotTimerTester tester(nullptr, Milliseconds(100));
[email protected]e68e62fa2009-02-20 02:00:04326 tester.Start();
gab175490c12016-11-28 23:01:33327 tester.WaitAndConfirmTimerFiredAfterDelay();
[email protected]e68e62fa2009-02-20 02:00:04328
329 ASSERT_TRUE(target.signaled());
330}
331
332struct ResetHelper {
gab175490c12016-11-28 23:01:33333 ResetHelper(DelayTimer* timer, DelayTimerTarget* target)
danakj8c3eb802015-09-24 07:53:00334 : timer_(timer), target_(target) {}
[email protected]e68e62fa2009-02-20 02:00:04335
336 void Reset() {
337 ASSERT_FALSE(target_->signaled());
338 timer_->Reset();
339 }
340
341 private:
gab175490c12016-11-28 23:01:33342 DelayTimer* const timer_;
danakj8c3eb802015-09-24 07:53:00343 DelayTimerTarget* const target_;
[email protected]e68e62fa2009-02-20 02:00:04344};
345
Sami Kyostila3f49cb572018-11-19 13:01:09346void RunTest_DelayTimer_Reset(
Gabriel Charette694c3c332019-08-19 14:53:05347 test::TaskEnvironment::MainThreadType main_thread_type) {
348 test::TaskEnvironment task_environment(main_thread_type);
[email protected]e68e62fa2009-02-20 02:00:04349
350 // If Delay is never called, the timer shouldn't go off.
351 DelayTimerTarget target;
Peter Kasting53fd6ee2021-10-05 20:40:48352 DelayTimer timer(FROM_HERE, Milliseconds(50), &target,
gab175490c12016-11-28 23:01:33353 &DelayTimerTarget::Signal);
[email protected]e68e62fa2009-02-20 02:00:04354 timer.Reset();
355
356 ResetHelper reset_helper(&timer, &target);
357
gab175490c12016-11-28 23:01:33358 OneShotTimer timers[20];
Avi Drissmane3b70bf2019-01-04 19:50:22359 for (size_t i = 0; i < base::size(timers); ++i) {
Peter Kasting53fd6ee2021-10-05 20:40:48360 timers[i].Start(FROM_HERE, Milliseconds(i * 10), &reset_helper,
361 &ResetHelper::Reset);
[email protected]e68e62fa2009-02-20 02:00:04362 }
363
Peter Kasting53fd6ee2021-10-05 20:40:48364 OneShotTimerTester tester(nullptr, Milliseconds(300));
[email protected]e68e62fa2009-02-20 02:00:04365 tester.Start();
gab175490c12016-11-28 23:01:33366 tester.WaitAndConfirmTimerFiredAfterDelay();
[email protected]e68e62fa2009-02-20 02:00:04367
368 ASSERT_TRUE(target.signaled());
369}
370
[email protected]02bf7f272009-02-26 23:17:56371class DelayTimerFatalTarget {
372 public:
373 void Signal() {
374 ASSERT_TRUE(false);
375 }
376};
377
Sami Kyostila3f49cb572018-11-19 13:01:09378void RunTest_DelayTimer_Deleted(
Gabriel Charette694c3c332019-08-19 14:53:05379 test::TaskEnvironment::MainThreadType main_thread_type) {
380 test::TaskEnvironment task_environment(main_thread_type);
[email protected]02bf7f272009-02-26 23:17:56381
382 DelayTimerFatalTarget target;
383
384 {
Peter Kasting53fd6ee2021-10-05 20:40:48385 DelayTimer timer(FROM_HERE, Milliseconds(50), &target,
gab175490c12016-11-28 23:01:33386 &DelayTimerFatalTarget::Signal);
[email protected]02bf7f272009-02-26 23:17:56387 timer.Reset();
388 }
389
390 // When the timer is deleted, the DelayTimerFatalTarget should never be
391 // called.
Peter Kasting53fd6ee2021-10-05 20:40:48392 PlatformThread::Sleep(Milliseconds(100));
[email protected]02bf7f272009-02-26 23:17:56393}
394
[email protected]4d9bdfaf2008-08-26 05:53:57395} // namespace
396
397//-----------------------------------------------------------------------------
Sami Kyostila3f49cb572018-11-19 13:01:09398// Each test is run against each type of main thread. That way we are sure
[email protected]4d9bdfaf2008-08-26 05:53:57399// that timers work properly in all configurations.
400
Sami Kyostila3f49cb572018-11-19 13:01:09401class TimerTestWithThreadType
Gabriel Charette694c3c332019-08-19 14:53:05402 : public testing::TestWithParam<test::TaskEnvironment::MainThreadType> {};
Sami Kyostila3f49cb572018-11-19 13:01:09403
404TEST_P(TimerTestWithThreadType, OneShotTimers) {
405 RunTest_OneShotTimers(GetParam());
[email protected]aeab57ea2008-08-28 20:50:12406}
407
Sami Kyostila3f49cb572018-11-19 13:01:09408TEST_P(TimerTestWithThreadType, OneShotTimers_Cancel) {
409 RunTest_OneShotTimers_Cancel(GetParam());
[email protected]aeab57ea2008-08-28 20:50:12410}
411
[email protected]95284322009-02-07 00:37:01412// If underline timer does not handle properly, we will crash or fail
[email protected]64e95e12011-08-17 17:41:02413// in full page heap environment.
Sami Kyostila3f49cb572018-11-19 13:01:09414TEST_P(TimerTestWithThreadType, OneShotSelfDeletingTimer) {
415 RunTest_OneShotSelfDeletingTimer(GetParam());
[email protected]95284322009-02-07 00:37:01416}
417
petrcermak7652da6d2014-11-06 02:17:57418TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
Gabriel Charettee92ccc02019-01-19 14:13:05419 auto task_runner = base::MakeRefCounted<TestSimpleTaskRunner>();
petrcermak7652da6d2014-11-06 02:17:57420
Gabriel Charettee92ccc02019-01-19 14:13:05421 OneShotTimer timer;
gab175490c12016-11-28 23:01:33422
Gabriel Charettee92ccc02019-01-19 14:13:05423 bool task_ran = false;
petrcermak7652da6d2014-11-06 02:17:57424
Gabriel Charettee92ccc02019-01-19 14:13:05425 // The timer will use the TestSimpleTaskRunner to schedule its delays.
426 timer.SetTaskRunner(task_runner);
Peter Kasting53fd6ee2021-10-05 20:40:48427 timer.Start(FROM_HERE, Days(1),
Gabriel Charettee92ccc02019-01-19 14:13:05428 BindLambdaForTesting([&]() { task_ran = true; }));
gab175490c12016-11-28 23:01:33429
Gabriel Charettee92ccc02019-01-19 14:13:05430 EXPECT_FALSE(task_ran);
431 EXPECT_TRUE(task_runner->HasPendingTask());
432
433 task_runner->RunPendingTasks();
434
435 EXPECT_TRUE(task_ran);
petrcermak7652da6d2014-11-06 02:17:57436}
437
jameswest6e0c8d22016-11-15 05:19:54438TEST(TimerTest, OneShotTimerWithTickClock) {
Gabriel Charette694c3c332019-08-19 14:53:05439 test::TaskEnvironment task_environment(
440 test::TaskEnvironment::TimeSource::MOCK_TIME);
jameswest6e0c8d22016-11-15 05:19:54441 Receiver receiver;
Gabriel Charette694c3c332019-08-19 14:53:05442 OneShotTimer timer(task_environment.GetMockTickClock());
Peter Kasting53fd6ee2021-10-05 20:40:48443 timer.Start(FROM_HERE, Seconds(1),
tzikf3336c92018-07-25 03:15:50444 BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
Peter Kasting53fd6ee2021-10-05 20:40:48445 task_environment.FastForwardBy(Seconds(1));
jameswest6e0c8d22016-11-15 05:19:54446 EXPECT_TRUE(receiver.WasCalled());
447}
448
Sami Kyostila3f49cb572018-11-19 13:01:09449TEST_P(TimerTestWithThreadType, RepeatingTimer) {
Peter Kasting53fd6ee2021-10-05 20:40:48450 RunTest_RepeatingTimer(GetParam(), Milliseconds(10));
[email protected]aeab57ea2008-08-28 20:50:12451}
452
Sami Kyostila3f49cb572018-11-19 13:01:09453TEST_P(TimerTestWithThreadType, RepeatingTimer_Cancel) {
Peter Kasting53fd6ee2021-10-05 20:40:48454 RunTest_RepeatingTimer_Cancel(GetParam(), Milliseconds(10));
[email protected]e495c532013-12-06 15:22:35455}
456
Sami Kyostila3f49cb572018-11-19 13:01:09457TEST_P(TimerTestWithThreadType, RepeatingTimerZeroDelay) {
Peter Kasting53fd6ee2021-10-05 20:40:48458 RunTest_RepeatingTimer(GetParam(), Milliseconds(0));
[email protected]e495c532013-12-06 15:22:35459}
460
Sami Kyostila3f49cb572018-11-19 13:01:09461TEST_P(TimerTestWithThreadType, RepeatingTimerZeroDelay_Cancel) {
Peter Kasting53fd6ee2021-10-05 20:40:48462 RunTest_RepeatingTimer_Cancel(GetParam(), Milliseconds(0));
[email protected]aeab57ea2008-08-28 20:50:12463}
[email protected]a0287cbd2008-12-02 23:16:55464
jameswest6e0c8d22016-11-15 05:19:54465TEST(TimerTest, RepeatingTimerWithTickClock) {
Gabriel Charette694c3c332019-08-19 14:53:05466 test::TaskEnvironment task_environment(
467 test::TaskEnvironment::TimeSource::MOCK_TIME);
jameswest6e0c8d22016-11-15 05:19:54468 Receiver receiver;
469 const int expected_times_called = 10;
Gabriel Charette694c3c332019-08-19 14:53:05470 RepeatingTimer timer(task_environment.GetMockTickClock());
Peter Kasting53fd6ee2021-10-05 20:40:48471 timer.Start(FROM_HERE, Seconds(1),
tzikf3336c92018-07-25 03:15:50472 BindRepeating(&Receiver::OnCalled, Unretained(&receiver)));
Peter Kasting53fd6ee2021-10-05 20:40:48473 task_environment.FastForwardBy(Seconds(expected_times_called));
jameswest6e0c8d22016-11-15 05:19:54474 timer.Stop();
475 EXPECT_EQ(expected_times_called, receiver.TimesCalled());
476}
477
Sami Kyostila3f49cb572018-11-19 13:01:09478TEST_P(TimerTestWithThreadType, DelayTimer_NoCall) {
479 RunTest_DelayTimer_NoCall(GetParam());
[email protected]e68e62fa2009-02-20 02:00:04480}
481
Sami Kyostila3f49cb572018-11-19 13:01:09482TEST_P(TimerTestWithThreadType, DelayTimer_OneCall) {
483 RunTest_DelayTimer_OneCall(GetParam());
[email protected]e68e62fa2009-02-20 02:00:04484}
485
[email protected]471d7d62009-10-16 15:26:16486// It's flaky on the buildbot, http://crbug.com/25038.
Sami Kyostila3f49cb572018-11-19 13:01:09487TEST_P(TimerTestWithThreadType, DISABLED_DelayTimer_Reset) {
488 RunTest_DelayTimer_Reset(GetParam());
[email protected]e68e62fa2009-02-20 02:00:04489}
490
Sami Kyostila3f49cb572018-11-19 13:01:09491TEST_P(TimerTestWithThreadType, DelayTimer_Deleted) {
492 RunTest_DelayTimer_Deleted(GetParam());
[email protected]02bf7f272009-02-26 23:17:56493}
494
jameswest6e0c8d22016-11-15 05:19:54495TEST(TimerTest, DelayTimerWithTickClock) {
Gabriel Charette694c3c332019-08-19 14:53:05496 test::TaskEnvironment task_environment(
497 test::TaskEnvironment::TimeSource::MOCK_TIME);
jameswest6e0c8d22016-11-15 05:19:54498 Receiver receiver;
Peter Kasting53fd6ee2021-10-05 20:40:48499 DelayTimer timer(FROM_HERE, Seconds(1), &receiver, &Receiver::OnCalled,
500 task_environment.GetMockTickClock());
501 task_environment.FastForwardBy(Milliseconds(999));
jameswest6e0c8d22016-11-15 05:19:54502 EXPECT_FALSE(receiver.WasCalled());
503 timer.Reset();
Peter Kasting53fd6ee2021-10-05 20:40:48504 task_environment.FastForwardBy(Milliseconds(999));
jameswest6e0c8d22016-11-15 05:19:54505 EXPECT_FALSE(receiver.WasCalled());
506 timer.Reset();
Peter Kasting53fd6ee2021-10-05 20:40:48507 task_environment.FastForwardBy(Seconds(1));
jameswest6e0c8d22016-11-15 05:19:54508 EXPECT_TRUE(receiver.WasCalled());
509}
510
Sami Kyostila3f49cb572018-11-19 13:01:09511TEST(TimerTest, TaskEnvironmentShutdown) {
[email protected]a0287cbd2008-12-02 23:16:55512 // This test is designed to verify that shutdown of the
513 // message loop does not cause crashes if there were pending
514 // timers not yet fired. It may only trigger exceptions
[email protected]64e95e12011-08-17 17:41:02515 // if debug heap checking is enabled.
gab175490c12016-11-28 23:01:33516 WaitableEvent did_run(WaitableEvent::ResetPolicy::MANUAL,
517 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]a0287cbd2008-12-02 23:16:55518 {
ahest68c9f102016-12-13 11:34:38519 OneShotTimerTesterBase a(&did_run);
520 OneShotTimerTesterBase b(&did_run);
521 OneShotTimerTesterBase c(&did_run);
522 OneShotTimerTesterBase d(&did_run);
[email protected]a0287cbd2008-12-02 23:16:55523 {
Gabriel Charette694c3c332019-08-19 14:53:05524 test::TaskEnvironment task_environment;
[email protected]a0287cbd2008-12-02 23:16:55525 a.Start();
526 b.Start();
Sami Kyostila3f49cb572018-11-19 13:01:09527 } // Task environment destructs by falling out of scope.
[email protected]a0287cbd2008-12-02 23:16:55528 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
529
gab175490c12016-11-28 23:01:33530 EXPECT_FALSE(did_run.IsSignaled());
[email protected]a0287cbd2008-12-02 23:16:55531}
[email protected]df9076a2012-03-27 00:18:57532
pkotwicz4a286ed2017-01-17 20:45:26533// Ref counted class which owns a Timer. The class passes a reference to itself
534// via the |user_task| parameter in Timer::Start(). |Timer::user_task_| might
535// end up holding the last reference to the class.
536class OneShotSelfOwningTimerTester
537 : public RefCounted<OneShotSelfOwningTimerTester> {
538 public:
539 OneShotSelfOwningTimerTester() = default;
540
Peter Boström75cd3c02021-09-28 15:23:18541 OneShotSelfOwningTimerTester(const OneShotSelfOwningTimerTester&) = delete;
542 OneShotSelfOwningTimerTester& operator=(const OneShotSelfOwningTimerTester&) =
543 delete;
544
pkotwicz4a286ed2017-01-17 20:45:26545 void StartTimer() {
546 // Start timer with long delay in order to test the timer getting destroyed
547 // while a timer task is still pending.
Peter Kasting53fd6ee2021-10-05 20:40:48548 timer_.Start(FROM_HERE, Days(1),
tzikf3336c92018-07-25 03:15:50549 BindOnce(&OneShotSelfOwningTimerTester::Run, this));
pkotwicz4a286ed2017-01-17 20:45:26550 }
551
552 private:
553 friend class RefCounted<OneShotSelfOwningTimerTester>;
554 ~OneShotSelfOwningTimerTester() = default;
555
556 void Run() {
557 ADD_FAILURE() << "Timer unexpectedly fired.";
558 }
559
560 OneShotTimer timer_;
pkotwicz4a286ed2017-01-17 20:45:26561};
562
Sami Kyostila3f49cb572018-11-19 13:01:09563TEST(TimerTest, TaskEnvironmentShutdownSelfOwningTimer) {
564 // This test verifies that shutdown of the task environment does not cause
565 // crashes if there is a pending timer not yet fired and |Timer::user_task_|
566 // owns the timer. The test may only trigger exceptions if debug heap checking
567 // is enabled.
pkotwicz4a286ed2017-01-17 20:45:26568
Gabriel Charette694c3c332019-08-19 14:53:05569 test::TaskEnvironment task_environment;
pkotwicz4a286ed2017-01-17 20:45:26570 scoped_refptr<OneShotSelfOwningTimerTester> tester =
571 new OneShotSelfOwningTimerTester();
572
573 std::move(tester)->StartTimer();
574 // |Timer::user_task_| owns sole reference to |tester|.
575
Sami Kyostila3f49cb572018-11-19 13:01:09576 // Task environment destructs by falling out of scope. SHOULD NOT CRASH.
pkotwicz4a286ed2017-01-17 20:45:26577}
578
[email protected]df9076a2012-03-27 00:18:57579void TimerTestCallback() {
580}
581
582TEST(TimerTest, NonRepeatIsRunning) {
583 {
Gabriel Charette694c3c332019-08-19 14:53:05584 test::TaskEnvironment task_environment;
tzikd93bb0862018-07-19 11:54:14585 OneShotTimer timer;
[email protected]df9076a2012-03-27 00:18:57586 EXPECT_FALSE(timer.IsRunning());
Peter Kasting53fd6ee2021-10-05 20:40:48587 timer.Start(FROM_HERE, Days(1), BindOnce(&TimerTestCallback));
[email protected]df9076a2012-03-27 00:18:57588 EXPECT_TRUE(timer.IsRunning());
589 timer.Stop();
590 EXPECT_FALSE(timer.IsRunning());
[email protected]df9076a2012-03-27 00:18:57591 }
592
593 {
tzikd93bb0862018-07-19 11:54:14594 RetainingOneShotTimer timer;
Gabriel Charette694c3c332019-08-19 14:53:05595 test::TaskEnvironment task_environment;
[email protected]df9076a2012-03-27 00:18:57596 EXPECT_FALSE(timer.IsRunning());
Peter Kasting53fd6ee2021-10-05 20:40:48597 timer.Start(FROM_HERE, Days(1), BindRepeating(&TimerTestCallback));
[email protected]df9076a2012-03-27 00:18:57598 EXPECT_TRUE(timer.IsRunning());
599 timer.Stop();
600 EXPECT_FALSE(timer.IsRunning());
601 ASSERT_FALSE(timer.user_task().is_null());
602 timer.Reset();
603 EXPECT_TRUE(timer.IsRunning());
604 }
605}
606
Sami Kyostila3f49cb572018-11-19 13:01:09607TEST(TimerTest, NonRepeatTaskEnvironmentDeath) {
tzikd93bb0862018-07-19 11:54:14608 OneShotTimer timer;
[email protected]df9076a2012-03-27 00:18:57609 {
Gabriel Charette694c3c332019-08-19 14:53:05610 test::TaskEnvironment task_environment;
[email protected]df9076a2012-03-27 00:18:57611 EXPECT_FALSE(timer.IsRunning());
Peter Kasting53fd6ee2021-10-05 20:40:48612 timer.Start(FROM_HERE, Days(1), BindOnce(&TimerTestCallback));
[email protected]df9076a2012-03-27 00:18:57613 EXPECT_TRUE(timer.IsRunning());
614 }
615 EXPECT_FALSE(timer.IsRunning());
[email protected]df9076a2012-03-27 00:18:57616}
617
618TEST(TimerTest, RetainRepeatIsRunning) {
Gabriel Charette694c3c332019-08-19 14:53:05619 test::TaskEnvironment task_environment;
Peter Kasting53fd6ee2021-10-05 20:40:48620 RepeatingTimer timer(FROM_HERE, Days(1), BindRepeating(&TimerTestCallback));
[email protected]df9076a2012-03-27 00:18:57621 EXPECT_FALSE(timer.IsRunning());
622 timer.Reset();
623 EXPECT_TRUE(timer.IsRunning());
624 timer.Stop();
625 EXPECT_FALSE(timer.IsRunning());
626 timer.Reset();
627 EXPECT_TRUE(timer.IsRunning());
628}
629
630TEST(TimerTest, RetainNonRepeatIsRunning) {
Gabriel Charette694c3c332019-08-19 14:53:05631 test::TaskEnvironment task_environment;
Peter Kasting53fd6ee2021-10-05 20:40:48632 RetainingOneShotTimer timer(FROM_HERE, Days(1),
tzikf3336c92018-07-25 03:15:50633 BindRepeating(&TimerTestCallback));
[email protected]df9076a2012-03-27 00:18:57634 EXPECT_FALSE(timer.IsRunning());
635 timer.Reset();
636 EXPECT_TRUE(timer.IsRunning());
637 timer.Stop();
638 EXPECT_FALSE(timer.IsRunning());
639 timer.Reset();
640 EXPECT_TRUE(timer.IsRunning());
641}
642
gab4e844bb2017-06-01 16:23:36643//-----------------------------------------------------------------------------
644
[email protected]df9076a2012-03-27 00:18:57645namespace {
646
647bool g_callback_happened1 = false;
648bool g_callback_happened2 = false;
649
650void ClearAllCallbackHappened() {
651 g_callback_happened1 = false;
652 g_callback_happened2 = false;
653}
654
655void SetCallbackHappened1() {
656 g_callback_happened1 = true;
Gabriel Charette53a9ef812017-07-26 12:36:23657 RunLoop::QuitCurrentWhenIdleDeprecated();
[email protected]df9076a2012-03-27 00:18:57658}
659
660void SetCallbackHappened2() {
661 g_callback_happened2 = true;
Gabriel Charette53a9ef812017-07-26 12:36:23662 RunLoop::QuitCurrentWhenIdleDeprecated();
[email protected]df9076a2012-03-27 00:18:57663}
664
gab175490c12016-11-28 23:01:33665} // namespace
666
[email protected]df9076a2012-03-27 00:18:57667TEST(TimerTest, ContinuationStopStart) {
668 {
669 ClearAllCallbackHappened();
Gabriel Charette694c3c332019-08-19 14:53:05670 test::TaskEnvironment task_environment;
tzikd93bb0862018-07-19 11:54:14671 OneShotTimer timer;
Peter Kasting53fd6ee2021-10-05 20:40:48672 timer.Start(FROM_HERE, Milliseconds(10), BindOnce(&SetCallbackHappened1));
[email protected]df9076a2012-03-27 00:18:57673 timer.Stop();
Peter Kasting53fd6ee2021-10-05 20:40:48674 timer.Start(FROM_HERE, Milliseconds(40), BindOnce(&SetCallbackHappened2));
gab175490c12016-11-28 23:01:33675 RunLoop().Run();
[email protected]df9076a2012-03-27 00:18:57676 EXPECT_FALSE(g_callback_happened1);
677 EXPECT_TRUE(g_callback_happened2);
678 }
679}
680
681TEST(TimerTest, ContinuationReset) {
682 {
683 ClearAllCallbackHappened();
Gabriel Charette694c3c332019-08-19 14:53:05684 test::TaskEnvironment task_environment;
tzikd93bb0862018-07-19 11:54:14685 OneShotTimer timer;
Peter Kasting53fd6ee2021-10-05 20:40:48686 timer.Start(FROM_HERE, Milliseconds(10), BindOnce(&SetCallbackHappened1));
[email protected]df9076a2012-03-27 00:18:57687 timer.Reset();
tzikf3336c92018-07-25 03:15:50688 // // Since Reset happened before task ran, the user_task must not be
689 // cleared: ASSERT_FALSE(timer.user_task().is_null());
gab175490c12016-11-28 23:01:33690 RunLoop().Run();
[email protected]df9076a2012-03-27 00:18:57691 EXPECT_TRUE(g_callback_happened1);
692 }
693}
694
Patrick Monette57d1c18d2021-04-22 00:50:44695TEST(TimerTest, AbandonedTaskIsCancelled) {
696 test::TaskEnvironment task_environment(
697 test::TaskEnvironment::TimeSource::MOCK_TIME);
698 OneShotTimer timer;
699
700 // Start a timer. There will be a pending task on the current sequence.
Peter Kasting53fd6ee2021-10-05 20:40:48701 timer.Start(FROM_HERE, Seconds(5), base::DoNothing());
Patrick Monette57d1c18d2021-04-22 00:50:44702 EXPECT_EQ(1u, task_environment.GetPendingMainThreadTaskCount());
703
704 // After AbandonAndStop(), the task is correctly treated as cancelled.
705 timer.AbandonAndStop();
706 EXPECT_EQ(0u, task_environment.GetPendingMainThreadTaskCount());
707}
708
Ilia Samsonova2885f72019-11-20 22:16:58709INSTANTIATE_TEST_SUITE_P(All,
Victor Costan033b9ac2019-01-29 00:52:16710 TimerTestWithThreadType,
711 testing::ValuesIn(testing_main_threads));
Sami Kyostila3f49cb572018-11-19 13:01:09712
gab175490c12016-11-28 23:01:33713} // namespace base