xref: /aosp_15_r20/external/cronet/base/win/object_watcher_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/win/object_watcher.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <windows.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <utility>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
14*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker namespace base {
17*6777b538SAndroid Build Coastguard Worker namespace win {
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker namespace {
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker class QuitDelegate : public ObjectWatcher::Delegate {
22*6777b538SAndroid Build Coastguard Worker  public:
QuitDelegate(base::OnceClosure quit_closure)23*6777b538SAndroid Build Coastguard Worker   explicit QuitDelegate(base::OnceClosure quit_closure)
24*6777b538SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)) {}
25*6777b538SAndroid Build Coastguard Worker 
OnObjectSignaled(HANDLE object)26*6777b538SAndroid Build Coastguard Worker   void OnObjectSignaled(HANDLE object) override {
27*6777b538SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
28*6777b538SAndroid Build Coastguard Worker   }
29*6777b538SAndroid Build Coastguard Worker 
30*6777b538SAndroid Build Coastguard Worker  private:
31*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
32*6777b538SAndroid Build Coastguard Worker };
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker class DecrementCountDelegate : public ObjectWatcher::Delegate {
35*6777b538SAndroid Build Coastguard Worker  public:
DecrementCountDelegate(int * counter)36*6777b538SAndroid Build Coastguard Worker   explicit DecrementCountDelegate(int* counter) : counter_(counter) {}
OnObjectSignaled(HANDLE object)37*6777b538SAndroid Build Coastguard Worker   void OnObjectSignaled(HANDLE object) override { --(*counter_); }
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker  private:
40*6777b538SAndroid Build Coastguard Worker   raw_ptr<int> counter_;
41*6777b538SAndroid Build Coastguard Worker };
42*6777b538SAndroid Build Coastguard Worker 
RunTest_BasicSignal(test::TaskEnvironment::MainThreadType main_thread_type)43*6777b538SAndroid Build Coastguard Worker void RunTest_BasicSignal(
44*6777b538SAndroid Build Coastguard Worker     test::TaskEnvironment::MainThreadType main_thread_type) {
45*6777b538SAndroid Build Coastguard Worker   test::TaskEnvironment task_environment(main_thread_type);
46*6777b538SAndroid Build Coastguard Worker 
47*6777b538SAndroid Build Coastguard Worker   ObjectWatcher watcher;
48*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(watcher.IsWatching());
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker   // A manual-reset event that is not yet signaled.
51*6777b538SAndroid Build Coastguard Worker   HANDLE event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker   base::RunLoop loop;
54*6777b538SAndroid Build Coastguard Worker   QuitDelegate delegate(loop.QuitWhenIdleClosure());
55*6777b538SAndroid Build Coastguard Worker   bool ok = watcher.StartWatchingOnce(event, &delegate);
56*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ok);
57*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(watcher.IsWatching());
58*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(event, watcher.GetWatchedObject());
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker   SetEvent(event);
61*6777b538SAndroid Build Coastguard Worker 
62*6777b538SAndroid Build Coastguard Worker   loop.Run();
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(watcher.IsWatching());
65*6777b538SAndroid Build Coastguard Worker   CloseHandle(event);
66*6777b538SAndroid Build Coastguard Worker }
67*6777b538SAndroid Build Coastguard Worker 
RunTest_BasicCancel(test::TaskEnvironment::MainThreadType main_thread_type)68*6777b538SAndroid Build Coastguard Worker void RunTest_BasicCancel(
69*6777b538SAndroid Build Coastguard Worker     test::TaskEnvironment::MainThreadType main_thread_type) {
70*6777b538SAndroid Build Coastguard Worker   test::TaskEnvironment task_environment(main_thread_type);
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker   ObjectWatcher watcher;
73*6777b538SAndroid Build Coastguard Worker 
74*6777b538SAndroid Build Coastguard Worker   // A manual-reset event that is not yet signaled.
75*6777b538SAndroid Build Coastguard Worker   HANDLE event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
76*6777b538SAndroid Build Coastguard Worker 
77*6777b538SAndroid Build Coastguard Worker   base::RunLoop loop;
78*6777b538SAndroid Build Coastguard Worker   QuitDelegate delegate(loop.QuitWhenIdleClosure());
79*6777b538SAndroid Build Coastguard Worker   bool ok = watcher.StartWatchingOnce(event, &delegate);
80*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ok);
81*6777b538SAndroid Build Coastguard Worker 
82*6777b538SAndroid Build Coastguard Worker   watcher.StopWatching();
83*6777b538SAndroid Build Coastguard Worker 
84*6777b538SAndroid Build Coastguard Worker   CloseHandle(event);
85*6777b538SAndroid Build Coastguard Worker }
86*6777b538SAndroid Build Coastguard Worker 
RunTest_CancelAfterSet(test::TaskEnvironment::MainThreadType main_thread_type)87*6777b538SAndroid Build Coastguard Worker void RunTest_CancelAfterSet(
88*6777b538SAndroid Build Coastguard Worker     test::TaskEnvironment::MainThreadType main_thread_type) {
89*6777b538SAndroid Build Coastguard Worker   test::TaskEnvironment task_environment(main_thread_type);
90*6777b538SAndroid Build Coastguard Worker 
91*6777b538SAndroid Build Coastguard Worker   ObjectWatcher watcher;
92*6777b538SAndroid Build Coastguard Worker 
93*6777b538SAndroid Build Coastguard Worker   int counter = 1;
94*6777b538SAndroid Build Coastguard Worker   DecrementCountDelegate delegate(&counter);
95*6777b538SAndroid Build Coastguard Worker   base::RunLoop loop;
96*6777b538SAndroid Build Coastguard Worker   // A manual-reset event that is not yet signaled.
97*6777b538SAndroid Build Coastguard Worker   HANDLE event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
98*6777b538SAndroid Build Coastguard Worker 
99*6777b538SAndroid Build Coastguard Worker   bool ok = watcher.StartWatchingOnce(event, &delegate);
100*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ok);
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker   SetEvent(event);
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker   // Let the background thread do its business
105*6777b538SAndroid Build Coastguard Worker   Sleep(30);
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker   watcher.StopWatching();
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker   loop.RunUntilIdle();
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker   // Our delegate should not have fired.
112*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, counter);
113*6777b538SAndroid Build Coastguard Worker 
114*6777b538SAndroid Build Coastguard Worker   CloseHandle(event);
115*6777b538SAndroid Build Coastguard Worker }
116*6777b538SAndroid Build Coastguard Worker 
RunTest_SignalBeforeWatch(test::TaskEnvironment::MainThreadType main_thread_type)117*6777b538SAndroid Build Coastguard Worker void RunTest_SignalBeforeWatch(
118*6777b538SAndroid Build Coastguard Worker     test::TaskEnvironment::MainThreadType main_thread_type) {
119*6777b538SAndroid Build Coastguard Worker   test::TaskEnvironment task_environment(main_thread_type);
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker   ObjectWatcher watcher;
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   // A manual-reset event that is signaled before we begin watching.
124*6777b538SAndroid Build Coastguard Worker   HANDLE event = CreateEvent(nullptr, TRUE, TRUE, nullptr);
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker   base::RunLoop loop;
127*6777b538SAndroid Build Coastguard Worker   QuitDelegate delegate(loop.QuitWhenIdleClosure());
128*6777b538SAndroid Build Coastguard Worker   bool ok = watcher.StartWatchingOnce(event, &delegate);
129*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ok);
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker   loop.Run();
132*6777b538SAndroid Build Coastguard Worker 
133*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(watcher.IsWatching());
134*6777b538SAndroid Build Coastguard Worker   CloseHandle(event);
135*6777b538SAndroid Build Coastguard Worker }
136*6777b538SAndroid Build Coastguard Worker 
RunTest_OutlivesTaskEnvironment(test::TaskEnvironment::MainThreadType main_thread_type)137*6777b538SAndroid Build Coastguard Worker void RunTest_OutlivesTaskEnvironment(
138*6777b538SAndroid Build Coastguard Worker     test::TaskEnvironment::MainThreadType main_thread_type) {
139*6777b538SAndroid Build Coastguard Worker   // Simulate a task environment that dies before an ObjectWatcher.  This
140*6777b538SAndroid Build Coastguard Worker   // ordinarily doesn't happen when people use the Thread class, but it can
141*6777b538SAndroid Build Coastguard Worker   // happen when people use the Singleton pattern or atexit.
142*6777b538SAndroid Build Coastguard Worker   HANDLE event = CreateEvent(nullptr, TRUE, FALSE, nullptr);  // not signaled
143*6777b538SAndroid Build Coastguard Worker   {
144*6777b538SAndroid Build Coastguard Worker     ObjectWatcher watcher;
145*6777b538SAndroid Build Coastguard Worker     {
146*6777b538SAndroid Build Coastguard Worker       test::TaskEnvironment task_environment(main_thread_type);
147*6777b538SAndroid Build Coastguard Worker 
148*6777b538SAndroid Build Coastguard Worker       base::RunLoop loop;
149*6777b538SAndroid Build Coastguard Worker       QuitDelegate delegate(loop.QuitWhenIdleClosure());
150*6777b538SAndroid Build Coastguard Worker       watcher.StartWatchingOnce(event, &delegate);
151*6777b538SAndroid Build Coastguard Worker     }
152*6777b538SAndroid Build Coastguard Worker   }
153*6777b538SAndroid Build Coastguard Worker   CloseHandle(event);
154*6777b538SAndroid Build Coastguard Worker }
155*6777b538SAndroid Build Coastguard Worker 
156*6777b538SAndroid Build Coastguard Worker class QuitAfterMultipleDelegate : public ObjectWatcher::Delegate {
157*6777b538SAndroid Build Coastguard Worker  public:
QuitAfterMultipleDelegate(HANDLE event,int iterations,base::OnceClosure quit_closure)158*6777b538SAndroid Build Coastguard Worker   QuitAfterMultipleDelegate(HANDLE event,
159*6777b538SAndroid Build Coastguard Worker                             int iterations,
160*6777b538SAndroid Build Coastguard Worker                             base::OnceClosure quit_closure)
161*6777b538SAndroid Build Coastguard Worker       : event_(event),
162*6777b538SAndroid Build Coastguard Worker         iterations_(iterations),
163*6777b538SAndroid Build Coastguard Worker         quit_closure_(std::move(quit_closure)) {}
OnObjectSignaled(HANDLE object)164*6777b538SAndroid Build Coastguard Worker   void OnObjectSignaled(HANDLE object) override {
165*6777b538SAndroid Build Coastguard Worker     if (--iterations_) {
166*6777b538SAndroid Build Coastguard Worker       SetEvent(event_);
167*6777b538SAndroid Build Coastguard Worker     } else {
168*6777b538SAndroid Build Coastguard Worker       std::move(quit_closure_).Run();
169*6777b538SAndroid Build Coastguard Worker     }
170*6777b538SAndroid Build Coastguard Worker   }
171*6777b538SAndroid Build Coastguard Worker 
172*6777b538SAndroid Build Coastguard Worker  private:
173*6777b538SAndroid Build Coastguard Worker   HANDLE event_;
174*6777b538SAndroid Build Coastguard Worker   int iterations_;
175*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
176*6777b538SAndroid Build Coastguard Worker };
177*6777b538SAndroid Build Coastguard Worker 
RunTest_ExecuteMultipleTimes(test::TaskEnvironment::MainThreadType main_thread_type)178*6777b538SAndroid Build Coastguard Worker void RunTest_ExecuteMultipleTimes(
179*6777b538SAndroid Build Coastguard Worker     test::TaskEnvironment::MainThreadType main_thread_type) {
180*6777b538SAndroid Build Coastguard Worker   test::TaskEnvironment task_environment(main_thread_type);
181*6777b538SAndroid Build Coastguard Worker 
182*6777b538SAndroid Build Coastguard Worker   ObjectWatcher watcher;
183*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(watcher.IsWatching());
184*6777b538SAndroid Build Coastguard Worker 
185*6777b538SAndroid Build Coastguard Worker   // An auto-reset event that is not yet signaled.
186*6777b538SAndroid Build Coastguard Worker   HANDLE event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
187*6777b538SAndroid Build Coastguard Worker 
188*6777b538SAndroid Build Coastguard Worker   base::RunLoop loop;
189*6777b538SAndroid Build Coastguard Worker   QuitAfterMultipleDelegate delegate(event, 2, loop.QuitWhenIdleClosure());
190*6777b538SAndroid Build Coastguard Worker   bool ok = watcher.StartWatchingMultipleTimes(event, &delegate);
191*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ok);
192*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(watcher.IsWatching());
193*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(event, watcher.GetWatchedObject());
194*6777b538SAndroid Build Coastguard Worker 
195*6777b538SAndroid Build Coastguard Worker   SetEvent(event);
196*6777b538SAndroid Build Coastguard Worker 
197*6777b538SAndroid Build Coastguard Worker   loop.Run();
198*6777b538SAndroid Build Coastguard Worker 
199*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(watcher.IsWatching());
200*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(watcher.StopWatching());
201*6777b538SAndroid Build Coastguard Worker   CloseHandle(event);
202*6777b538SAndroid Build Coastguard Worker }
203*6777b538SAndroid Build Coastguard Worker 
204*6777b538SAndroid Build Coastguard Worker }  // namespace
205*6777b538SAndroid Build Coastguard Worker 
206*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
207*6777b538SAndroid Build Coastguard Worker 
TEST(ObjectWatcherTest,BasicSignal)208*6777b538SAndroid Build Coastguard Worker TEST(ObjectWatcherTest, BasicSignal) {
209*6777b538SAndroid Build Coastguard Worker   RunTest_BasicSignal(test::TaskEnvironment::MainThreadType::DEFAULT);
210*6777b538SAndroid Build Coastguard Worker   RunTest_BasicSignal(test::TaskEnvironment::MainThreadType::IO);
211*6777b538SAndroid Build Coastguard Worker   RunTest_BasicSignal(test::TaskEnvironment::MainThreadType::UI);
212*6777b538SAndroid Build Coastguard Worker }
213*6777b538SAndroid Build Coastguard Worker 
TEST(ObjectWatcherTest,BasicCancel)214*6777b538SAndroid Build Coastguard Worker TEST(ObjectWatcherTest, BasicCancel) {
215*6777b538SAndroid Build Coastguard Worker   RunTest_BasicCancel(test::TaskEnvironment::MainThreadType::DEFAULT);
216*6777b538SAndroid Build Coastguard Worker   RunTest_BasicCancel(test::TaskEnvironment::MainThreadType::IO);
217*6777b538SAndroid Build Coastguard Worker   RunTest_BasicCancel(test::TaskEnvironment::MainThreadType::UI);
218*6777b538SAndroid Build Coastguard Worker }
219*6777b538SAndroid Build Coastguard Worker 
TEST(ObjectWatcherTest,CancelAfterSet)220*6777b538SAndroid Build Coastguard Worker TEST(ObjectWatcherTest, CancelAfterSet) {
221*6777b538SAndroid Build Coastguard Worker   RunTest_CancelAfterSet(test::TaskEnvironment::MainThreadType::DEFAULT);
222*6777b538SAndroid Build Coastguard Worker   RunTest_CancelAfterSet(test::TaskEnvironment::MainThreadType::IO);
223*6777b538SAndroid Build Coastguard Worker   RunTest_CancelAfterSet(test::TaskEnvironment::MainThreadType::UI);
224*6777b538SAndroid Build Coastguard Worker }
225*6777b538SAndroid Build Coastguard Worker 
TEST(ObjectWatcherTest,SignalBeforeWatch)226*6777b538SAndroid Build Coastguard Worker TEST(ObjectWatcherTest, SignalBeforeWatch) {
227*6777b538SAndroid Build Coastguard Worker   RunTest_SignalBeforeWatch(test::TaskEnvironment::MainThreadType::DEFAULT);
228*6777b538SAndroid Build Coastguard Worker   RunTest_SignalBeforeWatch(test::TaskEnvironment::MainThreadType::IO);
229*6777b538SAndroid Build Coastguard Worker   RunTest_SignalBeforeWatch(test::TaskEnvironment::MainThreadType::UI);
230*6777b538SAndroid Build Coastguard Worker }
231*6777b538SAndroid Build Coastguard Worker 
TEST(ObjectWatcherTest,OutlivesTaskEnvironment)232*6777b538SAndroid Build Coastguard Worker TEST(ObjectWatcherTest, OutlivesTaskEnvironment) {
233*6777b538SAndroid Build Coastguard Worker   RunTest_OutlivesTaskEnvironment(
234*6777b538SAndroid Build Coastguard Worker       test::TaskEnvironment::MainThreadType::DEFAULT);
235*6777b538SAndroid Build Coastguard Worker   RunTest_OutlivesTaskEnvironment(test::TaskEnvironment::MainThreadType::IO);
236*6777b538SAndroid Build Coastguard Worker   RunTest_OutlivesTaskEnvironment(test::TaskEnvironment::MainThreadType::UI);
237*6777b538SAndroid Build Coastguard Worker }
238*6777b538SAndroid Build Coastguard Worker 
TEST(ObjectWatcherTest,ExecuteMultipleTimes)239*6777b538SAndroid Build Coastguard Worker TEST(ObjectWatcherTest, ExecuteMultipleTimes) {
240*6777b538SAndroid Build Coastguard Worker   RunTest_ExecuteMultipleTimes(test::TaskEnvironment::MainThreadType::DEFAULT);
241*6777b538SAndroid Build Coastguard Worker   RunTest_ExecuteMultipleTimes(test::TaskEnvironment::MainThreadType::IO);
242*6777b538SAndroid Build Coastguard Worker   RunTest_ExecuteMultipleTimes(test::TaskEnvironment::MainThreadType::UI);
243*6777b538SAndroid Build Coastguard Worker }
244*6777b538SAndroid Build Coastguard Worker 
245*6777b538SAndroid Build Coastguard Worker }  // namespace win
246*6777b538SAndroid Build Coastguard Worker }  // namespace base
247