blob: fd1fff5361ea19066fac9a9fd4f9edc41ad28482 [file] [log] [blame]
evan@chromium.org3c0bc352012-02-14 09:29:14 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botf003cfe2008-08-24 09:55:55 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit3f4a7322008-07-27 06:49:38 +09004
dchengcc8e4d82016-04-05 06:25:51 +09005#include "base/timer/timer.h"
6
avia6a6a682015-12-27 07:15:14 +09007#include <stddef.h>
8
dchengcc8e4d82016-04-05 06:25:51 +09009#include <memory>
10
jameswest9f1f3a02016-11-15 14:19:54 +090011#include "base/bind.h"
12#include "base/bind_helpers.h"
gabccd5b952016-11-29 08:01:33 +090013#include "base/callback.h"
avia6a6a682015-12-27 07:15:14 +090014#include "base/macros.h"
gabccd5b952016-11-29 08:01:33 +090015#include "base/memory/ptr_util.h"
pkotwicz55d7a1e2017-01-18 05:45:26 +090016#include "base/memory/ref_counted.h"
avi@chromium.orga043a862013-07-18 17:12:40 +090017#include "base/message_loop/message_loop.h"
fdoray85919bb2016-07-01 03:17:39 +090018#include "base/run_loop.h"
gabccd5b952016-11-29 08:01:33 +090019#include "base/sequenced_task_runner.h"
gabccd5b952016-11-29 08:01:33 +090020#include "base/synchronization/waitable_event.h"
21#include "base/test/sequenced_worker_pool_owner.h"
jameswest9f1f3a02016-11-15 14:19:54 +090022#include "base/test/test_mock_time_task_runner.h"
gabccd5b952016-11-29 08:01:33 +090023#include "base/threading/platform_thread.h"
24#include "base/threading/sequenced_task_runner_handle.h"
25#include "base/threading/thread.h"
jameswest9f1f3a02016-11-15 14:19:54 +090026#include "base/time/tick_clock.h"
gabccd5b952016-11-29 08:01:33 +090027#include "base/time/time.h"
avia6a6a682015-12-27 07:15:14 +090028#include "build/build_config.h"
initial.commit3f4a7322008-07-27 06:49:38 +090029#include "testing/gtest/include/gtest/gtest.h"
30
gabccd5b952016-11-29 08:01:33 +090031namespace base {
dsh@google.com0f8dd262008-10-28 05:43:33 +090032
darin@google.com0b8a30c2008-08-29 05:50:12 +090033namespace {
34
leng@chromium.org44fe4d72012-07-17 20:22:59 +090035// The message loops on which each timer should be tested.
gabccd5b952016-11-29 08:01:33 +090036const MessageLoop::Type testing_message_loops[] = {
37 MessageLoop::TYPE_DEFAULT, MessageLoop::TYPE_IO,
leng@chromium.org44fe4d72012-07-17 20:22:59 +090038#if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
gabccd5b952016-11-29 08:01:33 +090039 MessageLoop::TYPE_UI,
leng@chromium.org44fe4d72012-07-17 20:22:59 +090040#endif
41};
42
43const int kNumTestingMessageLoops = arraysize(testing_message_loops);
44
jameswest9f1f3a02016-11-15 14:19:54 +090045class Receiver {
46 public:
47 Receiver() : count_(0) {}
48 void OnCalled() { count_++; }
49 bool WasCalled() { return count_ > 0; }
50 int TimesCalled() { return count_; }
51
52 private:
53 int count_;
54};
55
ahest9a63aa22016-12-13 20:34:38 +090056// A basic helper class that can start a one-shot timer and signal a
57// WaitableEvent when this timer fires.
58class OneShotTimerTesterBase {
59 public:
60 // |did_run|, if provided, will be signaled when Run() fires.
61 explicit OneShotTimerTesterBase(
62 WaitableEvent* did_run = nullptr,
63 const TimeDelta& delay = TimeDelta::FromMilliseconds(10))
64 : did_run_(did_run), delay_(delay) {}
65
66 virtual ~OneShotTimerTesterBase() = default;
67
68 void Start() {
69 started_time_ = TimeTicks::Now();
70 timer_->Start(FROM_HERE, delay_, this, &OneShotTimerTesterBase::Run);
71 }
72
73 bool IsRunning() { return timer_->IsRunning(); }
74
75 TimeTicks started_time() const { return started_time_; }
76 TimeDelta delay() const { return delay_; }
77
78 protected:
79 virtual void Run() {
80 if (did_run_) {
81 EXPECT_FALSE(did_run_->IsSignaled());
82 did_run_->Signal();
83 }
84 }
85
86 std::unique_ptr<OneShotTimer> timer_ = MakeUnique<OneShotTimer>();
87
88 private:
89 WaitableEvent* const did_run_;
90 const TimeDelta delay_;
91 TimeTicks started_time_;
92
93 DISALLOW_COPY_AND_ASSIGN(OneShotTimerTesterBase);
94};
95
96// Extends functionality of OneShotTimerTesterBase with the abilities to wait
97// until the timer fires and to change task runner for the timer.
98class OneShotTimerTester : public OneShotTimerTesterBase {
darin@google.com0b8a30c2008-08-29 05:50:12 +090099 public:
gabccd5b952016-11-29 08:01:33 +0900100 // |did_run|, if provided, will be signaled when Run() fires.
101 explicit OneShotTimerTester(
102 WaitableEvent* did_run = nullptr,
103 const TimeDelta& delay = TimeDelta::FromMilliseconds(10))
ahest9a63aa22016-12-13 20:34:38 +0900104 : OneShotTimerTesterBase(did_run, delay),
105 quit_closure_(run_loop_.QuitClosure()) {}
petrcermak4dec79e2014-11-06 11:17:57 +0900106
ahest9a63aa22016-12-13 20:34:38 +0900107 ~OneShotTimerTester() override = default;
petrcermak4dec79e2014-11-06 11:17:57 +0900108
gabb4a7cd42017-06-02 01:23:36 +0900109 void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) {
gabccd5b952016-11-29 08:01:33 +0900110 timer_->SetTaskRunner(std::move(task_runner));
111
112 // Run() will be invoked on |task_runner| but |run_loop_|'s QuitClosure
113 // needs to run on this thread (where the MessageLoop lives).
gabb4a7cd42017-06-02 01:23:36 +0900114 quit_closure_ = Bind(IgnoreResult(&SequencedTaskRunner::PostTask),
115 SequencedTaskRunnerHandle::Get(), FROM_HERE,
116 run_loop_.QuitClosure());
petrcermak4dec79e2014-11-06 11:17:57 +0900117 }
118
gabccd5b952016-11-29 08:01:33 +0900119 // Blocks until Run() executes and confirms that Run() didn't fire before
120 // |delay_| expired.
121 void WaitAndConfirmTimerFiredAfterDelay() {
122 run_loop_.Run();
123
ahest9a63aa22016-12-13 20:34:38 +0900124 EXPECT_NE(TimeTicks(), started_time());
125 EXPECT_GE(TimeTicks::Now() - started_time(), delay());
gabccd5b952016-11-29 08:01:33 +0900126 }
127
gabccd5b952016-11-29 08:01:33 +0900128 protected:
129 // Overridable method to do things on Run() before signaling events/closures
130 // managed by this helper.
131 virtual void OnRun() {}
132
huanr@chromium.org7d5b0582009-02-07 09:37:01 +0900133 private:
ahest9a63aa22016-12-13 20:34:38 +0900134 void Run() override {
gabccd5b952016-11-29 08:01:33 +0900135 OnRun();
ahest9a63aa22016-12-13 20:34:38 +0900136 OneShotTimerTesterBase::Run();
gabccd5b952016-11-29 08:01:33 +0900137 quit_closure_.Run();
huanr@chromium.org7d5b0582009-02-07 09:37:01 +0900138 }
petrcermak4dec79e2014-11-06 11:17:57 +0900139
gabccd5b952016-11-29 08:01:33 +0900140 RunLoop run_loop_;
141 Closure quit_closure_;
gabccd5b952016-11-29 08:01:33 +0900142
143 DISALLOW_COPY_AND_ASSIGN(OneShotTimerTester);
huanr@chromium.org7d5b0582009-02-07 09:37:01 +0900144};
145
gabccd5b952016-11-29 08:01:33 +0900146class OneShotSelfDeletingTimerTester : public OneShotTimerTester {
147 protected:
148 void OnRun() override { timer_.reset(); }
149};
150
151constexpr int kNumRepeats = 10;
152
darin@google.com0b8a30c2008-08-29 05:50:12 +0900153class RepeatingTimerTester {
154 public:
gabccd5b952016-11-29 08:01:33 +0900155 explicit RepeatingTimerTester(WaitableEvent* did_run, const TimeDelta& delay)
156 : counter_(kNumRepeats),
157 quit_closure_(run_loop_.QuitClosure()),
158 did_run_(did_run),
159 delay_(delay) {}
erg@google.combf6ce9f2010-01-27 08:08:02 +0900160
darin@google.com0b8a30c2008-08-29 05:50:12 +0900161 void Start() {
gabccd5b952016-11-29 08:01:33 +0900162 started_time_ = TimeTicks::Now();
qsr@chromium.org38b986c2013-12-07 00:22:35 +0900163 timer_.Start(FROM_HERE, delay_, this, &RepeatingTimerTester::Run);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900164 }
petrcermak4dec79e2014-11-06 11:17:57 +0900165
gabccd5b952016-11-29 08:01:33 +0900166 void WaitAndConfirmTimerFiredRepeatedlyAfterDelay() {
167 run_loop_.Run();
168
169 EXPECT_NE(TimeTicks(), started_time_);
170 EXPECT_GE(TimeTicks::Now() - started_time_, kNumRepeats * delay_);
171 }
172
darin@google.com0b8a30c2008-08-29 05:50:12 +0900173 private:
174 void Run() {
175 if (--counter_ == 0) {
gabccd5b952016-11-29 08:01:33 +0900176 if (did_run_) {
177 EXPECT_FALSE(did_run_->IsSignaled());
178 did_run_->Signal();
179 }
qsr@chromium.org38b986c2013-12-07 00:22:35 +0900180 timer_.Stop();
gabccd5b952016-11-29 08:01:33 +0900181 quit_closure_.Run();
darin@google.com0b8a30c2008-08-29 05:50:12 +0900182 }
183 }
petrcermak4dec79e2014-11-06 11:17:57 +0900184
gabccd5b952016-11-29 08:01:33 +0900185 RepeatingTimer timer_;
darin@google.com0b8a30c2008-08-29 05:50:12 +0900186 int counter_;
gabccd5b952016-11-29 08:01:33 +0900187
188 RunLoop run_loop_;
189 Closure quit_closure_;
190 WaitableEvent* const did_run_;
191
192 const TimeDelta delay_;
193 TimeTicks started_time_;
194
195 DISALLOW_COPY_AND_ASSIGN(RepeatingTimerTester);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900196};
197
gabccd5b952016-11-29 08:01:33 +0900198// Basic test with same setup as RunTest_OneShotTimers_Cancel below to confirm
199// that |did_run_a| would be signaled in that test if it wasn't for the
200// deletion.
201void RunTest_OneShotTimers(MessageLoop::Type message_loop_type) {
202 MessageLoop loop(message_loop_type);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900203
gabccd5b952016-11-29 08:01:33 +0900204 WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
205 WaitableEvent::InitialState::NOT_SIGNALED);
206 OneShotTimerTester a(&did_run_a);
207 a.Start();
darin@google.com0b8a30c2008-08-29 05:50:12 +0900208
gabccd5b952016-11-29 08:01:33 +0900209 OneShotTimerTester b;
210 b.Start();
darin@google.com0b8a30c2008-08-29 05:50:12 +0900211
gabccd5b952016-11-29 08:01:33 +0900212 b.WaitAndConfirmTimerFiredAfterDelay();
213
214 EXPECT_TRUE(did_run_a.IsSignaled());
darin@google.com0b8a30c2008-08-29 05:50:12 +0900215}
216
gabccd5b952016-11-29 08:01:33 +0900217void RunTest_OneShotTimers_Cancel(MessageLoop::Type message_loop_type) {
218 MessageLoop loop(message_loop_type);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900219
gabccd5b952016-11-29 08:01:33 +0900220 WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
221 WaitableEvent::InitialState::NOT_SIGNALED);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900222 OneShotTimerTester* a = new OneShotTimerTester(&did_run_a);
223
224 // This should run before the timer expires.
gabccd5b952016-11-29 08:01:33 +0900225 SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900226
227 // Now start the timer.
228 a->Start();
maruel@chromium.org8fe7adc2009-03-04 00:01:12 +0900229
gabccd5b952016-11-29 08:01:33 +0900230 OneShotTimerTester b;
darin@google.com0b8a30c2008-08-29 05:50:12 +0900231 b.Start();
232
gabccd5b952016-11-29 08:01:33 +0900233 b.WaitAndConfirmTimerFiredAfterDelay();
darin@google.com0b8a30c2008-08-29 05:50:12 +0900234
gabccd5b952016-11-29 08:01:33 +0900235 EXPECT_FALSE(did_run_a.IsSignaled());
darin@google.com0b8a30c2008-08-29 05:50:12 +0900236}
237
gabccd5b952016-11-29 08:01:33 +0900238void RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type) {
239 MessageLoop loop(message_loop_type);
huanr@chromium.org7d5b0582009-02-07 09:37:01 +0900240
gabccd5b952016-11-29 08:01:33 +0900241 OneShotSelfDeletingTimerTester f;
huanr@chromium.org7d5b0582009-02-07 09:37:01 +0900242 f.Start();
gabccd5b952016-11-29 08:01:33 +0900243 f.WaitAndConfirmTimerFiredAfterDelay();
huanr@chromium.org7d5b0582009-02-07 09:37:01 +0900244}
245
gabccd5b952016-11-29 08:01:33 +0900246void RunTest_RepeatingTimer(MessageLoop::Type message_loop_type,
qsr@chromium.org38b986c2013-12-07 00:22:35 +0900247 const TimeDelta& delay) {
gabccd5b952016-11-29 08:01:33 +0900248 MessageLoop loop(message_loop_type);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900249
gabccd5b952016-11-29 08:01:33 +0900250 RepeatingTimerTester f(nullptr, delay);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900251 f.Start();
gabccd5b952016-11-29 08:01:33 +0900252 f.WaitAndConfirmTimerFiredRepeatedlyAfterDelay();
darin@google.com0b8a30c2008-08-29 05:50:12 +0900253}
254
gabccd5b952016-11-29 08:01:33 +0900255void RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type,
qsr@chromium.org38b986c2013-12-07 00:22:35 +0900256 const TimeDelta& delay) {
gabccd5b952016-11-29 08:01:33 +0900257 MessageLoop loop(message_loop_type);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900258
gabccd5b952016-11-29 08:01:33 +0900259 WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
260 WaitableEvent::InitialState::NOT_SIGNALED);
qsr@chromium.org38b986c2013-12-07 00:22:35 +0900261 RepeatingTimerTester* a = new RepeatingTimerTester(&did_run_a, delay);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900262
263 // This should run before the timer expires.
gabccd5b952016-11-29 08:01:33 +0900264 SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900265
266 // Now start the timer.
267 a->Start();
agl@chromium.org31de02e2009-02-20 11:00:04 +0900268
gabccd5b952016-11-29 08:01:33 +0900269 RepeatingTimerTester b(nullptr, delay);
darin@google.com0b8a30c2008-08-29 05:50:12 +0900270 b.Start();
271
gabccd5b952016-11-29 08:01:33 +0900272 b.WaitAndConfirmTimerFiredRepeatedlyAfterDelay();
darin@google.com0b8a30c2008-08-29 05:50:12 +0900273
gabccd5b952016-11-29 08:01:33 +0900274 // |a| should not have fired despite |b| starting after it on the same
275 // sequence and being complete by now.
276 EXPECT_FALSE(did_run_a.IsSignaled());
darin@google.com0b8a30c2008-08-29 05:50:12 +0900277}
278
agl@chromium.org31de02e2009-02-20 11:00:04 +0900279class DelayTimerTarget {
280 public:
agl@chromium.org31de02e2009-02-20 11:00:04 +0900281 bool signaled() const { return signaled_; }
282
283 void Signal() {
284 ASSERT_FALSE(signaled_);
285 signaled_ = true;
286 }
287
288 private:
hashimoto9c170992015-01-23 00:21:41 +0900289 bool signaled_ = false;
agl@chromium.org31de02e2009-02-20 11:00:04 +0900290};
291
gabccd5b952016-11-29 08:01:33 +0900292void RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type) {
293 MessageLoop loop(message_loop_type);
agl@chromium.org31de02e2009-02-20 11:00:04 +0900294
295 // If Delay is never called, the timer shouldn't go off.
296 DelayTimerTarget target;
gabccd5b952016-11-29 08:01:33 +0900297 DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(1), &target,
298 &DelayTimerTarget::Signal);
agl@chromium.org31de02e2009-02-20 11:00:04 +0900299
gabccd5b952016-11-29 08:01:33 +0900300 OneShotTimerTester tester;
agl@chromium.org31de02e2009-02-20 11:00:04 +0900301 tester.Start();
gabccd5b952016-11-29 08:01:33 +0900302 tester.WaitAndConfirmTimerFiredAfterDelay();
agl@chromium.org31de02e2009-02-20 11:00:04 +0900303
304 ASSERT_FALSE(target.signaled());
305}
306
gabccd5b952016-11-29 08:01:33 +0900307void RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type) {
308 MessageLoop loop(message_loop_type);
agl@chromium.org31de02e2009-02-20 11:00:04 +0900309
310 DelayTimerTarget target;
gabccd5b952016-11-29 08:01:33 +0900311 DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(1), &target,
312 &DelayTimerTarget::Signal);
agl@chromium.org31de02e2009-02-20 11:00:04 +0900313 timer.Reset();
314
gabccd5b952016-11-29 08:01:33 +0900315 OneShotTimerTester tester(nullptr, TimeDelta::FromMilliseconds(100));
agl@chromium.org31de02e2009-02-20 11:00:04 +0900316 tester.Start();
gabccd5b952016-11-29 08:01:33 +0900317 tester.WaitAndConfirmTimerFiredAfterDelay();
agl@chromium.org31de02e2009-02-20 11:00:04 +0900318
319 ASSERT_TRUE(target.signaled());
320}
321
322struct ResetHelper {
gabccd5b952016-11-29 08:01:33 +0900323 ResetHelper(DelayTimer* timer, DelayTimerTarget* target)
danakj85d43f42015-09-24 16:53:00 +0900324 : timer_(timer), target_(target) {}
agl@chromium.org31de02e2009-02-20 11:00:04 +0900325
326 void Reset() {
327 ASSERT_FALSE(target_->signaled());
328 timer_->Reset();
329 }
330
331 private:
gabccd5b952016-11-29 08:01:33 +0900332 DelayTimer* const timer_;
danakj85d43f42015-09-24 16:53:00 +0900333 DelayTimerTarget* const target_;
agl@chromium.org31de02e2009-02-20 11:00:04 +0900334};
335
gabccd5b952016-11-29 08:01:33 +0900336void RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type) {
337 MessageLoop loop(message_loop_type);
agl@chromium.org31de02e2009-02-20 11:00:04 +0900338
339 // If Delay is never called, the timer shouldn't go off.
340 DelayTimerTarget target;
gabccd5b952016-11-29 08:01:33 +0900341 DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
342 &DelayTimerTarget::Signal);
agl@chromium.org31de02e2009-02-20 11:00:04 +0900343 timer.Reset();
344
345 ResetHelper reset_helper(&timer, &target);
346
gabccd5b952016-11-29 08:01:33 +0900347 OneShotTimer timers[20];
agl@chromium.org31de02e2009-02-20 11:00:04 +0900348 for (size_t i = 0; i < arraysize(timers); ++i) {
jbates@chromium.orgad6a3452011-09-03 03:23:02 +0900349 timers[i].Start(FROM_HERE, TimeDelta::FromMilliseconds(i * 10),
350 &reset_helper, &ResetHelper::Reset);
agl@chromium.org31de02e2009-02-20 11:00:04 +0900351 }
352
gabccd5b952016-11-29 08:01:33 +0900353 OneShotTimerTester tester(nullptr, TimeDelta::FromMilliseconds(300));
agl@chromium.org31de02e2009-02-20 11:00:04 +0900354 tester.Start();
gabccd5b952016-11-29 08:01:33 +0900355 tester.WaitAndConfirmTimerFiredAfterDelay();
agl@chromium.org31de02e2009-02-20 11:00:04 +0900356
357 ASSERT_TRUE(target.signaled());
358}
359
agl@chromium.orgf5890862009-02-27 08:17:56 +0900360class DelayTimerFatalTarget {
361 public:
362 void Signal() {
363 ASSERT_TRUE(false);
364 }
365};
366
gabccd5b952016-11-29 08:01:33 +0900367void RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type) {
368 MessageLoop loop(message_loop_type);
agl@chromium.orgf5890862009-02-27 08:17:56 +0900369
370 DelayTimerFatalTarget target;
371
372 {
gabccd5b952016-11-29 08:01:33 +0900373 DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
374 &DelayTimerFatalTarget::Signal);
agl@chromium.orgf5890862009-02-27 08:17:56 +0900375 timer.Reset();
376 }
377
378 // When the timer is deleted, the DelayTimerFatalTarget should never be
379 // called.
gabccd5b952016-11-29 08:01:33 +0900380 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
agl@chromium.orgf5890862009-02-27 08:17:56 +0900381}
382
darin@google.comd936b5b2008-08-26 14:53:57 +0900383} // namespace
384
385//-----------------------------------------------------------------------------
386// Each test is run against each type of MessageLoop. That way we are sure
387// that timers work properly in all configurations.
388
gabccd5b952016-11-29 08:01:33 +0900389TEST(TimerTest, OneShotTimers) {
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900390 for (int i = 0; i < kNumTestingMessageLoops; i++) {
gabccd5b952016-11-29 08:01:33 +0900391 RunTest_OneShotTimers(testing_message_loops[i]);
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900392 }
darin@google.com0b8a30c2008-08-29 05:50:12 +0900393}
394
gabccd5b952016-11-29 08:01:33 +0900395TEST(TimerTest, OneShotTimers_Cancel) {
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900396 for (int i = 0; i < kNumTestingMessageLoops; i++) {
gabccd5b952016-11-29 08:01:33 +0900397 RunTest_OneShotTimers_Cancel(testing_message_loops[i]);
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900398 }
darin@google.com0b8a30c2008-08-29 05:50:12 +0900399}
400
huanr@chromium.org7d5b0582009-02-07 09:37:01 +0900401// If underline timer does not handle properly, we will crash or fail
jeanluc@chromium.org5fcf7872011-08-18 02:41:02 +0900402// in full page heap environment.
huanr@chromium.org7d5b0582009-02-07 09:37:01 +0900403TEST(TimerTest, OneShotSelfDeletingTimer) {
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900404 for (int i = 0; i < kNumTestingMessageLoops; i++) {
405 RunTest_OneShotSelfDeletingTimer(testing_message_loops[i]);
406 }
huanr@chromium.org7d5b0582009-02-07 09:37:01 +0900407}
408
petrcermak4dec79e2014-11-06 11:17:57 +0900409TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
gabccd5b952016-11-29 08:01:33 +0900410 // A MessageLoop is required for the timer events on the other thread to
411 // communicate back to the Timer under test.
412 MessageLoop loop;
petrcermak4dec79e2014-11-06 11:17:57 +0900413
gabccd5b952016-11-29 08:01:33 +0900414 Thread other_thread("OneShotTimer_CustomTaskRunner");
415 other_thread.Start();
416
417 WaitableEvent did_run(WaitableEvent::ResetPolicy::MANUAL,
418 WaitableEvent::InitialState::NOT_SIGNALED);
petrcermak4dec79e2014-11-06 11:17:57 +0900419 OneShotTimerTester f(&did_run);
gabccd5b952016-11-29 08:01:33 +0900420 f.SetTaskRunner(other_thread.task_runner());
petrcermak4dec79e2014-11-06 11:17:57 +0900421 f.Start();
gabccd5b952016-11-29 08:01:33 +0900422 EXPECT_TRUE(f.IsRunning());
petrcermak4dec79e2014-11-06 11:17:57 +0900423
gabccd5b952016-11-29 08:01:33 +0900424 f.WaitAndConfirmTimerFiredAfterDelay();
425 EXPECT_TRUE(did_run.IsSignaled());
426
427 // |f| should already have communicated back to this |loop| before invoking
428 // Run() and as such this thread should already be aware that |f| is no longer
429 // running.
430 EXPECT_TRUE(loop.IsIdleForTesting());
431 EXPECT_FALSE(f.IsRunning());
petrcermak4dec79e2014-11-06 11:17:57 +0900432}
433
jameswest9f1f3a02016-11-15 14:19:54 +0900434TEST(TimerTest, OneShotTimerWithTickClock) {
gabccd5b952016-11-29 08:01:33 +0900435 scoped_refptr<TestMockTimeTaskRunner> task_runner(
436 new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
437 std::unique_ptr<TickClock> tick_clock(task_runner->GetMockTickClock());
438 MessageLoop message_loop;
jameswest9f1f3a02016-11-15 14:19:54 +0900439 message_loop.SetTaskRunner(task_runner);
440 Receiver receiver;
gabccd5b952016-11-29 08:01:33 +0900441 OneShotTimer timer(tick_clock.get());
442 timer.Start(FROM_HERE, TimeDelta::FromSeconds(1),
443 Bind(&Receiver::OnCalled, Unretained(&receiver)));
444 task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
jameswest9f1f3a02016-11-15 14:19:54 +0900445 EXPECT_TRUE(receiver.WasCalled());
446}
447
darin@google.com0b8a30c2008-08-29 05:50:12 +0900448TEST(TimerTest, RepeatingTimer) {
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900449 for (int i = 0; i < kNumTestingMessageLoops; i++) {
qsr@chromium.org38b986c2013-12-07 00:22:35 +0900450 RunTest_RepeatingTimer(testing_message_loops[i],
451 TimeDelta::FromMilliseconds(10));
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900452 }
darin@google.com0b8a30c2008-08-29 05:50:12 +0900453}
454
455TEST(TimerTest, RepeatingTimer_Cancel) {
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900456 for (int i = 0; i < kNumTestingMessageLoops; i++) {
qsr@chromium.org38b986c2013-12-07 00:22:35 +0900457 RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
458 TimeDelta::FromMilliseconds(10));
459 }
460}
461
462TEST(TimerTest, RepeatingTimerZeroDelay) {
463 for (int i = 0; i < kNumTestingMessageLoops; i++) {
464 RunTest_RepeatingTimer(testing_message_loops[i],
465 TimeDelta::FromMilliseconds(0));
466 }
467}
468
469TEST(TimerTest, RepeatingTimerZeroDelay_Cancel) {
470 for (int i = 0; i < kNumTestingMessageLoops; i++) {
471 RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
472 TimeDelta::FromMilliseconds(0));
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900473 }
darin@google.com0b8a30c2008-08-29 05:50:12 +0900474}
mbelshe@google.come0efec82008-12-03 08:16:55 +0900475
jameswest9f1f3a02016-11-15 14:19:54 +0900476TEST(TimerTest, RepeatingTimerWithTickClock) {
gabccd5b952016-11-29 08:01:33 +0900477 scoped_refptr<TestMockTimeTaskRunner> task_runner(
478 new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
479 std::unique_ptr<TickClock> tick_clock(task_runner->GetMockTickClock());
480 MessageLoop message_loop;
jameswest9f1f3a02016-11-15 14:19:54 +0900481 message_loop.SetTaskRunner(task_runner);
482 Receiver receiver;
483 const int expected_times_called = 10;
gabccd5b952016-11-29 08:01:33 +0900484 RepeatingTimer timer(tick_clock.get());
485 timer.Start(FROM_HERE, TimeDelta::FromSeconds(1),
486 Bind(&Receiver::OnCalled, Unretained(&receiver)));
487 task_runner->FastForwardBy(TimeDelta::FromSeconds(expected_times_called));
jameswest9f1f3a02016-11-15 14:19:54 +0900488 timer.Stop();
489 EXPECT_EQ(expected_times_called, receiver.TimesCalled());
490}
491
agl@chromium.org31de02e2009-02-20 11:00:04 +0900492TEST(TimerTest, DelayTimer_NoCall) {
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900493 for (int i = 0; i < kNumTestingMessageLoops; i++) {
494 RunTest_DelayTimer_NoCall(testing_message_loops[i]);
495 }
agl@chromium.org31de02e2009-02-20 11:00:04 +0900496}
497
498TEST(TimerTest, DelayTimer_OneCall) {
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900499 for (int i = 0; i < kNumTestingMessageLoops; i++) {
500 RunTest_DelayTimer_OneCall(testing_message_loops[i]);
501 }
agl@chromium.org31de02e2009-02-20 11:00:04 +0900502}
503
phajdan.jr@chromium.org0cafffe2009-10-17 00:26:16 +0900504// It's flaky on the buildbot, http://crbug.com/25038.
evan@chromium.org3c0bc352012-02-14 09:29:14 +0900505TEST(TimerTest, DISABLED_DelayTimer_Reset) {
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900506 for (int i = 0; i < kNumTestingMessageLoops; i++) {
507 RunTest_DelayTimer_Reset(testing_message_loops[i]);
508 }
agl@chromium.org31de02e2009-02-20 11:00:04 +0900509}
510
agl@chromium.orgf5890862009-02-27 08:17:56 +0900511TEST(TimerTest, DelayTimer_Deleted) {
leng@chromium.org44fe4d72012-07-17 20:22:59 +0900512 for (int i = 0; i < kNumTestingMessageLoops; i++) {
513 RunTest_DelayTimer_Deleted(testing_message_loops[i]);
514 }
agl@chromium.orgf5890862009-02-27 08:17:56 +0900515}
516
jameswest9f1f3a02016-11-15 14:19:54 +0900517TEST(TimerTest, DelayTimerWithTickClock) {
gabccd5b952016-11-29 08:01:33 +0900518 scoped_refptr<TestMockTimeTaskRunner> task_runner(
519 new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
520 std::unique_ptr<TickClock> tick_clock(task_runner->GetMockTickClock());
521 MessageLoop message_loop;
jameswest9f1f3a02016-11-15 14:19:54 +0900522 message_loop.SetTaskRunner(task_runner);
523 Receiver receiver;
gabccd5b952016-11-29 08:01:33 +0900524 DelayTimer timer(FROM_HERE, TimeDelta::FromSeconds(1), &receiver,
525 &Receiver::OnCalled, tick_clock.get());
526 task_runner->FastForwardBy(TimeDelta::FromMilliseconds(999));
jameswest9f1f3a02016-11-15 14:19:54 +0900527 EXPECT_FALSE(receiver.WasCalled());
528 timer.Reset();
gabccd5b952016-11-29 08:01:33 +0900529 task_runner->FastForwardBy(TimeDelta::FromMilliseconds(999));
jameswest9f1f3a02016-11-15 14:19:54 +0900530 EXPECT_FALSE(receiver.WasCalled());
531 timer.Reset();
gabccd5b952016-11-29 08:01:33 +0900532 task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
jameswest9f1f3a02016-11-15 14:19:54 +0900533 EXPECT_TRUE(receiver.WasCalled());
534}
535
mbelshe@google.come0efec82008-12-03 08:16:55 +0900536TEST(TimerTest, MessageLoopShutdown) {
537 // This test is designed to verify that shutdown of the
538 // message loop does not cause crashes if there were pending
539 // timers not yet fired. It may only trigger exceptions
jeanluc@chromium.org5fcf7872011-08-18 02:41:02 +0900540 // if debug heap checking is enabled.
gabccd5b952016-11-29 08:01:33 +0900541 WaitableEvent did_run(WaitableEvent::ResetPolicy::MANUAL,
542 WaitableEvent::InitialState::NOT_SIGNALED);
mbelshe@google.come0efec82008-12-03 08:16:55 +0900543 {
ahest9a63aa22016-12-13 20:34:38 +0900544 OneShotTimerTesterBase a(&did_run);
545 OneShotTimerTesterBase b(&did_run);
546 OneShotTimerTesterBase c(&did_run);
547 OneShotTimerTesterBase d(&did_run);
mbelshe@google.come0efec82008-12-03 08:16:55 +0900548 {
gabccd5b952016-11-29 08:01:33 +0900549 MessageLoop loop;
mbelshe@google.come0efec82008-12-03 08:16:55 +0900550 a.Start();
551 b.Start();
552 } // MessageLoop destructs by falling out of scope.
553 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
554
gabccd5b952016-11-29 08:01:33 +0900555 EXPECT_FALSE(did_run.IsSignaled());
mbelshe@google.come0efec82008-12-03 08:16:55 +0900556}
jbates@chromium.org18001832012-03-27 09:18:57 +0900557
pkotwicz55d7a1e2017-01-18 05:45:26 +0900558// Ref counted class which owns a Timer. The class passes a reference to itself
559// via the |user_task| parameter in Timer::Start(). |Timer::user_task_| might
560// end up holding the last reference to the class.
561class OneShotSelfOwningTimerTester
562 : public RefCounted<OneShotSelfOwningTimerTester> {
563 public:
564 OneShotSelfOwningTimerTester() = default;
565
566 void StartTimer() {
567 // Start timer with long delay in order to test the timer getting destroyed
568 // while a timer task is still pending.
569 timer_.Start(FROM_HERE, TimeDelta::FromDays(1),
570 base::Bind(&OneShotSelfOwningTimerTester::Run, this));
571 }
572
573 private:
574 friend class RefCounted<OneShotSelfOwningTimerTester>;
575 ~OneShotSelfOwningTimerTester() = default;
576
577 void Run() {
578 ADD_FAILURE() << "Timer unexpectedly fired.";
579 }
580
581 OneShotTimer timer_;
582
583 DISALLOW_COPY_AND_ASSIGN(OneShotSelfOwningTimerTester);
584};
585
586TEST(TimerTest, MessageLoopShutdownSelfOwningTimer) {
587 // This test verifies that shutdown of the message loop does not cause crashes
588 // if there is a pending timer not yet fired and |Timer::user_task_| owns the
589 // timer. The test may only trigger exceptions if debug heap checking is
590 // enabled.
591
592 MessageLoop loop;
593 scoped_refptr<OneShotSelfOwningTimerTester> tester =
594 new OneShotSelfOwningTimerTester();
595
596 std::move(tester)->StartTimer();
597 // |Timer::user_task_| owns sole reference to |tester|.
598
599 // MessageLoop destructs by falling out of scope. SHOULD NOT CRASH.
600}
601
jbates@chromium.org18001832012-03-27 09:18:57 +0900602void TimerTestCallback() {
603}
604
605TEST(TimerTest, NonRepeatIsRunning) {
606 {
gabccd5b952016-11-29 08:01:33 +0900607 MessageLoop loop;
608 Timer timer(false, false);
jbates@chromium.org18001832012-03-27 09:18:57 +0900609 EXPECT_FALSE(timer.IsRunning());
gabccd5b952016-11-29 08:01:33 +0900610 timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
jbates@chromium.org18001832012-03-27 09:18:57 +0900611 EXPECT_TRUE(timer.IsRunning());
612 timer.Stop();
613 EXPECT_FALSE(timer.IsRunning());
614 EXPECT_TRUE(timer.user_task().is_null());
615 }
616
617 {
gabccd5b952016-11-29 08:01:33 +0900618 Timer timer(true, false);
619 MessageLoop loop;
jbates@chromium.org18001832012-03-27 09:18:57 +0900620 EXPECT_FALSE(timer.IsRunning());
gabccd5b952016-11-29 08:01:33 +0900621 timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
jbates@chromium.org18001832012-03-27 09:18:57 +0900622 EXPECT_TRUE(timer.IsRunning());
623 timer.Stop();
624 EXPECT_FALSE(timer.IsRunning());
625 ASSERT_FALSE(timer.user_task().is_null());
626 timer.Reset();
627 EXPECT_TRUE(timer.IsRunning());
628 }
629}
630
631TEST(TimerTest, NonRepeatMessageLoopDeath) {
gabccd5b952016-11-29 08:01:33 +0900632 Timer timer(false, false);
jbates@chromium.org18001832012-03-27 09:18:57 +0900633 {
gabccd5b952016-11-29 08:01:33 +0900634 MessageLoop loop;
jbates@chromium.org18001832012-03-27 09:18:57 +0900635 EXPECT_FALSE(timer.IsRunning());
gabccd5b952016-11-29 08:01:33 +0900636 timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
jbates@chromium.org18001832012-03-27 09:18:57 +0900637 EXPECT_TRUE(timer.IsRunning());
638 }
639 EXPECT_FALSE(timer.IsRunning());
640 EXPECT_TRUE(timer.user_task().is_null());
641}
642
643TEST(TimerTest, RetainRepeatIsRunning) {
gabccd5b952016-11-29 08:01:33 +0900644 MessageLoop loop;
645 Timer timer(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback),
646 true);
jbates@chromium.org18001832012-03-27 09:18:57 +0900647 EXPECT_FALSE(timer.IsRunning());
648 timer.Reset();
649 EXPECT_TRUE(timer.IsRunning());
650 timer.Stop();
651 EXPECT_FALSE(timer.IsRunning());
652 timer.Reset();
653 EXPECT_TRUE(timer.IsRunning());
654}
655
656TEST(TimerTest, RetainNonRepeatIsRunning) {
gabccd5b952016-11-29 08:01:33 +0900657 MessageLoop loop;
658 Timer timer(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback),
659 false);
jbates@chromium.org18001832012-03-27 09:18:57 +0900660 EXPECT_FALSE(timer.IsRunning());
661 timer.Reset();
662 EXPECT_TRUE(timer.IsRunning());
663 timer.Stop();
664 EXPECT_FALSE(timer.IsRunning());
665 timer.Reset();
666 EXPECT_TRUE(timer.IsRunning());
667}
668
gabb4a7cd42017-06-02 01:23:36 +0900669//-----------------------------------------------------------------------------
670
jbates@chromium.org18001832012-03-27 09:18:57 +0900671namespace {
672
673bool g_callback_happened1 = false;
674bool g_callback_happened2 = false;
675
676void ClearAllCallbackHappened() {
677 g_callback_happened1 = false;
678 g_callback_happened2 = false;
679}
680
681void SetCallbackHappened1() {
682 g_callback_happened1 = true;
gabccd5b952016-11-29 08:01:33 +0900683 MessageLoop::current()->QuitWhenIdle();
jbates@chromium.org18001832012-03-27 09:18:57 +0900684}
685
686void SetCallbackHappened2() {
687 g_callback_happened2 = true;
gabccd5b952016-11-29 08:01:33 +0900688 MessageLoop::current()->QuitWhenIdle();
jbates@chromium.org18001832012-03-27 09:18:57 +0900689}
690
gabccd5b952016-11-29 08:01:33 +0900691} // namespace
692
jbates@chromium.org18001832012-03-27 09:18:57 +0900693TEST(TimerTest, ContinuationStopStart) {
694 {
695 ClearAllCallbackHappened();
gabccd5b952016-11-29 08:01:33 +0900696 MessageLoop loop;
697 Timer timer(false, false);
jbates@chromium.org18001832012-03-27 09:18:57 +0900698 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
gabccd5b952016-11-29 08:01:33 +0900699 Bind(&SetCallbackHappened1));
jbates@chromium.org18001832012-03-27 09:18:57 +0900700 timer.Stop();
701 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(40),
gabccd5b952016-11-29 08:01:33 +0900702 Bind(&SetCallbackHappened2));
703 RunLoop().Run();
jbates@chromium.org18001832012-03-27 09:18:57 +0900704 EXPECT_FALSE(g_callback_happened1);
705 EXPECT_TRUE(g_callback_happened2);
706 }
707}
708
709TEST(TimerTest, ContinuationReset) {
710 {
711 ClearAllCallbackHappened();
gabccd5b952016-11-29 08:01:33 +0900712 MessageLoop loop;
713 Timer timer(false, false);
jbates@chromium.org18001832012-03-27 09:18:57 +0900714 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
gabccd5b952016-11-29 08:01:33 +0900715 Bind(&SetCallbackHappened1));
jbates@chromium.org18001832012-03-27 09:18:57 +0900716 timer.Reset();
717 // Since Reset happened before task ran, the user_task must not be cleared:
718 ASSERT_FALSE(timer.user_task().is_null());
gabccd5b952016-11-29 08:01:33 +0900719 RunLoop().Run();
jbates@chromium.org18001832012-03-27 09:18:57 +0900720 EXPECT_TRUE(g_callback_happened1);
721 }
722}
723
gabb4a7cd42017-06-02 01:23:36 +0900724namespace {
725
726const size_t kNumWorkerThreads = 3;
727
728// Fixture for tests requiring a worker pool. Includes a WaitableEvent so
729// that cases may Wait() on one thread and Signal() (explicitly, or implicitly
730// via helper methods) on another.
731class TimerSequenceTest : public testing::Test {
732 public:
733 TimerSequenceTest()
734 : event_(WaitableEvent::ResetPolicy::AUTOMATIC,
735 WaitableEvent::InitialState::NOT_SIGNALED) {}
736
737 void SetUp() override {
738 pool1_owner_.reset(
739 new SequencedWorkerPoolOwner(kNumWorkerThreads, "test1"));
740 pool2_owner_.reset(
741 new SequencedWorkerPoolOwner(kNumWorkerThreads, "test2"));
742 }
743
744 // Block until Signal() is called on another thread.
745 void Wait() { event_.Wait(); }
746
747 void Signal() { event_.Signal(); }
748
749 // Helper to augment a task with a subsequent call to Signal().
750 Closure TaskWithSignal(const Closure& task) {
751 return Bind(&TimerSequenceTest::RunTaskAndSignal, Unretained(this), task);
752 }
753
754 // Create the timer.
755 void CreateTimer() { timer_.reset(new OneShotTimer); }
756
757 // Schedule an event on the timer.
758 void StartTimer(TimeDelta delay, const Closure& task) {
759 timer_->Start(FROM_HERE, delay, task);
760 }
761
762 void SetTaskRunnerForTimer(scoped_refptr<SequencedTaskRunner> task_runner) {
763 timer_->SetTaskRunner(std::move(task_runner));
764 }
765
766 // Tell the timer to abandon the task.
767 void AbandonTask() {
768 EXPECT_TRUE(timer_->IsRunning());
769 // Reset() to call Timer::AbandonScheduledTask()
770 timer_->Reset();
771 EXPECT_TRUE(timer_->IsRunning());
772 timer_->Stop();
773 EXPECT_FALSE(timer_->IsRunning());
774 }
775
776 static void VerifyAffinity(const SequencedTaskRunner* task_runner) {
777 EXPECT_TRUE(task_runner->RunsTasksOnCurrentThread());
778 }
779
780 // Delete the timer.
781 void DeleteTimer() { timer_.reset(); }
782
783 protected:
784 const scoped_refptr<SequencedWorkerPool>& pool1() {
785 return pool1_owner_->pool();
786 }
787 const scoped_refptr<SequencedWorkerPool>& pool2() {
788 return pool2_owner_->pool();
789 }
790
791 private:
792 void RunTaskAndSignal(const Closure& task) {
793 task.Run();
794 Signal();
795 }
796
797 WaitableEvent event_;
798
799 MessageLoop message_loop_;
800 std::unique_ptr<SequencedWorkerPoolOwner> pool1_owner_;
801 std::unique_ptr<SequencedWorkerPoolOwner> pool2_owner_;
802
803 std::unique_ptr<OneShotTimer> timer_;
804
805 DISALLOW_COPY_AND_ASSIGN(TimerSequenceTest);
806};
807
808} // namespace
809
810TEST_F(TimerSequenceTest, OneShotTimerTaskOnPoolThread) {
811 scoped_refptr<SequencedTaskRunner> task_runner =
812 pool1()->GetSequencedTaskRunner(pool1()->GetSequenceToken());
813
814 base::RunLoop run_loop_;
815
816 // Timer is created on this thread.
817 CreateTimer();
818
819 // Task will execute on a pool thread.
820 SetTaskRunnerForTimer(task_runner);
821 StartTimer(TimeDelta::FromMilliseconds(1),
822 Bind(IgnoreResult(&SequencedTaskRunner::PostTask),
823 SequencedTaskRunnerHandle::Get(), FROM_HERE,
824 run_loop_.QuitClosure()));
825
826 // Spin the loop so that the delayed task fires on it, which will forward it
827 // to |task_runner|. And since the Timer's task is one that posts back to this
828 // MessageLoop to quit, we finally unblock.
829 run_loop_.Run();
830
831 // Timer will be destroyed on this thread.
832 DeleteTimer();
833}
834
835TEST_F(TimerSequenceTest, OneShotTimerUsedOnPoolThread) {
836 scoped_refptr<SequencedTaskRunner> task_runner =
837 pool1()->GetSequencedTaskRunner(pool1()->GetSequenceToken());
838
839 // Timer is created on this thread.
840 CreateTimer();
841
842 // Task will be scheduled from a pool thread.
843 task_runner->PostTask(
844 FROM_HERE, Bind(&TimerSequenceTest::StartTimer, Unretained(this),
845 TimeDelta::FromMilliseconds(1),
846 Bind(&TimerSequenceTest::Signal, Unretained(this))));
847 Wait();
848
849 // Timer must be destroyed on pool thread, too.
850 task_runner->PostTask(
851 FROM_HERE,
852 TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
853 Wait();
854}
855
856TEST_F(TimerSequenceTest, OneShotTimerTwoPoolsAbandonTask) {
857 scoped_refptr<SequencedTaskRunner> task_runner1 =
858 pool1()->GetSequencedTaskRunner(pool1()->GetSequenceToken());
859 scoped_refptr<SequencedTaskRunner> task_runner2 =
860 pool2()->GetSequencedTaskRunner(pool2()->GetSequenceToken());
861
862 // Create timer on pool #1.
863 task_runner1->PostTask(
864 FROM_HERE,
865 TaskWithSignal(Bind(&TimerSequenceTest::CreateTimer, Unretained(this))));
866 Wait();
867
868 // And tell it to execute on a different pool (#2).
869 task_runner1->PostTask(
870 FROM_HERE, TaskWithSignal(Bind(&TimerSequenceTest::SetTaskRunnerForTimer,
871 Unretained(this), task_runner2)));
872 Wait();
873
874 // Task will be scheduled from pool #1.
875 task_runner1->PostTask(FROM_HERE,
876 Bind(&TimerSequenceTest::StartTimer, Unretained(this),
877 TimeDelta::FromHours(1), Bind(&DoNothing)));
878
879 // Abandon task - must be called from scheduling pool (#1).
880 task_runner1->PostTask(
881 FROM_HERE,
882 TaskWithSignal(Bind(&TimerSequenceTest::AbandonTask, Unretained(this))));
883 Wait();
884
885 // Timer must be destroyed on the pool it was scheduled from (#1).
886 task_runner1->PostTask(
887 FROM_HERE,
888 TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
889 Wait();
890}
891
892TEST_F(TimerSequenceTest, OneShotTimerUsedAndTaskedOnDifferentPools) {
893 scoped_refptr<SequencedTaskRunner> task_runner1 =
894 pool1()->GetSequencedTaskRunner(pool1()->GetSequenceToken());
895 scoped_refptr<SequencedTaskRunner> task_runner2 =
896 pool2()->GetSequencedTaskRunner(pool2()->GetSequenceToken());
897
898 // Create timer on pool #1.
899 task_runner1->PostTask(
900 FROM_HERE,
901 TaskWithSignal(Bind(&TimerSequenceTest::CreateTimer, Unretained(this))));
902 Wait();
903
904 // And tell it to execute on a different pool (#2).
905 task_runner1->PostTask(
906 FROM_HERE, TaskWithSignal(Bind(&TimerSequenceTest::SetTaskRunnerForTimer,
907 Unretained(this), task_runner2)));
908 Wait();
909
910 // Task will be scheduled from pool #1.
911 task_runner1->PostTask(
912 FROM_HERE, Bind(&TimerSequenceTest::StartTimer, Unretained(this),
913 TimeDelta::FromMilliseconds(1),
914 TaskWithSignal(Bind(&TimerSequenceTest::VerifyAffinity,
915 Unretained(task_runner2.get())))));
916
917 Wait();
918
919 // Timer must be destroyed on the pool it was scheduled from (#1).
920 task_runner1->PostTask(
921 FROM_HERE,
922 TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
923 Wait();
924}
925
gabccd5b952016-11-29 08:01:33 +0900926} // namespace base