xref: /aosp_15_r20/external/cronet/base/functional/concurrent_callbacks_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2024 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/functional/concurrent_callbacks.h"
6 
7 #include <vector>
8 
9 #include "base/functional/callback.h"
10 #include "base/test/gtest_util.h"
11 #include "base/test/task_environment.h"
12 #include "base/test/test_future.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace base {
16 
17 namespace {
18 
TEST(ConcurrentCallbacksTest,Empty)19 TEST(ConcurrentCallbacksTest, Empty) {
20   test::SingleThreadTaskEnvironment task_environment;
21 
22   ConcurrentCallbacks<size_t> concurrent;
23 
24   test::TestFuture<std::vector<size_t>> future;
25   std::move(concurrent).Done(future.GetCallback());
26 
27   std::vector<size_t> values = future.Take();
28   EXPECT_TRUE(values.empty());
29 }
30 
TEST(ConcurrentCallbacksTest,RunBeforeDone)31 TEST(ConcurrentCallbacksTest, RunBeforeDone) {
32   test::SingleThreadTaskEnvironment task_environment;
33 
34   ConcurrentCallbacks<size_t> concurrent;
35 
36   for (size_t i = 0; i < 10; ++i) {
37     concurrent.CreateCallback().Run(i);
38   }
39 
40   test::TestFuture<std::vector<size_t>> future;
41   std::move(concurrent).Done(future.GetCallback());
42 
43   EXPECT_FALSE(future.IsReady());
44 
45   std::vector<size_t> values = future.Take();
46   EXPECT_EQ(values.size(), 10u);
47   for (size_t i = 0; i < values.size(); ++i) {
48     EXPECT_EQ(values[i], i);
49   }
50 }
51 
TEST(ConcurrentCallbacksTest,RunAfterDone)52 TEST(ConcurrentCallbacksTest, RunAfterDone) {
53   test::SingleThreadTaskEnvironment task_environment;
54 
55   ConcurrentCallbacks<size_t> concurrent;
56 
57   std::vector<base::OnceCallback<void(size_t)>> callbacks;
58   for (size_t i = 0; i < 10; ++i) {
59     callbacks.push_back(concurrent.CreateCallback());
60   }
61 
62   test::TestFuture<std::vector<size_t>> future;
63   std::move(concurrent).Done(future.GetCallback());
64 
65   for (size_t i = 0; i < callbacks.size(); ++i) {
66     std::move(callbacks[i]).Run(i);
67   }
68 
69   EXPECT_FALSE(future.IsReady());
70 
71   std::vector<size_t> values = future.Take();
72   EXPECT_EQ(values.size(), 10u);
73   for (size_t i = 0; i < values.size(); ++i) {
74     EXPECT_EQ(values[i], i);
75   }
76 }
77 
TEST(ConcurrentCallbacksTest,CallbacksOutliveObject)78 TEST(ConcurrentCallbacksTest, CallbacksOutliveObject) {
79   test::SingleThreadTaskEnvironment task_environment;
80 
81   std::vector<base::OnceCallback<void(size_t)>> callbacks;
82   test::TestFuture<std::vector<size_t>> future;
83 
84   {
85     ConcurrentCallbacks<size_t> concurrent;
86     for (size_t i = 0; i < 10; ++i) {
87       callbacks.push_back(concurrent.CreateCallback());
88     }
89     std::move(concurrent).Done(future.GetCallback());
90   }
91 
92   for (size_t i = 0; i < callbacks.size(); ++i) {
93     std::move(callbacks[i]).Run(i);
94   }
95 
96   EXPECT_FALSE(future.IsReady());
97 
98   std::vector<size_t> values = future.Take();
99   EXPECT_EQ(values.size(), 10u);
100   for (size_t i = 0; i < values.size(); ++i) {
101     EXPECT_EQ(values[i], i);
102   }
103 }
104 
TEST(ConcurrentCallbacksTest,CallbackAcceptsConstRef)105 TEST(ConcurrentCallbacksTest, CallbackAcceptsConstRef) {
106   test::SingleThreadTaskEnvironment task_environment;
107 
108   ConcurrentCallbacks<const size_t&> concurrent;
109 
110   std::vector<base::OnceCallback<void(const size_t&)>> callbacks;
111   for (size_t i = 0; i < 10; ++i) {
112     callbacks.push_back(concurrent.CreateCallback());
113   }
114 
115   test::TestFuture<std::vector<size_t>> future;
116   std::move(concurrent).Done(future.GetCallback());
117 
118   for (size_t i = 0; i < callbacks.size(); ++i) {
119     std::move(callbacks[i]).Run(i);
120   }
121 
122   EXPECT_FALSE(future.IsReady());
123 
124   std::vector<size_t> values = future.Take();
125   EXPECT_EQ(values.size(), 10u);
126   for (size_t i = 0; i < values.size(); ++i) {
127     EXPECT_EQ(values[i], i);
128   }
129 }
130 
131 }  // namespace
132 
133 }  // namespace base
134