8d1f95d3ce203fbda13641c188875f42ce4f656a
[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/Memory.h>
27 #include <folly/wangle/Executor.h>
28 #include <folly/wangle/Future.h>
29 #include <folly/wangle/ManualExecutor.h>
30
31 using namespace folly::wangle;
32 using std::pair;
33 using std::string;
34 using std::unique_ptr;
35 using std::vector;
36
37 #define EXPECT_TYPE(x, T) \
38   EXPECT_TRUE((std::is_same<decltype(x), T>::value))
39
40 typedef WangleException eggs_t;
41 static eggs_t eggs("eggs");
42
43 // Future
44
45 TEST(Future, try) {
46   class A {
47    public:
48     A(int x) : x_(x) {}
49
50     int x() const {
51       return x_;
52     }
53    private:
54     int x_;
55   };
56
57   A a(5);
58   Try<A> t_a(std::move(a));
59
60   Try<void> t_void;
61
62   EXPECT_EQ(5, t_a.value().x());
63 }
64
65 TEST(Future, special) {
66   EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
67   EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
68   EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
69   EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
70 }
71
72 TEST(Future, thenTry) {
73   bool flag = false;
74
75   makeFuture<int>(42).then([&](Try<int>&& t) {
76                               flag = true;
77                               EXPECT_EQ(42, t.value());
78                             });
79   EXPECT_TRUE(flag); flag = false;
80
81   makeFuture<int>(42)
82     .then([](Try<int>&& t) { return t.value(); })
83     .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
84   EXPECT_TRUE(flag); flag = false;
85
86   makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
87   EXPECT_TRUE(flag); flag = false;
88
89   Promise<void> p;
90   auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
91   EXPECT_FALSE(flag);
92   EXPECT_FALSE(f.isReady());
93   p.setValue();
94   EXPECT_TRUE(flag);
95   EXPECT_TRUE(f.isReady());
96 }
97
98 TEST(Future, thenValue) {
99   bool flag = false;
100   makeFuture<int>(42).then([&](int i){
101     EXPECT_EQ(42, i);
102     flag = true;
103   });
104   EXPECT_TRUE(flag); flag = false;
105
106   makeFuture<int>(42)
107     .then([](int i){ return i; })
108     .then([&](int i) { flag = true; EXPECT_EQ(42, i); });
109   EXPECT_TRUE(flag); flag = false;
110
111   makeFuture().then([&]{
112     flag = true;
113   });
114   EXPECT_TRUE(flag); flag = false;
115
116   auto f = makeFuture<int>(eggs).then([&](int i){});
117   EXPECT_THROW(f.value(), eggs_t);
118
119   f = makeFuture<void>(eggs).then([&]{});
120   EXPECT_THROW(f.value(), eggs_t);
121 }
122
123 TEST(Future, thenValueFuture) {
124   bool flag = false;
125   makeFuture<int>(42)
126     .then([](int i){ return makeFuture<int>(std::move(i)); })
127     .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
128   EXPECT_TRUE(flag); flag = false;
129
130   makeFuture()
131     .then([]{ return makeFuture(); })
132     .then([&](Try<void>&& t) { flag = true; });
133   EXPECT_TRUE(flag); flag = false;
134 }
135
136 static string doWorkStatic(Try<string>&& t) {
137   return t.value() + ";static";
138 }
139
140 TEST(Future, thenFunction) {
141   struct Worker {
142     string doWork(Try<string>&& t) {
143       return t.value() + ";class";
144     }
145     static string doWorkStatic(Try<string>&& t) {
146       return t.value() + ";class-static";
147     }
148   } w;
149
150   auto f = makeFuture<string>("start")
151     .then(doWorkStatic)
152     .then(Worker::doWorkStatic)
153     .then(&w, &Worker::doWork);
154
155   EXPECT_EQ(f.value(), "start;static;class-static;class");
156 }
157
158 static Future<string> doWorkStaticFuture(Try<string>&& t) {
159   return makeFuture(t.value() + ";static");
160 }
161
162 TEST(Future, thenFunctionFuture) {
163   struct Worker {
164     Future<string> doWorkFuture(Try<string>&& t) {
165       return makeFuture(t.value() + ";class");
166     }
167     static Future<string> doWorkStaticFuture(Try<string>&& t) {
168       return makeFuture(t.value() + ";class-static");
169     }
170   } w;
171
172   auto f = makeFuture<string>("start")
173     .then(doWorkStaticFuture)
174     .then(Worker::doWorkStaticFuture)
175     .then(&w, &Worker::doWorkFuture);
176
177   EXPECT_EQ(f.value(), "start;static;class-static;class");
178 }
179
180 TEST(Future, value) {
181   auto f = makeFuture(unique_ptr<int>(new int(42)));
182   auto up = std::move(f.value());
183   EXPECT_EQ(42, *up);
184
185   EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
186 }
187
188 TEST(Future, isReady) {
189   Promise<int> p;
190   auto f = p.getFuture();
191   EXPECT_FALSE(f.isReady());
192   p.setValue(42);
193   EXPECT_TRUE(f.isReady());
194   }
195
196 TEST(Future, futureNotReady) {
197   Promise<int> p;
198   Future<int> f = p.getFuture();
199   EXPECT_THROW(f.value(), eggs_t);
200 }
201
202 TEST(Future, hasException) {
203   EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
204   EXPECT_FALSE(makeFuture(42).getTry().hasException());
205 }
206
207 TEST(Future, hasValue) {
208   EXPECT_TRUE(makeFuture(42).getTry().hasValue());
209   EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
210 }
211
212 TEST(Future, makeFuture) {
213   EXPECT_TYPE(makeFuture(42), Future<int>);
214   EXPECT_EQ(42, makeFuture(42).value());
215
216   EXPECT_TYPE(makeFuture<float>(42), Future<float>);
217   EXPECT_EQ(42, makeFuture<float>(42).value());
218
219   auto fun = [] { return 42; };
220   EXPECT_TYPE(makeFutureTry(fun), Future<int>);
221   EXPECT_EQ(42, makeFutureTry(fun).value());
222
223   auto failfun = []() -> int { throw eggs; };
224   EXPECT_TYPE(makeFutureTry(failfun), Future<int>);
225   EXPECT_THROW(makeFutureTry(failfun).value(), eggs_t);
226
227   EXPECT_TYPE(makeFuture(), Future<void>);
228 }
229
230 // Promise
231
232 TEST(Promise, special) {
233   EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
234   EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
235   EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
236   EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
237 }
238
239 TEST(Promise, getFuture) {
240   Promise<int> p;
241   Future<int> f = p.getFuture();
242   EXPECT_FALSE(f.isReady());
243 }
244
245 TEST(Promise, setValue) {
246   Promise<int> fund;
247   auto ffund = fund.getFuture();
248   fund.setValue(42);
249   EXPECT_EQ(42, ffund.value());
250
251   struct Foo {
252     string name;
253     int value;
254   };
255
256   Promise<Foo> pod;
257   auto fpod = pod.getFuture();
258   Foo f = {"the answer", 42};
259   pod.setValue(f);
260   Foo f2 = fpod.value();
261   EXPECT_EQ(f.name, f2.name);
262   EXPECT_EQ(f.value, f2.value);
263
264   pod = Promise<Foo>();
265   fpod = pod.getFuture();
266   pod.setValue(std::move(f2));
267   Foo f3 = fpod.value();
268   EXPECT_EQ(f.name, f3.name);
269   EXPECT_EQ(f.value, f3.value);
270
271   Promise<unique_ptr<int>> mov;
272   auto fmov = mov.getFuture();
273   mov.setValue(unique_ptr<int>(new int(42)));
274   unique_ptr<int> ptr = std::move(fmov.value());
275   EXPECT_EQ(42, *ptr);
276
277   Promise<void> v;
278   auto fv = v.getFuture();
279   v.setValue();
280   EXPECT_TRUE(fv.isReady());
281 }
282
283 TEST(Promise, setException) {
284   {
285     Promise<void> p;
286     auto f = p.getFuture();
287     p.setException(eggs);
288     EXPECT_THROW(f.value(), eggs_t);
289   }
290   {
291     Promise<void> p;
292     auto f = p.getFuture();
293     try {
294       throw eggs;
295     } catch (...) {
296       p.setException(std::current_exception());
297     }
298     EXPECT_THROW(f.value(), eggs_t);
299   }
300 }
301
302 TEST(Promise, fulfil) {
303   {
304     Promise<int> p;
305     auto f = p.getFuture();
306     p.fulfil([] { return 42; });
307     EXPECT_EQ(42, f.value());
308   }
309   {
310     Promise<int> p;
311     auto f = p.getFuture();
312     p.fulfil([]() -> int { throw eggs; });
313     EXPECT_THROW(f.value(), eggs_t);
314   }
315 }
316
317 TEST(Future, finish) {
318   auto x = std::make_shared<int>(0);
319   {
320     Promise<int> p;
321     auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
322
323     // The callback hasn't executed
324     EXPECT_EQ(0, *x);
325
326     // The callback has a reference to x
327     EXPECT_EQ(2, x.use_count());
328
329     p.setValue(42);
330
331     // the callback has executed
332     EXPECT_EQ(42, *x);
333   }
334   // the callback has been destructed
335   // and has released its reference to x
336   EXPECT_EQ(1, x.use_count());
337 }
338
339 TEST(Future, unwrap) {
340   Promise<int> a;
341   Promise<int> b;
342
343   auto fa = a.getFuture();
344   auto fb = b.getFuture();
345
346   bool flag1 = false;
347   bool flag2 = false;
348
349   // do a, then do b, and get the result of a + b.
350   Future<int> f = fa.then([&](Try<int>&& ta) {
351     auto va = ta.value();
352     flag1 = true;
353     return fb.then([va, &flag2](Try<int>&& tb) {
354       flag2 = true;
355       return va + tb.value();
356     });
357   });
358
359   EXPECT_FALSE(flag1);
360   EXPECT_FALSE(flag2);
361   EXPECT_FALSE(f.isReady());
362
363   a.setValue(3);
364   EXPECT_TRUE(flag1);
365   EXPECT_FALSE(flag2);
366   EXPECT_FALSE(f.isReady());
367
368   b.setValue(4);
369   EXPECT_TRUE(flag1);
370   EXPECT_TRUE(flag2);
371   EXPECT_EQ(7, f.value());
372 }
373
374 TEST(Future, whenAll) {
375   // returns a vector variant
376   {
377     vector<Promise<int>> promises(10);
378     vector<Future<int>> futures;
379
380     for (auto& p : promises)
381       futures.push_back(p.getFuture());
382
383     auto allf = whenAll(futures.begin(), futures.end());
384
385     random_shuffle(promises.begin(), promises.end());
386     for (auto& p : promises) {
387       EXPECT_FALSE(allf.isReady());
388       p.setValue(42);
389     }
390
391     EXPECT_TRUE(allf.isReady());
392     auto& results = allf.value();
393     for (auto& t : results) {
394       EXPECT_EQ(42, t.value());
395     }
396   }
397
398   // check error semantics
399   {
400     vector<Promise<int>> promises(4);
401     vector<Future<int>> futures;
402
403     for (auto& p : promises)
404       futures.push_back(p.getFuture());
405
406     auto allf = whenAll(futures.begin(), futures.end());
407
408
409     promises[0].setValue(42);
410     promises[1].setException(eggs);
411
412     EXPECT_FALSE(allf.isReady());
413
414     promises[2].setValue(42);
415
416     EXPECT_FALSE(allf.isReady());
417
418     promises[3].setException(eggs);
419
420     EXPECT_TRUE(allf.isReady());
421     EXPECT_FALSE(allf.getTry().hasException());
422
423     auto& results = allf.value();
424     EXPECT_EQ(42, results[0].value());
425     EXPECT_TRUE(results[1].hasException());
426     EXPECT_EQ(42, results[2].value());
427     EXPECT_TRUE(results[3].hasException());
428   }
429
430   // check that futures are ready in then()
431   {
432     vector<Promise<void>> promises(10);
433     vector<Future<void>> futures;
434
435     for (auto& p : promises)
436       futures.push_back(p.getFuture());
437
438     auto allf = whenAll(futures.begin(), futures.end())
439       .then([](Try<vector<Try<void>>>&& ts) {
440         for (auto& f : ts.value())
441           f.value();
442       });
443
444     random_shuffle(promises.begin(), promises.end());
445     for (auto& p : promises)
446       p.setValue();
447     EXPECT_TRUE(allf.isReady());
448   }
449 }
450
451
452 TEST(Future, whenAny) {
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     for (auto& f : futures) {
461       EXPECT_FALSE(f.isReady());
462     }
463
464     auto anyf = whenAny(futures.begin(), futures.end());
465
466     /* futures were moved in, so these are invalid now */
467     EXPECT_FALSE(anyf.isReady());
468
469     promises[7].setValue(42);
470     EXPECT_TRUE(anyf.isReady());
471     auto& idx_fut = anyf.value();
472
473     auto i = idx_fut.first;
474     EXPECT_EQ(7, i);
475
476     auto& f = idx_fut.second;
477     EXPECT_EQ(42, f.value());
478   }
479
480   // error
481   {
482     vector<Promise<void>> promises(10);
483     vector<Future<void>> futures;
484
485     for (auto& p : promises)
486       futures.push_back(p.getFuture());
487
488     for (auto& f : futures) {
489       EXPECT_FALSE(f.isReady());
490     }
491
492     auto anyf = whenAny(futures.begin(), futures.end());
493
494     EXPECT_FALSE(anyf.isReady());
495
496     promises[3].setException(eggs);
497     EXPECT_TRUE(anyf.isReady());
498     EXPECT_TRUE(anyf.value().second.hasException());
499   }
500
501   // then()
502   {
503     vector<Promise<int>> promises(10);
504     vector<Future<int>> futures;
505
506     for (auto& p : promises)
507       futures.push_back(p.getFuture());
508
509     auto anyf = whenAny(futures.begin(), futures.end())
510       .then([](Try<pair<size_t, Try<int>>>&& f) {
511         EXPECT_EQ(42, f.value().second.value());
512       });
513
514     promises[3].setValue(42);
515     EXPECT_TRUE(anyf.isReady());
516   }
517 }
518
519
520 TEST(when, already_completed) {
521   {
522     vector<Future<void>> fs;
523     for (int i = 0; i < 10; i++)
524       fs.push_back(makeFuture());
525
526     whenAll(fs.begin(), fs.end())
527       .then([&](Try<vector<Try<void>>>&& t) {
528         EXPECT_EQ(fs.size(), t.value().size());
529       });
530   }
531   {
532     vector<Future<int>> fs;
533     for (int i = 0; i < 10; i++)
534       fs.push_back(makeFuture(i));
535
536     whenAny(fs.begin(), fs.end())
537       .then([&](Try<pair<size_t, Try<int>>>&& t) {
538         auto& p = t.value();
539         EXPECT_EQ(p.first, p.second.value());
540       });
541   }
542 }
543
544 TEST(when, whenN) {
545   vector<Promise<void>> promises(10);
546   vector<Future<void>> futures;
547
548   for (auto& p : promises)
549     futures.push_back(p.getFuture());
550
551   bool flag = false;
552   size_t n = 3;
553   whenN(futures.begin(), futures.end(), n)
554     .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
555       flag = true;
556       auto v = t.value();
557       EXPECT_EQ(n, v.size());
558       for (auto& tt : v)
559         EXPECT_TRUE(tt.second.hasValue());
560     });
561
562   promises[0].setValue();
563   EXPECT_FALSE(flag);
564   promises[1].setValue();
565   EXPECT_FALSE(flag);
566   promises[2].setValue();
567   EXPECT_TRUE(flag);
568 }
569
570 /* Ensure that we can compile when_{all,any} with folly::small_vector */
571 TEST(when, small_vector) {
572
573   static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<void>),
574                 "Futures should not be trivially copyable");
575   static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<int>),
576                 "Futures should not be trivially copyable");
577
578   using folly::small_vector;
579   {
580     small_vector<Future<void>> futures;
581
582     for (int i = 0; i < 10; i++)
583       futures.push_back(makeFuture());
584
585     auto anyf = whenAny(futures.begin(), futures.end());
586   }
587
588   {
589     small_vector<Future<void>> futures;
590
591     for (int i = 0; i < 10; i++)
592       futures.push_back(makeFuture());
593
594     auto allf = whenAll(futures.begin(), futures.end());
595   }
596 }
597
598 TEST(Future, whenAllVariadic) {
599   Promise<bool> pb;
600   Promise<int> pi;
601   Future<bool> fb = pb.getFuture();
602   Future<int> fi = pi.getFuture();
603   bool flag = false;
604   whenAll(std::move(fb), std::move(fi))
605     .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
606       flag = true;
607       EXPECT_TRUE(t.hasValue());
608       EXPECT_TRUE(std::get<0>(t.value()).hasValue());
609       EXPECT_EQ(std::get<0>(t.value()).value(), true);
610       EXPECT_TRUE(std::get<1>(t.value()).hasValue());
611       EXPECT_EQ(std::get<1>(t.value()).value(), 42);
612     });
613   pb.setValue(true);
614   EXPECT_FALSE(flag);
615   pi.setValue(42);
616   EXPECT_TRUE(flag);
617 }
618
619 TEST(Future, whenAllVariadicReferences) {
620   Promise<bool> pb;
621   Promise<int> pi;
622   Future<bool> fb = pb.getFuture();
623   Future<int> fi = pi.getFuture();
624   bool flag = false;
625   whenAll(fb, fi)
626     .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
627       flag = true;
628       EXPECT_TRUE(t.hasValue());
629       EXPECT_TRUE(std::get<0>(t.value()).hasValue());
630       EXPECT_EQ(std::get<0>(t.value()).value(), true);
631       EXPECT_TRUE(std::get<1>(t.value()).hasValue());
632       EXPECT_EQ(std::get<1>(t.value()).value(), 42);
633     });
634   pb.setValue(true);
635   EXPECT_FALSE(flag);
636   pi.setValue(42);
637   EXPECT_TRUE(flag);
638 }
639
640 TEST(Future, whenAll_none) {
641   vector<Future<int>> fs;
642   auto f = whenAll(fs.begin(), fs.end());
643   EXPECT_TRUE(f.isReady());
644 }
645
646 TEST(Future, throwCaughtInImmediateThen) {
647   // Neither of these should throw "Promise already satisfied"
648   makeFuture().then(
649     [=](Try<void>&&) -> int { throw std::exception(); });
650   makeFuture().then(
651     [=](Try<void>&&) -> Future<int> { throw std::exception(); });
652 }
653
654 TEST(Future, throwIfFailed) {
655   makeFuture<void>(eggs)
656     .then([=](Try<void>&& t) {
657       EXPECT_THROW(t.throwIfFailed(), eggs_t);
658     });
659   makeFuture()
660     .then([=](Try<void>&& t) {
661       EXPECT_NO_THROW(t.throwIfFailed());
662     });
663
664   makeFuture<int>(eggs)
665     .then([=](Try<int>&& t) {
666       EXPECT_THROW(t.throwIfFailed(), eggs_t);
667     });
668   makeFuture<int>(42)
669     .then([=](Try<int>&& t) {
670       EXPECT_NO_THROW(t.throwIfFailed());
671     });
672 }
673
674 TEST(Future, waitWithSemaphoreImmediate) {
675   waitWithSemaphore(makeFuture());
676   auto done = waitWithSemaphore(makeFuture(42)).value();
677   EXPECT_EQ(42, done);
678
679   vector<int> v{1,2,3};
680   auto done_v = waitWithSemaphore(makeFuture(v)).value();
681   EXPECT_EQ(v.size(), done_v.size());
682   EXPECT_EQ(v, done_v);
683
684   vector<Future<void>> v_f;
685   v_f.push_back(makeFuture());
686   v_f.push_back(makeFuture());
687   auto done_v_f = waitWithSemaphore(whenAll(v_f.begin(), v_f.end())).value();
688   EXPECT_EQ(2, done_v_f.size());
689
690   vector<Future<bool>> v_fb;
691   v_fb.push_back(makeFuture(true));
692   v_fb.push_back(makeFuture(false));
693   auto fut = whenAll(v_fb.begin(), v_fb.end());
694   auto done_v_fb = std::move(waitWithSemaphore(std::move(fut)).value());
695   EXPECT_EQ(2, done_v_fb.size());
696 }
697
698 TEST(Future, waitWithSemaphore) {
699   Promise<int> p;
700   Future<int> f = p.getFuture();
701   std::atomic<bool> flag{false};
702   std::atomic<int> result{1};
703   std::atomic<std::thread::id> id;
704
705   std::thread t([&](Future<int>&& tf){
706       auto n = tf.then([&](Try<int> && t) {
707           id = std::this_thread::get_id();
708           return t.value();
709         });
710       flag = true;
711       result.store(waitWithSemaphore(std::move(n)).value());
712     },
713     std::move(f)
714     );
715   while(!flag){}
716   EXPECT_EQ(result.load(), 1);
717   p.setValue(42);
718   t.join();
719   // validate that the callback ended up executing in this thread, which
720   // is more to ensure that this test actually tests what it should
721   EXPECT_EQ(id, std::this_thread::get_id());
722   EXPECT_EQ(result.load(), 42);
723 }
724
725 TEST(Future, waitWithSemaphoreForTime) {
726  {
727   Promise<int> p;
728   Future<int> f = p.getFuture();
729   auto t = waitWithSemaphore(std::move(f),
730     std::chrono::microseconds(1));
731   EXPECT_FALSE(t.isReady());
732   p.setValue(1);
733   EXPECT_TRUE(t.isReady());
734  }
735  {
736   Promise<int> p;
737   Future<int> f = p.getFuture();
738   p.setValue(1);
739   auto t = waitWithSemaphore(std::move(f),
740     std::chrono::milliseconds(1));
741   EXPECT_TRUE(t.isReady());
742  }
743  {
744   vector<Future<bool>> v_fb;
745   v_fb.push_back(makeFuture(true));
746   v_fb.push_back(makeFuture(false));
747   auto f = whenAll(v_fb.begin(), v_fb.end());
748   auto t = waitWithSemaphore(std::move(f),
749     std::chrono::milliseconds(1));
750   EXPECT_TRUE(t.isReady());
751   EXPECT_EQ(2, t.value().size());
752  }
753  {
754   vector<Future<bool>> v_fb;
755   Promise<bool> p1;
756   Promise<bool> p2;
757   v_fb.push_back(p1.getFuture());
758   v_fb.push_back(p2.getFuture());
759   auto f = whenAll(v_fb.begin(), v_fb.end());
760   auto t = waitWithSemaphore(std::move(f),
761     std::chrono::milliseconds(1));
762   EXPECT_FALSE(t.isReady());
763   p1.setValue(true);
764   EXPECT_FALSE(t.isReady());
765   p2.setValue(true);
766   EXPECT_TRUE(t.isReady());
767  }
768  {
769   auto t = waitWithSemaphore(makeFuture(),
770     std::chrono::milliseconds(1));
771   EXPECT_TRUE(t.isReady());
772  }
773 }
774
775 TEST(Future, callbackAfterActivate) {
776   Promise<void> p;
777   auto f = p.getFuture();
778   f.deactivate();
779
780   size_t count = 0;
781   f.then([&](Try<void>&&) { count++; });
782
783   p.setValue();
784   EXPECT_EQ(0, count);
785
786   f.activate();
787   EXPECT_EQ(1, count);
788 }
789
790 TEST(Future, activateOnDestruct) {
791   Promise<void> p;
792   auto f = p.getFuture();
793   f.deactivate();
794
795   size_t count = 0;
796   f.then([&](Try<void>&&) { count++; });
797
798   p.setValue();
799   EXPECT_EQ(0, count);
800
801   f = makeFuture(); // force destruction of old f
802   EXPECT_EQ(1, count);
803 }
804
805 TEST(Future, viaActsCold) {
806   ManualExecutor x;
807   size_t count = 0;
808
809   auto fv = makeFuture().via(&x);
810   fv.then([&](Try<void>&&) { count++; });
811
812   EXPECT_EQ(0, count);
813
814   fv.activate();
815
816   EXPECT_EQ(1, x.run());
817   EXPECT_EQ(1, count);
818 }
819
820 TEST(Future, viaIsCold) {
821   ManualExecutor x;
822   EXPECT_FALSE(makeFuture().via(&x).isActive());
823 }
824
825 TEST(Future, viaRaces) {
826   ManualExecutor x;
827   Promise<void> p;
828   auto tid = std::this_thread::get_id();
829   bool done = false;
830
831   std::thread t1([&] {
832     p.getFuture()
833       .via(&x)
834       .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
835       .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
836       .then([&](Try<void>&&) { done = true; });
837   });
838
839   std::thread t2([&] {
840     p.setValue();
841   });
842
843   while (!done) x.run();
844   t1.join();
845   t2.join();
846 }
847
848 // TODO(#4920689)
849 TEST(Future, viaRaces_2stage) {
850   ManualExecutor x;
851   Promise<void> p;
852   auto tid = std::this_thread::get_id();
853   bool done = false;
854
855   std::thread t1([&] {
856     auto f2 = p.getFuture().via(&x);
857     f2.then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
858       .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
859       .then([&](Try<void>&&) { done = true; });
860
861     // the bug was in the promise being fulfilled before f2 is reactivated. we
862     // could sleep, but yielding should cause this to fail with reasonable
863     // probability
864     std::this_thread::yield();
865     f2.activate();
866   });
867
868   std::thread t2([&] {
869     p.setValue();
870   });
871
872   while (!done) x.run();
873   t1.join();
874   t2.join();
875 }
876
877 TEST(Future, getFuture_after_setValue) {
878   Promise<int> p;
879   p.setValue(42);
880   EXPECT_EQ(42, p.getFuture().value());
881 }
882
883 TEST(Future, getFuture_after_setException) {
884   Promise<void> p;
885   p.fulfil([]() -> void { throw std::logic_error("foo"); });
886   EXPECT_THROW(p.getFuture().value(), std::logic_error);
887 }
888
889 TEST(Future, detachRace) {
890   // Task #5438209
891   // This test is designed to detect a race that was in Core::detachOne()
892   // where detached_ was incremented and then tested, and that
893   // allowed a race where both Promise and Future would think they were the
894   // second and both try to delete. This showed up at scale but was very
895   // difficult to reliably repro in a test. As it is, this only fails about
896   // once in every 1,000 executions. Doing this 1,000 times is going to make a
897   // slow test so I won't do that but if it ever fails, take it seriously, and
898   // run the test binary with "--gtest_repeat=10000 --gtest_filter=*detachRace"
899   // (Don't forget to enable ASAN)
900   auto p = folly::make_unique<Promise<bool>>();
901   auto f = folly::make_unique<Future<bool>>(p->getFuture());
902   folly::Baton<> baton;
903   std::thread t1([&]{
904     baton.post();
905     p.reset();
906   });
907   baton.wait();
908   f.reset();
909   t1.join();
910 }