blob: 6b49f1672c96a941c9bd3688b6cd9a609912a03a [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2012 The Chromium Authors
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
Avi Drissman63e1f992023-01-13 18:54:4311#include "base/functional/bind.h"
12#include "base/functional/callback.h"
13#include "base/functional/callback_helpers.h"
pkotwicz4a286ed2017-01-17 20:45:2614#include "base/memory/ref_counted.h"
fdoray10224582016-06-30 18:17:3915#include "base/run_loop.h"
Patrick Monette643cdf62021-10-15 19:13:4216#include "base/task/sequenced_task_runner.h"
Guido Urdanetaef4e91942020-11-09 15:06:2417#include "base/test/bind.h"
Etienne Pierre-doray1a0edc72022-01-14 15:11:4418#include "base/test/mock_callback.h"
Gabriel Charettec7108742019-08-23 03:31:4019#include "base/test/task_environment.h"
Gabriel Charettee92ccc02019-01-19 14:13:0520#include "base/test/test_simple_task_runner.h"
jameswest6e0c8d22016-11-15 05:19:5421#include "base/time/tick_clock.h"
gab175490c12016-11-28 23:01:3322#include "base/time/time.h"
avi9b6f42932015-12-26 22:15:1423#include "build/build_config.h"
initial.commitd7cae122008-07-26 21:49:3824#include "testing/gtest/include/gtest/gtest.h"
25
gab175490c12016-11-28 23:01:3326namespace base {
[email protected]e1acf6f2008-10-27 20:43:3327
[email protected]aeab57ea2008-08-28 20:50:1228namespace {
29
Patrick Monette466823932022-01-10 20:33:5230constexpr TimeDelta kTestDelay = Seconds(10);
31constexpr TimeDelta kLongTestDelay = Minutes(10);
32
Sami Kyostila3f49cb572018-11-19 13:01:0933// The main thread types on which each timer should be tested.
Gabriel Charette694c3c332019-08-19 14:53:0534const test::TaskEnvironment::MainThreadType testing_main_threads[] = {
35 test::TaskEnvironment::MainThreadType::DEFAULT,
36 test::TaskEnvironment::MainThreadType::IO,
Xiaohan Wang7940de22022-01-15 14:47:5537#if !BUILDFLAG(IS_IOS) // iOS does not allow direct running of the UI loop.
Gabriel Charette694c3c332019-08-19 14:53:0538 test::TaskEnvironment::MainThreadType::UI,
[email protected]835332b2012-07-17 11:22:5939#endif
40};
41
jameswest6e0c8d22016-11-15 05:19:5442class Receiver {
43 public:
Peter Kasting6218bbad2025-01-10 11:26:4044 Receiver() = default;
jameswest6e0c8d22016-11-15 05:19:5445 void OnCalled() { count_++; }
46 bool WasCalled() { return count_ > 0; }
47 int TimesCalled() { return count_; }
48
49 private:
Peter Kasting811504a72025-01-09 03:18:5050 int count_ = 0;
jameswest6e0c8d22016-11-15 05:19:5451};
52
gab175490c12016-11-28 23:01:3353// Basic test with same setup as RunTest_OneShotTimers_Cancel below to confirm
Patrick Monette466823932022-01-10 20:33:5254// that |timer| would be fired in that test if it wasn't for the deletion.
Sami Kyostila3f49cb572018-11-19 13:01:0955void RunTest_OneShotTimers(
Gabriel Charette694c3c332019-08-19 14:53:0556 test::TaskEnvironment::MainThreadType main_thread_type) {
Patrick Monette466823932022-01-10 20:33:5257 test::TaskEnvironment task_environment(
58 test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
[email protected]aeab57ea2008-08-28 20:50:1259
Patrick Monette466823932022-01-10 20:33:5260 Receiver receiver;
61 OneShotTimer timer;
62 timer.Start(FROM_HERE, kTestDelay,
63 BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
[email protected]aeab57ea2008-08-28 20:50:1264
Patrick Monette466823932022-01-10 20:33:5265 task_environment.FastForwardBy(kTestDelay);
66 EXPECT_TRUE(receiver.WasCalled());
Etienne Pierre-doray9c3d17d82022-05-12 22:05:2967 EXPECT_FALSE(timer.IsRunning());
[email protected]aeab57ea2008-08-28 20:50:1268}
69
Sami Kyostila3f49cb572018-11-19 13:01:0970void RunTest_OneShotTimers_Cancel(
Gabriel Charette694c3c332019-08-19 14:53:0571 test::TaskEnvironment::MainThreadType main_thread_type) {
Patrick Monette466823932022-01-10 20:33:5272 test::TaskEnvironment task_environment(
73 test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
[email protected]aeab57ea2008-08-28 20:50:1274
Patrick Monette466823932022-01-10 20:33:5275 Receiver receiver;
76 auto timer = std::make_unique<OneShotTimer>();
77 auto* timer_ptr = timer.get();
[email protected]aeab57ea2008-08-28 20:50:1278
79 // This should run before the timer expires.
Sean Maher7d0e8052022-12-09 01:46:3280 SequencedTaskRunner::GetCurrentDefault()->DeleteSoon(FROM_HERE,
81 std::move(timer));
[email protected]aeab57ea2008-08-28 20:50:1282
Patrick Monette466823932022-01-10 20:33:5283 timer_ptr->Start(FROM_HERE, kTestDelay,
84 BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
[email protected]52a261f2009-03-03 15:01:1285
Patrick Monette466823932022-01-10 20:33:5286 task_environment.FastForwardBy(kTestDelay);
87 EXPECT_FALSE(receiver.WasCalled());
[email protected]aeab57ea2008-08-28 20:50:1288}
89
Sami Kyostila3f49cb572018-11-19 13:01:0990void RunTest_OneShotSelfDeletingTimer(
Gabriel Charette694c3c332019-08-19 14:53:0591 test::TaskEnvironment::MainThreadType main_thread_type) {
Patrick Monette466823932022-01-10 20:33:5292 test::TaskEnvironment task_environment(
93 test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
[email protected]95284322009-02-07 00:37:0194
Patrick Monette466823932022-01-10 20:33:5295 Receiver receiver;
96 auto timer = std::make_unique<OneShotTimer>();
97 auto* timer_ptr = timer.get();
98
99 timer_ptr->Start(
100 FROM_HERE, kTestDelay,
101 BindLambdaForTesting([&receiver, timer = std::move(timer)]() mutable {
102 receiver.OnCalled();
Etienne Pierre-doray9c3d17d82022-05-12 22:05:29103 EXPECT_FALSE(timer->IsRunning());
Patrick Monette466823932022-01-10 20:33:52104 timer.reset();
105 }));
106
107 task_environment.FastForwardBy(kTestDelay);
108 EXPECT_TRUE(receiver.WasCalled());
[email protected]95284322009-02-07 00:37:01109}
110
Sami Kyostila3f49cb572018-11-19 13:01:09111void RunTest_RepeatingTimer(
Gabriel Charette694c3c332019-08-19 14:53:05112 test::TaskEnvironment::MainThreadType main_thread_type,
Sami Kyostila3f49cb572018-11-19 13:01:09113 const TimeDelta& delay) {
Patrick Monette466823932022-01-10 20:33:52114 test::TaskEnvironment task_environment(
115 test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
[email protected]aeab57ea2008-08-28 20:50:12116
Patrick Monette466823932022-01-10 20:33:52117 Receiver receiver;
118 RepeatingTimer timer;
119 timer.Start(FROM_HERE, kTestDelay,
120 BindRepeating(&Receiver::OnCalled, Unretained(&receiver)));
121
122 task_environment.FastForwardBy(20 * kTestDelay);
123 EXPECT_EQ(receiver.TimesCalled(), 20);
Etienne Pierre-doray9c3d17d82022-05-12 22:05:29124 EXPECT_TRUE(timer.IsRunning());
[email protected]aeab57ea2008-08-28 20:50:12125}
126
Sami Kyostila3f49cb572018-11-19 13:01:09127void RunTest_RepeatingTimer_Cancel(
Gabriel Charette694c3c332019-08-19 14:53:05128 test::TaskEnvironment::MainThreadType main_thread_type,
Sami Kyostila3f49cb572018-11-19 13:01:09129 const TimeDelta& delay) {
Patrick Monette466823932022-01-10 20:33:52130 test::TaskEnvironment task_environment(
131 test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
[email protected]aeab57ea2008-08-28 20:50:12132
Patrick Monette466823932022-01-10 20:33:52133 Receiver receiver;
134 auto timer = std::make_unique<RepeatingTimer>();
135 auto* timer_ptr = timer.get();
[email protected]aeab57ea2008-08-28 20:50:12136
137 // This should run before the timer expires.
Sean Maher7d0e8052022-12-09 01:46:32138 SequencedTaskRunner::GetCurrentDefault()->DeleteSoon(FROM_HERE,
139 std::move(timer));
[email protected]aeab57ea2008-08-28 20:50:12140
Patrick Monette466823932022-01-10 20:33:52141 timer_ptr->Start(FROM_HERE, delay,
142 BindRepeating(&Receiver::OnCalled, Unretained(&receiver)));
[email protected]e68e62fa2009-02-20 02:00:04143
Patrick Monette466823932022-01-10 20:33:52144 task_environment.FastForwardBy(delay);
145 EXPECT_FALSE(receiver.WasCalled());
[email protected]aeab57ea2008-08-28 20:50:12146}
147
Sami Kyostila3f49cb572018-11-19 13:01:09148void RunTest_DelayTimer_NoCall(
Gabriel Charette694c3c332019-08-19 14:53:05149 test::TaskEnvironment::MainThreadType main_thread_type) {
Patrick Monette466823932022-01-10 20:33:52150 test::TaskEnvironment task_environment(
151 test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
[email protected]e68e62fa2009-02-20 02:00:04152
Patrick Monette466823932022-01-10 20:33:52153 Receiver receiver;
154 DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
[email protected]e68e62fa2009-02-20 02:00:04155
Patrick Monette466823932022-01-10 20:33:52156 task_environment.FastForwardBy(kTestDelay);
157 EXPECT_FALSE(receiver.WasCalled());
[email protected]e68e62fa2009-02-20 02:00:04158}
159
Sami Kyostila3f49cb572018-11-19 13:01:09160void RunTest_DelayTimer_OneCall(
Gabriel Charette694c3c332019-08-19 14:53:05161 test::TaskEnvironment::MainThreadType main_thread_type) {
Patrick Monette466823932022-01-10 20:33:52162 test::TaskEnvironment task_environment(
163 test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
[email protected]e68e62fa2009-02-20 02:00:04164
Patrick Monette466823932022-01-10 20:33:52165 Receiver receiver;
166 DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
[email protected]e68e62fa2009-02-20 02:00:04167 timer.Reset();
168
Patrick Monette466823932022-01-10 20:33:52169 task_environment.FastForwardBy(kTestDelay);
170 EXPECT_TRUE(receiver.WasCalled());
[email protected]e68e62fa2009-02-20 02:00:04171}
172
Sami Kyostila3f49cb572018-11-19 13:01:09173void RunTest_DelayTimer_Reset(
Gabriel Charette694c3c332019-08-19 14:53:05174 test::TaskEnvironment::MainThreadType main_thread_type) {
Patrick Monette466823932022-01-10 20:33:52175 test::TaskEnvironment task_environment(
176 test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
[email protected]e68e62fa2009-02-20 02:00:04177
Patrick Monette466823932022-01-10 20:33:52178 Receiver receiver;
179 DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
[email protected]e68e62fa2009-02-20 02:00:04180 timer.Reset();
181
Patrick Monette466823932022-01-10 20:33:52182 // Fast-forward by a delay smaller than the timer delay. The timer will not
183 // fire.
184 task_environment.FastForwardBy(kTestDelay / 2);
185 EXPECT_FALSE(receiver.WasCalled());
[email protected]e68e62fa2009-02-20 02:00:04186
Patrick Monette466823932022-01-10 20:33:52187 // Postpone the fire time.
188 timer.Reset();
[email protected]e68e62fa2009-02-20 02:00:04189
Patrick Monette466823932022-01-10 20:33:52190 // Verify that the timer does not fire at its original fire time.
191 task_environment.FastForwardBy(kTestDelay / 2);
192 EXPECT_FALSE(receiver.WasCalled());
[email protected]e68e62fa2009-02-20 02:00:04193
Patrick Monette466823932022-01-10 20:33:52194 // Fast-forward by the timer delay. The timer will fire.
195 task_environment.FastForwardBy(kTestDelay / 2);
196 EXPECT_TRUE(receiver.WasCalled());
[email protected]e68e62fa2009-02-20 02:00:04197}
198
Sami Kyostila3f49cb572018-11-19 13:01:09199void RunTest_DelayTimer_Deleted(
Gabriel Charette694c3c332019-08-19 14:53:05200 test::TaskEnvironment::MainThreadType main_thread_type) {
Patrick Monette466823932022-01-10 20:33:52201 test::TaskEnvironment task_environment(
202 test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
[email protected]02bf7f272009-02-26 23:17:56203
Patrick Monette466823932022-01-10 20:33:52204 Receiver receiver;
[email protected]02bf7f272009-02-26 23:17:56205
206 {
Patrick Monette466823932022-01-10 20:33:52207 DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
[email protected]02bf7f272009-02-26 23:17:56208 timer.Reset();
209 }
210
Patrick Monette466823932022-01-10 20:33:52211 // Because the timer was deleted, it will never fire.
212 task_environment.FastForwardBy(kTestDelay);
213 EXPECT_FALSE(receiver.WasCalled());
[email protected]02bf7f272009-02-26 23:17:56214}
215
[email protected]4d9bdfaf2008-08-26 05:53:57216} // namespace
217
218//-----------------------------------------------------------------------------
Sami Kyostila3f49cb572018-11-19 13:01:09219// Each test is run against each type of main thread. That way we are sure
[email protected]4d9bdfaf2008-08-26 05:53:57220// that timers work properly in all configurations.
221
Sami Kyostila3f49cb572018-11-19 13:01:09222class TimerTestWithThreadType
Gabriel Charette694c3c332019-08-19 14:53:05223 : public testing::TestWithParam<test::TaskEnvironment::MainThreadType> {};
Sami Kyostila3f49cb572018-11-19 13:01:09224
225TEST_P(TimerTestWithThreadType, OneShotTimers) {
226 RunTest_OneShotTimers(GetParam());
[email protected]aeab57ea2008-08-28 20:50:12227}
228
Sami Kyostila3f49cb572018-11-19 13:01:09229TEST_P(TimerTestWithThreadType, OneShotTimers_Cancel) {
230 RunTest_OneShotTimers_Cancel(GetParam());
[email protected]aeab57ea2008-08-28 20:50:12231}
232
[email protected]95284322009-02-07 00:37:01233// If underline timer does not handle properly, we will crash or fail
[email protected]64e95e12011-08-17 17:41:02234// in full page heap environment.
Sami Kyostila3f49cb572018-11-19 13:01:09235TEST_P(TimerTestWithThreadType, OneShotSelfDeletingTimer) {
236 RunTest_OneShotSelfDeletingTimer(GetParam());
[email protected]95284322009-02-07 00:37:01237}
238
petrcermak7652da6d2014-11-06 02:17:57239TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
Gabriel Charettee92ccc02019-01-19 14:13:05240 auto task_runner = base::MakeRefCounted<TestSimpleTaskRunner>();
petrcermak7652da6d2014-11-06 02:17:57241
Gabriel Charettee92ccc02019-01-19 14:13:05242 OneShotTimer timer;
gab175490c12016-11-28 23:01:33243
Gabriel Charettee92ccc02019-01-19 14:13:05244 bool task_ran = false;
petrcermak7652da6d2014-11-06 02:17:57245
Gabriel Charettee92ccc02019-01-19 14:13:05246 // The timer will use the TestSimpleTaskRunner to schedule its delays.
247 timer.SetTaskRunner(task_runner);
Peter Kasting53fd6ee2021-10-05 20:40:48248 timer.Start(FROM_HERE, Days(1),
Sorin Jianuad4cc6232024-10-08 19:06:01249 BindLambdaForTesting([&] { task_ran = true; }));
gab175490c12016-11-28 23:01:33250
Gabriel Charettee92ccc02019-01-19 14:13:05251 EXPECT_FALSE(task_ran);
252 EXPECT_TRUE(task_runner->HasPendingTask());
253
254 task_runner->RunPendingTasks();
255
256 EXPECT_TRUE(task_ran);
petrcermak7652da6d2014-11-06 02:17:57257}
258
jameswest6e0c8d22016-11-15 05:19:54259TEST(TimerTest, OneShotTimerWithTickClock) {
Gabriel Charette694c3c332019-08-19 14:53:05260 test::TaskEnvironment task_environment(
261 test::TaskEnvironment::TimeSource::MOCK_TIME);
jameswest6e0c8d22016-11-15 05:19:54262 Receiver receiver;
Gabriel Charette694c3c332019-08-19 14:53:05263 OneShotTimer timer(task_environment.GetMockTickClock());
Patrick Monette466823932022-01-10 20:33:52264 timer.Start(FROM_HERE, kTestDelay,
tzikf3336c92018-07-25 03:15:50265 BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
Patrick Monette466823932022-01-10 20:33:52266 task_environment.FastForwardBy(kTestDelay);
jameswest6e0c8d22016-11-15 05:19:54267 EXPECT_TRUE(receiver.WasCalled());
Etienne Pierre-doray9c3d17d82022-05-12 22:05:29268 EXPECT_FALSE(timer.IsRunning());
jameswest6e0c8d22016-11-15 05:19:54269}
270
Sami Kyostila3f49cb572018-11-19 13:01:09271TEST_P(TimerTestWithThreadType, RepeatingTimer) {
Patrick Monette466823932022-01-10 20:33:52272 RunTest_RepeatingTimer(GetParam(), kTestDelay);
[email protected]aeab57ea2008-08-28 20:50:12273}
274
Sami Kyostila3f49cb572018-11-19 13:01:09275TEST_P(TimerTestWithThreadType, RepeatingTimer_Cancel) {
Patrick Monette466823932022-01-10 20:33:52276 RunTest_RepeatingTimer_Cancel(GetParam(), kTestDelay);
[email protected]e495c532013-12-06 15:22:35277}
278
Sami Kyostila3f49cb572018-11-19 13:01:09279TEST_P(TimerTestWithThreadType, RepeatingTimerZeroDelay) {
Patrick Monette466823932022-01-10 20:33:52280 RunTest_RepeatingTimer(GetParam(), Seconds(0));
[email protected]e495c532013-12-06 15:22:35281}
282
Sami Kyostila3f49cb572018-11-19 13:01:09283TEST_P(TimerTestWithThreadType, RepeatingTimerZeroDelay_Cancel) {
Patrick Monette466823932022-01-10 20:33:52284 RunTest_RepeatingTimer_Cancel(GetParam(), Seconds(0));
[email protected]aeab57ea2008-08-28 20:50:12285}
[email protected]a0287cbd2008-12-02 23:16:55286
jameswest6e0c8d22016-11-15 05:19:54287TEST(TimerTest, RepeatingTimerWithTickClock) {
Gabriel Charette694c3c332019-08-19 14:53:05288 test::TaskEnvironment task_environment(
289 test::TaskEnvironment::TimeSource::MOCK_TIME);
jameswest6e0c8d22016-11-15 05:19:54290 Receiver receiver;
291 const int expected_times_called = 10;
Gabriel Charette694c3c332019-08-19 14:53:05292 RepeatingTimer timer(task_environment.GetMockTickClock());
Patrick Monette466823932022-01-10 20:33:52293 timer.Start(FROM_HERE, kTestDelay,
tzikf3336c92018-07-25 03:15:50294 BindRepeating(&Receiver::OnCalled, Unretained(&receiver)));
Patrick Monette466823932022-01-10 20:33:52295 task_environment.FastForwardBy(expected_times_called * kTestDelay);
jameswest6e0c8d22016-11-15 05:19:54296 timer.Stop();
297 EXPECT_EQ(expected_times_called, receiver.TimesCalled());
298}
299
Sami Kyostila3f49cb572018-11-19 13:01:09300TEST_P(TimerTestWithThreadType, DelayTimer_NoCall) {
301 RunTest_DelayTimer_NoCall(GetParam());
[email protected]e68e62fa2009-02-20 02:00:04302}
303
Sami Kyostila3f49cb572018-11-19 13:01:09304TEST_P(TimerTestWithThreadType, DelayTimer_OneCall) {
305 RunTest_DelayTimer_OneCall(GetParam());
[email protected]e68e62fa2009-02-20 02:00:04306}
307
Patrick Monette466823932022-01-10 20:33:52308TEST_P(TimerTestWithThreadType, DelayTimer_Reset) {
Sami Kyostila3f49cb572018-11-19 13:01:09309 RunTest_DelayTimer_Reset(GetParam());
[email protected]e68e62fa2009-02-20 02:00:04310}
311
Sami Kyostila3f49cb572018-11-19 13:01:09312TEST_P(TimerTestWithThreadType, DelayTimer_Deleted) {
313 RunTest_DelayTimer_Deleted(GetParam());
[email protected]02bf7f272009-02-26 23:17:56314}
315
jameswest6e0c8d22016-11-15 05:19:54316TEST(TimerTest, DelayTimerWithTickClock) {
Gabriel Charette694c3c332019-08-19 14:53:05317 test::TaskEnvironment task_environment(
318 test::TaskEnvironment::TimeSource::MOCK_TIME);
jameswest6e0c8d22016-11-15 05:19:54319 Receiver receiver;
Patrick Monette466823932022-01-10 20:33:52320 DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled,
Peter Kasting53fd6ee2021-10-05 20:40:48321 task_environment.GetMockTickClock());
Patrick Monette466823932022-01-10 20:33:52322 task_environment.FastForwardBy(kTestDelay - Microseconds(1));
jameswest6e0c8d22016-11-15 05:19:54323 EXPECT_FALSE(receiver.WasCalled());
324 timer.Reset();
Patrick Monette466823932022-01-10 20:33:52325 task_environment.FastForwardBy(kTestDelay - Microseconds(1));
jameswest6e0c8d22016-11-15 05:19:54326 EXPECT_FALSE(receiver.WasCalled());
327 timer.Reset();
Patrick Monette466823932022-01-10 20:33:52328 task_environment.FastForwardBy(kTestDelay);
jameswest6e0c8d22016-11-15 05:19:54329 EXPECT_TRUE(receiver.WasCalled());
330}
331
Sami Kyostila3f49cb572018-11-19 13:01:09332TEST(TimerTest, TaskEnvironmentShutdown) {
[email protected]a0287cbd2008-12-02 23:16:55333 // This test is designed to verify that shutdown of the
334 // message loop does not cause crashes if there were pending
335 // timers not yet fired. It may only trigger exceptions
[email protected]64e95e12011-08-17 17:41:02336 // if debug heap checking is enabled.
Patrick Monette466823932022-01-10 20:33:52337 Receiver receiver;
338 OneShotTimer timer;
339
[email protected]a0287cbd2008-12-02 23:16:55340 {
Patrick Monette466823932022-01-10 20:33:52341 test::TaskEnvironment task_environment;
342 timer.Start(FROM_HERE, kTestDelay,
343 BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
344 } // Task environment destructs by falling out of scope.
[email protected]a0287cbd2008-12-02 23:16:55345
Patrick Monette466823932022-01-10 20:33:52346 EXPECT_FALSE(receiver.WasCalled());
347 // Timer destruct. SHOULD NOT CRASH, of course.
[email protected]a0287cbd2008-12-02 23:16:55348}
[email protected]df9076a2012-03-27 00:18:57349
Etienne Pierre-doray9c3d17d82022-05-12 22:05:29350TEST(TimerTest, TaskEnvironmentSelfOwningTimer) {
351 // This test verifies that a timer does not cause crashes if
352 // |Timer::user_task_| owns the timer. The test may only trigger exceptions if
353 // debug heap checking is enabled.
pkotwicz4a286ed2017-01-17 20:45:26354
Patrick Monette466823932022-01-10 20:33:52355 auto timer = std::make_unique<OneShotTimer>();
356 auto* timer_ptr = timer.get();
pkotwicz4a286ed2017-01-17 20:45:26357
Etienne Pierre-doray9c3d17d82022-05-12 22:05:29358 test::TaskEnvironment task_environment(
359 test::TaskEnvironment::TimeSource::MOCK_TIME);
Patrick Monette466823932022-01-10 20:33:52360
361 timer_ptr->Start(FROM_HERE, kTestDelay,
362 BindLambdaForTesting([timer = std::move(timer)]() {}));
Etienne Pierre-doray9c3d17d82022-05-12 22:05:29363 // |Timer::user_task_| owns sole reference to |timer|. Both will be destroyed
364 // once the task ran. SHOULD NOT CRASH.
365 task_environment.FastForwardUntilNoTasksRemain();
366}
pkotwicz4a286ed2017-01-17 20:45:26367
Etienne Pierre-doray9c3d17d82022-05-12 22:05:29368TEST(TimerTest, TaskEnvironmentSelfOwningTimerStopped) {
369 // This test verifies that a timer does not cause crashes when stopped if
370 // |Timer::user_task_| owns the timer. The test may only trigger exceptions if
371 // debug heap checking is enabled.
372
373 auto timer = std::make_unique<OneShotTimer>();
374 auto* timer_ptr = timer.get();
375
376 test::TaskEnvironment task_environment(
377 test::TaskEnvironment::TimeSource::MOCK_TIME);
378
379 timer_ptr->Start(FROM_HERE, kTestDelay,
380 BindLambdaForTesting([timer = std::move(timer)]() {
381 // Stop destroys |Timer::user_task_| which owns sole
382 // reference to |timer|. SHOULD NOT CRASH.
383 timer->Stop();
384 }));
385 task_environment.FastForwardUntilNoTasksRemain();
pkotwicz4a286ed2017-01-17 20:45:26386}
387
[email protected]df9076a2012-03-27 00:18:57388TEST(TimerTest, NonRepeatIsRunning) {
389 {
Gabriel Charette694c3c332019-08-19 14:53:05390 test::TaskEnvironment task_environment;
tzikd93bb0862018-07-19 11:54:14391 OneShotTimer timer;
[email protected]df9076a2012-03-27 00:18:57392 EXPECT_FALSE(timer.IsRunning());
Patrick Monette466823932022-01-10 20:33:52393 timer.Start(FROM_HERE, kTestDelay, DoNothing());
[email protected]df9076a2012-03-27 00:18:57394 EXPECT_TRUE(timer.IsRunning());
395 timer.Stop();
396 EXPECT_FALSE(timer.IsRunning());
[email protected]df9076a2012-03-27 00:18:57397 }
398
399 {
tzikd93bb0862018-07-19 11:54:14400 RetainingOneShotTimer timer;
Gabriel Charette694c3c332019-08-19 14:53:05401 test::TaskEnvironment task_environment;
[email protected]df9076a2012-03-27 00:18:57402 EXPECT_FALSE(timer.IsRunning());
Patrick Monette466823932022-01-10 20:33:52403 timer.Start(FROM_HERE, kTestDelay, DoNothing());
[email protected]df9076a2012-03-27 00:18:57404 EXPECT_TRUE(timer.IsRunning());
405 timer.Stop();
406 EXPECT_FALSE(timer.IsRunning());
407 ASSERT_FALSE(timer.user_task().is_null());
408 timer.Reset();
409 EXPECT_TRUE(timer.IsRunning());
410 }
411}
412
Sami Kyostila3f49cb572018-11-19 13:01:09413TEST(TimerTest, NonRepeatTaskEnvironmentDeath) {
tzikd93bb0862018-07-19 11:54:14414 OneShotTimer timer;
[email protected]df9076a2012-03-27 00:18:57415 {
Gabriel Charette694c3c332019-08-19 14:53:05416 test::TaskEnvironment task_environment;
[email protected]df9076a2012-03-27 00:18:57417 EXPECT_FALSE(timer.IsRunning());
Patrick Monette466823932022-01-10 20:33:52418 timer.Start(FROM_HERE, kTestDelay, DoNothing());
[email protected]df9076a2012-03-27 00:18:57419 EXPECT_TRUE(timer.IsRunning());
420 }
421 EXPECT_FALSE(timer.IsRunning());
[email protected]df9076a2012-03-27 00:18:57422}
423
424TEST(TimerTest, RetainRepeatIsRunning) {
Gabriel Charette694c3c332019-08-19 14:53:05425 test::TaskEnvironment task_environment;
Patrick Monette466823932022-01-10 20:33:52426 RepeatingTimer timer(FROM_HERE, kTestDelay, DoNothing());
[email protected]df9076a2012-03-27 00:18:57427 EXPECT_FALSE(timer.IsRunning());
428 timer.Reset();
429 EXPECT_TRUE(timer.IsRunning());
430 timer.Stop();
431 EXPECT_FALSE(timer.IsRunning());
432 timer.Reset();
433 EXPECT_TRUE(timer.IsRunning());
434}
435
436TEST(TimerTest, RetainNonRepeatIsRunning) {
Gabriel Charette694c3c332019-08-19 14:53:05437 test::TaskEnvironment task_environment;
Patrick Monette466823932022-01-10 20:33:52438 RetainingOneShotTimer timer(FROM_HERE, kTestDelay, DoNothing());
[email protected]df9076a2012-03-27 00:18:57439 EXPECT_FALSE(timer.IsRunning());
440 timer.Reset();
441 EXPECT_TRUE(timer.IsRunning());
442 timer.Stop();
443 EXPECT_FALSE(timer.IsRunning());
444 timer.Reset();
445 EXPECT_TRUE(timer.IsRunning());
446}
447
gab4e844bb2017-06-01 16:23:36448//-----------------------------------------------------------------------------
449
[email protected]df9076a2012-03-27 00:18:57450TEST(TimerTest, ContinuationStopStart) {
Patrick Monette466823932022-01-10 20:33:52451 test::TaskEnvironment task_environment(
452 test::TaskEnvironment::TimeSource::MOCK_TIME);
453
454 Receiver receiver1;
455 Receiver receiver2;
456 OneShotTimer timer;
457 timer.Start(FROM_HERE, kTestDelay,
458 BindOnce(&Receiver::OnCalled, Unretained(&receiver1)));
459 timer.Stop();
460 timer.Start(FROM_HERE, kLongTestDelay,
461 BindOnce(&Receiver::OnCalled, Unretained(&receiver2)));
462 task_environment.FastForwardBy(kLongTestDelay);
463 EXPECT_FALSE(receiver1.WasCalled());
464 EXPECT_TRUE(receiver2.WasCalled());
[email protected]df9076a2012-03-27 00:18:57465}
466
467TEST(TimerTest, ContinuationReset) {
Patrick Monette466823932022-01-10 20:33:52468 test::TaskEnvironment task_environment(
469 test::TaskEnvironment::TimeSource::MOCK_TIME);
470
471 Receiver receiver;
472 OneShotTimer timer;
473 timer.Start(FROM_HERE, kTestDelay,
474 BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
475 timer.Reset();
476 // // Since Reset happened before task ran, the user_task must not be
477 // cleared: ASSERT_FALSE(timer.user_task().is_null());
478 task_environment.FastForwardBy(kTestDelay);
479 EXPECT_TRUE(receiver.WasCalled());
[email protected]df9076a2012-03-27 00:18:57480}
481
Patrick Monette57d1c18d2021-04-22 00:50:44482TEST(TimerTest, AbandonedTaskIsCancelled) {
483 test::TaskEnvironment task_environment(
484 test::TaskEnvironment::TimeSource::MOCK_TIME);
485 OneShotTimer timer;
486
487 // Start a timer. There will be a pending task on the current sequence.
Patrick Monette466823932022-01-10 20:33:52488 timer.Start(FROM_HERE, kTestDelay, base::DoNothing());
Patrick Monette57d1c18d2021-04-22 00:50:44489 EXPECT_EQ(1u, task_environment.GetPendingMainThreadTaskCount());
490
Alex Attar467b2ce2024-11-04 14:50:28491 // After Stop(), the task is correctly treated as cancelled.
492 timer.Stop();
Patrick Monette57d1c18d2021-04-22 00:50:44493 EXPECT_EQ(0u, task_environment.GetPendingMainThreadTaskCount());
Etienne Pierre-doray9c3d17d82022-05-12 22:05:29494 EXPECT_FALSE(timer.IsRunning());
Patrick Monette57d1c18d2021-04-22 00:50:44495}
496
Etienne Pierre-doray1a0edc72022-01-14 15:11:44497TEST(TimerTest, DeadlineTimer) {
498 test::TaskEnvironment task_environment(
499 test::TaskEnvironment::TimeSource::MOCK_TIME);
500 RunLoop run_loop;
501 DeadlineTimer timer;
502 TimeTicks start = TimeTicks::Now();
503
504 timer.Start(FROM_HERE, start + Seconds(5), run_loop.QuitClosure());
505 run_loop.Run();
506 EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
507}
508
509TEST(TimerTest, DeadlineTimerCancel) {
510 test::TaskEnvironment task_environment(
511 test::TaskEnvironment::TimeSource::MOCK_TIME);
512 RunLoop run_loop;
513 DeadlineTimer timer;
514 TimeTicks start = TimeTicks::Now();
515
516 MockRepeatingCallback<void()> callback;
517 timer.Start(FROM_HERE, start + Seconds(5), callback.Get());
518
519 EXPECT_CALL(callback, Run()).Times(0);
520 timer.Stop();
521 task_environment.FastForwardBy(Seconds(5));
522 EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
523}
524
Etienne Pierre-doray9c3d17d82022-05-12 22:05:29525TEST(TimerTest, DeadlineTimerTaskDestructed) {
526 test::TaskEnvironment task_environment(
527 test::TaskEnvironment::TimeSource::MOCK_TIME);
528 RunLoop run_loop;
529 DeadlineTimer timer;
530 TimeTicks start = TimeTicks::Now();
531
532 MockRepeatingCallback<void()> destructed;
533 ScopedClosureRunner scoped_closure(destructed.Get());
534 timer.Start(FROM_HERE, start + Seconds(5),
535 BindOnce([](ScopedClosureRunner) {}, std::move(scoped_closure)));
536
537 EXPECT_CALL(destructed, Run());
538 timer.Stop();
539 testing::Mock::VerifyAndClearExpectations(&destructed);
540}
541
Etienne Pierre-dorayfeab1c22022-12-01 15:31:05542TEST(TimerTest, DeadlineTimerStartTwice) {
543 test::TaskEnvironment task_environment(
544 test::TaskEnvironment::TimeSource::MOCK_TIME);
545 DeadlineTimer timer;
546 TimeTicks start = TimeTicks::Now();
547
548 RunLoop run_loop;
549 timer.Start(FROM_HERE, start + Seconds(5), run_loop.QuitClosure());
550 timer.Start(FROM_HERE, start + Seconds(10), run_loop.QuitClosure());
551 run_loop.Run();
552 EXPECT_EQ(start + Seconds(10), TimeTicks::Now());
553}
554
Etienne Pierre-dorayc7654612022-06-08 22:23:32555TEST(TimerTest, MetronomeTimer) {
556 test::TaskEnvironment task_environment(
557 test::TaskEnvironment::TimeSource::MOCK_TIME);
558 MetronomeTimer timer;
559 TimeTicks start = TimeTicks::Now();
560
561 // Ensure the run_loop.Run() below doesn't straddle over multiple ticks.
562 task_environment.AdvanceClock(
563 start.SnappedToNextTick(TimeTicks(), Seconds(5)) - start);
564 start = TimeTicks::Now();
565
566 RunLoop run_loop;
567 timer.Start(FROM_HERE, Seconds(5), run_loop.QuitClosure());
568 run_loop.Run();
569 EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
570}
571
572TEST(TimerTest, MetronomeTimerCustomPhase) {
573 test::TaskEnvironment task_environment(
574 test::TaskEnvironment::TimeSource::MOCK_TIME);
575 RunLoop run_loop;
576 MetronomeTimer timer;
577 TimeTicks start = TimeTicks::Now();
578
579 timer.Start(FROM_HERE, Seconds(5), run_loop.QuitClosure(), start);
580 run_loop.Run();
581 EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
582}
583
584TEST(TimerTest, MetronomeTimerReset) {
585 test::TaskEnvironment task_environment(
586 test::TaskEnvironment::TimeSource::MOCK_TIME);
587 RunLoop run_loop;
588 TimeTicks start = TimeTicks::Now();
589 MetronomeTimer timer(FROM_HERE, Seconds(5), run_loop.QuitClosure(), start);
590
591 timer.Reset();
592 run_loop.Run();
593 EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
594}
595
596TEST(TimerTest, MetronomeTimerStartTwice) {
597 test::TaskEnvironment task_environment(
598 test::TaskEnvironment::TimeSource::MOCK_TIME);
599 MetronomeTimer timer;
600 TimeTicks start = TimeTicks::Now();
601
602 {
603 RunLoop run_loop;
604 timer.Start(FROM_HERE, Seconds(4), run_loop.QuitClosure(), start);
605 run_loop.Run();
606 }
607 EXPECT_EQ(start + Seconds(4), TimeTicks::Now());
608
609 {
610 RunLoop run_loop;
611 timer.Start(FROM_HERE, Seconds(2), run_loop.QuitClosure(), start);
612 run_loop.Run();
613 }
614 EXPECT_EQ(start + Seconds(6), TimeTicks::Now());
615}
616
617TEST(TimerTest, MetronomeTimerMultiple) {
618 test::TaskEnvironment task_environment(
619 test::TaskEnvironment::TimeSource::MOCK_TIME);
620 MetronomeTimer timer;
621 TimeTicks start = TimeTicks::Now();
622
623 // Ensure the subsequent FastForwardBy() don't straddle over multiple ticks.
624 task_environment.AdvanceClock(
625 start.SnappedToNextTick(TimeTicks(), Seconds(5)) - start);
626
627 MockRepeatingCallback<void()> callback;
628 timer.Start(FROM_HERE, Seconds(5), callback.Get());
629
630 // The first tick is skipped because it is too close. Ticks at 5s and 10s.
631 EXPECT_CALL(callback, Run()).Times(2);
632 task_environment.FastForwardBy(Seconds(10));
633
634 EXPECT_CALL(callback, Run()).Times(2);
635 // Ticks at 15s and 25s, while 20s is missed.
636 task_environment.AdvanceClock(Seconds(12));
637 task_environment.FastForwardBy(Seconds(3));
638}
639
640TEST(TimerTest, MetronomeTimerCancel) {
641 test::TaskEnvironment task_environment(
642 test::TaskEnvironment::TimeSource::MOCK_TIME);
643 RunLoop run_loop;
644 MetronomeTimer timer;
645 TimeTicks start = TimeTicks::Now();
646
647 MockRepeatingCallback<void()> callback;
648 timer.Start(FROM_HERE, Seconds(5), callback.Get());
649
650 EXPECT_CALL(callback, Run()).Times(0);
651 timer.Stop();
652 task_environment.FastForwardBy(Seconds(5));
653 EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
654}
655
Ilia Samsonova2885f72019-11-20 22:16:58656INSTANTIATE_TEST_SUITE_P(All,
Victor Costan033b9ac2019-01-29 00:52:16657 TimerTestWithThreadType,
658 testing::ValuesIn(testing_main_threads));
Sami Kyostila3f49cb572018-11-19 13:01:09659
gab175490c12016-11-28 23:01:33660} // namespace base