84977c7437285ed9e4322d84392b478ee525545e
[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 <atomic>
19 #include <folly/small_vector.h>
20 #include <gtest/gtest.h>
21 #include <memory>
22 #include <string>
23 #include <thread>
24 #include <type_traits>
25 #include <unistd.h>
26 #include "folly/wangle/Executor.h"
27 #include "folly/wangle/Future.h"
28
29 using namespace folly::wangle;
30 using std::pair;
31 using std::string;
32 using std::unique_ptr;
33 using std::vector;
34
35 #define EXPECT_TYPE(x, T) \
36   EXPECT_TRUE((std::is_same<decltype(x), T>::value))
37
38 typedef WangleException eggs_t;
39 static eggs_t eggs("eggs");
40
41 // Future
42
43 TEST(Future, try) {
44   class A {
45    public:
46     A(int x) : x_(x) {}
47
48     int x() const {
49       return x_;
50     }
51    private:
52     int x_;
53   };
54
55   A a(5);
56   Try<A> t_a(std::move(a));
57
58   Try<void> t_void;
59
60   EXPECT_EQ(5, t_a.value().x());
61 }
62
63 TEST(Future, special) {
64   EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
65   EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
66   EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
67   EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
68 }
69
70 TEST(Future, then) {
71   bool flag = false;
72
73   makeFuture<int>(42).then([&](Try<int>&& t) {
74                               flag = true;
75                               EXPECT_EQ(42, t.value());
76                             });
77   EXPECT_TRUE(flag); flag = false;
78
79   makeFuture<int>(42)
80     .then([](Try<int>&& t) { return t.value(); })
81     .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
82   EXPECT_TRUE(flag); flag = false;
83
84   makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
85   EXPECT_TRUE(flag); flag = false;
86
87   Promise<void> p;
88   auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
89   EXPECT_FALSE(flag);
90   EXPECT_FALSE(f.isReady());
91   p.setValue();
92   EXPECT_TRUE(flag);
93   EXPECT_TRUE(f.isReady());
94 }
95
96 static string doWorkStatic(Try<string>&& t) {
97   return t.value() + ";static";
98 }
99
100 TEST(Future, thenFunction) {
101   struct Worker {
102     string doWork(Try<string>&& t) {
103       return t.value() + ";class";
104     }
105     static string doWorkStatic(Try<string>&& t) {
106       return t.value() + ";class-static";
107     }
108   } w;
109
110   auto f = makeFuture<string>("start")
111     .then(doWorkStatic)
112     .then(Worker::doWorkStatic)
113     .then(&w, &Worker::doWork);
114
115   EXPECT_EQ(f.value(), "start;static;class-static;class");
116 }
117
118 static Future<string> doWorkStaticFuture(Try<string>&& t) {
119   return makeFuture(t.value() + ";static");
120 }
121
122 TEST(Future, thenFunctionFuture) {
123   struct Worker {
124     Future<string> doWorkFuture(Try<string>&& t) {
125       return makeFuture(t.value() + ";class");
126     }
127     static Future<string> doWorkStaticFuture(Try<string>&& t) {
128       return makeFuture(t.value() + ";class-static");
129     }
130   } w;
131
132   auto f = makeFuture<string>("start")
133     .then(doWorkStaticFuture)
134     .then(Worker::doWorkStaticFuture)
135     .then(&w, &Worker::doWorkFuture);
136
137   EXPECT_EQ(f.value(), "start;static;class-static;class");
138 }
139
140 TEST(Future, value) {
141   auto f = makeFuture(unique_ptr<int>(new int(42)));
142   auto up = std::move(f.value());
143   EXPECT_EQ(42, *up);
144
145   EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
146 }
147
148 TEST(Future, isReady) {
149   Promise<int> p;
150   auto f = p.getFuture();
151   EXPECT_FALSE(f.isReady());
152   p.setValue(42);
153   EXPECT_TRUE(f.isReady());
154   }
155
156 TEST(Future, futureNotReady) {
157   Promise<int> p;
158   Future<int> f = p.getFuture();
159   EXPECT_THROW(f.value(), eggs_t);
160 }
161
162 TEST(Future, hasException) {
163   EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
164   EXPECT_FALSE(makeFuture(42).getTry().hasException());
165 }
166
167 TEST(Future, hasValue) {
168   EXPECT_TRUE(makeFuture(42).getTry().hasValue());
169   EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
170 }
171
172 TEST(Future, makeFuture) {
173   EXPECT_TYPE(makeFuture(42), Future<int>);
174   EXPECT_EQ(42, makeFuture(42).value());
175
176   EXPECT_TYPE(makeFuture<float>(42), Future<float>);
177   EXPECT_EQ(42, makeFuture<float>(42).value());
178
179   auto fun = [] { return 42; };
180   EXPECT_TYPE(makeFutureTry(fun), Future<int>);
181   EXPECT_EQ(42, makeFutureTry(fun).value());
182
183   auto failfun = []() -> int { throw eggs; };
184   EXPECT_TYPE(makeFutureTry(failfun), Future<int>);
185   EXPECT_THROW(makeFutureTry(failfun).value(), eggs_t);
186
187   EXPECT_TYPE(makeFuture(), Future<void>);
188 }
189
190 // Promise
191
192 TEST(Promise, special) {
193   EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
194   EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
195   EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
196   EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
197 }
198
199 TEST(Promise, getFuture) {
200   Promise<int> p;
201   Future<int> f = p.getFuture();
202   EXPECT_FALSE(f.isReady());
203 }
204
205 TEST(Promise, setValue) {
206   Promise<int> fund;
207   auto ffund = fund.getFuture();
208   fund.setValue(42);
209   EXPECT_EQ(42, ffund.value());
210
211   struct Foo {
212     string name;
213     int value;
214   };
215
216   Promise<Foo> pod;
217   auto fpod = pod.getFuture();
218   Foo f = {"the answer", 42};
219   pod.setValue(f);
220   Foo f2 = fpod.value();
221   EXPECT_EQ(f.name, f2.name);
222   EXPECT_EQ(f.value, f2.value);
223
224   pod = Promise<Foo>();
225   fpod = pod.getFuture();
226   pod.setValue(std::move(f2));
227   Foo f3 = fpod.value();
228   EXPECT_EQ(f.name, f3.name);
229   EXPECT_EQ(f.value, f3.value);
230
231   Promise<unique_ptr<int>> mov;
232   auto fmov = mov.getFuture();
233   mov.setValue(unique_ptr<int>(new int(42)));
234   unique_ptr<int> ptr = std::move(fmov.value());
235   EXPECT_EQ(42, *ptr);
236
237   Promise<void> v;
238   auto fv = v.getFuture();
239   v.setValue();
240   EXPECT_TRUE(fv.isReady());
241 }
242
243 TEST(Promise, setException) {
244   {
245     Promise<void> p;
246     auto f = p.getFuture();
247     p.setException(eggs);
248     EXPECT_THROW(f.value(), eggs_t);
249   }
250   {
251     Promise<void> p;
252     auto f = p.getFuture();
253     try {
254       throw eggs;
255     } catch (...) {
256       p.setException(std::current_exception());
257     }
258     EXPECT_THROW(f.value(), eggs_t);
259   }
260 }
261
262 TEST(Promise, fulfil) {
263   {
264     Promise<int> p;
265     auto f = p.getFuture();
266     p.fulfil([] { return 42; });
267     EXPECT_EQ(42, f.value());
268   }
269   {
270     Promise<int> p;
271     auto f = p.getFuture();
272     p.fulfil([]() -> int { throw eggs; });
273     EXPECT_THROW(f.value(), eggs_t);
274   }
275 }
276
277 TEST(Future, finish) {
278   auto x = std::make_shared<int>(0);
279   Promise<int> p;
280   auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
281
282   // The continuation hasn't executed
283   EXPECT_EQ(0, *x);
284
285   // The continuation has a reference to x
286   EXPECT_EQ(2, x.use_count());
287
288   p.setValue(42);
289
290   // the continuation has executed
291   EXPECT_EQ(42, *x);
292
293   // the continuation has been destructed
294   // and has released its reference to x
295   EXPECT_EQ(1, x.use_count());
296 }
297
298 TEST(Future, unwrap) {
299   Promise<int> a;
300   Promise<int> b;
301
302   auto fa = a.getFuture();
303   auto fb = b.getFuture();
304
305   bool flag1 = false;
306   bool flag2 = false;
307
308   // do a, then do b, and get the result of a + b.
309   Future<int> f = fa.then([&](Try<int>&& ta) {
310     auto va = ta.value();
311     flag1 = true;
312     return fb.then([va, &flag2](Try<int>&& tb) {
313       flag2 = true;
314       return va + tb.value();
315     });
316   });
317
318   EXPECT_FALSE(flag1);
319   EXPECT_FALSE(flag2);
320   EXPECT_FALSE(f.isReady());
321
322   a.setValue(3);
323   EXPECT_TRUE(flag1);
324   EXPECT_FALSE(flag2);
325   EXPECT_FALSE(f.isReady());
326
327   b.setValue(4);
328   EXPECT_TRUE(flag1);
329   EXPECT_TRUE(flag2);
330   EXPECT_EQ(7, f.value());
331 }
332
333 TEST(Future, whenAll) {
334   // returns a vector variant
335   {
336     vector<Promise<int>> promises(10);
337     vector<Future<int>> futures;
338
339     for (auto& p : promises)
340       futures.push_back(p.getFuture());
341
342     auto allf = whenAll(futures.begin(), futures.end());
343
344     random_shuffle(promises.begin(), promises.end());
345     for (auto& p : promises) {
346       EXPECT_FALSE(allf.isReady());
347       p.setValue(42);
348     }
349
350     EXPECT_TRUE(allf.isReady());
351     auto& results = allf.value();
352     for (auto& t : results) {
353       EXPECT_EQ(42, t.value());
354     }
355   }
356
357   // check error semantics
358   {
359     vector<Promise<int>> promises(4);
360     vector<Future<int>> futures;
361
362     for (auto& p : promises)
363       futures.push_back(p.getFuture());
364
365     auto allf = whenAll(futures.begin(), futures.end());
366
367
368     promises[0].setValue(42);
369     promises[1].setException(eggs);
370
371     EXPECT_FALSE(allf.isReady());
372
373     promises[2].setValue(42);
374
375     EXPECT_FALSE(allf.isReady());
376
377     promises[3].setException(eggs);
378
379     EXPECT_TRUE(allf.isReady());
380     EXPECT_FALSE(allf.getTry().hasException());
381
382     auto& results = allf.value();
383     EXPECT_EQ(42, results[0].value());
384     EXPECT_TRUE(results[1].hasException());
385     EXPECT_EQ(42, results[2].value());
386     EXPECT_TRUE(results[3].hasException());
387   }
388
389   // check that futures are ready in then()
390   {
391     vector<Promise<void>> promises(10);
392     vector<Future<void>> futures;
393
394     for (auto& p : promises)
395       futures.push_back(p.getFuture());
396
397     auto allf = whenAll(futures.begin(), futures.end())
398       .then([](Try<vector<Try<void>>>&& ts) {
399         for (auto& f : ts.value())
400           f.value();
401       });
402
403     random_shuffle(promises.begin(), promises.end());
404     for (auto& p : promises)
405       p.setValue();
406     EXPECT_TRUE(allf.isReady());
407   }
408 }
409
410
411 TEST(Future, whenAny) {
412   {
413     vector<Promise<int>> promises(10);
414     vector<Future<int>> futures;
415
416     for (auto& p : promises)
417       futures.push_back(p.getFuture());
418
419     for (auto& f : futures) {
420       EXPECT_FALSE(f.isReady());
421     }
422
423     auto anyf = whenAny(futures.begin(), futures.end());
424
425     /* futures were moved in, so these are invalid now */
426     EXPECT_FALSE(anyf.isReady());
427
428     promises[7].setValue(42);
429     EXPECT_TRUE(anyf.isReady());
430     auto& idx_fut = anyf.value();
431
432     auto i = idx_fut.first;
433     EXPECT_EQ(7, i);
434
435     auto& f = idx_fut.second;
436     EXPECT_EQ(42, f.value());
437   }
438
439   // error
440   {
441     vector<Promise<void>> promises(10);
442     vector<Future<void>> futures;
443
444     for (auto& p : promises)
445       futures.push_back(p.getFuture());
446
447     for (auto& f : futures) {
448       EXPECT_FALSE(f.isReady());
449     }
450
451     auto anyf = whenAny(futures.begin(), futures.end());
452
453     EXPECT_FALSE(anyf.isReady());
454
455     promises[3].setException(eggs);
456     EXPECT_TRUE(anyf.isReady());
457     EXPECT_TRUE(anyf.value().second.hasException());
458   }
459
460   // then()
461   {
462     vector<Promise<int>> promises(10);
463     vector<Future<int>> futures;
464
465     for (auto& p : promises)
466       futures.push_back(p.getFuture());
467
468     auto anyf = whenAny(futures.begin(), futures.end())
469       .then([](Try<pair<size_t, Try<int>>>&& f) {
470         EXPECT_EQ(42, f.value().second.value());
471       });
472
473     promises[3].setValue(42);
474     EXPECT_TRUE(anyf.isReady());
475   }
476 }
477
478
479 TEST(when, already_completed) {
480   {
481     vector<Future<void>> fs;
482     for (int i = 0; i < 10; i++)
483       fs.push_back(makeFuture());
484
485     whenAll(fs.begin(), fs.end())
486       .then([&](Try<vector<Try<void>>>&& t) {
487         EXPECT_EQ(fs.size(), t.value().size());
488       });
489   }
490   {
491     vector<Future<int>> fs;
492     for (int i = 0; i < 10; i++)
493       fs.push_back(makeFuture(i));
494
495     whenAny(fs.begin(), fs.end())
496       .then([&](Try<pair<size_t, Try<int>>>&& t) {
497         auto& p = t.value();
498         EXPECT_EQ(p.first, p.second.value());
499       });
500   }
501 }
502
503 TEST(when, whenN) {
504   vector<Promise<void>> promises(10);
505   vector<Future<void>> futures;
506
507   for (auto& p : promises)
508     futures.push_back(p.getFuture());
509
510   bool flag = false;
511   size_t n = 3;
512   whenN(futures.begin(), futures.end(), n)
513     .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
514       flag = true;
515       auto v = t.value();
516       EXPECT_EQ(n, v.size());
517       for (auto& tt : v)
518         EXPECT_TRUE(tt.second.hasValue());
519     });
520
521   promises[0].setValue();
522   EXPECT_FALSE(flag);
523   promises[1].setValue();
524   EXPECT_FALSE(flag);
525   promises[2].setValue();
526   EXPECT_TRUE(flag);
527 }
528
529 /* Ensure that we can compile when_{all,any} with folly::small_vector */
530 TEST(when, small_vector) {
531
532   static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<void>),
533                 "Futures should not be trivially copyable");
534   static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<int>),
535                 "Futures should not be trivially copyable");
536
537   using folly::small_vector;
538   {
539     small_vector<Future<void>> futures;
540
541     for (int i = 0; i < 10; i++)
542       futures.push_back(makeFuture());
543
544     auto anyf = whenAny(futures.begin(), futures.end());
545   }
546
547   {
548     small_vector<Future<void>> futures;
549
550     for (int i = 0; i < 10; i++)
551       futures.push_back(makeFuture());
552
553     auto allf = whenAll(futures.begin(), futures.end());
554   }
555 }
556
557 TEST(Future, whenAllVariadic) {
558   Promise<bool> pb;
559   Promise<int> pi;
560   Future<bool> fb = pb.getFuture();
561   Future<int> fi = pi.getFuture();
562   bool flag = false;
563   whenAll(std::move(fb), std::move(fi))
564     .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
565       flag = true;
566       EXPECT_TRUE(t.hasValue());
567       EXPECT_TRUE(std::get<0>(t.value()).hasValue());
568       EXPECT_EQ(std::get<0>(t.value()).value(), true);
569       EXPECT_TRUE(std::get<1>(t.value()).hasValue());
570       EXPECT_EQ(std::get<1>(t.value()).value(), 42);
571     });
572   pb.setValue(true);
573   EXPECT_FALSE(flag);
574   pi.setValue(42);
575   EXPECT_TRUE(flag);
576 }
577
578 TEST(Future, whenAllVariadicReferences) {
579   Promise<bool> pb;
580   Promise<int> pi;
581   Future<bool> fb = pb.getFuture();
582   Future<int> fi = pi.getFuture();
583   bool flag = false;
584   whenAll(fb, fi)
585     .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
586       flag = true;
587       EXPECT_TRUE(t.hasValue());
588       EXPECT_TRUE(std::get<0>(t.value()).hasValue());
589       EXPECT_EQ(std::get<0>(t.value()).value(), true);
590       EXPECT_TRUE(std::get<1>(t.value()).hasValue());
591       EXPECT_EQ(std::get<1>(t.value()).value(), 42);
592     });
593   pb.setValue(true);
594   EXPECT_FALSE(flag);
595   pi.setValue(42);
596   EXPECT_TRUE(flag);
597 }
598
599 TEST(Future, whenAll_none) {
600   vector<Future<int>> fs;
601   auto f = whenAll(fs.begin(), fs.end());
602   EXPECT_TRUE(f.isReady());
603 }
604
605 TEST(Future, throwCaughtInImmediateThen) {
606   // Neither of these should throw "Promise already satisfied"
607   makeFuture().then(
608     [=](Try<void>&&) -> int { throw std::exception(); });
609   makeFuture().then(
610     [=](Try<void>&&) -> Future<int> { throw std::exception(); });
611 }
612
613 TEST(Future, throwIfFailed) {
614   makeFuture<void>(eggs)
615     .then([=](Try<void>&& t) {
616       EXPECT_THROW(t.throwIfFailed(), eggs_t);
617     });
618   makeFuture()
619     .then([=](Try<void>&& t) {
620       EXPECT_NO_THROW(t.throwIfFailed());
621     });
622
623   makeFuture<int>(eggs)
624     .then([=](Try<int>&& t) {
625       EXPECT_THROW(t.throwIfFailed(), eggs_t);
626     });
627   makeFuture<int>(42)
628     .then([=](Try<int>&& t) {
629       EXPECT_NO_THROW(t.throwIfFailed());
630     });
631 }
632
633 TEST(Future, waitWithSemaphoreImmediate) {
634   waitWithSemaphore(makeFuture());
635   auto done = waitWithSemaphore(makeFuture(42));
636   EXPECT_EQ(42, done);
637
638   vector<int> v{1,2,3};
639   auto done_v = waitWithSemaphore(makeFuture(v));
640   EXPECT_EQ(v.size(), done_v.size());
641   EXPECT_EQ(v, done_v);
642
643   vector<Future<void>> v_f;
644   v_f.push_back(makeFuture());
645   v_f.push_back(makeFuture());
646   auto done_v_f = waitWithSemaphore(whenAll(v_f.begin(), v_f.end()));
647   EXPECT_EQ(2, done_v_f.size());
648
649   vector<Future<bool>> v_fb;
650   v_fb.push_back(makeFuture(true));
651   v_fb.push_back(makeFuture(false));
652   auto fut = whenAll(v_fb.begin(), v_fb.end());
653   auto done_v_fb = waitWithSemaphore(std::move(fut));
654   EXPECT_EQ(2, done_v_fb.size());
655 }
656
657 TEST(Future, waitWithSemaphore) {
658   Promise<int> p;
659   Future<int> f = p.getFuture();
660   std::atomic<bool> flag{false};
661   std::atomic<int> result{1};
662   std::atomic<std::thread::id> id;
663
664   std::thread t([&](Future<int>&& tf){
665       auto n = tf.then([&](Try<int> && t) {
666           id = std::this_thread::get_id();
667           return t.value();
668         });
669       flag = true;
670       result.store(waitWithSemaphore(std::move(n)));
671       LOG(INFO) << result;
672     },
673     std::move(f)
674     );
675   while(!flag){}
676   EXPECT_EQ(result.load(), 1);
677   p.setValue(42);
678   t.join();
679   // validate that the continuation ended up executing in this thread, which
680   // is more to ensure that this test actually tests what it should
681   EXPECT_EQ(id, std::this_thread::get_id());
682   EXPECT_EQ(result.load(), 42);
683 }