timer_unittest.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  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. #include "base/timer/timer.h"
  5. #include <stddef.h>
  6. #include <memory>
  7. #include "base/bind.h"
  8. #include "base/callback.h"
  9. #include "base/callback_helpers.h"
  10. #include "base/memory/ref_counted.h"
  11. #include "base/run_loop.h"
  12. #include "base/task/sequenced_task_runner.h"
  13. #include "base/test/bind.h"
  14. #include "base/test/mock_callback.h"
  15. #include "base/test/task_environment.h"
  16. #include "base/test/test_simple_task_runner.h"
  17. #include "base/threading/sequenced_task_runner_handle.h"
  18. #include "base/time/tick_clock.h"
  19. #include "base/time/time.h"
  20. #include "build/build_config.h"
  21. #include "testing/gtest/include/gtest/gtest.h"
  22. namespace base {
  23. namespace {
  24. constexpr TimeDelta kTestDelay = Seconds(10);
  25. constexpr TimeDelta kLongTestDelay = Minutes(10);
  26. // The main thread types on which each timer should be tested.
  27. const test::TaskEnvironment::MainThreadType testing_main_threads[] = {
  28. test::TaskEnvironment::MainThreadType::DEFAULT,
  29. test::TaskEnvironment::MainThreadType::IO,
  30. #if !BUILDFLAG(IS_IOS) // iOS does not allow direct running of the UI loop.
  31. test::TaskEnvironment::MainThreadType::UI,
  32. #endif
  33. };
  34. class Receiver {
  35. public:
  36. Receiver() : count_(0) {}
  37. void OnCalled() { count_++; }
  38. bool WasCalled() { return count_ > 0; }
  39. int TimesCalled() { return count_; }
  40. private:
  41. int count_;
  42. };
  43. // Basic test with same setup as RunTest_OneShotTimers_Cancel below to confirm
  44. // that |timer| would be fired in that test if it wasn't for the deletion.
  45. void RunTest_OneShotTimers(
  46. test::TaskEnvironment::MainThreadType main_thread_type) {
  47. test::TaskEnvironment task_environment(
  48. test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
  49. Receiver receiver;
  50. OneShotTimer timer;
  51. timer.Start(FROM_HERE, kTestDelay,
  52. BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
  53. task_environment.FastForwardBy(kTestDelay);
  54. EXPECT_TRUE(receiver.WasCalled());
  55. EXPECT_FALSE(timer.IsRunning());
  56. }
  57. void RunTest_OneShotTimers_Cancel(
  58. test::TaskEnvironment::MainThreadType main_thread_type) {
  59. test::TaskEnvironment task_environment(
  60. test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
  61. Receiver receiver;
  62. auto timer = std::make_unique<OneShotTimer>();
  63. auto* timer_ptr = timer.get();
  64. // This should run before the timer expires.
  65. SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, std::move(timer));
  66. timer_ptr->Start(FROM_HERE, kTestDelay,
  67. BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
  68. task_environment.FastForwardBy(kTestDelay);
  69. EXPECT_FALSE(receiver.WasCalled());
  70. }
  71. void RunTest_OneShotSelfDeletingTimer(
  72. test::TaskEnvironment::MainThreadType main_thread_type) {
  73. test::TaskEnvironment task_environment(
  74. test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
  75. Receiver receiver;
  76. auto timer = std::make_unique<OneShotTimer>();
  77. auto* timer_ptr = timer.get();
  78. timer_ptr->Start(
  79. FROM_HERE, kTestDelay,
  80. BindLambdaForTesting([&receiver, timer = std::move(timer)]() mutable {
  81. receiver.OnCalled();
  82. EXPECT_FALSE(timer->IsRunning());
  83. timer.reset();
  84. }));
  85. task_environment.FastForwardBy(kTestDelay);
  86. EXPECT_TRUE(receiver.WasCalled());
  87. }
  88. void RunTest_RepeatingTimer(
  89. test::TaskEnvironment::MainThreadType main_thread_type,
  90. const TimeDelta& delay) {
  91. test::TaskEnvironment task_environment(
  92. test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
  93. Receiver receiver;
  94. RepeatingTimer timer;
  95. timer.Start(FROM_HERE, kTestDelay,
  96. BindRepeating(&Receiver::OnCalled, Unretained(&receiver)));
  97. task_environment.FastForwardBy(20 * kTestDelay);
  98. EXPECT_EQ(receiver.TimesCalled(), 20);
  99. EXPECT_TRUE(timer.IsRunning());
  100. }
  101. void RunTest_RepeatingTimer_Cancel(
  102. test::TaskEnvironment::MainThreadType main_thread_type,
  103. const TimeDelta& delay) {
  104. test::TaskEnvironment task_environment(
  105. test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
  106. Receiver receiver;
  107. auto timer = std::make_unique<RepeatingTimer>();
  108. auto* timer_ptr = timer.get();
  109. // This should run before the timer expires.
  110. SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, std::move(timer));
  111. timer_ptr->Start(FROM_HERE, delay,
  112. BindRepeating(&Receiver::OnCalled, Unretained(&receiver)));
  113. task_environment.FastForwardBy(delay);
  114. EXPECT_FALSE(receiver.WasCalled());
  115. }
  116. void RunTest_DelayTimer_NoCall(
  117. test::TaskEnvironment::MainThreadType main_thread_type) {
  118. test::TaskEnvironment task_environment(
  119. test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
  120. Receiver receiver;
  121. DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
  122. task_environment.FastForwardBy(kTestDelay);
  123. EXPECT_FALSE(receiver.WasCalled());
  124. }
  125. void RunTest_DelayTimer_OneCall(
  126. test::TaskEnvironment::MainThreadType main_thread_type) {
  127. test::TaskEnvironment task_environment(
  128. test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
  129. Receiver receiver;
  130. DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
  131. timer.Reset();
  132. task_environment.FastForwardBy(kTestDelay);
  133. EXPECT_TRUE(receiver.WasCalled());
  134. }
  135. void RunTest_DelayTimer_Reset(
  136. test::TaskEnvironment::MainThreadType main_thread_type) {
  137. test::TaskEnvironment task_environment(
  138. test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
  139. Receiver receiver;
  140. DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
  141. timer.Reset();
  142. // Fast-forward by a delay smaller than the timer delay. The timer will not
  143. // fire.
  144. task_environment.FastForwardBy(kTestDelay / 2);
  145. EXPECT_FALSE(receiver.WasCalled());
  146. // Postpone the fire time.
  147. timer.Reset();
  148. // Verify that the timer does not fire at its original fire time.
  149. task_environment.FastForwardBy(kTestDelay / 2);
  150. EXPECT_FALSE(receiver.WasCalled());
  151. // Fast-forward by the timer delay. The timer will fire.
  152. task_environment.FastForwardBy(kTestDelay / 2);
  153. EXPECT_TRUE(receiver.WasCalled());
  154. }
  155. void RunTest_DelayTimer_Deleted(
  156. test::TaskEnvironment::MainThreadType main_thread_type) {
  157. test::TaskEnvironment task_environment(
  158. test::TaskEnvironment::TimeSource::MOCK_TIME, main_thread_type);
  159. Receiver receiver;
  160. {
  161. DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled);
  162. timer.Reset();
  163. }
  164. // Because the timer was deleted, it will never fire.
  165. task_environment.FastForwardBy(kTestDelay);
  166. EXPECT_FALSE(receiver.WasCalled());
  167. }
  168. } // namespace
  169. //-----------------------------------------------------------------------------
  170. // Each test is run against each type of main thread. That way we are sure
  171. // that timers work properly in all configurations.
  172. class TimerTestWithThreadType
  173. : public testing::TestWithParam<test::TaskEnvironment::MainThreadType> {};
  174. TEST_P(TimerTestWithThreadType, OneShotTimers) {
  175. RunTest_OneShotTimers(GetParam());
  176. }
  177. TEST_P(TimerTestWithThreadType, OneShotTimers_Cancel) {
  178. RunTest_OneShotTimers_Cancel(GetParam());
  179. }
  180. // If underline timer does not handle properly, we will crash or fail
  181. // in full page heap environment.
  182. TEST_P(TimerTestWithThreadType, OneShotSelfDeletingTimer) {
  183. RunTest_OneShotSelfDeletingTimer(GetParam());
  184. }
  185. TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
  186. auto task_runner = base::MakeRefCounted<TestSimpleTaskRunner>();
  187. OneShotTimer timer;
  188. bool task_ran = false;
  189. // The timer will use the TestSimpleTaskRunner to schedule its delays.
  190. timer.SetTaskRunner(task_runner);
  191. timer.Start(FROM_HERE, Days(1),
  192. BindLambdaForTesting([&]() { task_ran = true; }));
  193. EXPECT_FALSE(task_ran);
  194. EXPECT_TRUE(task_runner->HasPendingTask());
  195. task_runner->RunPendingTasks();
  196. EXPECT_TRUE(task_ran);
  197. }
  198. TEST(TimerTest, OneShotTimerWithTickClock) {
  199. test::TaskEnvironment task_environment(
  200. test::TaskEnvironment::TimeSource::MOCK_TIME);
  201. Receiver receiver;
  202. OneShotTimer timer(task_environment.GetMockTickClock());
  203. timer.Start(FROM_HERE, kTestDelay,
  204. BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
  205. task_environment.FastForwardBy(kTestDelay);
  206. EXPECT_TRUE(receiver.WasCalled());
  207. EXPECT_FALSE(timer.IsRunning());
  208. }
  209. TEST_P(TimerTestWithThreadType, RepeatingTimer) {
  210. RunTest_RepeatingTimer(GetParam(), kTestDelay);
  211. }
  212. TEST_P(TimerTestWithThreadType, RepeatingTimer_Cancel) {
  213. RunTest_RepeatingTimer_Cancel(GetParam(), kTestDelay);
  214. }
  215. TEST_P(TimerTestWithThreadType, RepeatingTimerZeroDelay) {
  216. RunTest_RepeatingTimer(GetParam(), Seconds(0));
  217. }
  218. TEST_P(TimerTestWithThreadType, RepeatingTimerZeroDelay_Cancel) {
  219. RunTest_RepeatingTimer_Cancel(GetParam(), Seconds(0));
  220. }
  221. TEST(TimerTest, RepeatingTimerWithTickClock) {
  222. test::TaskEnvironment task_environment(
  223. test::TaskEnvironment::TimeSource::MOCK_TIME);
  224. Receiver receiver;
  225. const int expected_times_called = 10;
  226. RepeatingTimer timer(task_environment.GetMockTickClock());
  227. timer.Start(FROM_HERE, kTestDelay,
  228. BindRepeating(&Receiver::OnCalled, Unretained(&receiver)));
  229. task_environment.FastForwardBy(expected_times_called * kTestDelay);
  230. timer.Stop();
  231. EXPECT_EQ(expected_times_called, receiver.TimesCalled());
  232. }
  233. TEST_P(TimerTestWithThreadType, DelayTimer_NoCall) {
  234. RunTest_DelayTimer_NoCall(GetParam());
  235. }
  236. TEST_P(TimerTestWithThreadType, DelayTimer_OneCall) {
  237. RunTest_DelayTimer_OneCall(GetParam());
  238. }
  239. TEST_P(TimerTestWithThreadType, DelayTimer_Reset) {
  240. RunTest_DelayTimer_Reset(GetParam());
  241. }
  242. TEST_P(TimerTestWithThreadType, DelayTimer_Deleted) {
  243. RunTest_DelayTimer_Deleted(GetParam());
  244. }
  245. TEST(TimerTest, DelayTimerWithTickClock) {
  246. test::TaskEnvironment task_environment(
  247. test::TaskEnvironment::TimeSource::MOCK_TIME);
  248. Receiver receiver;
  249. DelayTimer timer(FROM_HERE, kTestDelay, &receiver, &Receiver::OnCalled,
  250. task_environment.GetMockTickClock());
  251. task_environment.FastForwardBy(kTestDelay - Microseconds(1));
  252. EXPECT_FALSE(receiver.WasCalled());
  253. timer.Reset();
  254. task_environment.FastForwardBy(kTestDelay - Microseconds(1));
  255. EXPECT_FALSE(receiver.WasCalled());
  256. timer.Reset();
  257. task_environment.FastForwardBy(kTestDelay);
  258. EXPECT_TRUE(receiver.WasCalled());
  259. }
  260. TEST(TimerTest, TaskEnvironmentShutdown) {
  261. // This test is designed to verify that shutdown of the
  262. // message loop does not cause crashes if there were pending
  263. // timers not yet fired. It may only trigger exceptions
  264. // if debug heap checking is enabled.
  265. Receiver receiver;
  266. OneShotTimer timer;
  267. {
  268. test::TaskEnvironment task_environment;
  269. timer.Start(FROM_HERE, kTestDelay,
  270. BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
  271. } // Task environment destructs by falling out of scope.
  272. EXPECT_FALSE(receiver.WasCalled());
  273. // Timer destruct. SHOULD NOT CRASH, of course.
  274. }
  275. TEST(TimerTest, TaskEnvironmentSelfOwningTimer) {
  276. // This test verifies that a timer does not cause crashes if
  277. // |Timer::user_task_| owns the timer. The test may only trigger exceptions if
  278. // debug heap checking is enabled.
  279. auto timer = std::make_unique<OneShotTimer>();
  280. auto* timer_ptr = timer.get();
  281. test::TaskEnvironment task_environment(
  282. test::TaskEnvironment::TimeSource::MOCK_TIME);
  283. timer_ptr->Start(FROM_HERE, kTestDelay,
  284. BindLambdaForTesting([timer = std::move(timer)]() {}));
  285. // |Timer::user_task_| owns sole reference to |timer|. Both will be destroyed
  286. // once the task ran. SHOULD NOT CRASH.
  287. task_environment.FastForwardUntilNoTasksRemain();
  288. }
  289. TEST(TimerTest, TaskEnvironmentSelfOwningTimerStopped) {
  290. // This test verifies that a timer does not cause crashes when stopped if
  291. // |Timer::user_task_| owns the timer. The test may only trigger exceptions if
  292. // debug heap checking is enabled.
  293. auto timer = std::make_unique<OneShotTimer>();
  294. auto* timer_ptr = timer.get();
  295. test::TaskEnvironment task_environment(
  296. test::TaskEnvironment::TimeSource::MOCK_TIME);
  297. timer_ptr->Start(FROM_HERE, kTestDelay,
  298. BindLambdaForTesting([timer = std::move(timer)]() {
  299. // Stop destroys |Timer::user_task_| which owns sole
  300. // reference to |timer|. SHOULD NOT CRASH.
  301. timer->Stop();
  302. }));
  303. task_environment.FastForwardUntilNoTasksRemain();
  304. }
  305. TEST(TimerTest, NonRepeatIsRunning) {
  306. {
  307. test::TaskEnvironment task_environment;
  308. OneShotTimer timer;
  309. EXPECT_FALSE(timer.IsRunning());
  310. timer.Start(FROM_HERE, kTestDelay, DoNothing());
  311. EXPECT_TRUE(timer.IsRunning());
  312. timer.Stop();
  313. EXPECT_FALSE(timer.IsRunning());
  314. }
  315. {
  316. RetainingOneShotTimer timer;
  317. test::TaskEnvironment task_environment;
  318. EXPECT_FALSE(timer.IsRunning());
  319. timer.Start(FROM_HERE, kTestDelay, DoNothing());
  320. EXPECT_TRUE(timer.IsRunning());
  321. timer.Stop();
  322. EXPECT_FALSE(timer.IsRunning());
  323. ASSERT_FALSE(timer.user_task().is_null());
  324. timer.Reset();
  325. EXPECT_TRUE(timer.IsRunning());
  326. }
  327. }
  328. TEST(TimerTest, NonRepeatTaskEnvironmentDeath) {
  329. OneShotTimer timer;
  330. {
  331. test::TaskEnvironment task_environment;
  332. EXPECT_FALSE(timer.IsRunning());
  333. timer.Start(FROM_HERE, kTestDelay, DoNothing());
  334. EXPECT_TRUE(timer.IsRunning());
  335. }
  336. EXPECT_FALSE(timer.IsRunning());
  337. }
  338. TEST(TimerTest, RetainRepeatIsRunning) {
  339. test::TaskEnvironment task_environment;
  340. RepeatingTimer timer(FROM_HERE, kTestDelay, DoNothing());
  341. EXPECT_FALSE(timer.IsRunning());
  342. timer.Reset();
  343. EXPECT_TRUE(timer.IsRunning());
  344. timer.Stop();
  345. EXPECT_FALSE(timer.IsRunning());
  346. timer.Reset();
  347. EXPECT_TRUE(timer.IsRunning());
  348. }
  349. TEST(TimerTest, RetainNonRepeatIsRunning) {
  350. test::TaskEnvironment task_environment;
  351. RetainingOneShotTimer timer(FROM_HERE, kTestDelay, DoNothing());
  352. EXPECT_FALSE(timer.IsRunning());
  353. timer.Reset();
  354. EXPECT_TRUE(timer.IsRunning());
  355. timer.Stop();
  356. EXPECT_FALSE(timer.IsRunning());
  357. timer.Reset();
  358. EXPECT_TRUE(timer.IsRunning());
  359. }
  360. //-----------------------------------------------------------------------------
  361. TEST(TimerTest, ContinuationStopStart) {
  362. test::TaskEnvironment task_environment(
  363. test::TaskEnvironment::TimeSource::MOCK_TIME);
  364. Receiver receiver1;
  365. Receiver receiver2;
  366. OneShotTimer timer;
  367. timer.Start(FROM_HERE, kTestDelay,
  368. BindOnce(&Receiver::OnCalled, Unretained(&receiver1)));
  369. timer.Stop();
  370. timer.Start(FROM_HERE, kLongTestDelay,
  371. BindOnce(&Receiver::OnCalled, Unretained(&receiver2)));
  372. task_environment.FastForwardBy(kLongTestDelay);
  373. EXPECT_FALSE(receiver1.WasCalled());
  374. EXPECT_TRUE(receiver2.WasCalled());
  375. }
  376. TEST(TimerTest, ContinuationReset) {
  377. test::TaskEnvironment task_environment(
  378. test::TaskEnvironment::TimeSource::MOCK_TIME);
  379. Receiver receiver;
  380. OneShotTimer timer;
  381. timer.Start(FROM_HERE, kTestDelay,
  382. BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
  383. timer.Reset();
  384. // // Since Reset happened before task ran, the user_task must not be
  385. // cleared: ASSERT_FALSE(timer.user_task().is_null());
  386. task_environment.FastForwardBy(kTestDelay);
  387. EXPECT_TRUE(receiver.WasCalled());
  388. }
  389. TEST(TimerTest, AbandonedTaskIsCancelled) {
  390. test::TaskEnvironment task_environment(
  391. test::TaskEnvironment::TimeSource::MOCK_TIME);
  392. OneShotTimer timer;
  393. // Start a timer. There will be a pending task on the current sequence.
  394. timer.Start(FROM_HERE, kTestDelay, base::DoNothing());
  395. EXPECT_EQ(1u, task_environment.GetPendingMainThreadTaskCount());
  396. // After AbandonAndStop(), the task is correctly treated as cancelled.
  397. timer.AbandonAndStop();
  398. EXPECT_EQ(0u, task_environment.GetPendingMainThreadTaskCount());
  399. EXPECT_FALSE(timer.IsRunning());
  400. }
  401. TEST(TimerTest, DeadlineTimer) {
  402. test::TaskEnvironment task_environment(
  403. test::TaskEnvironment::TimeSource::MOCK_TIME);
  404. RunLoop run_loop;
  405. DeadlineTimer timer;
  406. TimeTicks start = TimeTicks::Now();
  407. timer.Start(FROM_HERE, start + Seconds(5), run_loop.QuitClosure());
  408. run_loop.Run();
  409. EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
  410. }
  411. TEST(TimerTest, DeadlineTimerCancel) {
  412. test::TaskEnvironment task_environment(
  413. test::TaskEnvironment::TimeSource::MOCK_TIME);
  414. RunLoop run_loop;
  415. DeadlineTimer timer;
  416. TimeTicks start = TimeTicks::Now();
  417. MockRepeatingCallback<void()> callback;
  418. timer.Start(FROM_HERE, start + Seconds(5), callback.Get());
  419. EXPECT_CALL(callback, Run()).Times(0);
  420. timer.Stop();
  421. task_environment.FastForwardBy(Seconds(5));
  422. EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
  423. }
  424. TEST(TimerTest, DeadlineTimerTaskDestructed) {
  425. test::TaskEnvironment task_environment(
  426. test::TaskEnvironment::TimeSource::MOCK_TIME);
  427. RunLoop run_loop;
  428. DeadlineTimer timer;
  429. TimeTicks start = TimeTicks::Now();
  430. MockRepeatingCallback<void()> destructed;
  431. ScopedClosureRunner scoped_closure(destructed.Get());
  432. timer.Start(FROM_HERE, start + Seconds(5),
  433. BindOnce([](ScopedClosureRunner) {}, std::move(scoped_closure)));
  434. EXPECT_CALL(destructed, Run());
  435. timer.Stop();
  436. testing::Mock::VerifyAndClearExpectations(&destructed);
  437. }
  438. TEST(TimerTest, MetronomeTimer) {
  439. test::TaskEnvironment task_environment(
  440. test::TaskEnvironment::TimeSource::MOCK_TIME);
  441. MetronomeTimer timer;
  442. TimeTicks start = TimeTicks::Now();
  443. // Ensure the run_loop.Run() below doesn't straddle over multiple ticks.
  444. task_environment.AdvanceClock(
  445. start.SnappedToNextTick(TimeTicks(), Seconds(5)) - start);
  446. start = TimeTicks::Now();
  447. RunLoop run_loop;
  448. timer.Start(FROM_HERE, Seconds(5), run_loop.QuitClosure());
  449. run_loop.Run();
  450. EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
  451. }
  452. TEST(TimerTest, MetronomeTimerCustomPhase) {
  453. test::TaskEnvironment task_environment(
  454. test::TaskEnvironment::TimeSource::MOCK_TIME);
  455. RunLoop run_loop;
  456. MetronomeTimer timer;
  457. TimeTicks start = TimeTicks::Now();
  458. timer.Start(FROM_HERE, Seconds(5), run_loop.QuitClosure(), start);
  459. run_loop.Run();
  460. EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
  461. }
  462. TEST(TimerTest, MetronomeTimerReset) {
  463. test::TaskEnvironment task_environment(
  464. test::TaskEnvironment::TimeSource::MOCK_TIME);
  465. RunLoop run_loop;
  466. TimeTicks start = TimeTicks::Now();
  467. MetronomeTimer timer(FROM_HERE, Seconds(5), run_loop.QuitClosure(), start);
  468. timer.Reset();
  469. run_loop.Run();
  470. EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
  471. }
  472. TEST(TimerTest, MetronomeTimerStartTwice) {
  473. test::TaskEnvironment task_environment(
  474. test::TaskEnvironment::TimeSource::MOCK_TIME);
  475. MetronomeTimer timer;
  476. TimeTicks start = TimeTicks::Now();
  477. {
  478. RunLoop run_loop;
  479. timer.Start(FROM_HERE, Seconds(4), run_loop.QuitClosure(), start);
  480. run_loop.Run();
  481. }
  482. EXPECT_EQ(start + Seconds(4), TimeTicks::Now());
  483. {
  484. RunLoop run_loop;
  485. timer.Start(FROM_HERE, Seconds(2), run_loop.QuitClosure(), start);
  486. run_loop.Run();
  487. }
  488. EXPECT_EQ(start + Seconds(6), TimeTicks::Now());
  489. }
  490. TEST(TimerTest, MetronomeTimerMultiple) {
  491. test::TaskEnvironment task_environment(
  492. test::TaskEnvironment::TimeSource::MOCK_TIME);
  493. MetronomeTimer timer;
  494. TimeTicks start = TimeTicks::Now();
  495. // Ensure the subsequent FastForwardBy() don't straddle over multiple ticks.
  496. task_environment.AdvanceClock(
  497. start.SnappedToNextTick(TimeTicks(), Seconds(5)) - start);
  498. MockRepeatingCallback<void()> callback;
  499. timer.Start(FROM_HERE, Seconds(5), callback.Get());
  500. // The first tick is skipped because it is too close. Ticks at 5s and 10s.
  501. EXPECT_CALL(callback, Run()).Times(2);
  502. task_environment.FastForwardBy(Seconds(10));
  503. EXPECT_CALL(callback, Run()).Times(2);
  504. // Ticks at 15s and 25s, while 20s is missed.
  505. task_environment.AdvanceClock(Seconds(12));
  506. task_environment.FastForwardBy(Seconds(3));
  507. }
  508. TEST(TimerTest, MetronomeTimerCancel) {
  509. test::TaskEnvironment task_environment(
  510. test::TaskEnvironment::TimeSource::MOCK_TIME);
  511. RunLoop run_loop;
  512. MetronomeTimer timer;
  513. TimeTicks start = TimeTicks::Now();
  514. MockRepeatingCallback<void()> callback;
  515. timer.Start(FROM_HERE, Seconds(5), callback.Get());
  516. EXPECT_CALL(callback, Run()).Times(0);
  517. timer.Stop();
  518. task_environment.FastForwardBy(Seconds(5));
  519. EXPECT_EQ(start + Seconds(5), TimeTicks::Now());
  520. }
  521. INSTANTIATE_TEST_SUITE_P(All,
  522. TimerTestWithThreadType,
  523. testing::ValuesIn(testing_main_threads));
  524. } // namespace base