xref: /aosp_15_r20/external/cronet/base/task/delayed_task_handle_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/task/delayed_task_handle.h"
6 
7 #include "base/memory/raw_ptr.h"
8 #include "base/test/gtest_util.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 
11 namespace base {
12 
13 namespace {
14 
15 // A non-working delegate that allows the testing of DelayedTaskHandle.
16 class TestDelegate : public DelayedTaskHandle::Delegate {
17  public:
TestDelegate(bool * was_cancel_task_called=nullptr)18   explicit TestDelegate(bool* was_cancel_task_called = nullptr)
19       : was_cancel_task_called_(was_cancel_task_called) {
20     DCHECK(!was_cancel_task_called_ || !*was_cancel_task_called_);
21   }
22   ~TestDelegate() override = default;
23 
IsValid() const24   bool IsValid() const override { return is_valid_; }
CancelTask()25   void CancelTask() override {
26     is_valid_ = false;
27 
28     if (was_cancel_task_called_)
29       *was_cancel_task_called_ = true;
30   }
31 
32  private:
33   // Indicates if this delegate is currently valid.
34   bool is_valid_ = true;
35 
36   // Indicates if CancelTask() was invoked, if not null. Must outlives |this|.
37   raw_ptr<bool> was_cancel_task_called_;
38 };
39 
40 }  // namespace
41 
42 // Tests that a default-constructed handle is invalid.
TEST(DelayedTaskHandleTest,DefaultConstructor)43 TEST(DelayedTaskHandleTest, DefaultConstructor) {
44   DelayedTaskHandle delayed_task_handle;
45   EXPECT_FALSE(delayed_task_handle.IsValid());
46 }
47 
48 // Tests that creating a handle with an invalid delegate will DCHECK.
TEST(DelayedTaskHandleTest,RequiresValidDelegateOnConstruction)49 TEST(DelayedTaskHandleTest, RequiresValidDelegateOnConstruction) {
50   auto delegate = std::make_unique<TestDelegate>();
51   EXPECT_TRUE(delegate->IsValid());
52 
53   // Invalidate the delegate before creating the handle.
54   delegate->CancelTask();
55   EXPECT_FALSE(delegate->IsValid());
56 
57   EXPECT_DCHECK_DEATH(
58       { DelayedTaskHandle delayed_task_handle(std::move(delegate)); });
59 }
60 
61 // Tests that calling CancelTask() on the handle will call CancelTask() on the
62 // delegate and invalidate it.
TEST(DelayedTaskHandleTest,CancelTask)63 TEST(DelayedTaskHandleTest, CancelTask) {
64   bool was_cancel_task_called = false;
65   auto delegate = std::make_unique<TestDelegate>(&was_cancel_task_called);
66   EXPECT_FALSE(was_cancel_task_called);
67   EXPECT_TRUE(delegate->IsValid());
68 
69   auto* delegate_ptr = delegate.get();
70   DelayedTaskHandle delayed_task_handle(std::move(delegate));
71   EXPECT_FALSE(was_cancel_task_called);
72   EXPECT_TRUE(delegate_ptr->IsValid());
73   EXPECT_TRUE(delayed_task_handle.IsValid());
74 
75   delayed_task_handle.CancelTask();
76 
77   EXPECT_TRUE(was_cancel_task_called);
78   EXPECT_FALSE(delayed_task_handle.IsValid());
79 }
80 
81 // Tests that calling CancelTask() on a handle with no delegate will no-op.
TEST(DelayedTaskHandleTest,CancelTaskNoDelegate)82 TEST(DelayedTaskHandleTest, CancelTaskNoDelegate) {
83   DelayedTaskHandle delayed_task_handle;
84   EXPECT_FALSE(delayed_task_handle.IsValid());
85 
86   delayed_task_handle.CancelTask();
87   EXPECT_FALSE(delayed_task_handle.IsValid());
88 }
89 
90 // Tests that calling CancelTask() on a handle with an invalid delegate doesn't
91 // crash and keeps the handle invalid.
TEST(DelayedTaskHandleTest,CancelTaskInvalidDelegate)92 TEST(DelayedTaskHandleTest, CancelTaskInvalidDelegate) {
93   bool was_cancel_task_called = false;
94   auto delegate = std::make_unique<TestDelegate>(&was_cancel_task_called);
95   EXPECT_FALSE(was_cancel_task_called);
96   EXPECT_TRUE(delegate->IsValid());
97 
98   auto* delegate_ptr = delegate.get();
99   DelayedTaskHandle delayed_task_handle(std::move(delegate));
100   EXPECT_FALSE(was_cancel_task_called);
101   EXPECT_TRUE(delegate_ptr->IsValid());
102   EXPECT_TRUE(delayed_task_handle.IsValid());
103 
104   delegate_ptr->CancelTask();
105 
106   EXPECT_TRUE(was_cancel_task_called);
107   EXPECT_FALSE(delegate_ptr->IsValid());
108   EXPECT_FALSE(delayed_task_handle.IsValid());
109 
110   // Reset |was_cancel_task_called| to ensure Delegate::CancelTask() is still
111   // invoked on an invalid delegate.
112   was_cancel_task_called = false;
113 
114   delayed_task_handle.CancelTask();
115 
116   EXPECT_TRUE(was_cancel_task_called);
117   EXPECT_FALSE(delayed_task_handle.IsValid());
118 }
119 
120 // Tests that invalidating the delegate will also invalidate the handle.
TEST(DelayedTaskHandleTest,InvalidateDelegate)121 TEST(DelayedTaskHandleTest, InvalidateDelegate) {
122   auto delegate = std::make_unique<TestDelegate>();
123   EXPECT_TRUE(delegate->IsValid());
124 
125   auto* delegate_ptr = delegate.get();
126   DelayedTaskHandle delayed_task_handle(std::move(delegate));
127   EXPECT_TRUE(delegate_ptr->IsValid());
128   EXPECT_TRUE(delayed_task_handle.IsValid());
129 
130   delegate_ptr->CancelTask();
131 
132   EXPECT_FALSE(delegate_ptr->IsValid());
133   EXPECT_FALSE(delayed_task_handle.IsValid());
134 }
135 
136 // Tests that destroying a valid handle will DCHECK.
TEST(DelayedTaskHandleTest,InvalidOnDestuction)137 TEST(DelayedTaskHandleTest, InvalidOnDestuction) {
138   auto delegate = std::make_unique<TestDelegate>();
139   EXPECT_TRUE(delegate->IsValid());
140 
141   auto* delegate_ptr = delegate.get();
142   EXPECT_DCHECK_DEATH({
143     DelayedTaskHandle delayed_task_handle(std::move(delegate));
144     EXPECT_TRUE(delegate_ptr->IsValid());
145     EXPECT_TRUE(delayed_task_handle.IsValid());
146   });
147 }
148 
149 // Tests the move-constructor.
TEST(DelayedTaskHandleTest,MoveConstructor)150 TEST(DelayedTaskHandleTest, MoveConstructor) {
151   auto delegate = std::make_unique<TestDelegate>();
152   EXPECT_TRUE(delegate->IsValid());
153 
154   auto* delegate_ptr = delegate.get();
155   DelayedTaskHandle delayed_task_handle(std::move(delegate));
156   EXPECT_TRUE(delegate_ptr->IsValid());
157   EXPECT_TRUE(delayed_task_handle.IsValid());
158 
159   DelayedTaskHandle other_delayed_task_handle(std::move(delayed_task_handle));
160   EXPECT_TRUE(delegate_ptr->IsValid());
161   EXPECT_TRUE(other_delayed_task_handle.IsValid());
162 
163   // Clean-up.
164   other_delayed_task_handle.CancelTask();
165 }
166 
167 // Tests the move-assignment.
TEST(DelayedTaskHandleTest,MoveAssignment)168 TEST(DelayedTaskHandleTest, MoveAssignment) {
169   auto delegate = std::make_unique<TestDelegate>();
170   EXPECT_TRUE(delegate->IsValid());
171 
172   auto* delegate_ptr = delegate.get();
173   DelayedTaskHandle delayed_task_handle(std::move(delegate));
174   EXPECT_TRUE(delegate_ptr->IsValid());
175   EXPECT_TRUE(delayed_task_handle.IsValid());
176 
177   DelayedTaskHandle other_delayed_task_handle;
178   EXPECT_FALSE(other_delayed_task_handle.IsValid());
179 
180   other_delayed_task_handle = std::move(delayed_task_handle);
181   EXPECT_TRUE(delegate_ptr->IsValid());
182   EXPECT_TRUE(other_delayed_task_handle.IsValid());
183 
184   // Clean-up.
185   other_delayed_task_handle.CancelTask();
186 }
187 
188 // Tests that assigning to a valid handle will DCHECK.
TEST(DelayedTaskHandleTest,AssignToValidHandle)189 TEST(DelayedTaskHandleTest, AssignToValidHandle) {
190   auto delegate = std::make_unique<TestDelegate>();
191   EXPECT_TRUE(delegate->IsValid());
192 
193   auto* delegate_ptr = delegate.get();
194   DelayedTaskHandle delayed_task_handle(std::move(delegate));
195   EXPECT_TRUE(delegate_ptr->IsValid());
196   EXPECT_TRUE(delayed_task_handle.IsValid());
197 
198   EXPECT_DCHECK_DEATH({ delayed_task_handle = DelayedTaskHandle(); });
199 
200   // Clean-up.
201   delayed_task_handle.CancelTask();
202 }
203 
204 }  // namespace base
205