e5906058f1a33e37d0ebd6cfba961b9195d06ddf
[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   pod.setValue(std::move(f2));
175   Foo f3 = fpod.value();
176   EXPECT_EQ(f.name, f3.name);
177   EXPECT_EQ(f.value, f3.value);
178
179   Promise<unique_ptr<int>> mov;
180   auto fmov = mov.getFuture();
181   mov.setValue(unique_ptr<int>(new int(42)));
182   unique_ptr<int> ptr = std::move(fmov.value());
183   EXPECT_EQ(42, *ptr);
184
185   Promise<void> v;
186   auto fv = v.getFuture();
187   v.setValue();
188   EXPECT_TRUE(fv.isReady());
189 }
190
191 TEST(Promise, setException) {
192   {
193     Promise<void> p;
194     auto f = p.getFuture();
195     p.setException(eggs);
196     EXPECT_THROW(f.value(), eggs_t);
197   }
198   {
199     Promise<void> p;
200     auto f = p.getFuture();
201     try {
202       throw eggs;
203     } catch (...) {
204       p.setException(std::current_exception());
205     }
206     EXPECT_THROW(f.value(), eggs_t);
207   }
208 }
209
210 TEST(Promise, fulfil) {
211   {
212     Promise<int> p;
213     auto f = p.getFuture();
214     p.fulfil([] { return 42; });
215     EXPECT_EQ(42, f.value());
216   }
217   {
218     Promise<int> p;
219     auto f = p.getFuture();
220     p.fulfil([]() -> int { throw eggs; });
221     EXPECT_THROW(f.value(), eggs_t);
222   }
223 }
224
225 TEST(Future, finish) {
226   auto x = std::make_shared<int>(0);
227   Promise<int> p;
228   auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
229
230   // The continuation hasn't executed
231   EXPECT_EQ(0, *x);
232
233   // The continuation has a reference to x
234   EXPECT_EQ(2, x.use_count());
235
236   p.setValue(42);
237
238   // the continuation has executed
239   EXPECT_EQ(42, *x);
240
241   // the continuation has been destructed
242   // and has released its reference to x
243   EXPECT_EQ(1, x.use_count());
244 }
245
246 TEST(Future, unwrap) {
247   Promise<int> a;
248   Promise<int> b;
249
250   auto fa = a.getFuture();
251   auto fb = b.getFuture();
252
253   bool flag1 = false;
254   bool flag2 = false;
255
256   // do a, then do b, and get the result of a + b.
257   Future<int> f = fa.then([&](Try<int>&& ta) {
258     auto va = ta.value();
259     flag1 = true;
260     return fb.then([va, &flag2](Try<int>&& tb) {
261       flag2 = true;
262       return va + tb.value();
263     });
264   });
265
266   EXPECT_FALSE(flag1);
267   EXPECT_FALSE(flag2);
268   EXPECT_FALSE(f.isReady());
269
270   a.setValue(3);
271   EXPECT_TRUE(flag1);
272   EXPECT_FALSE(flag2);
273   EXPECT_FALSE(f.isReady());
274
275   b.setValue(4);
276   EXPECT_TRUE(flag1);
277   EXPECT_TRUE(flag2);
278   EXPECT_EQ(7, f.value());
279 }
280
281 TEST(Future, whenAll) {
282   // returns a vector variant
283   {
284     vector<Promise<int>> promises(10);
285     vector<Future<int>> futures;
286
287     for (auto& p : promises)
288       futures.push_back(p.getFuture());
289
290     auto allf = whenAll(futures.begin(), futures.end());
291
292     random_shuffle(promises.begin(), promises.end());
293     for (auto& p : promises) {
294       EXPECT_FALSE(allf.isReady());
295       p.setValue(42);
296     }
297
298     EXPECT_TRUE(allf.isReady());
299     auto& results = allf.value();
300     for (auto& t : results) {
301       EXPECT_EQ(42, t.value());
302     }
303   }
304
305   // check error semantics
306   {
307     vector<Promise<int>> promises(4);
308     vector<Future<int>> futures;
309
310     for (auto& p : promises)
311       futures.push_back(p.getFuture());
312
313     auto allf = whenAll(futures.begin(), futures.end());
314
315
316     promises[0].setValue(42);
317     promises[1].setException(eggs);
318
319     EXPECT_FALSE(allf.isReady());
320
321     promises[2].setValue(42);
322
323     EXPECT_FALSE(allf.isReady());
324
325     promises[3].setException(eggs);
326
327     EXPECT_TRUE(allf.isReady());
328     EXPECT_FALSE(allf.getTry().hasException());
329
330     auto& results = allf.value();
331     EXPECT_EQ(42, results[0].value());
332     EXPECT_TRUE(results[1].hasException());
333     EXPECT_EQ(42, results[2].value());
334     EXPECT_TRUE(results[3].hasException());
335   }
336
337   // check that futures are ready in then()
338   {
339     vector<Promise<void>> promises(10);
340     vector<Future<void>> futures;
341
342     for (auto& p : promises)
343       futures.push_back(p.getFuture());
344
345     auto allf = whenAll(futures.begin(), futures.end())
346       .then([](Try<vector<Try<void>>>&& ts) {
347         for (auto& f : ts.value())
348           f.value();
349       });
350
351     random_shuffle(promises.begin(), promises.end());
352     for (auto& p : promises)
353       p.setValue();
354     EXPECT_TRUE(allf.isReady());
355   }
356 }
357
358
359 TEST(Future, whenAny) {
360   {
361     vector<Promise<int>> promises(10);
362     vector<Future<int>> futures;
363
364     for (auto& p : promises)
365       futures.push_back(p.getFuture());
366
367     for (auto& f : futures) {
368       EXPECT_FALSE(f.isReady());
369     }
370
371     auto anyf = whenAny(futures.begin(), futures.end());
372
373     /* futures were moved in, so these are invalid now */
374     EXPECT_FALSE(anyf.isReady());
375
376     promises[7].setValue(42);
377     EXPECT_TRUE(anyf.isReady());
378     auto& idx_fut = anyf.value();
379
380     auto i = idx_fut.first;
381     EXPECT_EQ(7, i);
382
383     auto& f = idx_fut.second;
384     EXPECT_EQ(42, f.value());
385   }
386
387   // error
388   {
389     vector<Promise<void>> promises(10);
390     vector<Future<void>> futures;
391
392     for (auto& p : promises)
393       futures.push_back(p.getFuture());
394
395     for (auto& f : futures) {
396       EXPECT_FALSE(f.isReady());
397     }
398
399     auto anyf = whenAny(futures.begin(), futures.end());
400
401     EXPECT_FALSE(anyf.isReady());
402
403     promises[3].setException(eggs);
404     EXPECT_TRUE(anyf.isReady());
405     EXPECT_TRUE(anyf.value().second.hasException());
406   }
407
408   // then()
409   {
410     vector<Promise<int>> promises(10);
411     vector<Future<int>> futures;
412
413     for (auto& p : promises)
414       futures.push_back(p.getFuture());
415
416     auto anyf = whenAny(futures.begin(), futures.end())
417       .then([](Try<pair<size_t, Try<int>>>&& f) {
418         EXPECT_EQ(42, f.value().second.value());
419       });
420
421     promises[3].setValue(42);
422     EXPECT_TRUE(anyf.isReady());
423   }
424 }
425
426
427 TEST(when, already_completed) {
428   {
429     vector<Future<void>> fs;
430     for (int i = 0; i < 10; i++)
431       fs.push_back(makeFuture());
432
433     whenAll(fs.begin(), fs.end())
434       .then([&](Try<vector<Try<void>>>&& t) {
435         EXPECT_EQ(fs.size(), t.value().size());
436       });
437   }
438   {
439     vector<Future<int>> fs;
440     for (int i = 0; i < 10; i++)
441       fs.push_back(makeFuture(i));
442
443     whenAny(fs.begin(), fs.end())
444       .then([&](Try<pair<size_t, Try<int>>>&& t) {
445         auto& p = t.value();
446         EXPECT_EQ(p.first, p.second.value());
447       });
448   }
449 }
450
451 TEST(when, whenN) {
452   vector<Promise<void>> promises(10);
453   vector<Future<void>> futures;
454
455   for (auto& p : promises)
456     futures.push_back(p.getFuture());
457
458   bool flag = false;
459   size_t n = 3;
460   whenN(futures.begin(), futures.end(), n)
461     .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
462       flag = true;
463       auto v = t.value();
464       EXPECT_EQ(n, v.size());
465       for (auto& tt : v)
466         EXPECT_TRUE(tt.second.hasValue());
467     });
468
469   promises[0].setValue();
470   EXPECT_FALSE(flag);
471   promises[1].setValue();
472   EXPECT_FALSE(flag);
473   promises[2].setValue();
474   EXPECT_TRUE(flag);
475 }
476
477 /* Ensure that we can compile when_{all,any} with folly::small_vector */
478 TEST(when, small_vector) {
479   using folly::small_vector;
480   {
481     small_vector<Future<void>> futures;
482
483     for (int i = 0; i < 10; i++)
484       futures.push_back(makeFuture());
485
486     auto anyf = whenAny(futures.begin(), futures.end());
487   }
488
489   {
490     small_vector<Future<void>> futures;
491
492     for (int i = 0; i < 10; i++)
493       futures.push_back(makeFuture());
494
495     auto allf = whenAll(futures.begin(), futures.end());
496   }
497 }
498
499 TEST(Future, whenAllVariadic) {
500   Promise<bool> pb;
501   Promise<int> pi;
502   Future<bool> fb = pb.getFuture();
503   Future<int> fi = pi.getFuture();
504   bool flag = false;
505   whenAll(std::move(fb), std::move(fi))
506     .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
507       flag = true;
508       EXPECT_TRUE(t.hasValue());
509       EXPECT_TRUE(std::get<0>(t.value()).hasValue());
510       EXPECT_EQ(std::get<0>(t.value()).value(), true);
511       EXPECT_TRUE(std::get<1>(t.value()).hasValue());
512       EXPECT_EQ(std::get<1>(t.value()).value(), 42);
513     });
514   pb.setValue(true);
515   EXPECT_FALSE(flag);
516   pi.setValue(42);
517   EXPECT_TRUE(flag);
518 }
519
520 TEST(Future, whenAllVariadicReferences) {
521   Promise<bool> pb;
522   Promise<int> pi;
523   Future<bool> fb = pb.getFuture();
524   Future<int> fi = pi.getFuture();
525   bool flag = false;
526   whenAll(fb, fi)
527     .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
528       flag = true;
529       EXPECT_TRUE(t.hasValue());
530       EXPECT_TRUE(std::get<0>(t.value()).hasValue());
531       EXPECT_EQ(std::get<0>(t.value()).value(), true);
532       EXPECT_TRUE(std::get<1>(t.value()).hasValue());
533       EXPECT_EQ(std::get<1>(t.value()).value(), 42);
534     });
535   pb.setValue(true);
536   EXPECT_FALSE(flag);
537   pi.setValue(42);
538   EXPECT_TRUE(flag);
539 }
540
541 TEST(Future, whenAll_none) {
542   vector<Future<int>> fs;
543   auto f = whenAll(fs.begin(), fs.end());
544   EXPECT_TRUE(f.isReady());
545 }
546
547 TEST(Future, throwCaughtInImmediateThen) {
548   // Neither of these should throw "Promise already satisfied"
549   makeFuture().then(
550     [=](Try<void>&&) -> int { throw std::exception(); });
551   makeFuture().then(
552     [=](Try<void>&&) -> Future<int> { throw std::exception(); });
553 }
554
555 TEST(Future, throwIfFailed) {
556   makeFuture<void>(eggs)
557     .then([=](Try<void>&& t) {
558       EXPECT_THROW(t.throwIfFailed(), eggs_t);
559     });
560   makeFuture()
561     .then([=](Try<void>&& t) {
562       EXPECT_NO_THROW(t.throwIfFailed());
563     });
564
565   makeFuture<int>(eggs)
566     .then([=](Try<int>&& t) {
567       EXPECT_THROW(t.throwIfFailed(), eggs_t);
568     });
569   makeFuture<int>(42)
570     .then([=](Try<int>&& t) {
571       EXPECT_NO_THROW(t.throwIfFailed());
572     });
573 }