s/valueTry/getTry/
[folly.git] / folly / wangle / test / FutureTest.cpp
1 /*
2  * Copyright 2014 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <algorithm>
18 #include <folly/small_vector.h>
19 #include <gtest/gtest.h>
20 #include <memory>
21 #include <string>
22 #include <type_traits>
23 #include <unistd.h>
24 #include "folly/wangle/Executor.h"
25 #include "folly/wangle/Future.h"
26
27 using namespace folly::wangle;
28 using std::pair;
29 using std::string;
30 using std::unique_ptr;
31 using std::vector;
32
33 #define EXPECT_TYPE(x, T) \
34   EXPECT_TRUE((std::is_same<decltype(x), T>::value))
35
36 typedef WangleException eggs_t;
37 static eggs_t eggs("eggs");
38
39 // Future
40
41 TEST(Future, try) {
42   class A {
43    public:
44     A(int x) : x_(x) {}
45
46     int x() const {
47       return x_;
48     }
49    private:
50     int x_;
51   };
52
53   A a(5);
54   Try<A> t_a(std::move(a));
55
56   Try<void> t_void;
57
58   EXPECT_EQ(5, t_a.value().x());
59 }
60
61 TEST(Future, special) {
62   EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
63   EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
64   EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
65   EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
66 }
67
68 TEST(Future, then) {
69   bool flag = false;
70
71   makeFuture<int>(42).then([&](Try<int>&& t) {
72                               flag = true;
73                               EXPECT_EQ(42, t.value());
74                             });
75   EXPECT_TRUE(flag); flag = false;
76
77   makeFuture<int>(42)
78     .then([](Try<int>&& t) { return t.value(); })
79     .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
80   EXPECT_TRUE(flag); flag = false;
81
82   makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
83   EXPECT_TRUE(flag); flag = false;
84
85   Promise<void> p;
86   auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
87   EXPECT_FALSE(flag);
88   EXPECT_FALSE(f.isReady());
89   p.setValue();
90   EXPECT_TRUE(flag);
91   EXPECT_TRUE(f.isReady());
92 }
93
94 TEST(Future, value) {
95   auto f = makeFuture(unique_ptr<int>(new int(42)));
96   auto up = std::move(f.value());
97   EXPECT_EQ(42, *up);
98
99   EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
100 }
101
102 TEST(Future, isReady) {
103   Promise<int> p;
104   auto f = p.getFuture();
105   EXPECT_FALSE(f.isReady());
106   p.setValue(42);
107   EXPECT_TRUE(f.isReady());
108   }
109
110 TEST(Future, hasException) {
111   EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
112   EXPECT_FALSE(makeFuture(42).getTry().hasException());
113 }
114
115 TEST(Future, hasValue) {
116   EXPECT_TRUE(makeFuture(42).getTry().hasValue());
117   EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
118 }
119
120 TEST(Future, makeFuture) {
121   EXPECT_TYPE(makeFuture(42), Future<int>);
122   EXPECT_EQ(42, makeFuture(42).value());
123
124   EXPECT_TYPE(makeFuture<float>(42), Future<float>);
125   EXPECT_EQ(42, makeFuture<float>(42).value());
126
127   auto fun = [] { return 42; };
128   EXPECT_TYPE(makeFutureTry(fun), Future<int>);
129   EXPECT_EQ(42, makeFutureTry(fun).value());
130
131   auto failfun = []() -> int { throw eggs; };
132   EXPECT_TYPE(makeFutureTry(failfun), Future<int>);
133   EXPECT_THROW(makeFutureTry(failfun).value(), eggs_t);
134
135   EXPECT_TYPE(makeFuture(), Future<void>);
136 }
137
138 // Promise
139
140 TEST(Promise, special) {
141   EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
142   EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
143   EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
144   EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
145 }
146
147 TEST(Promise, getFuture) {
148   Promise<int> p;
149   Future<int> f = p.getFuture();
150   EXPECT_FALSE(f.isReady());
151 }
152
153 TEST(Promise, setValue) {
154   Promise<int> fund;
155   auto ffund = fund.getFuture();
156   fund.setValue(42);
157   EXPECT_EQ(42, ffund.value());
158
159   struct Foo {
160     string name;
161     int value;
162   };
163
164   Promise<Foo> pod;
165   auto fpod = pod.getFuture();
166   Foo f = {"the answer", 42};
167   pod.setValue(f);
168   Foo f2 = fpod.value();
169   EXPECT_EQ(f.name, f2.name);
170   EXPECT_EQ(f.value, f2.value);
171
172   pod = Promise<Foo>();
173   fpod = pod.getFuture();
174   return;
175   pod.setValue(std::move(f2));
176   Foo f3 = fpod.value();
177   EXPECT_EQ(f.name, f3.name);
178   EXPECT_EQ(f.value, f3.value);
179   EXPECT_NE(f.name, f2.name);
180
181   return;
182
183   Promise<unique_ptr<int>> mov;
184   auto fmov = mov.getFuture();
185   mov.setValue(unique_ptr<int>(new int(42)));
186   unique_ptr<int> ptr = std::move(fmov.value());
187   EXPECT_EQ(42, *ptr);
188
189   Promise<void> v;
190   auto fv = v.getFuture();
191   v.setValue();
192   EXPECT_TRUE(fv.isReady());
193 }
194
195 TEST(Promise, setException) {
196   {
197     Promise<void> p;
198     auto f = p.getFuture();
199     p.setException(eggs);
200     EXPECT_THROW(f.value(), eggs_t);
201   }
202   {
203     Promise<void> p;
204     auto f = p.getFuture();
205     try {
206       throw eggs;
207     } catch (...) {
208       p.setException(std::current_exception());
209     }
210     EXPECT_THROW(f.value(), eggs_t);
211   }
212 }
213
214 TEST(Promise, fulfil) {
215   {
216     Promise<int> p;
217     auto f = p.getFuture();
218     p.fulfil([] { return 42; });
219     EXPECT_EQ(42, f.value());
220   }
221   {
222     Promise<int> p;
223     auto f = p.getFuture();
224     p.fulfil([]() -> int { throw eggs; });
225     EXPECT_THROW(f.value(), eggs_t);
226   }
227 }
228
229 TEST(Future, finish) {
230   auto x = std::make_shared<int>(0);
231   Promise<int> p;
232   auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
233
234   // The continuation hasn't executed
235   EXPECT_EQ(0, *x);
236
237   // The continuation has a reference to x
238   EXPECT_EQ(2, x.use_count());
239
240   p.setValue(42);
241
242   // the continuation has executed
243   EXPECT_EQ(42, *x);
244
245   // the continuation has been destructed
246   // and has released its reference to x
247   EXPECT_EQ(1, x.use_count());
248 }
249
250 TEST(Future, unwrap) {
251   Promise<int> a;
252   Promise<int> b;
253
254   auto fa = a.getFuture();
255   auto fb = b.getFuture();
256
257   bool flag1 = false;
258   bool flag2 = false;
259
260   // do a, then do b, and get the result of a + b.
261   Future<int> f = fa.then([&](Try<int>&& ta) {
262     auto va = ta.value();
263     flag1 = true;
264     return fb.then([va, &flag2](Try<int>&& tb) {
265       flag2 = true;
266       return va + tb.value();
267     });
268   });
269
270   EXPECT_FALSE(flag1);
271   EXPECT_FALSE(flag2);
272   EXPECT_FALSE(f.isReady());
273
274   a.setValue(3);
275   EXPECT_TRUE(flag1);
276   EXPECT_FALSE(flag2);
277   EXPECT_FALSE(f.isReady());
278
279   b.setValue(4);
280   EXPECT_TRUE(flag1);
281   EXPECT_TRUE(flag2);
282   EXPECT_EQ(7, f.value());
283 }
284
285 TEST(Future, whenAll) {
286   // returns a vector variant
287   {
288     vector<Promise<int>> promises(10);
289     vector<Future<int>> futures;
290
291     for (auto& p : promises)
292       futures.push_back(p.getFuture());
293
294     auto allf = whenAll(futures.begin(), futures.end());
295
296     random_shuffle(promises.begin(), promises.end());
297     for (auto& p : promises) {
298       EXPECT_FALSE(allf.isReady());
299       p.setValue(42);
300     }
301
302     EXPECT_TRUE(allf.isReady());
303     auto& results = allf.value();
304     for (auto& t : results) {
305       EXPECT_EQ(42, t.value());
306     }
307   }
308
309   // check error semantics
310   {
311     vector<Promise<int>> promises(4);
312     vector<Future<int>> futures;
313
314     for (auto& p : promises)
315       futures.push_back(p.getFuture());
316
317     auto allf = whenAll(futures.begin(), futures.end());
318
319
320     promises[0].setValue(42);
321     promises[1].setException(eggs);
322
323     EXPECT_FALSE(allf.isReady());
324
325     promises[2].setValue(42);
326
327     EXPECT_FALSE(allf.isReady());
328
329     promises[3].setException(eggs);
330
331     EXPECT_TRUE(allf.isReady());
332     EXPECT_FALSE(allf.getTry().hasException());
333
334     auto& results = allf.value();
335     EXPECT_EQ(42, results[0].value());
336     EXPECT_TRUE(results[1].hasException());
337     EXPECT_EQ(42, results[2].value());
338     EXPECT_TRUE(results[3].hasException());
339   }
340
341   // check that futures are ready in then()
342   {
343     vector<Promise<void>> promises(10);
344     vector<Future<void>> futures;
345
346     for (auto& p : promises)
347       futures.push_back(p.getFuture());
348
349     auto allf = whenAll(futures.begin(), futures.end())
350       .then([](Try<vector<Try<void>>>&& ts) {
351         for (auto& f : ts.value())
352           f.value();
353       });
354
355     random_shuffle(promises.begin(), promises.end());
356     for (auto& p : promises)
357       p.setValue();
358     EXPECT_TRUE(allf.isReady());
359   }
360 }
361
362
363 TEST(Future, whenAny) {
364   {
365     vector<Promise<int>> promises(10);
366     vector<Future<int>> futures;
367
368     for (auto& p : promises)
369       futures.push_back(p.getFuture());
370
371     for (auto& f : futures) {
372       EXPECT_FALSE(f.isReady());
373     }
374
375     auto anyf = whenAny(futures.begin(), futures.end());
376
377     /* futures were moved in, so these are invalid now */
378     EXPECT_FALSE(anyf.isReady());
379
380     promises[7].setValue(42);
381     EXPECT_TRUE(anyf.isReady());
382     auto& idx_fut = anyf.value();
383
384     auto i = idx_fut.first;
385     EXPECT_EQ(7, i);
386
387     auto& f = idx_fut.second;
388     EXPECT_EQ(42, f.value());
389   }
390
391   // error
392   {
393     vector<Promise<void>> promises(10);
394     vector<Future<void>> futures;
395
396     for (auto& p : promises)
397       futures.push_back(p.getFuture());
398
399     for (auto& f : futures) {
400       EXPECT_FALSE(f.isReady());
401     }
402
403     auto anyf = whenAny(futures.begin(), futures.end());
404
405     EXPECT_FALSE(anyf.isReady());
406
407     promises[3].setException(eggs);
408     EXPECT_TRUE(anyf.isReady());
409     EXPECT_TRUE(anyf.value().second.hasException());
410   }
411
412   // then()
413   {
414     vector<Promise<int>> promises(10);
415     vector<Future<int>> futures;
416
417     for (auto& p : promises)
418       futures.push_back(p.getFuture());
419
420     auto anyf = whenAny(futures.begin(), futures.end())
421       .then([](Try<pair<size_t, Try<int>>>&& f) {
422         EXPECT_EQ(42, f.value().second.value());
423       });
424
425     promises[3].setValue(42);
426     EXPECT_TRUE(anyf.isReady());
427   }
428 }
429
430
431 TEST(when, already_completed) {
432   {
433     vector<Future<void>> fs;
434     for (int i = 0; i < 10; i++)
435       fs.push_back(makeFuture());
436
437     whenAll(fs.begin(), fs.end())
438       .then([&](Try<vector<Try<void>>>&& t) {
439         EXPECT_EQ(fs.size(), t.value().size());
440       });
441   }
442   {
443     vector<Future<int>> fs;
444     for (int i = 0; i < 10; i++)
445       fs.push_back(makeFuture(i));
446
447     whenAny(fs.begin(), fs.end())
448       .then([&](Try<pair<size_t, Try<int>>>&& t) {
449         auto& p = t.value();
450         EXPECT_EQ(p.first, p.second.value());
451       });
452   }
453 }
454
455 TEST(when, whenN) {
456   vector<Promise<void>> promises(10);
457   vector<Future<void>> futures;
458
459   for (auto& p : promises)
460     futures.push_back(p.getFuture());
461
462   bool flag = false;
463   size_t n = 3;
464   whenN(futures.begin(), futures.end(), n)
465     .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
466       flag = true;
467       auto v = t.value();
468       EXPECT_EQ(n, v.size());
469       for (auto& tt : v)
470         EXPECT_TRUE(tt.second.hasValue());
471     });
472
473   promises[0].setValue();
474   EXPECT_FALSE(flag);
475   promises[1].setValue();
476   EXPECT_FALSE(flag);
477   promises[2].setValue();
478   EXPECT_TRUE(flag);
479 }
480
481 /* Ensure that we can compile when_{all,any} with folly::small_vector */
482 TEST(when, small_vector) {
483   using folly::small_vector;
484   {
485     small_vector<Future<void>> futures;
486
487     for (int i = 0; i < 10; i++)
488       futures.push_back(makeFuture());
489
490     auto anyf = whenAny(futures.begin(), futures.end());
491   }
492
493   {
494     small_vector<Future<void>> futures;
495
496     for (int i = 0; i < 10; i++)
497       futures.push_back(makeFuture());
498
499     auto allf = whenAll(futures.begin(), futures.end());
500   }
501 }
502
503 TEST(Future, whenAllVariadic) {
504   Promise<bool> pb;
505   Promise<int> pi;
506   Future<bool> fb = pb.getFuture();
507   Future<int> fi = pi.getFuture();
508   bool flag = false;
509   whenAll(fb, fi)
510     .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
511       flag = true;
512       EXPECT_TRUE(t.hasValue());
513       EXPECT_TRUE(std::get<0>(t.value()).hasValue());
514       EXPECT_EQ(std::get<0>(t.value()).value(), true);
515       EXPECT_TRUE(std::get<1>(t.value()).hasValue());
516       EXPECT_EQ(std::get<1>(t.value()).value(), 42);
517     });
518   pb.setValue(true);
519   EXPECT_FALSE(flag);
520   pi.setValue(42);
521   EXPECT_TRUE(flag);
522 }
523
524 TEST(Future, whenAll_none) {
525   vector<Future<int>> fs;
526   auto f = whenAll(fs.begin(), fs.end());
527   EXPECT_TRUE(f.isReady());
528 }
529
530 TEST(Future, throwCaughtInImmediateThen) {
531   // Neither of these should throw "Promise already satisfied"
532   makeFuture().then(
533     [=](Try<void>&&) -> int { throw std::exception(); });
534   makeFuture().then(
535     [=](Try<void>&&) -> Future<int> { throw std::exception(); });
536 }
537
538 TEST(Future, throwIfFailed) {
539   makeFuture<void>(eggs)
540     .then([=](Try<void>&& t) {
541       EXPECT_THROW(t.throwIfFailed(), eggs_t);
542     });
543   makeFuture()
544     .then([=](Try<void>&& t) {
545       EXPECT_NO_THROW(t.throwIfFailed());
546     });
547
548   makeFuture<int>(eggs)
549     .then([=](Try<int>&& t) {
550       EXPECT_THROW(t.throwIfFailed(), eggs_t);
551     });
552   makeFuture<int>(42)
553     .then([=](Try<int>&& t) {
554       EXPECT_NO_THROW(t.throwIfFailed());
555     });
556 }