8a66184af8e5dceec1417c8eac57244ab9104f31
[folly.git] / folly / futures / test / FutureTest.cpp
1 /*
2  * Copyright 2016 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 <folly/futures/Future.h>
18 #include <folly/Unit.h>
19 #include <folly/Memory.h>
20 #include <folly/Executor.h>
21 #include <folly/dynamic.h>
22 #include <folly/Baton.h>
23 #include <folly/portability/GTest.h>
24 #include <folly/portability/Unistd.h>
25
26 #include <algorithm>
27 #include <atomic>
28 #include <memory>
29 #include <numeric>
30 #include <string>
31 #include <thread>
32 #include <type_traits>
33
34 using namespace folly;
35
36 #define EXPECT_TYPE(x, T) \
37   EXPECT_TRUE((std::is_same<decltype(x), T>::value))
38
39 typedef FutureException eggs_t;
40 static eggs_t eggs("eggs");
41
42 // Future
43
44 TEST(Future, futureDefaultCtor) {
45   Future<Unit>();
46 }
47
48 TEST(Future, futureToUnit) {
49   Future<Unit> fu = makeFuture(42).unit();
50   fu.value();
51   EXPECT_TRUE(makeFuture<int>(eggs).unit().hasException());
52 }
53
54 TEST(Future, voidFutureToUnit) {
55   Future<Unit> fu = makeFuture().unit();
56   fu.value();
57   EXPECT_TRUE(makeFuture<Unit>(eggs).unit().hasException());
58 }
59
60 TEST(Future, unitFutureToUnitIdentity) {
61   Future<Unit> fu = makeFuture(Unit{}).unit();
62   fu.value();
63   EXPECT_TRUE(makeFuture<Unit>(eggs).unit().hasException());
64 }
65
66 TEST(Future, toUnitWhileInProgress) {
67   Promise<int> p;
68   Future<Unit> fu = p.getFuture().unit();
69   EXPECT_FALSE(fu.isReady());
70   p.setValue(42);
71   EXPECT_TRUE(fu.isReady());
72 }
73
74 TEST(Future, makeFutureWithUnit) {
75   int count = 0;
76   Future<Unit> fu = makeFutureWith([&] { count++; });
77   EXPECT_EQ(1, count);
78 }
79
80 TEST(Future, onError) {
81   bool theFlag = false;
82   auto flag = [&]{ theFlag = true; };
83 #define EXPECT_FLAG() \
84   do { \
85     EXPECT_TRUE(theFlag); \
86     theFlag = false; \
87   } while(0);
88
89 #define EXPECT_NO_FLAG() \
90   do { \
91     EXPECT_FALSE(theFlag); \
92     theFlag = false; \
93   } while(0);
94
95   // By reference
96   {
97     auto f = makeFuture().then([] {
98       throw eggs;
99     }).onError([&](eggs_t& /* e */) { flag(); });
100     EXPECT_FLAG();
101     EXPECT_NO_THROW(f.value());
102   }
103
104   {
105     auto f = makeFuture()
106                  .then([] { throw eggs; })
107                  .onError([&](eggs_t& /* e */) {
108                    flag();
109                    return makeFuture();
110                  });
111     EXPECT_FLAG();
112     EXPECT_NO_THROW(f.value());
113   }
114
115   // By value
116   {
117     auto f = makeFuture().then([] {
118       throw eggs;
119     }).onError([&](eggs_t /* e */) { flag(); });
120     EXPECT_FLAG();
121     EXPECT_NO_THROW(f.value());
122   }
123
124   {
125     auto f = makeFuture()
126                  .then([] { throw eggs; })
127                  .onError([&](eggs_t /* e */) {
128                    flag();
129                    return makeFuture();
130                  });
131     EXPECT_FLAG();
132     EXPECT_NO_THROW(f.value());
133   }
134
135   // Polymorphic
136   {
137     auto f = makeFuture().then([] {
138       throw eggs;
139     }).onError([&](std::exception& /* e */) { flag(); });
140     EXPECT_FLAG();
141     EXPECT_NO_THROW(f.value());
142   }
143
144   {
145     auto f = makeFuture()
146                  .then([] { throw eggs; })
147                  .onError([&](std::exception& /* e */) {
148                    flag();
149                    return makeFuture();
150                  });
151     EXPECT_FLAG();
152     EXPECT_NO_THROW(f.value());
153   }
154
155   // Non-exceptions
156   {
157     auto f = makeFuture().then([] {
158       throw - 1;
159     }).onError([&](int /* e */) { flag(); });
160     EXPECT_FLAG();
161     EXPECT_NO_THROW(f.value());
162   }
163
164   {
165     auto f = makeFuture()
166                  .then([] { throw - 1; })
167                  .onError([&](int /* e */) {
168                    flag();
169                    return makeFuture();
170                  });
171     EXPECT_FLAG();
172     EXPECT_NO_THROW(f.value());
173   }
174
175   // Mutable lambda
176   {
177     auto f = makeFuture().then([] {
178       throw eggs;
179     }).onError([&](eggs_t& /* e */) mutable { flag(); });
180     EXPECT_FLAG();
181     EXPECT_NO_THROW(f.value());
182   }
183
184   {
185     auto f = makeFuture()
186                  .then([] { throw eggs; })
187                  .onError([&](eggs_t& /* e */) mutable {
188                    flag();
189                    return makeFuture();
190                  });
191     EXPECT_FLAG();
192     EXPECT_NO_THROW(f.value());
193   }
194
195   // No throw
196   {
197     auto f = makeFuture()
198                  .then([] { return 42; })
199                  .onError([&](eggs_t& /* e */) {
200                    flag();
201                    return -1;
202                  });
203     EXPECT_NO_FLAG();
204     EXPECT_EQ(42, f.value());
205   }
206
207   {
208     auto f = makeFuture()
209                  .then([] { return 42; })
210                  .onError([&](eggs_t& /* e */) {
211                    flag();
212                    return makeFuture<int>(-1);
213                  });
214     EXPECT_NO_FLAG();
215     EXPECT_EQ(42, f.value());
216   }
217
218   // Catch different exception
219   {
220     auto f = makeFuture().then([] {
221       throw eggs;
222     }).onError([&](std::runtime_error& /* e */) { flag(); });
223     EXPECT_NO_FLAG();
224     EXPECT_THROW(f.value(), eggs_t);
225   }
226
227   {
228     auto f = makeFuture()
229                  .then([] { throw eggs; })
230                  .onError([&](std::runtime_error& /* e */) {
231                    flag();
232                    return makeFuture();
233                  });
234     EXPECT_NO_FLAG();
235     EXPECT_THROW(f.value(), eggs_t);
236   }
237
238   // Returned value propagates
239   {
240     auto f = makeFuture().then([] {
241       throw eggs;
242       return 0;
243     }).onError([&](eggs_t& /* e */) { return 42; });
244     EXPECT_EQ(42, f.value());
245   }
246
247   // Returned future propagates
248   {
249     auto f = makeFuture().then([] {
250       throw eggs;
251       return 0;
252     }).onError([&](eggs_t& /* e */) { return makeFuture<int>(42); });
253     EXPECT_EQ(42, f.value());
254   }
255
256   // Throw in callback
257   {
258     auto f = makeFuture()
259       .then([] { throw eggs; return 0; })
260       .onError([&] (eggs_t& e) { throw e; return -1; });
261     EXPECT_THROW(f.value(), eggs_t);
262   }
263
264   {
265     auto f = makeFuture()
266       .then([] { throw eggs; return 0; })
267       .onError([&] (eggs_t& e) { throw e; return makeFuture<int>(-1); });
268     EXPECT_THROW(f.value(), eggs_t);
269   }
270
271   // exception_wrapper, return Future<T>
272   {
273     auto f = makeFuture()
274                  .then([] { throw eggs; })
275                  .onError([&](exception_wrapper /* e */) {
276                    flag();
277                    return makeFuture();
278                  });
279     EXPECT_FLAG();
280     EXPECT_NO_THROW(f.value());
281   }
282
283   // exception_wrapper, return Future<T> but throw
284   {
285     auto f = makeFuture()
286                  .then([] {
287                    throw eggs;
288                    return 0;
289                  })
290                  .onError([&](exception_wrapper /* e */) {
291                    flag();
292                    throw eggs;
293                    return makeFuture<int>(-1);
294                  });
295     EXPECT_FLAG();
296     EXPECT_THROW(f.value(), eggs_t);
297   }
298
299   // exception_wrapper, return T
300   {
301     auto f = makeFuture()
302                  .then([] {
303                    throw eggs;
304                    return 0;
305                  })
306                  .onError([&](exception_wrapper /* e */) {
307                    flag();
308                    return -1;
309                  });
310     EXPECT_FLAG();
311     EXPECT_EQ(-1, f.value());
312   }
313
314   // exception_wrapper, return T but throw
315   {
316     auto f = makeFuture()
317                  .then([] {
318                    throw eggs;
319                    return 0;
320                  })
321                  .onError([&](exception_wrapper /* e */) {
322                    flag();
323                    throw eggs;
324                    return -1;
325                  });
326     EXPECT_FLAG();
327     EXPECT_THROW(f.value(), eggs_t);
328   }
329
330   // const exception_wrapper&
331   {
332     auto f = makeFuture()
333                  .then([] { throw eggs; })
334                  .onError([&](const exception_wrapper& /* e */) {
335                    flag();
336                    return makeFuture();
337                  });
338     EXPECT_FLAG();
339     EXPECT_NO_THROW(f.value());
340   }
341
342 }
343
344 TEST(Future, special) {
345   EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
346   EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
347   EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
348   EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
349 }
350
351 TEST(Future, then) {
352   auto f = makeFuture<std::string>("0")
353     .then([](){
354       return makeFuture<std::string>("1"); })
355     .then([](Try<std::string>&& t) {
356       return makeFuture(t.value() + ";2"); })
357     .then([](const Try<std::string>&& t) {
358       return makeFuture(t.value() + ";3"); })
359     .then([](Try<std::string>& t) {
360       return makeFuture(t.value() + ";4"); })
361     .then([](const Try<std::string>& t) {
362       return makeFuture(t.value() + ";5"); })
363     .then([](Try<std::string> t) {
364       return makeFuture(t.value() + ";6"); })
365     .then([](const Try<std::string> t) {
366       return makeFuture(t.value() + ";7"); })
367     .then([](std::string&& s) {
368       return makeFuture(s + ";8"); })
369     .then([](const std::string&& s) {
370       return makeFuture(s + ";9"); })
371     .then([](std::string& s) {
372       return makeFuture(s + ";10"); })
373     .then([](const std::string& s) {
374       return makeFuture(s + ";11"); })
375     .then([](std::string s) {
376       return makeFuture(s + ";12"); })
377     .then([](const std::string s) {
378       return makeFuture(s + ";13"); })
379   ;
380   EXPECT_EQ(f.value(), "1;2;3;4;5;6;7;8;9;10;11;12;13");
381 }
382
383 TEST(Future, thenTry) {
384   bool flag = false;
385
386   makeFuture<int>(42).then([&](Try<int>&& t) {
387                               flag = true;
388                               EXPECT_EQ(42, t.value());
389                             });
390   EXPECT_TRUE(flag); flag = false;
391
392   makeFuture<int>(42)
393     .then([](Try<int>&& t) { return t.value(); })
394     .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
395   EXPECT_TRUE(flag); flag = false;
396
397   makeFuture().then([&](Try<Unit>&& t) { flag = true; t.value(); });
398   EXPECT_TRUE(flag); flag = false;
399
400   Promise<Unit> p;
401   auto f = p.getFuture().then([&](Try<Unit>&& /* t */) { flag = true; });
402   EXPECT_FALSE(flag);
403   EXPECT_FALSE(f.isReady());
404   p.setValue();
405   EXPECT_TRUE(flag);
406   EXPECT_TRUE(f.isReady());
407 }
408
409 TEST(Future, thenValue) {
410   bool flag = false;
411   makeFuture<int>(42).then([&](int i){
412     EXPECT_EQ(42, i);
413     flag = true;
414   });
415   EXPECT_TRUE(flag); flag = false;
416
417   makeFuture<int>(42)
418     .then([](int i){ return i; })
419     .then([&](int i) { flag = true; EXPECT_EQ(42, i); });
420   EXPECT_TRUE(flag); flag = false;
421
422   makeFuture().then([&]{
423     flag = true;
424   });
425   EXPECT_TRUE(flag); flag = false;
426
427   auto f = makeFuture<int>(eggs).then([&](int /* i */) {});
428   EXPECT_THROW(f.value(), eggs_t);
429
430   f = makeFuture<Unit>(eggs).then([&]{});
431   EXPECT_THROW(f.value(), eggs_t);
432 }
433
434 TEST(Future, thenValueFuture) {
435   bool flag = false;
436   makeFuture<int>(42)
437     .then([](int i){ return makeFuture<int>(std::move(i)); })
438     .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
439   EXPECT_TRUE(flag); flag = false;
440
441   makeFuture().then([] {
442     return makeFuture();
443   }).then([&](Try<Unit>&& /* t */) { flag = true; });
444   EXPECT_TRUE(flag); flag = false;
445 }
446
447 static std::string doWorkStatic(Try<std::string>&& t) {
448   return t.value() + ";static";
449 }
450
451 TEST(Future, thenFunction) {
452   struct Worker {
453     std::string doWork(Try<std::string>&& t) {
454       return t.value() + ";class";
455     }
456     static std::string doWorkStatic(Try<std::string>&& t) {
457       return t.value() + ";class-static";
458     }
459   } w;
460
461   auto f = makeFuture<std::string>("start")
462     .then(doWorkStatic)
463     .then(Worker::doWorkStatic)
464     .then(&Worker::doWork, &w);
465
466   EXPECT_EQ(f.value(), "start;static;class-static;class");
467 }
468
469 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
470   return makeFuture(t.value() + ";static");
471 }
472
473 TEST(Future, thenFunctionFuture) {
474   struct Worker {
475     Future<std::string> doWorkFuture(Try<std::string>&& t) {
476       return makeFuture(t.value() + ";class");
477     }
478     static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
479       return makeFuture(t.value() + ";class-static");
480     }
481   } w;
482
483   auto f = makeFuture<std::string>("start")
484     .then(doWorkStaticFuture)
485     .then(Worker::doWorkStaticFuture)
486     .then(&Worker::doWorkFuture, &w);
487
488   EXPECT_EQ(f.value(), "start;static;class-static;class");
489 }
490
491 TEST(Future, thenStdFunction) {
492   {
493     std::function<int()> fn = [](){ return 42; };
494     auto f = makeFuture().then(std::move(fn));
495     EXPECT_EQ(f.value(), 42);
496   }
497   {
498     std::function<int(int)> fn = [](int i){ return i + 23; };
499     auto f = makeFuture(19).then(std::move(fn));
500     EXPECT_EQ(f.value(), 42);
501   }
502   {
503     std::function<int(Try<int>&)> fn = [](Try<int>& t){ return t.value() + 2; };
504     auto f = makeFuture(1).then(std::move(fn));
505     EXPECT_EQ(f.value(), 3);
506   }
507   {
508     bool flag = false;
509     std::function<void()> fn = [&flag](){ flag = true; };
510     auto f = makeFuture().then(std::move(fn));
511     EXPECT_TRUE(f.isReady());
512     EXPECT_TRUE(flag);
513   }
514 }
515
516 TEST(Future, thenBind) {
517   auto l = []() {
518     return makeFuture("bind");
519   };
520   auto b = std::bind(l);
521   auto f = makeFuture().then(std::move(b));
522   EXPECT_EQ(f.value(), "bind");
523 }
524
525 TEST(Future, thenBindTry) {
526   auto l = [](Try<std::string>&& t) {
527     return makeFuture(t.value() + ";bind");
528   };
529   auto b = std::bind(l, std::placeholders::_1);
530   auto f = makeFuture<std::string>("start").then(std::move(b));
531
532   EXPECT_EQ(f.value(), "start;bind");
533 }
534
535 TEST(Future, value) {
536   auto f = makeFuture(std::unique_ptr<int>(new int(42)));
537   auto up = std::move(f.value());
538   EXPECT_EQ(42, *up);
539
540   EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
541 }
542
543 TEST(Future, isReady) {
544   Promise<int> p;
545   auto f = p.getFuture();
546   EXPECT_FALSE(f.isReady());
547   p.setValue(42);
548   EXPECT_TRUE(f.isReady());
549   }
550
551 TEST(Future, futureNotReady) {
552   Promise<int> p;
553   Future<int> f = p.getFuture();
554   EXPECT_THROW(f.value(), eggs_t);
555 }
556
557 TEST(Future, hasException) {
558   EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
559   EXPECT_FALSE(makeFuture(42).getTry().hasException());
560 }
561
562 TEST(Future, hasValue) {
563   EXPECT_TRUE(makeFuture(42).getTry().hasValue());
564   EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
565 }
566
567 TEST(Future, makeFuture) {
568   EXPECT_TYPE(makeFuture(42), Future<int>);
569   EXPECT_EQ(42, makeFuture(42).value());
570
571   EXPECT_TYPE(makeFuture<float>(42), Future<float>);
572   EXPECT_EQ(42, makeFuture<float>(42).value());
573
574   auto fun = [] { return 42; };
575   EXPECT_TYPE(makeFutureWith(fun), Future<int>);
576   EXPECT_EQ(42, makeFutureWith(fun).value());
577
578   auto funf = [] { return makeFuture<int>(43); };
579   EXPECT_TYPE(makeFutureWith(funf), Future<int>);
580   EXPECT_EQ(43, makeFutureWith(funf).value());
581
582   auto failfun = []() -> int { throw eggs; };
583   EXPECT_TYPE(makeFutureWith(failfun), Future<int>);
584   EXPECT_NO_THROW(makeFutureWith(failfun));
585   EXPECT_THROW(makeFutureWith(failfun).value(), eggs_t);
586
587   auto failfunf = []() -> Future<int> { throw eggs; };
588   EXPECT_TYPE(makeFutureWith(failfunf), Future<int>);
589   EXPECT_NO_THROW(makeFutureWith(failfunf));
590   EXPECT_THROW(makeFutureWith(failfunf).value(), eggs_t);
591
592   EXPECT_TYPE(makeFuture(), Future<Unit>);
593 }
594
595 TEST(Future, finish) {
596   auto x = std::make_shared<int>(0);
597
598   Promise<int> p;
599   auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
600
601   // The callback hasn't executed
602   EXPECT_EQ(0, *x);
603
604   // The callback has a reference to x
605   EXPECT_EQ(2, x.use_count());
606
607   p.setValue(42);
608
609   // the callback has executed
610   EXPECT_EQ(42, *x);
611
612   // the callback has been destructed
613   // and has released its reference to x
614   EXPECT_EQ(1, x.use_count());
615 }
616
617 TEST(Future, finishBigLambda) {
618   auto x = std::make_shared<int>(0);
619
620   // bulk_data, to be captured in the lambda passed to Future::then.
621   // This is meant to force that the lambda can't be stored inside
622   // the Future object.
623   std::array<char, sizeof(detail::Core<int>)> bulk_data = {0};
624
625   // suppress gcc warning about bulk_data not being used
626   EXPECT_EQ(bulk_data[0], 0);
627
628   Promise<int> p;
629   auto f = p.getFuture().then([x, bulk_data](Try<int>&& t) { *x = t.value(); });
630
631   // The callback hasn't executed
632   EXPECT_EQ(0, *x);
633
634   // The callback has a reference to x
635   EXPECT_EQ(2, x.use_count());
636
637   p.setValue(42);
638
639   // the callback has executed
640   EXPECT_EQ(42, *x);
641
642   // the callback has been destructed
643   // and has released its reference to x
644   EXPECT_EQ(1, x.use_count());
645 }
646
647 TEST(Future, unwrap) {
648   Promise<int> a;
649   Promise<int> b;
650
651   auto fa = a.getFuture();
652   auto fb = b.getFuture();
653
654   bool flag1 = false;
655   bool flag2 = false;
656
657   // do a, then do b, and get the result of a + b.
658   Future<int> f = fa.then([&](Try<int>&& ta) {
659     auto va = ta.value();
660     flag1 = true;
661     return fb.then([va, &flag2](Try<int>&& tb) {
662       flag2 = true;
663       return va + tb.value();
664     });
665   });
666
667   EXPECT_FALSE(flag1);
668   EXPECT_FALSE(flag2);
669   EXPECT_FALSE(f.isReady());
670
671   a.setValue(3);
672   EXPECT_TRUE(flag1);
673   EXPECT_FALSE(flag2);
674   EXPECT_FALSE(f.isReady());
675
676   b.setValue(4);
677   EXPECT_TRUE(flag1);
678   EXPECT_TRUE(flag2);
679   EXPECT_EQ(7, f.value());
680 }
681
682 TEST(Future, throwCaughtInImmediateThen) {
683   // Neither of these should throw "Promise already satisfied"
684   makeFuture().then(
685     [=](Try<Unit>&&) -> int { throw std::exception(); });
686   makeFuture().then(
687     [=](Try<Unit>&&) -> Future<int> { throw std::exception(); });
688 }
689
690 TEST(Future, throwIfFailed) {
691   makeFuture<Unit>(eggs)
692     .then([=](Try<Unit>&& t) {
693       EXPECT_THROW(t.throwIfFailed(), eggs_t);
694     });
695   makeFuture()
696     .then([=](Try<Unit>&& t) {
697       EXPECT_NO_THROW(t.throwIfFailed());
698     });
699
700   makeFuture<int>(eggs)
701     .then([=](Try<int>&& t) {
702       EXPECT_THROW(t.throwIfFailed(), eggs_t);
703     });
704   makeFuture<int>(42)
705     .then([=](Try<int>&& t) {
706       EXPECT_NO_THROW(t.throwIfFailed());
707     });
708 }
709
710 TEST(Future, getFutureAfterSetValue) {
711   Promise<int> p;
712   p.setValue(42);
713   EXPECT_EQ(42, p.getFuture().value());
714 }
715
716 TEST(Future, getFutureAfterSetException) {
717   Promise<Unit> p;
718   p.setWith([]() -> void { throw std::logic_error("foo"); });
719   EXPECT_THROW(p.getFuture().value(), std::logic_error);
720 }
721
722 TEST(Future, detachRace) {
723   // Task #5438209
724   // This test is designed to detect a race that was in Core::detachOne()
725   // where detached_ was incremented and then tested, and that
726   // allowed a race where both Promise and Future would think they were the
727   // second and both try to delete. This showed up at scale but was very
728   // difficult to reliably repro in a test. As it is, this only fails about
729   // once in every 1,000 executions. Doing this 1,000 times is going to make a
730   // slow test so I won't do that but if it ever fails, take it seriously, and
731   // run the test binary with "--gtest_repeat=10000 --gtest_filter=*detachRace"
732   // (Don't forget to enable ASAN)
733   auto p = folly::make_unique<Promise<bool>>();
734   auto f = folly::make_unique<Future<bool>>(p->getFuture());
735   folly::Baton<> baton;
736   std::thread t1([&]{
737     baton.post();
738     p.reset();
739   });
740   baton.wait();
741   f.reset();
742   t1.join();
743 }
744
745 // Test of handling of a circular dependency. It's never recommended
746 // to have one because of possible memory leaks. Here we test that
747 // we can handle freeing of the Future while it is running.
748 TEST(Future, CircularDependencySharedPtrSelfReset) {
749   Promise<int64_t> promise;
750   auto ptr = std::make_shared<Future<int64_t>>(promise.getFuture());
751
752   ptr->then([ptr](folly::Try<int64_t>&& /* uid */) mutable {
753     EXPECT_EQ(1, ptr.use_count());
754
755     // Leaving no references to ourselves.
756     ptr.reset();
757     EXPECT_EQ(0, ptr.use_count());
758   });
759
760   EXPECT_EQ(2, ptr.use_count());
761
762   ptr.reset();
763
764   promise.setValue(1);
765 }
766
767 TEST(Future, Constructor) {
768   auto f1 = []() -> Future<int> { return Future<int>(3); }();
769   EXPECT_EQ(f1.value(), 3);
770   auto f2 = []() -> Future<Unit> { return Future<Unit>(); }();
771   EXPECT_NO_THROW(f2.value());
772 }
773
774 TEST(Future, ImplicitConstructor) {
775   auto f1 = []() -> Future<int> { return 3; }();
776   EXPECT_EQ(f1.value(), 3);
777   // Unfortunately, the C++ standard does not allow the
778   // following implicit conversion to work:
779   //auto f2 = []() -> Future<Unit> { }();
780 }
781
782 TEST(Future, thenDynamic) {
783   // folly::dynamic has a constructor that takes any T, this test makes
784   // sure that we call the then lambda with folly::dynamic and not
785   // Try<folly::dynamic> because that then fails to compile
786   Promise<folly::dynamic> p;
787   Future<folly::dynamic> f = p.getFuture().then(
788       [](const folly::dynamic& d) {
789         return folly::dynamic(d.asInt() + 3);
790       }
791   );
792   p.setValue(2);
793   EXPECT_EQ(f.get(), 5);
794 }
795
796 TEST(Future, RequestContext) {
797   class NewThreadExecutor : public Executor {
798    public:
799     ~NewThreadExecutor() override {
800       std::for_each(v_.begin(), v_.end(), [](std::thread& t){ t.join(); });
801     }
802     void add(Func f) override {
803       if (throwsOnAdd_) { throw std::exception(); }
804       v_.emplace_back(std::move(f));
805     }
806     void addWithPriority(Func f, int8_t /* prio */) override {
807       add(std::move(f));
808     }
809     uint8_t getNumPriorities() const override { return numPriorities_; }
810
811     void setHandlesPriorities() { numPriorities_ = 2; }
812     void setThrowsOnAdd() { throwsOnAdd_ = true; }
813    private:
814     std::vector<std::thread> v_;
815     uint8_t numPriorities_ = 1;
816     bool throwsOnAdd_ = false;
817   };
818
819   struct MyRequestData : RequestData {
820     MyRequestData(bool value = false) : value(value) {}
821     bool value;
822   };
823
824   Promise<int> p1, p2;
825   {
826     NewThreadExecutor e;
827     folly::RequestContextScopeGuard rctx;
828     RequestContext::get()->setContextData(
829         "key", folly::make_unique<MyRequestData>(true));
830     auto checker = [](int lineno) {
831       return [lineno](Try<int>&& /* t */) {
832         auto d = static_cast<MyRequestData*>(
833             RequestContext::get()->getContextData("key"));
834         EXPECT_TRUE(d && d->value) << "on line " << lineno;
835       };
836     };
837
838     makeFuture(1).via(&e).then(checker(__LINE__));
839
840     e.setHandlesPriorities();
841     makeFuture(2).via(&e).then(checker(__LINE__));
842
843     p1.getFuture().then(checker(__LINE__));
844
845     e.setThrowsOnAdd();
846     p2.getFuture().via(&e).then(checker(__LINE__));
847   }
848   // Assert that no RequestContext is set
849   EXPECT_FALSE(RequestContext::saveContext());
850   p1.setValue(3);
851   p2.setValue(4);
852 }
853
854 TEST(Future, makeFutureNoThrow) {
855   makeFuture().value();
856 }