1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
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 <lib/fit/promise.h>
6 #include <unittest/unittest.h>
7
8 #include "unittest_utils.h"
9
10 namespace {
11
12 class fake_context : public fit::context {
13 public:
executor() const14 fit::executor* executor() const override {
15 ASSERT_CRITICAL(false);
16 }
suspend_task()17 fit::suspended_task suspend_task() override {
18 ASSERT_CRITICAL(false);
19 }
20 };
21
empty_future()22 bool empty_future() {
23 BEGIN_TEST;
24
25 fake_context context;
26
27 {
28 fit::future<> nihil;
29 EXPECT_EQ(fit::future_state::empty, nihil.state());
30 EXPECT_FALSE(nihil);
31 EXPECT_TRUE(nihil.is_empty());
32 EXPECT_FALSE(nihil.is_pending());
33 EXPECT_FALSE(nihil.is_ok());
34 EXPECT_FALSE(nihil.is_error());
35 EXPECT_FALSE(nihil.is_ready());
36 EXPECT_FALSE(nihil(context));
37
38 EXPECT_TRUE(nihil == nullptr);
39 EXPECT_TRUE(nullptr == nihil);
40 EXPECT_FALSE(nihil != nullptr);
41 EXPECT_FALSE(nullptr != nihil);
42 }
43
44 {
45 fit::future<> nihil(nullptr);
46 EXPECT_EQ(fit::future_state::empty, nihil.state());
47 EXPECT_FALSE(nihil);
48 EXPECT_TRUE(nihil.is_empty());
49 EXPECT_FALSE(nihil.is_pending());
50 EXPECT_FALSE(nihil.is_ok());
51 EXPECT_FALSE(nihil.is_error());
52 EXPECT_FALSE(nihil.is_ready());
53 EXPECT_FALSE(nihil(context));
54 }
55
56 {
57 fit::future<> nihil(fit::promise<>(nullptr));
58 EXPECT_EQ(fit::future_state::empty, nihil.state());
59 EXPECT_FALSE(nihil);
60 EXPECT_TRUE(nihil.is_empty());
61 EXPECT_FALSE(nihil.is_pending());
62 EXPECT_FALSE(nihil.is_ok());
63 EXPECT_FALSE(nihil.is_error());
64 EXPECT_FALSE(nihil.is_ready());
65 EXPECT_FALSE(nihil(context));
66 }
67
68 {
69 fit::future<> nihil(fit::pending());
70 EXPECT_EQ(fit::future_state::empty, nihil.state());
71 EXPECT_FALSE(nihil);
72 EXPECT_TRUE(nihil.is_empty());
73 EXPECT_FALSE(nihil.is_pending());
74 EXPECT_FALSE(nihil.is_ok());
75 EXPECT_FALSE(nihil.is_error());
76 EXPECT_FALSE(nihil.is_ready());
77 EXPECT_FALSE(nihil(context));
78 }
79
80 END_TEST;
81 }
82
pending_future()83 bool pending_future() {
84 BEGIN_TEST;
85
86 fake_context context;
87
88 uint64_t run_count = 0;
89 fit::future<int, int> fut(fit::make_promise([&](fit::context& context)
90 -> fit::result<int, int> {
91 if (++run_count == 3)
92 return fit::ok(42);
93 return fit::pending();
94 }));
95 EXPECT_EQ(fit::future_state::pending, fut.state());
96 EXPECT_TRUE(fut);
97 EXPECT_FALSE(fut.is_empty());
98 EXPECT_TRUE(fut.is_pending());
99 EXPECT_FALSE(fut.is_ok());
100 EXPECT_FALSE(fut.is_error());
101 EXPECT_FALSE(fut.is_ready());
102
103 EXPECT_FALSE(fut == nullptr);
104 EXPECT_FALSE(nullptr == fut);
105 EXPECT_TRUE(fut != nullptr);
106 EXPECT_TRUE(nullptr != fut);
107
108 // evaluate the future
109 EXPECT_FALSE(fut(context));
110 EXPECT_EQ(1, run_count);
111 EXPECT_FALSE(fut(context));
112 EXPECT_EQ(2, run_count);
113 EXPECT_TRUE(fut(context));
114 EXPECT_EQ(3, run_count);
115
116 // check the result
117 EXPECT_EQ(fit::future_state::ok, fut.state());
118 EXPECT_EQ(fit::result_state::ok, fut.result().state());
119 EXPECT_EQ(42, fut.result().value());
120
121 // do something similar but this time produce an error to ensure
122 // that this state change works as expected too
123 fut = fit::make_promise([&](fit::context& context)
124 -> fit::result<int, int> {
125 if (++run_count == 5)
126 return fit::error(42);
127 return fit::pending();
128 });
129 EXPECT_EQ(fit::future_state::pending, fut.state());
130 EXPECT_FALSE(fut(context));
131 EXPECT_EQ(4, run_count);
132 EXPECT_TRUE(fut(context));
133 EXPECT_EQ(5, run_count);
134 EXPECT_EQ(fit::future_state::error, fut.state());
135 EXPECT_EQ(fit::result_state::error, fut.result().state());
136 EXPECT_EQ(42, fut.result().error());
137
138 END_TEST;
139 }
140
ok_future()141 bool ok_future() {
142 BEGIN_TEST;
143
144 fake_context context;
145 fit::future<int> fut(fit::ok(42));
146 EXPECT_EQ(fit::future_state::ok, fut.state());
147 EXPECT_TRUE(fut);
148 EXPECT_FALSE(fut.is_empty());
149 EXPECT_FALSE(fut.is_pending());
150 EXPECT_TRUE(fut.is_ok());
151 EXPECT_FALSE(fut.is_error());
152 EXPECT_TRUE(fut.is_ready());
153 EXPECT_TRUE(fut(context));
154
155 EXPECT_FALSE(fut == nullptr);
156 EXPECT_FALSE(nullptr == fut);
157 EXPECT_TRUE(fut != nullptr);
158 EXPECT_TRUE(nullptr != fut);
159
160 // non-destructive access
161 EXPECT_EQ(fit::result_state::ok, fut.result().state());
162 EXPECT_EQ(42, fut.result().value());
163 EXPECT_EQ(42, fut.value());
164
165 // destructive access
166 fut = fit::ok(43);
167 EXPECT_EQ(fit::future_state::ok, fut.state());
168 EXPECT_EQ(43, fut.take_result().value());
169 EXPECT_EQ(fit::future_state::empty, fut.state());
170
171 fut = fit::ok(44);
172 EXPECT_EQ(fit::future_state::ok, fut.state());
173 EXPECT_EQ(44, fut.take_value());
174 EXPECT_EQ(fit::future_state::empty, fut.state());
175
176 fut = fit::ok(45);
177 EXPECT_EQ(fit::future_state::ok, fut.state());
178 EXPECT_EQ(45, fut.take_ok_result().value);
179 EXPECT_EQ(fit::future_state::empty, fut.state());
180
181 END_TEST;
182 }
183
error_future()184 bool error_future() {
185 BEGIN_TEST;
186
187 fake_context context;
188 fit::future<void, int> fut(fit::error(42));
189 EXPECT_EQ(fit::future_state::error, fut.state());
190 EXPECT_TRUE(fut);
191 EXPECT_FALSE(fut.is_empty());
192 EXPECT_FALSE(fut.is_pending());
193 EXPECT_FALSE(fut.is_ok());
194 EXPECT_TRUE(fut.is_error());
195 EXPECT_TRUE(fut.is_ready());
196 EXPECT_TRUE(fut(context));
197
198 EXPECT_FALSE(fut == nullptr);
199 EXPECT_FALSE(nullptr == fut);
200 EXPECT_TRUE(fut != nullptr);
201 EXPECT_TRUE(nullptr != fut);
202
203 // non-destructive access
204 EXPECT_EQ(fit::result_state::error, fut.result().state());
205 EXPECT_EQ(42, fut.result().error());
206 EXPECT_EQ(42, fut.error());
207
208 // destructive access
209 fut = fit::error(43);
210 EXPECT_EQ(fit::future_state::error, fut.state());
211 EXPECT_EQ(43, fut.take_result().error());
212 EXPECT_EQ(fit::future_state::empty, fut.state());
213
214 fut = fit::error(44);
215 EXPECT_EQ(fit::future_state::error, fut.state());
216 EXPECT_EQ(44, fut.take_error());
217 EXPECT_EQ(fit::future_state::empty, fut.state());
218
219 fut = fit::error(45);
220 EXPECT_EQ(fit::future_state::error, fut.state());
221 EXPECT_EQ(45, fut.take_error_result().error);
222 EXPECT_EQ(fit::future_state::empty, fut.state());
223
224 END_TEST;
225 }
226
assignment_and_swap()227 bool assignment_and_swap() {
228 BEGIN_TEST;
229
230 fit::future<> x;
231 EXPECT_EQ(fit::future_state::empty, x.state());
232
233 x = fit::ok();
234 EXPECT_EQ(fit::future_state::ok, x.state());
235
236 x = fit::error();
237 EXPECT_EQ(fit::future_state::error, x.state());
238
239 x = fit::pending();
240 EXPECT_EQ(fit::future_state::empty, x.state());
241
242 x = nullptr;
243 EXPECT_EQ(fit::future_state::empty, x.state());
244
245 x = fit::promise<>();
246 EXPECT_EQ(fit::future_state::empty, x.state());
247
248 x = fit::make_promise([] {});
249 EXPECT_EQ(fit::future_state::pending, x.state());
250
251 fit::future<> y(std::move(x));
252 EXPECT_EQ(fit::future_state::pending, y.state());
253 EXPECT_EQ(fit::future_state::empty, x.state());
254
255 x.swap(y);
256 EXPECT_EQ(fit::future_state::pending, x.state());
257 EXPECT_EQ(fit::future_state::empty, y.state());
258
259 x.swap(x);
260 EXPECT_EQ(fit::future_state::pending, x.state());
261
262 END_TEST;
263 }
264
make_future()265 bool make_future() {
266 BEGIN_TEST;
267
268 fake_context context;
269 uint64_t run_count = 0;
270 auto fut = fit::make_future(fit::make_promise([&] {
271 run_count++;
272 return fit::ok(42);
273 }));
274 EXPECT_TRUE(fut(context));
275 EXPECT_EQ(42, fut.value());
276
277 END_TEST;
278 }
279
280 // Ensure that fit::future is considered nullable so that there is
281 // consistency with the fact that it can be initialized and assigned from
282 // nullptr similar to fit::function.
283 static_assert(fit::is_nullable<fit::future<>>::value, "");
284
285 } // namespace
286
287 BEGIN_TEST_CASE(future_tests)
288 RUN_TEST(empty_future)
289 RUN_TEST(pending_future)
290 RUN_TEST(ok_future)
291 RUN_TEST(error_future)
292 RUN_TEST(assignment_and_swap)
293 RUN_TEST(make_future)
294 END_TEST_CASE(future_tests)
295