2 * Copyright 2016 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>
24 #include <folly/portability/Unistd.h>
32 #include <type_traits>
34 using namespace folly;
36 #define EXPECT_TYPE(x, T) \
37 EXPECT_TRUE((std::is_same<decltype(x), T>::value))
39 typedef FutureException eggs_t;
40 static eggs_t eggs("eggs");
44 TEST(Future, futureDefaultCtor) {
48 TEST(Future, futureToUnit) {
49 Future<Unit> fu = makeFuture(42).unit();
51 EXPECT_TRUE(makeFuture<int>(eggs).unit().hasException());
54 TEST(Future, voidFutureToUnit) {
55 Future<Unit> fu = makeFuture().unit();
57 EXPECT_TRUE(makeFuture<Unit>(eggs).unit().hasException());
60 TEST(Future, unitFutureToUnitIdentity) {
61 Future<Unit> fu = makeFuture(Unit{}).unit();
63 EXPECT_TRUE(makeFuture<Unit>(eggs).unit().hasException());
66 TEST(Future, toUnitWhileInProgress) {
68 Future<Unit> fu = p.getFuture().unit();
69 EXPECT_FALSE(fu.isReady());
71 EXPECT_TRUE(fu.isReady());
74 TEST(Future, makeFutureWithUnit) {
76 Future<Unit> fu = makeFutureWith([&] { count++; });
80 TEST(Future, onError) {
82 auto flag = [&]{ theFlag = true; };
83 #define EXPECT_FLAG() \
85 EXPECT_TRUE(theFlag); \
89 #define EXPECT_NO_FLAG() \
91 EXPECT_FALSE(theFlag); \
97 auto f = makeFuture().then([] {
99 }).onError([&](eggs_t& /* e */) { flag(); });
101 EXPECT_NO_THROW(f.value());
105 auto f = makeFuture()
106 .then([] { throw eggs; })
107 .onError([&](eggs_t& /* e */) {
112 EXPECT_NO_THROW(f.value());
117 auto f = makeFuture().then([] {
119 }).onError([&](eggs_t /* e */) { flag(); });
121 EXPECT_NO_THROW(f.value());
125 auto f = makeFuture()
126 .then([] { throw eggs; })
127 .onError([&](eggs_t /* e */) {
132 EXPECT_NO_THROW(f.value());
137 auto f = makeFuture().then([] {
139 }).onError([&](std::exception& /* e */) { flag(); });
141 EXPECT_NO_THROW(f.value());
145 auto f = makeFuture()
146 .then([] { throw eggs; })
147 .onError([&](std::exception& /* e */) {
152 EXPECT_NO_THROW(f.value());
157 auto f = makeFuture().then([] {
159 }).onError([&](int /* e */) { flag(); });
161 EXPECT_NO_THROW(f.value());
165 auto f = makeFuture()
166 .then([] { throw - 1; })
167 .onError([&](int /* e */) {
172 EXPECT_NO_THROW(f.value());
177 auto f = makeFuture().then([] {
179 }).onError([&](eggs_t& /* e */) mutable { flag(); });
181 EXPECT_NO_THROW(f.value());
185 auto f = makeFuture()
186 .then([] { throw eggs; })
187 .onError([&](eggs_t& /* e */) mutable {
192 EXPECT_NO_THROW(f.value());
197 auto f = makeFuture()
198 .then([] { return 42; })
199 .onError([&](eggs_t& /* e */) {
204 EXPECT_EQ(42, f.value());
208 auto f = makeFuture()
209 .then([] { return 42; })
210 .onError([&](eggs_t& /* e */) {
212 return makeFuture<int>(-1);
215 EXPECT_EQ(42, f.value());
218 // Catch different exception
220 auto f = makeFuture().then([] {
222 }).onError([&](std::runtime_error& /* e */) { flag(); });
224 EXPECT_THROW(f.value(), eggs_t);
228 auto f = makeFuture()
229 .then([] { throw eggs; })
230 .onError([&](std::runtime_error& /* e */) {
235 EXPECT_THROW(f.value(), eggs_t);
238 // Returned value propagates
240 auto f = makeFuture().then([] {
243 }).onError([&](eggs_t& /* e */) { return 42; });
244 EXPECT_EQ(42, f.value());
247 // Returned future propagates
249 auto f = makeFuture().then([] {
252 }).onError([&](eggs_t& /* e */) { return makeFuture<int>(42); });
253 EXPECT_EQ(42, f.value());
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);
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);
271 // exception_wrapper, return Future<T>
273 auto f = makeFuture()
274 .then([] { throw eggs; })
275 .onError([&](exception_wrapper /* e */) {
280 EXPECT_NO_THROW(f.value());
283 // exception_wrapper, return Future<T> but throw
285 auto f = makeFuture()
290 .onError([&](exception_wrapper /* e */) {
293 return makeFuture<int>(-1);
296 EXPECT_THROW(f.value(), eggs_t);
299 // exception_wrapper, return T
301 auto f = makeFuture()
306 .onError([&](exception_wrapper /* e */) {
311 EXPECT_EQ(-1, f.value());
314 // exception_wrapper, return T but throw
316 auto f = makeFuture()
321 .onError([&](exception_wrapper /* e */) {
327 EXPECT_THROW(f.value(), eggs_t);
330 // const exception_wrapper&
332 auto f = makeFuture()
333 .then([] { throw eggs; })
334 .onError([&](const exception_wrapper& /* e */) {
339 EXPECT_NO_THROW(f.value());
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);
352 auto f = makeFuture<std::string>("0")
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"); })
380 EXPECT_EQ(f.value(), "1;2;3;4;5;6;7;8;9;10;11;12;13");
383 TEST(Future, thenTry) {
386 makeFuture<int>(42).then([&](Try<int>&& t) {
388 EXPECT_EQ(42, t.value());
390 EXPECT_TRUE(flag); flag = false;
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;
397 makeFuture().then([&](Try<Unit>&& t) { flag = true; t.value(); });
398 EXPECT_TRUE(flag); flag = false;
401 auto f = p.getFuture().then([&](Try<Unit>&& /* t */) { flag = true; });
403 EXPECT_FALSE(f.isReady());
406 EXPECT_TRUE(f.isReady());
409 TEST(Future, thenValue) {
411 makeFuture<int>(42).then([&](int i){
415 EXPECT_TRUE(flag); flag = false;
418 .then([](int i){ return i; })
419 .then([&](int i) { flag = true; EXPECT_EQ(42, i); });
420 EXPECT_TRUE(flag); flag = false;
422 makeFuture().then([&]{
425 EXPECT_TRUE(flag); flag = false;
427 auto f = makeFuture<int>(eggs).then([&](int /* i */) {});
428 EXPECT_THROW(f.value(), eggs_t);
430 f = makeFuture<Unit>(eggs).then([&]{});
431 EXPECT_THROW(f.value(), eggs_t);
434 TEST(Future, thenValueFuture) {
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;
441 makeFuture().then([] {
443 }).then([&](Try<Unit>&& /* t */) { flag = true; });
444 EXPECT_TRUE(flag); flag = false;
447 static std::string doWorkStatic(Try<std::string>&& t) {
448 return t.value() + ";static";
451 TEST(Future, thenFunction) {
453 std::string doWork(Try<std::string>&& t) {
454 return t.value() + ";class";
456 static std::string doWorkStatic(Try<std::string>&& t) {
457 return t.value() + ";class-static";
461 auto f = makeFuture<std::string>("start")
463 .then(Worker::doWorkStatic)
464 .then(&Worker::doWork, &w);
466 EXPECT_EQ(f.value(), "start;static;class-static;class");
469 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
470 return makeFuture(t.value() + ";static");
473 TEST(Future, thenFunctionFuture) {
475 Future<std::string> doWorkFuture(Try<std::string>&& t) {
476 return makeFuture(t.value() + ";class");
478 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
479 return makeFuture(t.value() + ";class-static");
483 auto f = makeFuture<std::string>("start")
484 .then(doWorkStaticFuture)
485 .then(Worker::doWorkStaticFuture)
486 .then(&Worker::doWorkFuture, &w);
488 EXPECT_EQ(f.value(), "start;static;class-static;class");
491 TEST(Future, thenStdFunction) {
493 std::function<int()> fn = [](){ return 42; };
494 auto f = makeFuture().then(std::move(fn));
495 EXPECT_EQ(f.value(), 42);
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);
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);
509 std::function<void()> fn = [&flag](){ flag = true; };
510 auto f = makeFuture().then(std::move(fn));
511 EXPECT_TRUE(f.isReady());
516 TEST(Future, thenBind) {
518 return makeFuture("bind");
520 auto b = std::bind(l);
521 auto f = makeFuture().then(std::move(b));
522 EXPECT_EQ(f.value(), "bind");
525 TEST(Future, thenBindTry) {
526 auto l = [](Try<std::string>&& t) {
527 return makeFuture(t.value() + ";bind");
529 auto b = std::bind(l, std::placeholders::_1);
530 auto f = makeFuture<std::string>("start").then(std::move(b));
532 EXPECT_EQ(f.value(), "start;bind");
535 TEST(Future, value) {
536 auto f = makeFuture(std::unique_ptr<int>(new int(42)));
537 auto up = std::move(f.value());
540 EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
543 TEST(Future, isReady) {
545 auto f = p.getFuture();
546 EXPECT_FALSE(f.isReady());
548 EXPECT_TRUE(f.isReady());
551 TEST(Future, futureNotReady) {
553 Future<int> f = p.getFuture();
554 EXPECT_THROW(f.value(), eggs_t);
557 TEST(Future, hasException) {
558 EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
559 EXPECT_FALSE(makeFuture(42).getTry().hasException());
562 TEST(Future, hasValue) {
563 EXPECT_TRUE(makeFuture(42).getTry().hasValue());
564 EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
567 TEST(Future, makeFuture) {
568 EXPECT_TYPE(makeFuture(42), Future<int>);
569 EXPECT_EQ(42, makeFuture(42).value());
571 EXPECT_TYPE(makeFuture<float>(42), Future<float>);
572 EXPECT_EQ(42, makeFuture<float>(42).value());
574 auto fun = [] { return 42; };
575 EXPECT_TYPE(makeFutureWith(fun), Future<int>);
576 EXPECT_EQ(42, makeFutureWith(fun).value());
578 auto funf = [] { return makeFuture<int>(43); };
579 EXPECT_TYPE(makeFutureWith(funf), Future<int>);
580 EXPECT_EQ(43, makeFutureWith(funf).value());
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);
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);
592 EXPECT_TYPE(makeFuture(), Future<Unit>);
595 TEST(Future, finish) {
596 auto x = std::make_shared<int>(0);
599 auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
601 // The callback hasn't executed
604 // The callback has a reference to x
605 EXPECT_EQ(2, x.use_count());
609 // the callback has executed
612 // the callback has been destructed
613 // and has released its reference to x
614 EXPECT_EQ(1, x.use_count());
617 TEST(Future, finishBigLambda) {
618 auto x = std::make_shared<int>(0);
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}};
625 // suppress gcc warning about bulk_data not being used
626 EXPECT_EQ(bulk_data[0], 0);
629 auto f = p.getFuture().then([x, bulk_data](Try<int>&& t) { *x = t.value(); });
631 // The callback hasn't executed
634 // The callback has a reference to x
635 EXPECT_EQ(2, x.use_count());
639 // the callback has executed
642 // the callback has been destructed
643 // and has released its reference to x
644 EXPECT_EQ(1, x.use_count());
647 TEST(Future, unwrap) {
651 auto fa = a.getFuture();
652 auto fb = b.getFuture();
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();
661 return fb.then([va, &flag2](Try<int>&& tb) {
663 return va + tb.value();
669 EXPECT_FALSE(f.isReady());
674 EXPECT_FALSE(f.isReady());
679 EXPECT_EQ(7, f.value());
682 TEST(Future, throwCaughtInImmediateThen) {
683 // Neither of these should throw "Promise already satisfied"
685 [=](Try<Unit>&&) -> int { throw std::exception(); });
687 [=](Try<Unit>&&) -> Future<int> { throw std::exception(); });
690 TEST(Future, throwIfFailed) {
691 makeFuture<Unit>(eggs)
692 .then([=](Try<Unit>&& t) {
693 EXPECT_THROW(t.throwIfFailed(), eggs_t);
696 .then([=](Try<Unit>&& t) {
697 EXPECT_NO_THROW(t.throwIfFailed());
700 makeFuture<int>(eggs)
701 .then([=](Try<int>&& t) {
702 EXPECT_THROW(t.throwIfFailed(), eggs_t);
705 .then([=](Try<int>&& t) {
706 EXPECT_NO_THROW(t.throwIfFailed());
710 TEST(Future, getFutureAfterSetValue) {
713 EXPECT_EQ(42, p.getFuture().value());
716 TEST(Future, getFutureAfterSetException) {
718 p.setWith([]() -> void { throw std::logic_error("foo"); });
719 EXPECT_THROW(p.getFuture().value(), std::logic_error);
722 TEST(Future, detachRace) {
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;
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());
752 ptr->then([ptr](folly::Try<int64_t>&& /* uid */) mutable {
753 EXPECT_EQ(1, ptr.use_count());
755 // Leaving no references to ourselves.
757 EXPECT_EQ(0, ptr.use_count());
760 EXPECT_EQ(2, ptr.use_count());
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());
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> { }();
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);
793 EXPECT_EQ(f.get(), 5);
796 TEST(Future, RequestContext) {
797 class NewThreadExecutor : public Executor {
799 ~NewThreadExecutor() override {
800 std::for_each(v_.begin(), v_.end(), [](std::thread& t){ t.join(); });
802 void add(Func f) override {
803 if (throwsOnAdd_) { throw std::exception(); }
804 v_.emplace_back(std::move(f));
806 void addWithPriority(Func f, int8_t /* prio */) override {
809 uint8_t getNumPriorities() const override { return numPriorities_; }
811 void setHandlesPriorities() { numPriorities_ = 2; }
812 void setThrowsOnAdd() { throwsOnAdd_ = true; }
814 std::vector<std::thread> v_;
815 uint8_t numPriorities_ = 1;
816 bool throwsOnAdd_ = false;
819 struct MyRequestData : RequestData {
820 MyRequestData(bool value = false) : value(value) {}
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;
838 makeFuture(1).via(&e).then(checker(__LINE__));
840 e.setHandlesPriorities();
841 makeFuture(2).via(&e).then(checker(__LINE__));
843 p1.getFuture().then(checker(__LINE__));
846 p2.getFuture().via(&e).then(checker(__LINE__));
848 // Assert that no RequestContext is set
849 EXPECT_FALSE(RequestContext::saveContext());
854 TEST(Future, makeFutureNoThrow) {
855 makeFuture().value();