2 * Copyright 2015 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 <gtest/gtest.h>
19 #include <folly/futures/Future.h>
20 #include <folly/Memory.h>
21 #include <folly/Executor.h>
22 #include <folly/dynamic.h>
23 #include <folly/Baton.h>
31 #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, onError) {
46 auto flag = [&]{ theFlag = true; };
47 #define EXPECT_FLAG() \
49 EXPECT_TRUE(theFlag); \
53 #define EXPECT_NO_FLAG() \
55 EXPECT_FALSE(theFlag); \
61 auto f = makeFuture().then([] {
63 }).onError([&](eggs_t& /* e */) { flag(); });
65 EXPECT_NO_THROW(f.value());
70 .then([] { throw eggs; })
71 .onError([&](eggs_t& /* e */) {
76 EXPECT_NO_THROW(f.value());
81 auto f = makeFuture().then([] {
83 }).onError([&](eggs_t /* e */) { flag(); });
85 EXPECT_NO_THROW(f.value());
90 .then([] { throw eggs; })
91 .onError([&](eggs_t /* e */) {
96 EXPECT_NO_THROW(f.value());
101 auto f = makeFuture().then([] {
103 }).onError([&](std::exception& /* e */) { flag(); });
105 EXPECT_NO_THROW(f.value());
109 auto f = makeFuture()
110 .then([] { throw eggs; })
111 .onError([&](std::exception& /* e */) {
116 EXPECT_NO_THROW(f.value());
121 auto f = makeFuture().then([] {
123 }).onError([&](int /* e */) { flag(); });
125 EXPECT_NO_THROW(f.value());
129 auto f = makeFuture()
130 .then([] { throw - 1; })
131 .onError([&](int /* e */) {
136 EXPECT_NO_THROW(f.value());
141 auto f = makeFuture().then([] {
143 }).onError([&](eggs_t& /* e */) mutable { flag(); });
145 EXPECT_NO_THROW(f.value());
149 auto f = makeFuture()
150 .then([] { throw eggs; })
151 .onError([&](eggs_t& /* e */) mutable {
156 EXPECT_NO_THROW(f.value());
161 auto f = makeFuture()
162 .then([] { return 42; })
163 .onError([&](eggs_t& /* e */) {
168 EXPECT_EQ(42, f.value());
172 auto f = makeFuture()
173 .then([] { return 42; })
174 .onError([&](eggs_t& /* e */) {
176 return makeFuture<int>(-1);
179 EXPECT_EQ(42, f.value());
182 // Catch different exception
184 auto f = makeFuture().then([] {
186 }).onError([&](std::runtime_error& /* e */) { flag(); });
188 EXPECT_THROW(f.value(), eggs_t);
192 auto f = makeFuture()
193 .then([] { throw eggs; })
194 .onError([&](std::runtime_error& /* e */) {
199 EXPECT_THROW(f.value(), eggs_t);
202 // Returned value propagates
204 auto f = makeFuture().then([] {
207 }).onError([&](eggs_t& /* e */) { return 42; });
208 EXPECT_EQ(42, f.value());
211 // Returned future propagates
213 auto f = makeFuture().then([] {
216 }).onError([&](eggs_t& /* e */) { return makeFuture<int>(42); });
217 EXPECT_EQ(42, f.value());
222 auto f = makeFuture()
223 .then([] { throw eggs; return 0; })
224 .onError([&] (eggs_t& e) { throw e; return -1; });
225 EXPECT_THROW(f.value(), eggs_t);
229 auto f = makeFuture()
230 .then([] { throw eggs; return 0; })
231 .onError([&] (eggs_t& e) { throw e; return makeFuture<int>(-1); });
232 EXPECT_THROW(f.value(), eggs_t);
235 // exception_wrapper, return Future<T>
237 auto f = makeFuture()
238 .then([] { throw eggs; })
239 .onError([&](exception_wrapper /* e */) {
244 EXPECT_NO_THROW(f.value());
247 // exception_wrapper, return Future<T> but throw
249 auto f = makeFuture()
254 .onError([&](exception_wrapper /* e */) {
257 return makeFuture<int>(-1);
260 EXPECT_THROW(f.value(), eggs_t);
263 // exception_wrapper, return T
265 auto f = makeFuture()
270 .onError([&](exception_wrapper /* e */) {
275 EXPECT_EQ(-1, f.value());
278 // exception_wrapper, return T but throw
280 auto f = makeFuture()
285 .onError([&](exception_wrapper /* e */) {
291 EXPECT_THROW(f.value(), eggs_t);
294 // const exception_wrapper&
296 auto f = makeFuture()
297 .then([] { throw eggs; })
298 .onError([&](const exception_wrapper& /* e */) {
303 EXPECT_NO_THROW(f.value());
308 TEST(Future, special) {
309 EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
310 EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
311 EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
312 EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
316 auto f = makeFuture<std::string>("0")
318 return makeFuture<std::string>("1"); })
319 .then([](Try<std::string>&& t) {
320 return makeFuture(t.value() + ";2"); })
321 .then([](const Try<std::string>&& t) {
322 return makeFuture(t.value() + ";3"); })
323 .then([](Try<std::string>& t) {
324 return makeFuture(t.value() + ";4"); })
325 .then([](const Try<std::string>& t) {
326 return makeFuture(t.value() + ";5"); })
327 .then([](Try<std::string> t) {
328 return makeFuture(t.value() + ";6"); })
329 .then([](const Try<std::string> t) {
330 return makeFuture(t.value() + ";7"); })
331 .then([](std::string&& s) {
332 return makeFuture(s + ";8"); })
333 .then([](const std::string&& s) {
334 return makeFuture(s + ";9"); })
335 .then([](std::string& s) {
336 return makeFuture(s + ";10"); })
337 .then([](const std::string& s) {
338 return makeFuture(s + ";11"); })
339 .then([](std::string s) {
340 return makeFuture(s + ";12"); })
341 .then([](const std::string s) {
342 return makeFuture(s + ";13"); })
344 EXPECT_EQ(f.value(), "1;2;3;4;5;6;7;8;9;10;11;12;13");
347 TEST(Future, thenTry) {
350 makeFuture<int>(42).then([&](Try<int>&& t) {
352 EXPECT_EQ(42, t.value());
354 EXPECT_TRUE(flag); flag = false;
357 .then([](Try<int>&& t) { return t.value(); })
358 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
359 EXPECT_TRUE(flag); flag = false;
361 makeFuture().then([&](Try<Unit>&& t) { flag = true; t.value(); });
362 EXPECT_TRUE(flag); flag = false;
365 auto f = p.getFuture().then([&](Try<Unit>&& /* t */) { flag = true; });
367 EXPECT_FALSE(f.isReady());
370 EXPECT_TRUE(f.isReady());
373 TEST(Future, thenValue) {
375 makeFuture<int>(42).then([&](int i){
379 EXPECT_TRUE(flag); flag = false;
382 .then([](int i){ return i; })
383 .then([&](int i) { flag = true; EXPECT_EQ(42, i); });
384 EXPECT_TRUE(flag); flag = false;
386 makeFuture().then([&]{
389 EXPECT_TRUE(flag); flag = false;
391 auto f = makeFuture<int>(eggs).then([&](int /* i */) {});
392 EXPECT_THROW(f.value(), eggs_t);
394 f = makeFuture<Unit>(eggs).then([&]{});
395 EXPECT_THROW(f.value(), eggs_t);
398 TEST(Future, thenValueFuture) {
401 .then([](int i){ return makeFuture<int>(std::move(i)); })
402 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
403 EXPECT_TRUE(flag); flag = false;
405 makeFuture().then([] {
407 }).then([&](Try<Unit>&& /* t */) { flag = true; });
408 EXPECT_TRUE(flag); flag = false;
411 static std::string doWorkStatic(Try<std::string>&& t) {
412 return t.value() + ";static";
415 TEST(Future, thenFunction) {
417 std::string doWork(Try<std::string>&& t) {
418 return t.value() + ";class";
420 static std::string doWorkStatic(Try<std::string>&& t) {
421 return t.value() + ";class-static";
425 auto f = makeFuture<std::string>("start")
427 .then(Worker::doWorkStatic)
428 .then(&Worker::doWork, &w);
430 EXPECT_EQ(f.value(), "start;static;class-static;class");
433 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
434 return makeFuture(t.value() + ";static");
437 TEST(Future, thenFunctionFuture) {
439 Future<std::string> doWorkFuture(Try<std::string>&& t) {
440 return makeFuture(t.value() + ";class");
442 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
443 return makeFuture(t.value() + ";class-static");
447 auto f = makeFuture<std::string>("start")
448 .then(doWorkStaticFuture)
449 .then(Worker::doWorkStaticFuture)
450 .then(&Worker::doWorkFuture, &w);
452 EXPECT_EQ(f.value(), "start;static;class-static;class");
455 TEST(Future, thenStdFunction) {
457 std::function<int()> fn = [](){ return 42; };
458 auto f = makeFuture().then(std::move(fn));
459 EXPECT_EQ(f.value(), 42);
462 std::function<int(int)> fn = [](int i){ return i + 23; };
463 auto f = makeFuture(19).then(std::move(fn));
464 EXPECT_EQ(f.value(), 42);
467 std::function<int(Try<int>&)> fn = [](Try<int>& t){ return t.value() + 2; };
468 auto f = makeFuture(1).then(std::move(fn));
469 EXPECT_EQ(f.value(), 3);
473 std::function<void()> fn = [&flag](){ flag = true; };
474 auto f = makeFuture().then(std::move(fn));
475 EXPECT_TRUE(f.isReady());
480 TEST(Future, thenBind) {
482 return makeFuture("bind");
484 auto b = std::bind(l);
485 auto f = makeFuture().then(std::move(b));
486 EXPECT_EQ(f.value(), "bind");
489 TEST(Future, thenBindTry) {
490 auto l = [](Try<std::string>&& t) {
491 return makeFuture(t.value() + ";bind");
493 auto b = std::bind(l, std::placeholders::_1);
494 auto f = makeFuture<std::string>("start").then(std::move(b));
496 EXPECT_EQ(f.value(), "start;bind");
499 TEST(Future, value) {
500 auto f = makeFuture(std::unique_ptr<int>(new int(42)));
501 auto up = std::move(f.value());
504 EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
507 TEST(Future, isReady) {
509 auto f = p.getFuture();
510 EXPECT_FALSE(f.isReady());
512 EXPECT_TRUE(f.isReady());
515 TEST(Future, futureNotReady) {
517 Future<int> f = p.getFuture();
518 EXPECT_THROW(f.value(), eggs_t);
521 TEST(Future, hasException) {
522 EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
523 EXPECT_FALSE(makeFuture(42).getTry().hasException());
526 TEST(Future, hasValue) {
527 EXPECT_TRUE(makeFuture(42).getTry().hasValue());
528 EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
531 TEST(Future, makeFuture) {
532 EXPECT_TYPE(makeFuture(42), Future<int>);
533 EXPECT_EQ(42, makeFuture(42).value());
535 EXPECT_TYPE(makeFuture<float>(42), Future<float>);
536 EXPECT_EQ(42, makeFuture<float>(42).value());
538 auto fun = [] { return 42; };
539 EXPECT_TYPE(makeFutureWith(fun), Future<int>);
540 EXPECT_EQ(42, makeFutureWith(fun).value());
542 auto funf = [] { return makeFuture<int>(43); };
543 EXPECT_TYPE(makeFutureWith(funf), Future<int>);
544 EXPECT_EQ(43, makeFutureWith(funf).value());
546 auto failfun = []() -> int { throw eggs; };
547 EXPECT_TYPE(makeFutureWith(failfun), Future<int>);
548 EXPECT_NO_THROW(makeFutureWith(failfun));
549 EXPECT_THROW(makeFutureWith(failfun).value(), eggs_t);
551 auto failfunf = []() -> Future<int> { throw eggs; };
552 EXPECT_TYPE(makeFutureWith(failfunf), Future<int>);
553 EXPECT_NO_THROW(makeFutureWith(failfunf));
554 EXPECT_THROW(makeFutureWith(failfunf).value(), eggs_t);
556 EXPECT_TYPE(makeFuture(), Future<Unit>);
559 TEST(Future, finish) {
560 auto x = std::make_shared<int>(0);
563 auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
565 // The callback hasn't executed
568 // The callback has a reference to x
569 EXPECT_EQ(2, x.use_count());
573 // the callback has executed
576 // the callback has been destructed
577 // and has released its reference to x
578 EXPECT_EQ(1, x.use_count());
581 TEST(Future, finishBigLambda) {
582 auto x = std::make_shared<int>(0);
584 // bulk_data, to be captured in the lambda passed to Future::then.
585 // This is meant to force that the lambda can't be stored inside
586 // the Future object.
587 std::array<char, sizeof(detail::Core<int>)> bulk_data = {0};
589 // suppress gcc warning about bulk_data not being used
590 EXPECT_EQ(bulk_data[0], 0);
593 auto f = p.getFuture().then([x, bulk_data](Try<int>&& t) { *x = t.value(); });
595 // The callback hasn't executed
598 // The callback has a reference to x
599 EXPECT_EQ(2, x.use_count());
603 // the callback has executed
606 // the callback has been destructed
607 // and has released its reference to x
608 EXPECT_EQ(1, x.use_count());
611 TEST(Future, unwrap) {
615 auto fa = a.getFuture();
616 auto fb = b.getFuture();
621 // do a, then do b, and get the result of a + b.
622 Future<int> f = fa.then([&](Try<int>&& ta) {
623 auto va = ta.value();
625 return fb.then([va, &flag2](Try<int>&& tb) {
627 return va + tb.value();
633 EXPECT_FALSE(f.isReady());
638 EXPECT_FALSE(f.isReady());
643 EXPECT_EQ(7, f.value());
646 TEST(Future, throwCaughtInImmediateThen) {
647 // Neither of these should throw "Promise already satisfied"
649 [=](Try<Unit>&&) -> int { throw std::exception(); });
651 [=](Try<Unit>&&) -> Future<int> { throw std::exception(); });
654 TEST(Future, throwIfFailed) {
655 makeFuture<Unit>(eggs)
656 .then([=](Try<Unit>&& t) {
657 EXPECT_THROW(t.throwIfFailed(), eggs_t);
660 .then([=](Try<Unit>&& t) {
661 EXPECT_NO_THROW(t.throwIfFailed());
664 makeFuture<int>(eggs)
665 .then([=](Try<int>&& t) {
666 EXPECT_THROW(t.throwIfFailed(), eggs_t);
669 .then([=](Try<int>&& t) {
670 EXPECT_NO_THROW(t.throwIfFailed());
674 TEST(Future, getFutureAfterSetValue) {
677 EXPECT_EQ(42, p.getFuture().value());
680 TEST(Future, getFutureAfterSetException) {
682 p.setWith([]() -> void { throw std::logic_error("foo"); });
683 EXPECT_THROW(p.getFuture().value(), std::logic_error);
686 TEST(Future, detachRace) {
688 // This test is designed to detect a race that was in Core::detachOne()
689 // where detached_ was incremented and then tested, and that
690 // allowed a race where both Promise and Future would think they were the
691 // second and both try to delete. This showed up at scale but was very
692 // difficult to reliably repro in a test. As it is, this only fails about
693 // once in every 1,000 executions. Doing this 1,000 times is going to make a
694 // slow test so I won't do that but if it ever fails, take it seriously, and
695 // run the test binary with "--gtest_repeat=10000 --gtest_filter=*detachRace"
696 // (Don't forget to enable ASAN)
697 auto p = folly::make_unique<Promise<bool>>();
698 auto f = folly::make_unique<Future<bool>>(p->getFuture());
699 folly::Baton<> baton;
709 // Test of handling of a circular dependency. It's never recommended
710 // to have one because of possible memory leaks. Here we test that
711 // we can handle freeing of the Future while it is running.
712 TEST(Future, CircularDependencySharedPtrSelfReset) {
713 Promise<int64_t> promise;
714 auto ptr = std::make_shared<Future<int64_t>>(promise.getFuture());
716 ptr->then([ptr](folly::Try<int64_t>&& /* uid */) mutable {
717 EXPECT_EQ(1, ptr.use_count());
719 // Leaving no references to ourselves.
721 EXPECT_EQ(0, ptr.use_count());
724 EXPECT_EQ(2, ptr.use_count());
731 TEST(Future, Constructor) {
732 auto f1 = []() -> Future<int> { return Future<int>(3); }();
733 EXPECT_EQ(f1.value(), 3);
734 auto f2 = []() -> Future<Unit> { return Future<Unit>(); }();
735 EXPECT_NO_THROW(f2.value());
738 TEST(Future, ImplicitConstructor) {
739 auto f1 = []() -> Future<int> { return 3; }();
740 EXPECT_EQ(f1.value(), 3);
741 // Unfortunately, the C++ standard does not allow the
742 // following implicit conversion to work:
743 //auto f2 = []() -> Future<Unit> { }();
746 TEST(Future, thenDynamic) {
747 // folly::dynamic has a constructor that takes any T, this test makes
748 // sure that we call the then lambda with folly::dynamic and not
749 // Try<folly::dynamic> because that then fails to compile
750 Promise<folly::dynamic> p;
751 Future<folly::dynamic> f = p.getFuture().then(
752 [](const folly::dynamic& d) {
753 return folly::dynamic(d.asInt() + 3);
757 EXPECT_EQ(f.get(), 5);
760 TEST(Future, RequestContext) {
761 class NewThreadExecutor : public Executor {
763 ~NewThreadExecutor() override {
764 std::for_each(v_.begin(), v_.end(), [](std::thread& t){ t.join(); });
766 void add(Func f) override {
767 if (throwsOnAdd_) { throw std::exception(); }
768 v_.emplace_back(std::move(f));
770 void addWithPriority(Func f, int8_t /* prio */) override {
773 uint8_t getNumPriorities() const override { return numPriorities_; }
775 void setHandlesPriorities() { numPriorities_ = 2; }
776 void setThrowsOnAdd() { throwsOnAdd_ = true; }
778 std::vector<std::thread> v_;
779 uint8_t numPriorities_ = 1;
780 bool throwsOnAdd_ = false;
783 struct MyRequestData : RequestData {
784 MyRequestData(bool value = false) : value(value) {}
789 RequestContext::create();
790 RequestContext::get()->setContextData("key",
791 folly::make_unique<MyRequestData>(true));
792 auto checker = [](int lineno) {
793 return [lineno](Try<int>&& /* t */) {
794 auto d = static_cast<MyRequestData*>(
795 RequestContext::get()->getContextData("key"));
796 EXPECT_TRUE(d && d->value) << "on line " << lineno;
800 makeFuture(1).via(&e).then(checker(__LINE__));
802 e.setHandlesPriorities();
803 makeFuture(2).via(&e).then(checker(__LINE__));
806 p1.getFuture().then(checker(__LINE__));
809 p2.getFuture().via(&e).then(checker(__LINE__));
811 RequestContext::create();
816 TEST(Future, makeFutureNoThrow) {
817 makeFuture().value();