xref: /aosp_15_r20/external/libchrome/components/timers/alarm_timer_unittest.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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