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