1*635a8641SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include <sys/timerfd.h>
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <memory>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
10*635a8641SAndroid Build Coastguard Worker #include "base/bind_helpers.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/files/file_descriptor_watcher_posix.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/location.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/message_loop/message_loop.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/run_loop.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/single_thread_task_runner.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_task_runner_handle.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
20*635a8641SAndroid Build Coastguard Worker #include "components/timers/alarm_timer_chromeos.h"
21*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
22*635a8641SAndroid Build Coastguard Worker
23*635a8641SAndroid Build Coastguard Worker // Most of these tests have been lifted right out of timer_unittest.cc with only
24*635a8641SAndroid Build Coastguard Worker // cosmetic changes. We want the AlarmTimer to be a drop-in replacement for the
25*635a8641SAndroid Build Coastguard Worker // regular Timer so it should pass the same tests as the Timer class.
26*635a8641SAndroid Build Coastguard Worker namespace timers {
27*635a8641SAndroid Build Coastguard Worker namespace {
28*635a8641SAndroid Build Coastguard Worker const base::TimeDelta kTenMilliseconds = base::TimeDelta::FromMilliseconds(10);
29*635a8641SAndroid Build Coastguard Worker
30*635a8641SAndroid Build Coastguard Worker class AlarmTimerTester {
31*635a8641SAndroid Build Coastguard Worker public:
AlarmTimerTester(bool * did_run,base::TimeDelta delay,base::OnceClosure quit_closure)32*635a8641SAndroid Build Coastguard Worker AlarmTimerTester(bool* did_run,
33*635a8641SAndroid Build Coastguard Worker base::TimeDelta delay,
34*635a8641SAndroid Build Coastguard Worker base::OnceClosure quit_closure)
35*635a8641SAndroid Build Coastguard Worker : did_run_(did_run),
36*635a8641SAndroid Build Coastguard Worker quit_closure_(std::move(quit_closure)),
37*635a8641SAndroid Build Coastguard Worker delay_(delay),
38*635a8641SAndroid Build Coastguard Worker timer_(new timers::SimpleAlarmTimer()) {}
Start()39*635a8641SAndroid Build Coastguard Worker void Start() {
40*635a8641SAndroid Build Coastguard Worker timer_->Start(
41*635a8641SAndroid Build Coastguard Worker FROM_HERE, delay_,
42*635a8641SAndroid Build Coastguard Worker base::BindRepeating(&AlarmTimerTester::Run, base::Unretained(this)));
43*635a8641SAndroid Build Coastguard Worker }
44*635a8641SAndroid Build Coastguard Worker
45*635a8641SAndroid Build Coastguard Worker private:
Run()46*635a8641SAndroid Build Coastguard Worker void Run() {
47*635a8641SAndroid Build Coastguard Worker *did_run_ = true;
48*635a8641SAndroid Build Coastguard Worker if (quit_closure_)
49*635a8641SAndroid Build Coastguard Worker std::move(quit_closure_).Run();
50*635a8641SAndroid Build Coastguard Worker }
51*635a8641SAndroid Build Coastguard Worker
52*635a8641SAndroid Build Coastguard Worker bool* did_run_;
53*635a8641SAndroid Build Coastguard Worker base::OnceClosure quit_closure_;
54*635a8641SAndroid Build Coastguard Worker const base::TimeDelta delay_;
55*635a8641SAndroid Build Coastguard Worker std::unique_ptr<timers::SimpleAlarmTimer> timer_;
56*635a8641SAndroid Build Coastguard Worker
57*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(AlarmTimerTester);
58*635a8641SAndroid Build Coastguard Worker };
59*635a8641SAndroid Build Coastguard Worker
60*635a8641SAndroid Build Coastguard Worker class SelfDeletingAlarmTimerTester {
61*635a8641SAndroid Build Coastguard Worker public:
SelfDeletingAlarmTimerTester(bool * did_run,base::TimeDelta delay,base::OnceClosure quit_closure)62*635a8641SAndroid Build Coastguard Worker SelfDeletingAlarmTimerTester(bool* did_run,
63*635a8641SAndroid Build Coastguard Worker base::TimeDelta delay,
64*635a8641SAndroid Build Coastguard Worker base::OnceClosure quit_closure)
65*635a8641SAndroid Build Coastguard Worker : did_run_(did_run),
66*635a8641SAndroid Build Coastguard Worker quit_closure_(std::move(quit_closure)),
67*635a8641SAndroid Build Coastguard Worker delay_(delay),
68*635a8641SAndroid Build Coastguard Worker timer_(new timers::SimpleAlarmTimer()) {}
Start()69*635a8641SAndroid Build Coastguard Worker void Start() {
70*635a8641SAndroid Build Coastguard Worker timer_->Start(FROM_HERE, delay_,
71*635a8641SAndroid Build Coastguard Worker base::BindRepeating(&SelfDeletingAlarmTimerTester::Run,
72*635a8641SAndroid Build Coastguard Worker base::Unretained(this)));
73*635a8641SAndroid Build Coastguard Worker }
74*635a8641SAndroid Build Coastguard Worker
75*635a8641SAndroid Build Coastguard Worker private:
Run()76*635a8641SAndroid Build Coastguard Worker void Run() {
77*635a8641SAndroid Build Coastguard Worker *did_run_ = true;
78*635a8641SAndroid Build Coastguard Worker timer_.reset();
79*635a8641SAndroid Build Coastguard Worker
80*635a8641SAndroid Build Coastguard Worker if (quit_closure_)
81*635a8641SAndroid Build Coastguard Worker std::move(quit_closure_).Run();
82*635a8641SAndroid Build Coastguard Worker }
83*635a8641SAndroid Build Coastguard Worker
84*635a8641SAndroid Build Coastguard Worker bool* did_run_;
85*635a8641SAndroid Build Coastguard Worker base::OnceClosure quit_closure_;
86*635a8641SAndroid Build Coastguard Worker const base::TimeDelta delay_;
87*635a8641SAndroid Build Coastguard Worker std::unique_ptr<timers::SimpleAlarmTimer> timer_;
88*635a8641SAndroid Build Coastguard Worker
89*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(SelfDeletingAlarmTimerTester);
90*635a8641SAndroid Build Coastguard Worker };
91*635a8641SAndroid Build Coastguard Worker
92*635a8641SAndroid Build Coastguard Worker } // namespace
93*635a8641SAndroid Build Coastguard Worker
94*635a8641SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
95*635a8641SAndroid Build Coastguard Worker // Each test is run against each type of MessageLoop. That way we are sure
96*635a8641SAndroid Build Coastguard Worker // that timers work properly in all configurations.
97*635a8641SAndroid Build Coastguard Worker
TEST(AlarmTimerTest,SimpleAlarmTimer)98*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, SimpleAlarmTimer) {
99*635a8641SAndroid Build Coastguard Worker base::MessageLoopForIO loop;
100*635a8641SAndroid Build Coastguard Worker base::FileDescriptorWatcher file_descriptor_watcher(&loop);
101*635a8641SAndroid Build Coastguard Worker
102*635a8641SAndroid Build Coastguard Worker base::RunLoop run_loop;
103*635a8641SAndroid Build Coastguard Worker bool did_run = false;
104*635a8641SAndroid Build Coastguard Worker AlarmTimerTester f(&did_run, kTenMilliseconds,
105*635a8641SAndroid Build Coastguard Worker run_loop.QuitWhenIdleClosure());
106*635a8641SAndroid Build Coastguard Worker f.Start();
107*635a8641SAndroid Build Coastguard Worker
108*635a8641SAndroid Build Coastguard Worker run_loop.Run();
109*635a8641SAndroid Build Coastguard Worker
110*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(did_run);
111*635a8641SAndroid Build Coastguard Worker }
112*635a8641SAndroid Build Coastguard Worker
TEST(AlarmTimerTest,SimpleAlarmTimer_Cancel)113*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, SimpleAlarmTimer_Cancel) {
114*635a8641SAndroid Build Coastguard Worker base::MessageLoopForIO loop;
115*635a8641SAndroid Build Coastguard Worker base::FileDescriptorWatcher file_descriptor_watcher(&loop);
116*635a8641SAndroid Build Coastguard Worker
117*635a8641SAndroid Build Coastguard Worker bool did_run_a = false;
118*635a8641SAndroid Build Coastguard Worker AlarmTimerTester* a =
119*635a8641SAndroid Build Coastguard Worker new AlarmTimerTester(&did_run_a, kTenMilliseconds, base::OnceClosure());
120*635a8641SAndroid Build Coastguard Worker
121*635a8641SAndroid Build Coastguard Worker // This should run before the timer expires.
122*635a8641SAndroid Build Coastguard Worker base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
123*635a8641SAndroid Build Coastguard Worker
124*635a8641SAndroid Build Coastguard Worker // Now start the timer.
125*635a8641SAndroid Build Coastguard Worker a->Start();
126*635a8641SAndroid Build Coastguard Worker
127*635a8641SAndroid Build Coastguard Worker base::RunLoop run_loop;
128*635a8641SAndroid Build Coastguard Worker bool did_run_b = false;
129*635a8641SAndroid Build Coastguard Worker AlarmTimerTester b(&did_run_b, kTenMilliseconds,
130*635a8641SAndroid Build Coastguard Worker run_loop.QuitWhenIdleClosure());
131*635a8641SAndroid Build Coastguard Worker b.Start();
132*635a8641SAndroid Build Coastguard Worker
133*635a8641SAndroid Build Coastguard Worker run_loop.Run();
134*635a8641SAndroid Build Coastguard Worker
135*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(did_run_a);
136*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(did_run_b);
137*635a8641SAndroid Build Coastguard Worker }
138*635a8641SAndroid Build Coastguard Worker
139*635a8641SAndroid Build Coastguard Worker // If underlying timer does not handle this properly, we will crash or fail
140*635a8641SAndroid Build Coastguard Worker // in full page heap environment.
TEST(AlarmTimerTest,SelfDeletingAlarmTimer)141*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, SelfDeletingAlarmTimer) {
142*635a8641SAndroid Build Coastguard Worker base::MessageLoopForIO loop;
143*635a8641SAndroid Build Coastguard Worker base::FileDescriptorWatcher file_descriptor_watcher(&loop);
144*635a8641SAndroid Build Coastguard Worker
145*635a8641SAndroid Build Coastguard Worker base::RunLoop run_loop;
146*635a8641SAndroid Build Coastguard Worker bool did_run = false;
147*635a8641SAndroid Build Coastguard Worker SelfDeletingAlarmTimerTester f(&did_run, kTenMilliseconds,
148*635a8641SAndroid Build Coastguard Worker run_loop.QuitWhenIdleClosure());
149*635a8641SAndroid Build Coastguard Worker f.Start();
150*635a8641SAndroid Build Coastguard Worker
151*635a8641SAndroid Build Coastguard Worker run_loop.Run();
152*635a8641SAndroid Build Coastguard Worker
153*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(did_run);
154*635a8641SAndroid Build Coastguard Worker }
155*635a8641SAndroid Build Coastguard Worker
TEST(AlarmTimerTest,AlarmTimerZeroDelay)156*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, AlarmTimerZeroDelay) {
157*635a8641SAndroid Build Coastguard Worker base::MessageLoopForIO loop;
158*635a8641SAndroid Build Coastguard Worker base::FileDescriptorWatcher file_descriptor_watcher(&loop);
159*635a8641SAndroid Build Coastguard Worker
160*635a8641SAndroid Build Coastguard Worker base::RunLoop run_loop;
161*635a8641SAndroid Build Coastguard Worker bool did_run = false;
162*635a8641SAndroid Build Coastguard Worker AlarmTimerTester f(&did_run, base::TimeDelta(),
163*635a8641SAndroid Build Coastguard Worker run_loop.QuitWhenIdleClosure());
164*635a8641SAndroid Build Coastguard Worker f.Start();
165*635a8641SAndroid Build Coastguard Worker
166*635a8641SAndroid Build Coastguard Worker run_loop.Run();
167*635a8641SAndroid Build Coastguard Worker
168*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(did_run);
169*635a8641SAndroid Build Coastguard Worker }
170*635a8641SAndroid Build Coastguard Worker
TEST(AlarmTimerTest,AlarmTimerZeroDelay_Cancel)171*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, AlarmTimerZeroDelay_Cancel) {
172*635a8641SAndroid Build Coastguard Worker base::MessageLoopForIO loop;
173*635a8641SAndroid Build Coastguard Worker base::FileDescriptorWatcher file_descriptor_watcher(&loop);
174*635a8641SAndroid Build Coastguard Worker
175*635a8641SAndroid Build Coastguard Worker bool did_run_a = false;
176*635a8641SAndroid Build Coastguard Worker AlarmTimerTester* a =
177*635a8641SAndroid Build Coastguard Worker new AlarmTimerTester(&did_run_a, base::TimeDelta(), base::OnceClosure());
178*635a8641SAndroid Build Coastguard Worker
179*635a8641SAndroid Build Coastguard Worker // This should run before the timer expires.
180*635a8641SAndroid Build Coastguard Worker base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
181*635a8641SAndroid Build Coastguard Worker
182*635a8641SAndroid Build Coastguard Worker // Now start the timer.
183*635a8641SAndroid Build Coastguard Worker a->Start();
184*635a8641SAndroid Build Coastguard Worker
185*635a8641SAndroid Build Coastguard Worker base::RunLoop run_loop;
186*635a8641SAndroid Build Coastguard Worker bool did_run_b = false;
187*635a8641SAndroid Build Coastguard Worker AlarmTimerTester b(&did_run_b, base::TimeDelta(),
188*635a8641SAndroid Build Coastguard Worker run_loop.QuitWhenIdleClosure());
189*635a8641SAndroid Build Coastguard Worker b.Start();
190*635a8641SAndroid Build Coastguard Worker
191*635a8641SAndroid Build Coastguard Worker run_loop.Run();
192*635a8641SAndroid Build Coastguard Worker
193*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(did_run_a);
194*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(did_run_b);
195*635a8641SAndroid Build Coastguard Worker }
196*635a8641SAndroid Build Coastguard Worker
TEST(AlarmTimerTest,MessageLoopShutdown)197*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, MessageLoopShutdown) {
198*635a8641SAndroid Build Coastguard Worker // This test is designed to verify that shutdown of the
199*635a8641SAndroid Build Coastguard Worker // message loop does not cause crashes if there were pending
200*635a8641SAndroid Build Coastguard Worker // timers not yet fired. It may only trigger exceptions
201*635a8641SAndroid Build Coastguard Worker // if debug heap checking is enabled.
202*635a8641SAndroid Build Coastguard Worker bool did_run = false;
203*635a8641SAndroid Build Coastguard Worker {
204*635a8641SAndroid Build Coastguard Worker auto loop = std::make_unique<base::MessageLoopForIO>();
205*635a8641SAndroid Build Coastguard Worker auto file_descriptor_watcher =
206*635a8641SAndroid Build Coastguard Worker std::make_unique<base::FileDescriptorWatcher>(loop.get());
207*635a8641SAndroid Build Coastguard Worker AlarmTimerTester a(&did_run, kTenMilliseconds, base::OnceClosure());
208*635a8641SAndroid Build Coastguard Worker AlarmTimerTester b(&did_run, kTenMilliseconds, base::OnceClosure());
209*635a8641SAndroid Build Coastguard Worker AlarmTimerTester c(&did_run, kTenMilliseconds, base::OnceClosure());
210*635a8641SAndroid Build Coastguard Worker AlarmTimerTester d(&did_run, kTenMilliseconds, base::OnceClosure());
211*635a8641SAndroid Build Coastguard Worker
212*635a8641SAndroid Build Coastguard Worker a.Start();
213*635a8641SAndroid Build Coastguard Worker b.Start();
214*635a8641SAndroid Build Coastguard Worker
215*635a8641SAndroid Build Coastguard Worker // Allow FileDescriptorWatcher to start watching the timers. Without this,
216*635a8641SAndroid Build Coastguard Worker // tasks posted by FileDescriptorWatcher::WatchReadable() are leaked.
217*635a8641SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
218*635a8641SAndroid Build Coastguard Worker
219*635a8641SAndroid Build Coastguard Worker // MessageLoop and FileDescriptorWatcher destruct.
220*635a8641SAndroid Build Coastguard Worker file_descriptor_watcher.reset();
221*635a8641SAndroid Build Coastguard Worker loop.reset();
222*635a8641SAndroid Build Coastguard Worker } // SimpleAlarmTimers destruct. SHOULD NOT CRASH, of course.
223*635a8641SAndroid Build Coastguard Worker
224*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(did_run);
225*635a8641SAndroid Build Coastguard Worker }
226*635a8641SAndroid Build Coastguard Worker
TEST(AlarmTimerTest,NonRepeatIsRunning)227*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, NonRepeatIsRunning) {
228*635a8641SAndroid Build Coastguard Worker {
229*635a8641SAndroid Build Coastguard Worker base::MessageLoopForIO loop;
230*635a8641SAndroid Build Coastguard Worker base::FileDescriptorWatcher file_descriptor_watcher(&loop);
231*635a8641SAndroid Build Coastguard Worker timers::SimpleAlarmTimer timer;
232*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(timer.IsRunning());
233*635a8641SAndroid Build Coastguard Worker timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), base::DoNothing());
234*635a8641SAndroid Build Coastguard Worker
235*635a8641SAndroid Build Coastguard Worker // Allow FileDescriptorWatcher to start watching the timer. Without this, a
236*635a8641SAndroid Build Coastguard Worker // task posted by FileDescriptorWatcher::WatchReadable() is leaked.
237*635a8641SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
238*635a8641SAndroid Build Coastguard Worker
239*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(timer.IsRunning());
240*635a8641SAndroid Build Coastguard Worker timer.Stop();
241*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(timer.IsRunning());
242*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(timer.user_task().is_null());
243*635a8641SAndroid Build Coastguard Worker timer.Reset();
244*635a8641SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
245*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(timer.IsRunning());
246*635a8641SAndroid Build Coastguard Worker }
247*635a8641SAndroid Build Coastguard Worker }
248*635a8641SAndroid Build Coastguard Worker
TEST(AlarmTimerTest,RetainNonRepeatIsRunning)249*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, RetainNonRepeatIsRunning) {
250*635a8641SAndroid Build Coastguard Worker base::MessageLoopForIO loop;
251*635a8641SAndroid Build Coastguard Worker base::FileDescriptorWatcher file_descriptor_watcher(&loop);
252*635a8641SAndroid Build Coastguard Worker timers::SimpleAlarmTimer timer;
253*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(timer.IsRunning());
254*635a8641SAndroid Build Coastguard Worker timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), base::DoNothing());
255*635a8641SAndroid Build Coastguard Worker
256*635a8641SAndroid Build Coastguard Worker // Allow FileDescriptorWatcher to start watching the timer. Without this, a
257*635a8641SAndroid Build Coastguard Worker // task posted by FileDescriptorWatcher::WatchReadable() is leaked.
258*635a8641SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
259*635a8641SAndroid Build Coastguard Worker
260*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(timer.IsRunning());
261*635a8641SAndroid Build Coastguard Worker timer.Reset();
262*635a8641SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
263*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(timer.IsRunning());
264*635a8641SAndroid Build Coastguard Worker timer.Stop();
265*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(timer.IsRunning());
266*635a8641SAndroid Build Coastguard Worker timer.Reset();
267*635a8641SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
268*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(timer.IsRunning());
269*635a8641SAndroid Build Coastguard Worker }
270*635a8641SAndroid Build Coastguard Worker
271*635a8641SAndroid Build Coastguard Worker namespace {
272*635a8641SAndroid Build Coastguard Worker
273*635a8641SAndroid Build Coastguard Worker bool g_callback_happened1 = false;
274*635a8641SAndroid Build Coastguard Worker bool g_callback_happened2 = false;
275*635a8641SAndroid Build Coastguard Worker
ClearAllCallbackHappened()276*635a8641SAndroid Build Coastguard Worker void ClearAllCallbackHappened() {
277*635a8641SAndroid Build Coastguard Worker g_callback_happened1 = false;
278*635a8641SAndroid Build Coastguard Worker g_callback_happened2 = false;
279*635a8641SAndroid Build Coastguard Worker }
280*635a8641SAndroid Build Coastguard Worker
SetCallbackHappened1(base::OnceClosure quit_closure)281*635a8641SAndroid Build Coastguard Worker void SetCallbackHappened1(base::OnceClosure quit_closure) {
282*635a8641SAndroid Build Coastguard Worker g_callback_happened1 = true;
283*635a8641SAndroid Build Coastguard Worker if (quit_closure)
284*635a8641SAndroid Build Coastguard Worker std::move(quit_closure).Run();
285*635a8641SAndroid Build Coastguard Worker }
286*635a8641SAndroid Build Coastguard Worker
SetCallbackHappened2(base::OnceClosure quit_closure)287*635a8641SAndroid Build Coastguard Worker void SetCallbackHappened2(base::OnceClosure quit_closure) {
288*635a8641SAndroid Build Coastguard Worker g_callback_happened2 = true;
289*635a8641SAndroid Build Coastguard Worker if (quit_closure)
290*635a8641SAndroid Build Coastguard Worker std::move(quit_closure).Run();
291*635a8641SAndroid Build Coastguard Worker }
292*635a8641SAndroid Build Coastguard Worker
TEST(AlarmTimerTest,ContinuationStopStart)293*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, ContinuationStopStart) {
294*635a8641SAndroid Build Coastguard Worker ClearAllCallbackHappened();
295*635a8641SAndroid Build Coastguard Worker base::MessageLoopForIO loop;
296*635a8641SAndroid Build Coastguard Worker base::FileDescriptorWatcher file_descriptor_watcher(&loop);
297*635a8641SAndroid Build Coastguard Worker timers::SimpleAlarmTimer timer;
298*635a8641SAndroid Build Coastguard Worker timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10),
299*635a8641SAndroid Build Coastguard Worker base::BindRepeating(&SetCallbackHappened1,
300*635a8641SAndroid Build Coastguard Worker base::DoNothing().Repeatedly()));
301*635a8641SAndroid Build Coastguard Worker timer.Stop();
302*635a8641SAndroid Build Coastguard Worker
303*635a8641SAndroid Build Coastguard Worker base::RunLoop run_loop;
304*635a8641SAndroid Build Coastguard Worker timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(40),
305*635a8641SAndroid Build Coastguard Worker base::BindRepeating(&SetCallbackHappened2,
306*635a8641SAndroid Build Coastguard Worker run_loop.QuitWhenIdleClosure()));
307*635a8641SAndroid Build Coastguard Worker run_loop.Run();
308*635a8641SAndroid Build Coastguard Worker
309*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(g_callback_happened1);
310*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(g_callback_happened2);
311*635a8641SAndroid Build Coastguard Worker }
312*635a8641SAndroid Build Coastguard Worker
TEST(AlarmTimerTest,ContinuationReset)313*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, ContinuationReset) {
314*635a8641SAndroid Build Coastguard Worker ClearAllCallbackHappened();
315*635a8641SAndroid Build Coastguard Worker base::MessageLoopForIO loop;
316*635a8641SAndroid Build Coastguard Worker base::FileDescriptorWatcher file_descriptor_watcher(&loop);
317*635a8641SAndroid Build Coastguard Worker
318*635a8641SAndroid Build Coastguard Worker base::RunLoop run_loop;
319*635a8641SAndroid Build Coastguard Worker timers::SimpleAlarmTimer timer;
320*635a8641SAndroid Build Coastguard Worker timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10),
321*635a8641SAndroid Build Coastguard Worker base::BindRepeating(&SetCallbackHappened1,
322*635a8641SAndroid Build Coastguard Worker run_loop.QuitWhenIdleClosure()));
323*635a8641SAndroid Build Coastguard Worker timer.Reset();
324*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(timer.user_task().is_null());
325*635a8641SAndroid Build Coastguard Worker run_loop.Run();
326*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(g_callback_happened1);
327*635a8641SAndroid Build Coastguard Worker }
328*635a8641SAndroid Build Coastguard Worker
329*635a8641SAndroid Build Coastguard Worker // Verify that no crash occurs if a timer is deleted while its callback is
330*635a8641SAndroid Build Coastguard Worker // running.
TEST(AlarmTimerTest,DeleteTimerWhileCallbackIsRunning)331*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, DeleteTimerWhileCallbackIsRunning) {
332*635a8641SAndroid Build Coastguard Worker base::MessageLoopForIO loop;
333*635a8641SAndroid Build Coastguard Worker base::FileDescriptorWatcher file_descriptor_watcher(&loop);
334*635a8641SAndroid Build Coastguard Worker base::RunLoop run_loop;
335*635a8641SAndroid Build Coastguard Worker
336*635a8641SAndroid Build Coastguard Worker // Will be deleted by the callback.
337*635a8641SAndroid Build Coastguard Worker timers::SimpleAlarmTimer* timer = new timers::SimpleAlarmTimer;
338*635a8641SAndroid Build Coastguard Worker
339*635a8641SAndroid Build Coastguard Worker timer->Start(
340*635a8641SAndroid Build Coastguard Worker FROM_HERE, base::TimeDelta::FromMilliseconds(10),
341*635a8641SAndroid Build Coastguard Worker base::BindRepeating(
342*635a8641SAndroid Build Coastguard Worker [](timers::SimpleAlarmTimer* timer, base::RunLoop* run_loop) {
343*635a8641SAndroid Build Coastguard Worker delete timer;
344*635a8641SAndroid Build Coastguard Worker run_loop->Quit();
345*635a8641SAndroid Build Coastguard Worker },
346*635a8641SAndroid Build Coastguard Worker timer, &run_loop));
347*635a8641SAndroid Build Coastguard Worker run_loop.Run();
348*635a8641SAndroid Build Coastguard Worker }
349*635a8641SAndroid Build Coastguard Worker
350*635a8641SAndroid Build Coastguard Worker // Verify that no crash occurs if a zero-delay timer is deleted while its
351*635a8641SAndroid Build Coastguard Worker // callback is running.
TEST(AlarmTimerTest,DeleteTimerWhileCallbackIsRunningZeroDelay)352*635a8641SAndroid Build Coastguard Worker TEST(AlarmTimerTest, DeleteTimerWhileCallbackIsRunningZeroDelay) {
353*635a8641SAndroid Build Coastguard Worker base::MessageLoopForIO loop;
354*635a8641SAndroid Build Coastguard Worker base::FileDescriptorWatcher file_descriptor_watcher(&loop);
355*635a8641SAndroid Build Coastguard Worker base::RunLoop run_loop;
356*635a8641SAndroid Build Coastguard Worker
357*635a8641SAndroid Build Coastguard Worker // Will be deleted by the callback.
358*635a8641SAndroid Build Coastguard Worker timers::SimpleAlarmTimer* timer = new timers::SimpleAlarmTimer;
359*635a8641SAndroid Build Coastguard Worker
360*635a8641SAndroid Build Coastguard Worker timer->Start(
361*635a8641SAndroid Build Coastguard Worker FROM_HERE, base::TimeDelta(),
362*635a8641SAndroid Build Coastguard Worker base::BindRepeating(
363*635a8641SAndroid Build Coastguard Worker [](timers::SimpleAlarmTimer* timer, base::RunLoop* run_loop) {
364*635a8641SAndroid Build Coastguard Worker delete timer;
365*635a8641SAndroid Build Coastguard Worker run_loop->Quit();
366*635a8641SAndroid Build Coastguard Worker },
367*635a8641SAndroid Build Coastguard Worker timer, &run_loop));
368*635a8641SAndroid Build Coastguard Worker run_loop.Run();
369*635a8641SAndroid Build Coastguard Worker }
370*635a8641SAndroid Build Coastguard Worker
371*635a8641SAndroid Build Coastguard Worker } // namespace
372*635a8641SAndroid Build Coastguard Worker } // namespace timers
373