xref: /aosp_15_r20/external/cronet/base/barrier_callback_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2021 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/barrier_callback.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
12*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
13*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker namespace {
16*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierCallbackTest,RunsImmediatelyForZeroCallbacks)17*6777b538SAndroid Build Coastguard Worker TEST(BarrierCallbackTest, RunsImmediatelyForZeroCallbacks) {
18*6777b538SAndroid Build Coastguard Worker   bool done = false;
19*6777b538SAndroid Build Coastguard Worker   auto barrier_callback = base::BarrierCallback<int>(
20*6777b538SAndroid Build Coastguard Worker       0, base::BindLambdaForTesting([&done](std::vector<int> results) {
21*6777b538SAndroid Build Coastguard Worker         EXPECT_THAT(results, testing::IsEmpty());
22*6777b538SAndroid Build Coastguard Worker         done = true;
23*6777b538SAndroid Build Coastguard Worker       }));
24*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(done);
25*6777b538SAndroid Build Coastguard Worker }
26*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierCallbackTest,ErrorToCallCallbackWithZeroCallbacks)27*6777b538SAndroid Build Coastguard Worker TEST(BarrierCallbackTest, ErrorToCallCallbackWithZeroCallbacks) {
28*6777b538SAndroid Build Coastguard Worker   auto barrier_callback =
29*6777b538SAndroid Build Coastguard Worker       base::BarrierCallback<int>(0, base::BindOnce([](std::vector<int>) {}));
30*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(barrier_callback.is_null());
31*6777b538SAndroid Build Coastguard Worker 
32*6777b538SAndroid Build Coastguard Worker   EXPECT_CHECK_DEATH(barrier_callback.Run(3));
33*6777b538SAndroid Build Coastguard Worker }
34*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierCallbackTest,RunAfterNumCallbacks)35*6777b538SAndroid Build Coastguard Worker TEST(BarrierCallbackTest, RunAfterNumCallbacks) {
36*6777b538SAndroid Build Coastguard Worker   bool done = false;
37*6777b538SAndroid Build Coastguard Worker   auto barrier_callback = base::BarrierCallback<int>(
38*6777b538SAndroid Build Coastguard Worker       3, base::BindLambdaForTesting([&done](std::vector<int> results) {
39*6777b538SAndroid Build Coastguard Worker         EXPECT_THAT(results, testing::ElementsAre(1, 3, 2));
40*6777b538SAndroid Build Coastguard Worker         done = true;
41*6777b538SAndroid Build Coastguard Worker       }));
42*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(done);
43*6777b538SAndroid Build Coastguard Worker 
44*6777b538SAndroid Build Coastguard Worker   barrier_callback.Run(1);
45*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(done);
46*6777b538SAndroid Build Coastguard Worker 
47*6777b538SAndroid Build Coastguard Worker   barrier_callback.Run(3);
48*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(done);
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker   barrier_callback.Run(2);
51*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(done);
52*6777b538SAndroid Build Coastguard Worker }
53*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierCallbackTest,CopiesShareState)54*6777b538SAndroid Build Coastguard Worker TEST(BarrierCallbackTest, CopiesShareState) {
55*6777b538SAndroid Build Coastguard Worker   bool done = false;
56*6777b538SAndroid Build Coastguard Worker   const auto barrier_callback = base::BarrierCallback<int>(
57*6777b538SAndroid Build Coastguard Worker       3, base::BindLambdaForTesting([&done](std::vector<int> results) {
58*6777b538SAndroid Build Coastguard Worker         EXPECT_THAT(results, testing::ElementsAre(1, 3, 2));
59*6777b538SAndroid Build Coastguard Worker         done = true;
60*6777b538SAndroid Build Coastguard Worker       }));
61*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(done);
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker   const auto barrier_copy1 = barrier_callback;
64*6777b538SAndroid Build Coastguard Worker   const auto barrier_copy2 = barrier_callback;
65*6777b538SAndroid Build Coastguard Worker   const auto barrier_copy3 = barrier_callback;
66*6777b538SAndroid Build Coastguard Worker 
67*6777b538SAndroid Build Coastguard Worker   barrier_copy1.Run(1);
68*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(done);
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker   barrier_copy2.Run(3);
71*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(done);
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker   barrier_copy3.Run(2);
74*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(done);
75*6777b538SAndroid Build Coastguard Worker }
76*6777b538SAndroid Build Coastguard Worker 
77*6777b538SAndroid Build Coastguard Worker template <typename... Args>
78*6777b538SAndroid Build Coastguard Worker class DestructionIndicator {
79*6777b538SAndroid Build Coastguard Worker  public:
80*6777b538SAndroid Build Coastguard Worker   // Sets `*destructed` to true in destructor.
DestructionIndicator(bool * destructed)81*6777b538SAndroid Build Coastguard Worker   explicit DestructionIndicator(bool* destructed) : destructed_(destructed) {
82*6777b538SAndroid Build Coastguard Worker     *destructed_ = false;
83*6777b538SAndroid Build Coastguard Worker   }
84*6777b538SAndroid Build Coastguard Worker 
~DestructionIndicator()85*6777b538SAndroid Build Coastguard Worker   ~DestructionIndicator() { *destructed_ = true; }
86*6777b538SAndroid Build Coastguard Worker 
DoNothing(Args...)87*6777b538SAndroid Build Coastguard Worker   void DoNothing(Args...) {}
88*6777b538SAndroid Build Coastguard Worker 
89*6777b538SAndroid Build Coastguard Worker  private:
90*6777b538SAndroid Build Coastguard Worker   raw_ptr<bool> destructed_;
91*6777b538SAndroid Build Coastguard Worker };
92*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierCallbackTest,ReleasesDoneCallbackWhenDone)93*6777b538SAndroid Build Coastguard Worker TEST(BarrierCallbackTest, ReleasesDoneCallbackWhenDone) {
94*6777b538SAndroid Build Coastguard Worker   bool done_destructed = false;
95*6777b538SAndroid Build Coastguard Worker   auto barrier_callback = base::BarrierCallback<bool>(
96*6777b538SAndroid Build Coastguard Worker       1,
97*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&DestructionIndicator<std::vector<bool>>::DoNothing,
98*6777b538SAndroid Build Coastguard Worker                      std::make_unique<DestructionIndicator<std::vector<bool>>>(
99*6777b538SAndroid Build Coastguard Worker                          &done_destructed)));
100*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(done_destructed);
101*6777b538SAndroid Build Coastguard Worker   barrier_callback.Run(true);
102*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(done_destructed);
103*6777b538SAndroid Build Coastguard Worker }
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker // Tests a case when `done_callback` resets the `barrier_callback`.
106*6777b538SAndroid Build Coastguard Worker // `barrier_callback` is a RepeatingCallback holding the `done_callback`.
107*6777b538SAndroid Build Coastguard Worker // `done_callback` holds a reference back to the `barrier_callback`. When
108*6777b538SAndroid Build Coastguard Worker // `barrier_callback` is Run() it calls `done_callback` which erases the
109*6777b538SAndroid Build Coastguard Worker // `barrier_callback` while still inside of its Run(). The Run() implementation
110*6777b538SAndroid Build Coastguard Worker // (in base::BarrierCallback) must not try use itself after executing
111*6777b538SAndroid Build Coastguard Worker // ResetBarrierCallback() or this test would crash inside Run().
TEST(BarrierCallbackTest,KeepingCallbackAliveUntilDone)112*6777b538SAndroid Build Coastguard Worker TEST(BarrierCallbackTest, KeepingCallbackAliveUntilDone) {
113*6777b538SAndroid Build Coastguard Worker   base::RepeatingCallback<void(bool)> barrier_callback;
114*6777b538SAndroid Build Coastguard Worker   barrier_callback = base::BarrierCallback<bool>(
115*6777b538SAndroid Build Coastguard Worker       1, base::BindLambdaForTesting(
116*6777b538SAndroid Build Coastguard Worker              [&barrier_callback](std::vector<bool> results) {
117*6777b538SAndroid Build Coastguard Worker                barrier_callback = base::RepeatingCallback<void(bool)>();
118*6777b538SAndroid Build Coastguard Worker                EXPECT_THAT(results, testing::ElementsAre(true));
119*6777b538SAndroid Build Coastguard Worker              }));
120*6777b538SAndroid Build Coastguard Worker   barrier_callback.Run(true);
121*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(barrier_callback.is_null());
122*6777b538SAndroid Build Coastguard Worker }
123*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierCallbackTest,SupportsMoveonlyTypes)124*6777b538SAndroid Build Coastguard Worker TEST(BarrierCallbackTest, SupportsMoveonlyTypes) {
125*6777b538SAndroid Build Coastguard Worker   class MoveOnly {
126*6777b538SAndroid Build Coastguard Worker    public:
127*6777b538SAndroid Build Coastguard Worker     MoveOnly() = default;
128*6777b538SAndroid Build Coastguard Worker     MoveOnly(MoveOnly&&) = default;
129*6777b538SAndroid Build Coastguard Worker     MoveOnly& operator=(MoveOnly&&) = default;
130*6777b538SAndroid Build Coastguard Worker   };
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker   // No need to assert anything here, since if BarrierCallback didn't work with
133*6777b538SAndroid Build Coastguard Worker   // move-only types, this wouldn't compile.
134*6777b538SAndroid Build Coastguard Worker   auto barrier_callback = base::BarrierCallback<MoveOnly>(
135*6777b538SAndroid Build Coastguard Worker       1, base::BindOnce([](std::vector<MoveOnly>) {}));
136*6777b538SAndroid Build Coastguard Worker   barrier_callback.Run(MoveOnly());
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker   auto barrier_callback2 = base::BarrierCallback<MoveOnly>(
139*6777b538SAndroid Build Coastguard Worker       1, base::BindOnce([](const std::vector<MoveOnly>&) {}));
140*6777b538SAndroid Build Coastguard Worker   barrier_callback2.Run(MoveOnly());
141*6777b538SAndroid Build Coastguard Worker }
142*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierCallbackTest,SupportsConstRefResults)143*6777b538SAndroid Build Coastguard Worker TEST(BarrierCallbackTest, SupportsConstRefResults) {
144*6777b538SAndroid Build Coastguard Worker   auto barrier_callback = base::BarrierCallback<int>(
145*6777b538SAndroid Build Coastguard Worker       1, base::BindOnce([](const std::vector<int>&) {}));
146*6777b538SAndroid Build Coastguard Worker 
147*6777b538SAndroid Build Coastguard Worker   barrier_callback.Run(1);
148*6777b538SAndroid Build Coastguard Worker }
149*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierCallbackTest,SupportsReferenceTypes)150*6777b538SAndroid Build Coastguard Worker TEST(BarrierCallbackTest, SupportsReferenceTypes) {
151*6777b538SAndroid Build Coastguard Worker   class Referenceable {
152*6777b538SAndroid Build Coastguard Worker     // Must be copyable.
153*6777b538SAndroid Build Coastguard Worker   };
154*6777b538SAndroid Build Coastguard Worker   Referenceable ref;
155*6777b538SAndroid Build Coastguard Worker 
156*6777b538SAndroid Build Coastguard Worker   // No need to assert anything here, since if BarrierCallback didn't work with
157*6777b538SAndroid Build Coastguard Worker   // by-reference args, this wouldn't compile.
158*6777b538SAndroid Build Coastguard Worker   auto barrier_callback = base::BarrierCallback<const Referenceable&>(
159*6777b538SAndroid Build Coastguard Worker       1, base::BindOnce([](std::vector<Referenceable>) {}));
160*6777b538SAndroid Build Coastguard Worker   barrier_callback.Run(ref);
161*6777b538SAndroid Build Coastguard Worker 
162*6777b538SAndroid Build Coastguard Worker   auto barrier_callback2 = base::BarrierCallback<const Referenceable&>(
163*6777b538SAndroid Build Coastguard Worker       1, base::BindOnce([](const std::vector<Referenceable>&) {}));
164*6777b538SAndroid Build Coastguard Worker   barrier_callback2.Run(ref);
165*6777b538SAndroid Build Coastguard Worker }
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker }  // namespace
168