2 * Copyright 2017 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
31 #include <type_traits>
33 using namespace folly;
35 #define EXPECT_TYPE(x, T) \
36 EXPECT_TRUE((std::is_same<decltype(x), T>::value))
38 typedef FutureException eggs_t;
39 static eggs_t eggs("eggs");
43 TEST(Future, futureDefaultCtor) {
47 TEST(Future, futureToUnit) {
48 Future<Unit> fu = makeFuture(42).unit();
50 EXPECT_TRUE(makeFuture<int>(eggs).unit().hasException());
53 TEST(Future, voidFutureToUnit) {
54 Future<Unit> fu = makeFuture().unit();
56 EXPECT_TRUE(makeFuture<Unit>(eggs).unit().hasException());
59 TEST(Future, unitFutureToUnitIdentity) {
60 Future<Unit> fu = makeFuture(Unit{}).unit();
62 EXPECT_TRUE(makeFuture<Unit>(eggs).unit().hasException());
65 TEST(Future, toUnitWhileInProgress) {
67 Future<Unit> fu = p.getFuture().unit();
68 EXPECT_FALSE(fu.isReady());
70 EXPECT_TRUE(fu.isReady());
73 TEST(Future, makeFutureWithUnit) {
75 Future<Unit> fu = makeFutureWith([&] { count++; });
80 Future<int> onErrorHelperEggs(const eggs_t&) {
81 return makeFuture(10);
83 Future<int> onErrorHelperGeneric(const std::exception&) {
84 return makeFuture(20);
88 TEST(Future, onError) {
90 auto flag = [&]{ theFlag = true; };
91 #define EXPECT_FLAG() \
93 EXPECT_TRUE(theFlag); \
97 #define EXPECT_NO_FLAG() \
99 EXPECT_FALSE(theFlag); \
105 auto f = makeFuture().then([] {
107 }).onError([&](eggs_t& /* e */) { flag(); });
109 EXPECT_NO_THROW(f.value());
113 auto f = makeFuture()
114 .then([] { throw eggs; })
115 .onError([&](eggs_t& /* e */) {
120 EXPECT_NO_THROW(f.value());
125 auto f = makeFuture().then([] {
127 }).onError([&](eggs_t /* e */) { flag(); });
129 EXPECT_NO_THROW(f.value());
133 auto f = makeFuture()
134 .then([] { throw eggs; })
135 .onError([&](eggs_t /* e */) {
140 EXPECT_NO_THROW(f.value());
145 auto f = makeFuture().then([] {
147 }).onError([&](std::exception& /* e */) { flag(); });
149 EXPECT_NO_THROW(f.value());
153 auto f = makeFuture()
154 .then([] { throw eggs; })
155 .onError([&](std::exception& /* e */) {
160 EXPECT_NO_THROW(f.value());
165 auto f = makeFuture().then([] {
167 }).onError([&](int /* e */) { flag(); });
169 EXPECT_NO_THROW(f.value());
173 auto f = makeFuture()
174 .then([] { throw - 1; })
175 .onError([&](int /* e */) {
180 EXPECT_NO_THROW(f.value());
185 auto f = makeFuture().then([] {
187 }).onError([&](eggs_t& /* e */) mutable { flag(); });
189 EXPECT_NO_THROW(f.value());
193 auto f = makeFuture()
194 .then([] { throw eggs; })
195 .onError([&](eggs_t& /* e */) mutable {
200 EXPECT_NO_THROW(f.value());
205 auto f = makeFuture()
206 .then([]() -> int { throw eggs; })
207 .onError(onErrorHelperEggs)
208 .onError(onErrorHelperGeneric);
209 EXPECT_EQ(10, f.value());
212 auto f = makeFuture()
213 .then([]() -> int { throw std::runtime_error("test"); })
214 .onError(onErrorHelperEggs)
215 .onError(onErrorHelperGeneric);
216 EXPECT_EQ(20, f.value());
219 auto f = makeFuture()
220 .then([]() -> int { throw std::runtime_error("test"); })
221 .onError(onErrorHelperEggs);
222 EXPECT_THROW(f.value(), std::runtime_error);
227 auto f = makeFuture()
228 .then([] { return 42; })
229 .onError([&](eggs_t& /* e */) {
234 EXPECT_EQ(42, f.value());
238 auto f = makeFuture()
239 .then([] { return 42; })
240 .onError([&](eggs_t& /* e */) {
242 return makeFuture<int>(-1);
245 EXPECT_EQ(42, f.value());
248 // Catch different exception
250 auto f = makeFuture().then([] {
252 }).onError([&](std::runtime_error& /* e */) { flag(); });
254 EXPECT_THROW(f.value(), eggs_t);
258 auto f = makeFuture()
259 .then([] { throw eggs; })
260 .onError([&](std::runtime_error& /* e */) {
265 EXPECT_THROW(f.value(), eggs_t);
268 // Returned value propagates
270 auto f = makeFuture().then([]() -> int {
272 }).onError([&](eggs_t& /* e */) { return 42; });
273 EXPECT_EQ(42, f.value());
276 // Returned future propagates
278 auto f = makeFuture().then([]() -> int {
280 }).onError([&](eggs_t& /* e */) { return makeFuture<int>(42); });
281 EXPECT_EQ(42, f.value());
286 auto f = makeFuture()
287 .then([]() -> int { throw eggs; })
288 .onError([&] (eggs_t& e) -> int { throw e; });
289 EXPECT_THROW(f.value(), eggs_t);
293 auto f = makeFuture()
294 .then([]() -> int { throw eggs; })
295 .onError([&] (eggs_t& e) -> Future<int> { throw e; });
296 EXPECT_THROW(f.value(), eggs_t);
299 // exception_wrapper, return Future<T>
301 auto f = makeFuture()
302 .then([] { throw eggs; })
303 .onError([&](exception_wrapper /* e */) {
308 EXPECT_NO_THROW(f.value());
311 // exception_wrapper, return Future<T> but throw
313 auto f = makeFuture()
317 .onError([&](exception_wrapper /* e */) -> Future<int> {
322 EXPECT_THROW(f.value(), eggs_t);
325 // exception_wrapper, return T
327 auto f = makeFuture()
331 .onError([&](exception_wrapper /* e */) {
336 EXPECT_EQ(-1, f.value());
339 // exception_wrapper, return T but throw
341 auto f = makeFuture()
345 .onError([&](exception_wrapper /* e */) -> int {
350 EXPECT_THROW(f.value(), eggs_t);
353 // const exception_wrapper&
355 auto f = makeFuture()
356 .then([] { throw eggs; })
357 .onError([&](const exception_wrapper& /* e */) {
362 EXPECT_NO_THROW(f.value());
367 TEST(Future, special) {
368 EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
369 EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
370 EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
371 EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
375 auto f = makeFuture<std::string>("0")
377 return makeFuture<std::string>("1"); })
378 .then([](Try<std::string>&& t) {
379 return makeFuture(t.value() + ";2"); })
380 .then([](const Try<std::string>&& t) {
381 return makeFuture(t.value() + ";3"); })
382 .then([](Try<std::string>& t) {
383 return makeFuture(t.value() + ";4"); })
384 .then([](const Try<std::string>& t) {
385 return makeFuture(t.value() + ";5"); })
386 .then([](Try<std::string> t) {
387 return makeFuture(t.value() + ";6"); })
388 .then([](const Try<std::string> t) {
389 return makeFuture(t.value() + ";7"); })
390 .then([](std::string&& s) {
391 return makeFuture(s + ";8"); })
392 .then([](const std::string&& s) {
393 return makeFuture(s + ";9"); })
394 .then([](std::string& s) {
395 return makeFuture(s + ";10"); })
396 .then([](const std::string& s) {
397 return makeFuture(s + ";11"); })
398 .then([](std::string s) {
399 return makeFuture(s + ";12"); })
400 .then([](const std::string s) {
401 return makeFuture(s + ";13"); })
403 EXPECT_EQ(f.value(), "1;2;3;4;5;6;7;8;9;10;11;12;13");
406 TEST(Future, thenTry) {
409 makeFuture<int>(42).then([&](Try<int>&& t) {
411 EXPECT_EQ(42, t.value());
413 EXPECT_TRUE(flag); flag = false;
416 .then([](Try<int>&& t) { return t.value(); })
417 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
418 EXPECT_TRUE(flag); flag = false;
420 makeFuture().then([&](Try<Unit>&& t) { flag = true; t.value(); });
421 EXPECT_TRUE(flag); flag = false;
424 auto f = p.getFuture().then([&](Try<Unit>&& /* t */) { flag = true; });
426 EXPECT_FALSE(f.isReady());
429 EXPECT_TRUE(f.isReady());
432 TEST(Future, thenValue) {
434 makeFuture<int>(42).then([&](int i){
438 EXPECT_TRUE(flag); flag = false;
441 .then([](int i){ return i; })
442 .then([&](int i) { flag = true; EXPECT_EQ(42, i); });
443 EXPECT_TRUE(flag); flag = false;
445 makeFuture().then([&]{
448 EXPECT_TRUE(flag); flag = false;
450 auto f = makeFuture<int>(eggs).then([&](int /* i */) {});
451 EXPECT_THROW(f.value(), eggs_t);
453 f = makeFuture<Unit>(eggs).then([&]{});
454 EXPECT_THROW(f.value(), eggs_t);
457 TEST(Future, thenValueFuture) {
460 .then([](int i){ return makeFuture<int>(std::move(i)); })
461 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
462 EXPECT_TRUE(flag); flag = false;
464 makeFuture().then([] {
466 }).then([&](Try<Unit>&& /* t */) { flag = true; });
467 EXPECT_TRUE(flag); flag = false;
470 static std::string doWorkStatic(Try<std::string>&& t) {
471 return t.value() + ";static";
474 TEST(Future, thenFunction) {
476 std::string doWork(Try<std::string>&& t) {
477 return t.value() + ";class";
479 static std::string doWorkStatic(Try<std::string>&& t) {
480 return t.value() + ";class-static";
484 auto f = makeFuture<std::string>("start")
486 .then(Worker::doWorkStatic)
487 .then(&Worker::doWork, &w);
489 EXPECT_EQ(f.value(), "start;static;class-static;class");
492 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
493 return makeFuture(t.value() + ";static");
496 TEST(Future, thenFunctionFuture) {
498 Future<std::string> doWorkFuture(Try<std::string>&& t) {
499 return makeFuture(t.value() + ";class");
501 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
502 return makeFuture(t.value() + ";class-static");
506 auto f = makeFuture<std::string>("start")
507 .then(doWorkStaticFuture)
508 .then(Worker::doWorkStaticFuture)
509 .then(&Worker::doWorkFuture, &w);
511 EXPECT_EQ(f.value(), "start;static;class-static;class");
514 TEST(Future, thenStdFunction) {
516 std::function<int()> fn = [](){ return 42; };
517 auto f = makeFuture().then(std::move(fn));
518 EXPECT_EQ(f.value(), 42);
521 std::function<int(int)> fn = [](int i){ return i + 23; };
522 auto f = makeFuture(19).then(std::move(fn));
523 EXPECT_EQ(f.value(), 42);
526 std::function<int(Try<int>&)> fn = [](Try<int>& t){ return t.value() + 2; };
527 auto f = makeFuture(1).then(std::move(fn));
528 EXPECT_EQ(f.value(), 3);
532 std::function<void()> fn = [&flag](){ flag = true; };
533 auto f = makeFuture().then(std::move(fn));
534 EXPECT_TRUE(f.isReady());
539 TEST(Future, thenBind) {
541 return makeFuture("bind");
543 auto b = std::bind(l);
544 auto f = makeFuture().then(std::move(b));
545 EXPECT_EQ(f.value(), "bind");
548 TEST(Future, thenBindTry) {
549 auto l = [](Try<std::string>&& t) {
550 return makeFuture(t.value() + ";bind");
552 auto b = std::bind(l, std::placeholders::_1);
553 auto f = makeFuture<std::string>("start").then(std::move(b));
555 EXPECT_EQ(f.value(), "start;bind");
558 TEST(Future, value) {
559 auto f = makeFuture(std::unique_ptr<int>(new int(42)));
560 auto up = std::move(f.value());
563 EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
566 TEST(Future, isReady) {
568 auto f = p.getFuture();
569 EXPECT_FALSE(f.isReady());
571 EXPECT_TRUE(f.isReady());
574 TEST(Future, futureNotReady) {
576 Future<int> f = p.getFuture();
577 EXPECT_THROW(f.value(), eggs_t);
580 TEST(Future, hasException) {
581 EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
582 EXPECT_FALSE(makeFuture(42).getTry().hasException());
585 TEST(Future, hasValue) {
586 EXPECT_TRUE(makeFuture(42).getTry().hasValue());
587 EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
590 TEST(Future, makeFuture) {
591 EXPECT_TYPE(makeFuture(42), Future<int>);
592 EXPECT_EQ(42, makeFuture(42).value());
594 EXPECT_TYPE(makeFuture<float>(42), Future<float>);
595 EXPECT_EQ(42, makeFuture<float>(42).value());
597 auto fun = [] { return 42; };
598 EXPECT_TYPE(makeFutureWith(fun), Future<int>);
599 EXPECT_EQ(42, makeFutureWith(fun).value());
601 auto funf = [] { return makeFuture<int>(43); };
602 EXPECT_TYPE(makeFutureWith(funf), Future<int>);
603 EXPECT_EQ(43, makeFutureWith(funf).value());
605 auto failfun = []() -> int { throw eggs; };
606 EXPECT_TYPE(makeFutureWith(failfun), Future<int>);
607 EXPECT_NO_THROW(makeFutureWith(failfun));
608 EXPECT_THROW(makeFutureWith(failfun).value(), eggs_t);
610 auto failfunf = []() -> Future<int> { throw eggs; };
611 EXPECT_TYPE(makeFutureWith(failfunf), Future<int>);
612 EXPECT_NO_THROW(makeFutureWith(failfunf));
613 EXPECT_THROW(makeFutureWith(failfunf).value(), eggs_t);
615 EXPECT_TYPE(makeFuture(), Future<Unit>);
618 TEST(Future, finish) {
619 auto x = std::make_shared<int>(0);
622 auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
624 // The callback hasn't executed
627 // The callback has a reference to x
628 EXPECT_EQ(2, x.use_count());
632 // the callback has executed
635 // the callback has been destructed
636 // and has released its reference to x
637 EXPECT_EQ(1, x.use_count());
640 TEST(Future, finishBigLambda) {
641 auto x = std::make_shared<int>(0);
643 // bulk_data, to be captured in the lambda passed to Future::then.
644 // This is meant to force that the lambda can't be stored inside
645 // the Future object.
646 std::array<char, sizeof(detail::Core<int>)> bulk_data = {{0}};
648 // suppress gcc warning about bulk_data not being used
649 EXPECT_EQ(bulk_data[0], 0);
652 auto f = p.getFuture().then([x, bulk_data](Try<int>&& t) {
657 // The callback hasn't executed
660 // The callback has a reference to x
661 EXPECT_EQ(2, x.use_count());
665 // the callback has executed
668 // the callback has been destructed
669 // and has released its reference to x
670 EXPECT_EQ(1, x.use_count());
673 TEST(Future, unwrap) {
677 auto fa = a.getFuture();
678 auto fb = b.getFuture();
683 // do a, then do b, and get the result of a + b.
684 Future<int> f = fa.then([&](Try<int>&& ta) {
685 auto va = ta.value();
687 return fb.then([va, &flag2](Try<int>&& tb) {
689 return va + tb.value();
695 EXPECT_FALSE(f.isReady());
700 EXPECT_FALSE(f.isReady());
705 EXPECT_EQ(7, f.value());
708 TEST(Future, throwCaughtInImmediateThen) {
709 // Neither of these should throw "Promise already satisfied"
711 [=](Try<Unit>&&) -> int { throw std::exception(); });
713 [=](Try<Unit>&&) -> Future<int> { throw std::exception(); });
716 TEST(Future, throwIfFailed) {
717 makeFuture<Unit>(eggs)
718 .then([=](Try<Unit>&& t) {
719 EXPECT_THROW(t.throwIfFailed(), eggs_t);
722 .then([=](Try<Unit>&& t) {
723 EXPECT_NO_THROW(t.throwIfFailed());
726 makeFuture<int>(eggs)
727 .then([=](Try<int>&& t) {
728 EXPECT_THROW(t.throwIfFailed(), eggs_t);
731 .then([=](Try<int>&& t) {
732 EXPECT_NO_THROW(t.throwIfFailed());
736 TEST(Future, getFutureAfterSetValue) {
739 EXPECT_EQ(42, p.getFuture().value());
742 TEST(Future, getFutureAfterSetException) {
744 p.setWith([]() -> void { throw std::logic_error("foo"); });
745 EXPECT_THROW(p.getFuture().value(), std::logic_error);
748 TEST(Future, detachRace) {
750 // This test is designed to detect a race that was in Core::detachOne()
751 // where detached_ was incremented and then tested, and that
752 // allowed a race where both Promise and Future would think they were the
753 // second and both try to delete. This showed up at scale but was very
754 // difficult to reliably repro in a test. As it is, this only fails about
755 // once in every 1,000 executions. Doing this 1,000 times is going to make a
756 // slow test so I won't do that but if it ever fails, take it seriously, and
757 // run the test binary with "--gtest_repeat=10000 --gtest_filter=*detachRace"
758 // (Don't forget to enable ASAN)
759 auto p = std::make_unique<Promise<bool>>();
760 auto f = std::make_unique<Future<bool>>(p->getFuture());
761 folly::Baton<> baton;
771 // Test of handling of a circular dependency. It's never recommended
772 // to have one because of possible memory leaks. Here we test that
773 // we can handle freeing of the Future while it is running.
774 TEST(Future, CircularDependencySharedPtrSelfReset) {
775 Promise<int64_t> promise;
776 auto ptr = std::make_shared<Future<int64_t>>(promise.getFuture());
778 ptr->then([ptr](folly::Try<int64_t>&& /* uid */) mutable {
779 EXPECT_EQ(1, ptr.use_count());
781 // Leaving no references to ourselves.
783 EXPECT_EQ(0, ptr.use_count());
786 EXPECT_EQ(2, ptr.use_count());
793 TEST(Future, Constructor) {
794 auto f1 = []() -> Future<int> { return Future<int>(3); }();
795 EXPECT_EQ(f1.value(), 3);
796 auto f2 = []() -> Future<Unit> { return Future<Unit>(); }();
797 EXPECT_NO_THROW(f2.value());
800 TEST(Future, ImplicitConstructor) {
801 auto f1 = []() -> Future<int> { return 3; }();
802 EXPECT_EQ(f1.value(), 3);
803 // Unfortunately, the C++ standard does not allow the
804 // following implicit conversion to work:
805 //auto f2 = []() -> Future<Unit> { }();
808 TEST(Future, thenDynamic) {
809 // folly::dynamic has a constructor that takes any T, this test makes
810 // sure that we call the then lambda with folly::dynamic and not
811 // Try<folly::dynamic> because that then fails to compile
812 Promise<folly::dynamic> p;
813 Future<folly::dynamic> f = p.getFuture().then(
814 [](const folly::dynamic& d) {
815 return folly::dynamic(d.asInt() + 3);
819 EXPECT_EQ(f.get(), 5);
822 TEST(Future, RequestContext) {
823 class NewThreadExecutor : public Executor {
825 ~NewThreadExecutor() override {
826 std::for_each(v_.begin(), v_.end(), [](std::thread& t){ t.join(); });
828 void add(Func f) override {
829 if (throwsOnAdd_) { throw std::exception(); }
830 v_.emplace_back(std::move(f));
832 void addWithPriority(Func f, int8_t /* prio */) override {
835 uint8_t getNumPriorities() const override { return numPriorities_; }
837 void setHandlesPriorities() { numPriorities_ = 2; }
838 void setThrowsOnAdd() { throwsOnAdd_ = true; }
840 std::vector<std::thread> v_;
841 uint8_t numPriorities_ = 1;
842 bool throwsOnAdd_ = false;
845 struct MyRequestData : RequestData {
846 MyRequestData(bool value = false) : value(value) {}
853 folly::RequestContextScopeGuard rctx;
854 RequestContext::get()->setContextData(
855 "key", std::make_unique<MyRequestData>(true));
856 auto checker = [](int lineno) {
857 return [lineno](Try<int>&& /* t */) {
858 auto d = static_cast<MyRequestData*>(
859 RequestContext::get()->getContextData("key"));
860 EXPECT_TRUE(d && d->value) << "on line " << lineno;
864 makeFuture(1).via(&e).then(checker(__LINE__));
866 e.setHandlesPriorities();
867 makeFuture(2).via(&e).then(checker(__LINE__));
869 p1.getFuture().then(checker(__LINE__));
872 p2.getFuture().via(&e).then(checker(__LINE__));
874 // Assert that no RequestContext is set
875 EXPECT_FALSE(RequestContext::saveContext());
880 TEST(Future, makeFutureNoThrow) {
881 makeFuture().value();
884 TEST(Future, invokeCallbackReturningValueAsRvalue) {
886 int operator()(int x) & {
889 int operator()(int x) const& {
892 int operator()(int x) && {
900 // The callback will be copied when given as lvalue or const ref, and moved
901 // if provided as rvalue. Either way, it should be executed as rvalue.
902 EXPECT_EQ(103, makeFuture<int>(100).then(foo).value());
903 EXPECT_EQ(203, makeFuture<int>(200).then(cfoo).value());
904 EXPECT_EQ(303, makeFuture<int>(300).then(Foo()).value());
907 TEST(Future, invokeCallbackReturningFutureAsRvalue) {
909 Future<int> operator()(int x) & {
912 Future<int> operator()(int x) const& {
915 Future<int> operator()(int x) && {
923 // The callback will be copied when given as lvalue or const ref, and moved
924 // if provided as rvalue. Either way, it should be executed as rvalue.
925 EXPECT_EQ(103, makeFuture<int>(100).then(foo).value());
926 EXPECT_EQ(203, makeFuture<int>(200).then(cfoo).value());
927 EXPECT_EQ(303, makeFuture<int>(300).then(Foo()).value());