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