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); \
62 .then([] { throw eggs; })
63 .onError([&] (eggs_t& e) { flag(); });
65 EXPECT_NO_THROW(f.value());
70 .then([] { throw eggs; })
71 .onError([&] (eggs_t& e) { flag(); return makeFuture(); });
73 EXPECT_NO_THROW(f.value());
79 .then([] { throw eggs; })
80 .onError([&] (eggs_t e) { flag(); });
82 EXPECT_NO_THROW(f.value());
87 .then([] { throw eggs; })
88 .onError([&] (eggs_t e) { flag(); return makeFuture(); });
90 EXPECT_NO_THROW(f.value());
96 .then([] { throw eggs; })
97 .onError([&] (std::exception& e) { flag(); });
99 EXPECT_NO_THROW(f.value());
103 auto f = makeFuture()
104 .then([] { throw eggs; })
105 .onError([&] (std::exception& e) { flag(); return makeFuture(); });
107 EXPECT_NO_THROW(f.value());
112 auto f = makeFuture()
113 .then([] { throw -1; })
114 .onError([&] (int e) { flag(); });
116 EXPECT_NO_THROW(f.value());
120 auto f = makeFuture()
121 .then([] { throw -1; })
122 .onError([&] (int e) { flag(); return makeFuture(); });
124 EXPECT_NO_THROW(f.value());
129 auto f = makeFuture()
130 .then([] { throw eggs; })
131 .onError([&] (eggs_t& e) mutable { flag(); });
133 EXPECT_NO_THROW(f.value());
137 auto f = makeFuture()
138 .then([] { throw eggs; })
139 .onError([&] (eggs_t& e) mutable { flag(); return makeFuture(); });
141 EXPECT_NO_THROW(f.value());
146 auto f = makeFuture()
147 .then([] { return 42; })
148 .onError([&] (eggs_t& e) { flag(); return -1; });
150 EXPECT_EQ(42, f.value());
154 auto f = makeFuture()
155 .then([] { return 42; })
156 .onError([&] (eggs_t& e) { flag(); return makeFuture<int>(-1); });
158 EXPECT_EQ(42, f.value());
161 // Catch different exception
163 auto f = makeFuture()
164 .then([] { throw eggs; })
165 .onError([&] (std::runtime_error& e) { flag(); });
167 EXPECT_THROW(f.value(), eggs_t);
171 auto f = makeFuture()
172 .then([] { throw eggs; })
173 .onError([&] (std::runtime_error& e) { flag(); return makeFuture(); });
175 EXPECT_THROW(f.value(), eggs_t);
178 // Returned value propagates
180 auto f = makeFuture()
181 .then([] { throw eggs; return 0; })
182 .onError([&] (eggs_t& e) { return 42; });
183 EXPECT_EQ(42, f.value());
186 // Returned future propagates
188 auto f = makeFuture()
189 .then([] { throw eggs; return 0; })
190 .onError([&] (eggs_t& e) { return makeFuture<int>(42); });
191 EXPECT_EQ(42, f.value());
196 auto f = makeFuture()
197 .then([] { throw eggs; return 0; })
198 .onError([&] (eggs_t& e) { throw e; return -1; });
199 EXPECT_THROW(f.value(), eggs_t);
203 auto f = makeFuture()
204 .then([] { throw eggs; return 0; })
205 .onError([&] (eggs_t& e) { throw e; return makeFuture<int>(-1); });
206 EXPECT_THROW(f.value(), eggs_t);
209 // exception_wrapper, return Future<T>
211 auto f = makeFuture()
212 .then([] { throw eggs; })
213 .onError([&] (exception_wrapper e) { flag(); return makeFuture(); });
215 EXPECT_NO_THROW(f.value());
218 // exception_wrapper, return Future<T> but throw
220 auto f = makeFuture()
221 .then([]{ throw eggs; return 0; })
222 .onError([&] (exception_wrapper e) {
225 return makeFuture<int>(-1);
228 EXPECT_THROW(f.value(), eggs_t);
231 // exception_wrapper, return T
233 auto f = makeFuture()
234 .then([]{ throw eggs; return 0; })
235 .onError([&] (exception_wrapper e) {
240 EXPECT_EQ(-1, f.value());
243 // exception_wrapper, return T but throw
245 auto f = makeFuture()
246 .then([]{ throw eggs; return 0; })
247 .onError([&] (exception_wrapper e) {
253 EXPECT_THROW(f.value(), eggs_t);
256 // const exception_wrapper&
258 auto f = makeFuture()
259 .then([] { throw eggs; })
260 .onError([&] (const exception_wrapper& e) {
265 EXPECT_NO_THROW(f.value());
270 TEST(Future, special) {
271 EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
272 EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
273 EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
274 EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
278 auto f = makeFuture<std::string>("0")
280 return makeFuture<std::string>("1"); })
281 .then([](Try<std::string>&& t) {
282 return makeFuture(t.value() + ";2"); })
283 .then([](const Try<std::string>&& t) {
284 return makeFuture(t.value() + ";3"); })
285 .then([](Try<std::string>& t) {
286 return makeFuture(t.value() + ";4"); })
287 .then([](const Try<std::string>& t) {
288 return makeFuture(t.value() + ";5"); })
289 .then([](Try<std::string> t) {
290 return makeFuture(t.value() + ";6"); })
291 .then([](const Try<std::string> t) {
292 return makeFuture(t.value() + ";7"); })
293 .then([](std::string&& s) {
294 return makeFuture(s + ";8"); })
295 .then([](const std::string&& s) {
296 return makeFuture(s + ";9"); })
297 .then([](std::string& s) {
298 return makeFuture(s + ";10"); })
299 .then([](const std::string& s) {
300 return makeFuture(s + ";11"); })
301 .then([](std::string s) {
302 return makeFuture(s + ";12"); })
303 .then([](const std::string s) {
304 return makeFuture(s + ";13"); })
306 EXPECT_EQ(f.value(), "1;2;3;4;5;6;7;8;9;10;11;12;13");
309 TEST(Future, thenTry) {
312 makeFuture<int>(42).then([&](Try<int>&& t) {
314 EXPECT_EQ(42, t.value());
316 EXPECT_TRUE(flag); flag = false;
319 .then([](Try<int>&& t) { return t.value(); })
320 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
321 EXPECT_TRUE(flag); flag = false;
323 makeFuture().then([&](Try<Unit>&& t) { flag = true; t.value(); });
324 EXPECT_TRUE(flag); flag = false;
327 auto f = p.getFuture().then([&](Try<Unit>&& t) { flag = true; });
329 EXPECT_FALSE(f.isReady());
332 EXPECT_TRUE(f.isReady());
335 TEST(Future, thenValue) {
337 makeFuture<int>(42).then([&](int i){
341 EXPECT_TRUE(flag); flag = false;
344 .then([](int i){ return i; })
345 .then([&](int i) { flag = true; EXPECT_EQ(42, i); });
346 EXPECT_TRUE(flag); flag = false;
348 makeFuture().then([&]{
351 EXPECT_TRUE(flag); flag = false;
353 auto f = makeFuture<int>(eggs).then([&](int i){});
354 EXPECT_THROW(f.value(), eggs_t);
356 f = makeFuture<Unit>(eggs).then([&]{});
357 EXPECT_THROW(f.value(), eggs_t);
360 TEST(Future, thenValueFuture) {
363 .then([](int i){ return makeFuture<int>(std::move(i)); })
364 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
365 EXPECT_TRUE(flag); flag = false;
368 .then([]{ return makeFuture(); })
369 .then([&](Try<Unit>&& t) { flag = true; });
370 EXPECT_TRUE(flag); flag = false;
373 static std::string doWorkStatic(Try<std::string>&& t) {
374 return t.value() + ";static";
377 TEST(Future, thenFunction) {
379 std::string doWork(Try<std::string>&& t) {
380 return t.value() + ";class";
382 static std::string doWorkStatic(Try<std::string>&& t) {
383 return t.value() + ";class-static";
387 auto f = makeFuture<std::string>("start")
389 .then(Worker::doWorkStatic)
390 .then(&Worker::doWork, &w);
392 EXPECT_EQ(f.value(), "start;static;class-static;class");
395 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
396 return makeFuture(t.value() + ";static");
399 TEST(Future, thenFunctionFuture) {
401 Future<std::string> doWorkFuture(Try<std::string>&& t) {
402 return makeFuture(t.value() + ";class");
404 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
405 return makeFuture(t.value() + ";class-static");
409 auto f = makeFuture<std::string>("start")
410 .then(doWorkStaticFuture)
411 .then(Worker::doWorkStaticFuture)
412 .then(&Worker::doWorkFuture, &w);
414 EXPECT_EQ(f.value(), "start;static;class-static;class");
417 TEST(Future, thenStdFunction) {
419 std::function<int()> fn = [](){ return 42; };
420 auto f = makeFuture().then(std::move(fn));
421 EXPECT_EQ(f.value(), 42);
424 std::function<int(int)> fn = [](int i){ return i + 23; };
425 auto f = makeFuture(19).then(std::move(fn));
426 EXPECT_EQ(f.value(), 42);
429 std::function<int(Try<int>&)> fn = [](Try<int>& t){ return t.value() + 2; };
430 auto f = makeFuture(1).then(std::move(fn));
431 EXPECT_EQ(f.value(), 3);
435 std::function<void()> fn = [&flag](){ flag = true; };
436 auto f = makeFuture().then(std::move(fn));
437 EXPECT_TRUE(f.isReady());
442 TEST(Future, thenBind) {
444 return makeFuture("bind");
446 auto b = std::bind(l);
447 auto f = makeFuture().then(std::move(b));
448 EXPECT_EQ(f.value(), "bind");
451 TEST(Future, thenBindTry) {
452 auto l = [](Try<std::string>&& t) {
453 return makeFuture(t.value() + ";bind");
455 auto b = std::bind(l, std::placeholders::_1);
456 auto f = makeFuture<std::string>("start").then(std::move(b));
458 EXPECT_EQ(f.value(), "start;bind");
461 TEST(Future, value) {
462 auto f = makeFuture(std::unique_ptr<int>(new int(42)));
463 auto up = std::move(f.value());
466 EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
469 TEST(Future, isReady) {
471 auto f = p.getFuture();
472 EXPECT_FALSE(f.isReady());
474 EXPECT_TRUE(f.isReady());
477 TEST(Future, futureNotReady) {
479 Future<int> f = p.getFuture();
480 EXPECT_THROW(f.value(), eggs_t);
483 TEST(Future, hasException) {
484 EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
485 EXPECT_FALSE(makeFuture(42).getTry().hasException());
488 TEST(Future, hasValue) {
489 EXPECT_TRUE(makeFuture(42).getTry().hasValue());
490 EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
493 TEST(Future, makeFuture) {
494 EXPECT_TYPE(makeFuture(42), Future<int>);
495 EXPECT_EQ(42, makeFuture(42).value());
497 EXPECT_TYPE(makeFuture<float>(42), Future<float>);
498 EXPECT_EQ(42, makeFuture<float>(42).value());
500 auto fun = [] { return 42; };
501 EXPECT_TYPE(makeFutureWith(fun), Future<int>);
502 EXPECT_EQ(42, makeFutureWith(fun).value());
504 auto funf = [] { return makeFuture<int>(43); };
505 EXPECT_TYPE(makeFutureWith(funf), Future<int>);
506 EXPECT_EQ(43, makeFutureWith(funf).value());
508 auto failfun = []() -> int { throw eggs; };
509 EXPECT_TYPE(makeFutureWith(failfun), Future<int>);
510 EXPECT_NO_THROW(makeFutureWith(failfun));
511 EXPECT_THROW(makeFutureWith(failfun).value(), eggs_t);
513 auto failfunf = []() -> Future<int> { throw eggs; };
514 EXPECT_TYPE(makeFutureWith(failfunf), Future<int>);
515 EXPECT_NO_THROW(makeFutureWith(failfunf));
516 EXPECT_THROW(makeFutureWith(failfunf).value(), eggs_t);
518 EXPECT_TYPE(makeFuture(), Future<Unit>);
521 TEST(Future, finish) {
522 auto x = std::make_shared<int>(0);
525 auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
527 // The callback hasn't executed
530 // The callback has a reference to x
531 EXPECT_EQ(2, x.use_count());
535 // the callback has executed
538 // the callback has been destructed
539 // and has released its reference to x
540 EXPECT_EQ(1, x.use_count());
543 TEST(Future, unwrap) {
547 auto fa = a.getFuture();
548 auto fb = b.getFuture();
553 // do a, then do b, and get the result of a + b.
554 Future<int> f = fa.then([&](Try<int>&& ta) {
555 auto va = ta.value();
557 return fb.then([va, &flag2](Try<int>&& tb) {
559 return va + tb.value();
565 EXPECT_FALSE(f.isReady());
570 EXPECT_FALSE(f.isReady());
575 EXPECT_EQ(7, f.value());
578 TEST(Future, throwCaughtInImmediateThen) {
579 // Neither of these should throw "Promise already satisfied"
581 [=](Try<Unit>&&) -> int { throw std::exception(); });
583 [=](Try<Unit>&&) -> Future<int> { throw std::exception(); });
586 TEST(Future, throwIfFailed) {
587 makeFuture<Unit>(eggs)
588 .then([=](Try<Unit>&& t) {
589 EXPECT_THROW(t.throwIfFailed(), eggs_t);
592 .then([=](Try<Unit>&& t) {
593 EXPECT_NO_THROW(t.throwIfFailed());
596 makeFuture<int>(eggs)
597 .then([=](Try<int>&& t) {
598 EXPECT_THROW(t.throwIfFailed(), eggs_t);
601 .then([=](Try<int>&& t) {
602 EXPECT_NO_THROW(t.throwIfFailed());
606 TEST(Future, getFutureAfterSetValue) {
609 EXPECT_EQ(42, p.getFuture().value());
612 TEST(Future, getFutureAfterSetException) {
614 p.setWith([]() -> void { throw std::logic_error("foo"); });
615 EXPECT_THROW(p.getFuture().value(), std::logic_error);
618 TEST(Future, detachRace) {
620 // This test is designed to detect a race that was in Core::detachOne()
621 // where detached_ was incremented and then tested, and that
622 // allowed a race where both Promise and Future would think they were the
623 // second and both try to delete. This showed up at scale but was very
624 // difficult to reliably repro in a test. As it is, this only fails about
625 // once in every 1,000 executions. Doing this 1,000 times is going to make a
626 // slow test so I won't do that but if it ever fails, take it seriously, and
627 // run the test binary with "--gtest_repeat=10000 --gtest_filter=*detachRace"
628 // (Don't forget to enable ASAN)
629 auto p = folly::make_unique<Promise<bool>>();
630 auto f = folly::make_unique<Future<bool>>(p->getFuture());
631 folly::Baton<> baton;
641 // Test of handling of a circular dependency. It's never recommended
642 // to have one because of possible memory leaks. Here we test that
643 // we can handle freeing of the Future while it is running.
644 TEST(Future, CircularDependencySharedPtrSelfReset) {
645 Promise<int64_t> promise;
646 auto ptr = std::make_shared<Future<int64_t>>(promise.getFuture());
649 [ptr] (folly::Try<int64_t>&& uid) mutable {
650 EXPECT_EQ(1, ptr.use_count());
652 // Leaving no references to ourselves.
654 EXPECT_EQ(0, ptr.use_count());
658 EXPECT_EQ(2, ptr.use_count());
665 TEST(Future, Constructor) {
666 auto f1 = []() -> Future<int> { return Future<int>(3); }();
667 EXPECT_EQ(f1.value(), 3);
668 auto f2 = []() -> Future<Unit> { return Future<Unit>(); }();
669 EXPECT_NO_THROW(f2.value());
672 TEST(Future, ImplicitConstructor) {
673 auto f1 = []() -> Future<int> { return 3; }();
674 EXPECT_EQ(f1.value(), 3);
675 // Unfortunately, the C++ standard does not allow the
676 // following implicit conversion to work:
677 //auto f2 = []() -> Future<Unit> { }();
680 TEST(Future, thenDynamic) {
681 // folly::dynamic has a constructor that takes any T, this test makes
682 // sure that we call the then lambda with folly::dynamic and not
683 // Try<folly::dynamic> because that then fails to compile
684 Promise<folly::dynamic> p;
685 Future<folly::dynamic> f = p.getFuture().then(
686 [](const folly::dynamic& d) {
687 return folly::dynamic(d.asInt() + 3);
691 EXPECT_EQ(f.get(), 5);
694 TEST(Future, RequestContext) {
695 class NewThreadExecutor : public Executor {
697 ~NewThreadExecutor() override {
698 std::for_each(v_.begin(), v_.end(), [](std::thread& t){ t.join(); });
700 void add(Func f) override {
701 if (throwsOnAdd_) { throw std::exception(); }
702 v_.emplace_back(std::move(f));
704 void addWithPriority(Func f, int8_t prio) override { add(std::move(f)); }
705 uint8_t getNumPriorities() const override { return numPriorities_; }
707 void setHandlesPriorities() { numPriorities_ = 2; }
708 void setThrowsOnAdd() { throwsOnAdd_ = true; }
710 std::vector<std::thread> v_;
711 uint8_t numPriorities_ = 1;
712 bool throwsOnAdd_ = false;
715 struct MyRequestData : RequestData {
716 MyRequestData(bool value = false) : value(value) {}
721 RequestContext::create();
722 RequestContext::get()->setContextData("key",
723 folly::make_unique<MyRequestData>(true));
724 auto checker = [](int lineno) {
725 return [lineno](Try<int>&& t) {
726 auto d = static_cast<MyRequestData*>(
727 RequestContext::get()->getContextData("key"));
728 EXPECT_TRUE(d && d->value) << "on line " << lineno;
732 makeFuture(1).via(&e).then(checker(__LINE__));
734 e.setHandlesPriorities();
735 makeFuture(2).via(&e).then(checker(__LINE__));
738 p1.getFuture().then(checker(__LINE__));
741 p2.getFuture().via(&e).then(checker(__LINE__));
743 RequestContext::create();
748 TEST(Future, makeFutureNoThrow) {
749 makeFuture().value();