a362e9bf4b5cef61ded48983195e4a4bfa82deeb
[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 static string doWorkStatic(Try<string>&& t) {
95   return t.value() + ";static";
96 }
97
98 TEST(Future, thenFunction) {
99   struct Worker {
100     string doWork(Try<string>&& t) {
101       return t.value() + ";class";
102     }
103     static string doWorkStatic(Try<string>&& t) {
104       return t.value() + ";class-static";
105     }
106   } w;
107
108   auto f = makeFuture<string>("start")
109     .then(doWorkStatic)
110     .then(Worker::doWorkStatic)
111     .then(&w, &Worker::doWork);
112
113   EXPECT_EQ(f.value(), "start;static;class-static;class");
114 }
115
116 static Future<string> doWorkStaticFuture(Try<string>&& t) {
117   return makeFuture(t.value() + ";static");
118 }
119
120 TEST(Future, thenFunctionFuture) {
121   struct Worker {
122     Future<string> doWorkFuture(Try<string>&& t) {
123       return makeFuture(t.value() + ";class");
124     }
125     static Future<string> doWorkStaticFuture(Try<string>&& t) {
126       return makeFuture(t.value() + ";class-static");
127     }
128   } w;
129
130   auto f = makeFuture<string>("start")
131     .then(doWorkStaticFuture)
132     .then(Worker::doWorkStaticFuture)
133     .then(&w, &Worker::doWorkFuture);
134
135   EXPECT_EQ(f.value(), "start;static;class-static;class");
136 }
137
138 TEST(Future, value) {
139   auto f = makeFuture(unique_ptr<int>(new int(42)));
140   auto up = std::move(f.value());
141   EXPECT_EQ(42, *up);
142
143   EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
144 }
145
146 TEST(Future, isReady) {
147   Promise<int> p;
148   auto f = p.getFuture();
149   EXPECT_FALSE(f.isReady());
150   p.setValue(42);
151   EXPECT_TRUE(f.isReady());
152   }
153
154 TEST(Future, hasException) {
155   EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
156   EXPECT_FALSE(makeFuture(42).getTry().hasException());
157 }
158
159 TEST(Future, hasValue) {
160   EXPECT_TRUE(makeFuture(42).getTry().hasValue());
161   EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
162 }
163
164 TEST(Future, makeFuture) {
165   EXPECT_TYPE(makeFuture(42), Future<int>);
166   EXPECT_EQ(42, makeFuture(42).value());
167
168   EXPECT_TYPE(makeFuture<float>(42), Future<float>);
169   EXPECT_EQ(42, makeFuture<float>(42).value());
170
171   auto fun = [] { return 42; };
172   EXPECT_TYPE(makeFutureTry(fun), Future<int>);
173   EXPECT_EQ(42, makeFutureTry(fun).value());
174
175   auto failfun = []() -> int { throw eggs; };
176   EXPECT_TYPE(makeFutureTry(failfun), Future<int>);
177   EXPECT_THROW(makeFutureTry(failfun).value(), eggs_t);
178
179   EXPECT_TYPE(makeFuture(), Future<void>);
180 }
181
182 // Promise
183
184 TEST(Promise, special) {
185   EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
186   EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
187   EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
188   EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
189 }
190
191 TEST(Promise, getFuture) {
192   Promise<int> p;
193   Future<int> f = p.getFuture();
194   EXPECT_FALSE(f.isReady());
195 }
196
197 TEST(Promise, setValue) {
198   Promise<int> fund;
199   auto ffund = fund.getFuture();
200   fund.setValue(42);
201   EXPECT_EQ(42, ffund.value());
202
203   struct Foo {
204     string name;
205     int value;
206   };
207
208   Promise<Foo> pod;
209   auto fpod = pod.getFuture();
210   Foo f = {"the answer", 42};
211   pod.setValue(f);
212   Foo f2 = fpod.value();
213   EXPECT_EQ(f.name, f2.name);
214   EXPECT_EQ(f.value, f2.value);
215
216   pod = Promise<Foo>();
217   fpod = pod.getFuture();
218   pod.setValue(std::move(f2));
219   Foo f3 = fpod.value();
220   EXPECT_EQ(f.name, f3.name);
221   EXPECT_EQ(f.value, f3.value);
222
223   Promise<unique_ptr<int>> mov;
224   auto fmov = mov.getFuture();
225   mov.setValue(unique_ptr<int>(new int(42)));
226   unique_ptr<int> ptr = std::move(fmov.value());
227   EXPECT_EQ(42, *ptr);
228
229   Promise<void> v;
230   auto fv = v.getFuture();
231   v.setValue();
232   EXPECT_TRUE(fv.isReady());
233 }
234
235 TEST(Promise, setException) {
236   {
237     Promise<void> p;
238     auto f = p.getFuture();
239     p.setException(eggs);
240     EXPECT_THROW(f.value(), eggs_t);
241   }
242   {
243     Promise<void> p;
244     auto f = p.getFuture();
245     try {
246       throw eggs;
247     } catch (...) {
248       p.setException(std::current_exception());
249     }
250     EXPECT_THROW(f.value(), eggs_t);
251   }
252 }
253
254 TEST(Promise, fulfil) {
255   {
256     Promise<int> p;
257     auto f = p.getFuture();
258     p.fulfil([] { return 42; });
259     EXPECT_EQ(42, f.value());
260   }
261   {
262     Promise<int> p;
263     auto f = p.getFuture();
264     p.fulfil([]() -> int { throw eggs; });
265     EXPECT_THROW(f.value(), eggs_t);
266   }
267 }
268
269 TEST(Future, finish) {
270   auto x = std::make_shared<int>(0);
271   Promise<int> p;
272   auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
273
274   // The continuation hasn't executed
275   EXPECT_EQ(0, *x);
276
277   // The continuation has a reference to x
278   EXPECT_EQ(2, x.use_count());
279
280   p.setValue(42);
281
282   // the continuation has executed
283   EXPECT_EQ(42, *x);
284
285   // the continuation has been destructed
286   // and has released its reference to x
287   EXPECT_EQ(1, x.use_count());
288 }
289
290 TEST(Future, unwrap) {
291   Promise<int> a;
292   Promise<int> b;
293
294   auto fa = a.getFuture();
295   auto fb = b.getFuture();
296
297   bool flag1 = false;
298   bool flag2 = false;
299
300   // do a, then do b, and get the result of a + b.
301   Future<int> f = fa.then([&](Try<int>&& ta) {
302     auto va = ta.value();
303     flag1 = true;
304     return fb.then([va, &flag2](Try<int>&& tb) {
305       flag2 = true;
306       return va + tb.value();
307     });
308   });
309
310   EXPECT_FALSE(flag1);
311   EXPECT_FALSE(flag2);
312   EXPECT_FALSE(f.isReady());
313
314   a.setValue(3);
315   EXPECT_TRUE(flag1);
316   EXPECT_FALSE(flag2);
317   EXPECT_FALSE(f.isReady());
318
319   b.setValue(4);
320   EXPECT_TRUE(flag1);
321   EXPECT_TRUE(flag2);
322   EXPECT_EQ(7, f.value());
323 }
324
325 TEST(Future, whenAll) {
326   // returns a vector variant
327   {
328     vector<Promise<int>> promises(10);
329     vector<Future<int>> futures;
330
331     for (auto& p : promises)
332       futures.push_back(p.getFuture());
333
334     auto allf = whenAll(futures.begin(), futures.end());
335
336     random_shuffle(promises.begin(), promises.end());
337     for (auto& p : promises) {
338       EXPECT_FALSE(allf.isReady());
339       p.setValue(42);
340     }
341
342     EXPECT_TRUE(allf.isReady());
343     auto& results = allf.value();
344     for (auto& t : results) {
345       EXPECT_EQ(42, t.value());
346     }
347   }
348
349   // check error semantics
350   {
351     vector<Promise<int>> promises(4);
352     vector<Future<int>> futures;
353
354     for (auto& p : promises)
355       futures.push_back(p.getFuture());
356
357     auto allf = whenAll(futures.begin(), futures.end());
358
359
360     promises[0].setValue(42);
361     promises[1].setException(eggs);
362
363     EXPECT_FALSE(allf.isReady());
364
365     promises[2].setValue(42);
366
367     EXPECT_FALSE(allf.isReady());
368
369     promises[3].setException(eggs);
370
371     EXPECT_TRUE(allf.isReady());
372     EXPECT_FALSE(allf.getTry().hasException());
373
374     auto& results = allf.value();
375     EXPECT_EQ(42, results[0].value());
376     EXPECT_TRUE(results[1].hasException());
377     EXPECT_EQ(42, results[2].value());
378     EXPECT_TRUE(results[3].hasException());
379   }
380
381   // check that futures are ready in then()
382   {
383     vector<Promise<void>> promises(10);
384     vector<Future<void>> futures;
385
386     for (auto& p : promises)
387       futures.push_back(p.getFuture());
388
389     auto allf = whenAll(futures.begin(), futures.end())
390       .then([](Try<vector<Try<void>>>&& ts) {
391         for (auto& f : ts.value())
392           f.value();
393       });
394
395     random_shuffle(promises.begin(), promises.end());
396     for (auto& p : promises)
397       p.setValue();
398     EXPECT_TRUE(allf.isReady());
399   }
400 }
401
402
403 TEST(Future, whenAny) {
404   {
405     vector<Promise<int>> promises(10);
406     vector<Future<int>> futures;
407
408     for (auto& p : promises)
409       futures.push_back(p.getFuture());
410
411     for (auto& f : futures) {
412       EXPECT_FALSE(f.isReady());
413     }
414
415     auto anyf = whenAny(futures.begin(), futures.end());
416
417     /* futures were moved in, so these are invalid now */
418     EXPECT_FALSE(anyf.isReady());
419
420     promises[7].setValue(42);
421     EXPECT_TRUE(anyf.isReady());
422     auto& idx_fut = anyf.value();
423
424     auto i = idx_fut.first;
425     EXPECT_EQ(7, i);
426
427     auto& f = idx_fut.second;
428     EXPECT_EQ(42, f.value());
429   }
430
431   // error
432   {
433     vector<Promise<void>> promises(10);
434     vector<Future<void>> futures;
435
436     for (auto& p : promises)
437       futures.push_back(p.getFuture());
438
439     for (auto& f : futures) {
440       EXPECT_FALSE(f.isReady());
441     }
442
443     auto anyf = whenAny(futures.begin(), futures.end());
444
445     EXPECT_FALSE(anyf.isReady());
446
447     promises[3].setException(eggs);
448     EXPECT_TRUE(anyf.isReady());
449     EXPECT_TRUE(anyf.value().second.hasException());
450   }
451
452   // then()
453   {
454     vector<Promise<int>> promises(10);
455     vector<Future<int>> futures;
456
457     for (auto& p : promises)
458       futures.push_back(p.getFuture());
459
460     auto anyf = whenAny(futures.begin(), futures.end())
461       .then([](Try<pair<size_t, Try<int>>>&& f) {
462         EXPECT_EQ(42, f.value().second.value());
463       });
464
465     promises[3].setValue(42);
466     EXPECT_TRUE(anyf.isReady());
467   }
468 }
469
470
471 TEST(when, already_completed) {
472   {
473     vector<Future<void>> fs;
474     for (int i = 0; i < 10; i++)
475       fs.push_back(makeFuture());
476
477     whenAll(fs.begin(), fs.end())
478       .then([&](Try<vector<Try<void>>>&& t) {
479         EXPECT_EQ(fs.size(), t.value().size());
480       });
481   }
482   {
483     vector<Future<int>> fs;
484     for (int i = 0; i < 10; i++)
485       fs.push_back(makeFuture(i));
486
487     whenAny(fs.begin(), fs.end())
488       .then([&](Try<pair<size_t, Try<int>>>&& t) {
489         auto& p = t.value();
490         EXPECT_EQ(p.first, p.second.value());
491       });
492   }
493 }
494
495 TEST(when, whenN) {
496   vector<Promise<void>> promises(10);
497   vector<Future<void>> futures;
498
499   for (auto& p : promises)
500     futures.push_back(p.getFuture());
501
502   bool flag = false;
503   size_t n = 3;
504   whenN(futures.begin(), futures.end(), n)
505     .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
506       flag = true;
507       auto v = t.value();
508       EXPECT_EQ(n, v.size());
509       for (auto& tt : v)
510         EXPECT_TRUE(tt.second.hasValue());
511     });
512
513   promises[0].setValue();
514   EXPECT_FALSE(flag);
515   promises[1].setValue();
516   EXPECT_FALSE(flag);
517   promises[2].setValue();
518   EXPECT_TRUE(flag);
519 }
520
521 /* Ensure that we can compile when_{all,any} with folly::small_vector */
522 TEST(when, small_vector) {
523
524   static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<void>),
525                 "Futures should not be trivially copyable");
526   static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<int>),
527                 "Futures should not be trivially copyable");
528
529   using folly::small_vector;
530   {
531     small_vector<Future<void>> futures;
532
533     for (int i = 0; i < 10; i++)
534       futures.push_back(makeFuture());
535
536     auto anyf = whenAny(futures.begin(), futures.end());
537   }
538
539   {
540     small_vector<Future<void>> futures;
541
542     for (int i = 0; i < 10; i++)
543       futures.push_back(makeFuture());
544
545     auto allf = whenAll(futures.begin(), futures.end());
546   }
547 }
548
549 TEST(Future, whenAllVariadic) {
550   Promise<bool> pb;
551   Promise<int> pi;
552   Future<bool> fb = pb.getFuture();
553   Future<int> fi = pi.getFuture();
554   bool flag = false;
555   whenAll(std::move(fb), std::move(fi))
556     .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
557       flag = true;
558       EXPECT_TRUE(t.hasValue());
559       EXPECT_TRUE(std::get<0>(t.value()).hasValue());
560       EXPECT_EQ(std::get<0>(t.value()).value(), true);
561       EXPECT_TRUE(std::get<1>(t.value()).hasValue());
562       EXPECT_EQ(std::get<1>(t.value()).value(), 42);
563     });
564   pb.setValue(true);
565   EXPECT_FALSE(flag);
566   pi.setValue(42);
567   EXPECT_TRUE(flag);
568 }
569
570 TEST(Future, whenAllVariadicReferences) {
571   Promise<bool> pb;
572   Promise<int> pi;
573   Future<bool> fb = pb.getFuture();
574   Future<int> fi = pi.getFuture();
575   bool flag = false;
576   whenAll(fb, fi)
577     .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
578       flag = true;
579       EXPECT_TRUE(t.hasValue());
580       EXPECT_TRUE(std::get<0>(t.value()).hasValue());
581       EXPECT_EQ(std::get<0>(t.value()).value(), true);
582       EXPECT_TRUE(std::get<1>(t.value()).hasValue());
583       EXPECT_EQ(std::get<1>(t.value()).value(), 42);
584     });
585   pb.setValue(true);
586   EXPECT_FALSE(flag);
587   pi.setValue(42);
588   EXPECT_TRUE(flag);
589 }
590
591 TEST(Future, whenAll_none) {
592   vector<Future<int>> fs;
593   auto f = whenAll(fs.begin(), fs.end());
594   EXPECT_TRUE(f.isReady());
595 }
596
597 TEST(Future, throwCaughtInImmediateThen) {
598   // Neither of these should throw "Promise already satisfied"
599   makeFuture().then(
600     [=](Try<void>&&) -> int { throw std::exception(); });
601   makeFuture().then(
602     [=](Try<void>&&) -> Future<int> { throw std::exception(); });
603 }
604
605 TEST(Future, throwIfFailed) {
606   makeFuture<void>(eggs)
607     .then([=](Try<void>&& t) {
608       EXPECT_THROW(t.throwIfFailed(), eggs_t);
609     });
610   makeFuture()
611     .then([=](Try<void>&& t) {
612       EXPECT_NO_THROW(t.throwIfFailed());
613     });
614
615   makeFuture<int>(eggs)
616     .then([=](Try<int>&& t) {
617       EXPECT_THROW(t.throwIfFailed(), eggs_t);
618     });
619   makeFuture<int>(42)
620     .then([=](Try<int>&& t) {
621       EXPECT_NO_THROW(t.throwIfFailed());
622     });
623 }