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