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>
30 #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, onError) {
45 auto flag = [&]{ theFlag = true; };
46 #define EXPECT_FLAG() \
48 EXPECT_TRUE(theFlag); \
52 #define EXPECT_NO_FLAG() \
54 EXPECT_FALSE(theFlag); \
61 .then([] { throw eggs; })
62 .onError([&] (eggs_t& e) { flag(); });
64 EXPECT_NO_THROW(f.value());
69 .then([] { throw eggs; })
70 .onError([&] (eggs_t& e) { flag(); return makeFuture(); });
72 EXPECT_NO_THROW(f.value());
78 .then([] { throw eggs; })
79 .onError([&] (eggs_t e) { flag(); });
81 EXPECT_NO_THROW(f.value());
86 .then([] { throw eggs; })
87 .onError([&] (eggs_t e) { flag(); return makeFuture(); });
89 EXPECT_NO_THROW(f.value());
95 .then([] { throw eggs; })
96 .onError([&] (std::exception& e) { flag(); });
98 EXPECT_NO_THROW(f.value());
102 auto f = makeFuture()
103 .then([] { throw eggs; })
104 .onError([&] (std::exception& e) { flag(); return makeFuture(); });
106 EXPECT_NO_THROW(f.value());
111 auto f = makeFuture()
112 .then([] { throw -1; })
113 .onError([&] (int e) { flag(); });
115 EXPECT_NO_THROW(f.value());
119 auto f = makeFuture()
120 .then([] { throw -1; })
121 .onError([&] (int e) { flag(); return makeFuture(); });
123 EXPECT_NO_THROW(f.value());
128 auto f = makeFuture()
129 .then([] { throw eggs; })
130 .onError([&] (eggs_t& e) mutable { flag(); });
132 EXPECT_NO_THROW(f.value());
136 auto f = makeFuture()
137 .then([] { throw eggs; })
138 .onError([&] (eggs_t& e) mutable { flag(); return makeFuture(); });
140 EXPECT_NO_THROW(f.value());
145 auto f = makeFuture()
146 .then([] { return 42; })
147 .onError([&] (eggs_t& e) { flag(); return -1; });
149 EXPECT_EQ(42, f.value());
153 auto f = makeFuture()
154 .then([] { return 42; })
155 .onError([&] (eggs_t& e) { flag(); return makeFuture<int>(-1); });
157 EXPECT_EQ(42, f.value());
160 // Catch different exception
162 auto f = makeFuture()
163 .then([] { throw eggs; })
164 .onError([&] (std::runtime_error& e) { flag(); });
166 EXPECT_THROW(f.value(), eggs_t);
170 auto f = makeFuture()
171 .then([] { throw eggs; })
172 .onError([&] (std::runtime_error& e) { flag(); return makeFuture(); });
174 EXPECT_THROW(f.value(), eggs_t);
177 // Returned value propagates
179 auto f = makeFuture()
180 .then([] { throw eggs; return 0; })
181 .onError([&] (eggs_t& e) { return 42; });
182 EXPECT_EQ(42, f.value());
185 // Returned future propagates
187 auto f = makeFuture()
188 .then([] { throw eggs; return 0; })
189 .onError([&] (eggs_t& e) { return makeFuture<int>(42); });
190 EXPECT_EQ(42, f.value());
195 auto f = makeFuture()
196 .then([] { throw eggs; return 0; })
197 .onError([&] (eggs_t& e) { throw e; return -1; });
198 EXPECT_THROW(f.value(), eggs_t);
202 auto f = makeFuture()
203 .then([] { throw eggs; return 0; })
204 .onError([&] (eggs_t& e) { throw e; return makeFuture<int>(-1); });
205 EXPECT_THROW(f.value(), eggs_t);
208 // exception_wrapper, return Future<T>
210 auto f = makeFuture()
211 .then([] { throw eggs; })
212 .onError([&] (exception_wrapper e) { flag(); return makeFuture(); });
214 EXPECT_NO_THROW(f.value());
217 // exception_wrapper, return Future<T> but throw
219 auto f = makeFuture()
220 .then([]{ throw eggs; return 0; })
221 .onError([&] (exception_wrapper e) {
224 return makeFuture<int>(-1);
227 EXPECT_THROW(f.value(), eggs_t);
230 // exception_wrapper, return T
232 auto f = makeFuture()
233 .then([]{ throw eggs; return 0; })
234 .onError([&] (exception_wrapper e) {
239 EXPECT_EQ(-1, f.value());
242 // exception_wrapper, return T but throw
244 auto f = makeFuture()
245 .then([]{ throw eggs; return 0; })
246 .onError([&] (exception_wrapper e) {
252 EXPECT_THROW(f.value(), eggs_t);
255 // const exception_wrapper&
257 auto f = makeFuture()
258 .then([] { throw eggs; })
259 .onError([&] (const exception_wrapper& e) {
264 EXPECT_NO_THROW(f.value());
269 TEST(Future, special) {
270 EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
271 EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
272 EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
273 EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
277 auto f = makeFuture<std::string>("0")
279 return makeFuture<std::string>("1"); })
280 .then([](Try<std::string>&& t) {
281 return makeFuture(t.value() + ";2"); })
282 .then([](const Try<std::string>&& t) {
283 return makeFuture(t.value() + ";3"); })
284 .then([](Try<std::string>& t) {
285 return makeFuture(t.value() + ";4"); })
286 .then([](const Try<std::string>& t) {
287 return makeFuture(t.value() + ";5"); })
288 .then([](Try<std::string> t) {
289 return makeFuture(t.value() + ";6"); })
290 .then([](const Try<std::string> t) {
291 return makeFuture(t.value() + ";7"); })
292 .then([](std::string&& s) {
293 return makeFuture(s + ";8"); })
294 .then([](const std::string&& s) {
295 return makeFuture(s + ";9"); })
296 .then([](std::string& s) {
297 return makeFuture(s + ";10"); })
298 .then([](const std::string& s) {
299 return makeFuture(s + ";11"); })
300 .then([](std::string s) {
301 return makeFuture(s + ";12"); })
302 .then([](const std::string s) {
303 return makeFuture(s + ";13"); })
305 EXPECT_EQ(f.value(), "1;2;3;4;5;6;7;8;9;10;11;12;13");
308 TEST(Future, thenTry) {
311 makeFuture<int>(42).then([&](Try<int>&& t) {
313 EXPECT_EQ(42, t.value());
315 EXPECT_TRUE(flag); flag = false;
318 .then([](Try<int>&& t) { return t.value(); })
319 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
320 EXPECT_TRUE(flag); flag = false;
322 makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
323 EXPECT_TRUE(flag); flag = false;
326 auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
328 EXPECT_FALSE(f.isReady());
331 EXPECT_TRUE(f.isReady());
334 TEST(Future, thenValue) {
336 makeFuture<int>(42).then([&](int i){
340 EXPECT_TRUE(flag); flag = false;
343 .then([](int i){ return i; })
344 .then([&](int i) { flag = true; EXPECT_EQ(42, i); });
345 EXPECT_TRUE(flag); flag = false;
347 makeFuture().then([&]{
350 EXPECT_TRUE(flag); flag = false;
352 auto f = makeFuture<int>(eggs).then([&](int i){});
353 EXPECT_THROW(f.value(), eggs_t);
355 f = makeFuture<void>(eggs).then([&]{});
356 EXPECT_THROW(f.value(), eggs_t);
359 TEST(Future, thenValueFuture) {
362 .then([](int i){ return makeFuture<int>(std::move(i)); })
363 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
364 EXPECT_TRUE(flag); flag = false;
367 .then([]{ return makeFuture(); })
368 .then([&](Try<void>&& t) { flag = true; });
369 EXPECT_TRUE(flag); flag = false;
372 static std::string doWorkStatic(Try<std::string>&& t) {
373 return t.value() + ";static";
376 TEST(Future, thenFunction) {
378 std::string doWork(Try<std::string>&& t) {
379 return t.value() + ";class";
381 static std::string doWorkStatic(Try<std::string>&& t) {
382 return t.value() + ";class-static";
386 auto f = makeFuture<std::string>("start")
388 .then(Worker::doWorkStatic)
389 .then(&Worker::doWork, &w);
391 EXPECT_EQ(f.value(), "start;static;class-static;class");
394 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
395 return makeFuture(t.value() + ";static");
398 TEST(Future, thenFunctionFuture) {
400 Future<std::string> doWorkFuture(Try<std::string>&& t) {
401 return makeFuture(t.value() + ";class");
403 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
404 return makeFuture(t.value() + ";class-static");
408 auto f = makeFuture<std::string>("start")
409 .then(doWorkStaticFuture)
410 .then(Worker::doWorkStaticFuture)
411 .then(&Worker::doWorkFuture, &w);
413 EXPECT_EQ(f.value(), "start;static;class-static;class");
416 TEST(Future, thenBind) {
418 return makeFuture("bind");
420 auto b = std::bind(l);
421 auto f = makeFuture().then(std::move(b));
422 EXPECT_EQ(f.value(), "bind");
425 TEST(Future, thenBindTry) {
426 auto l = [](Try<std::string>&& t) {
427 return makeFuture(t.value() + ";bind");
429 auto b = std::bind(l, std::placeholders::_1);
430 auto f = makeFuture<std::string>("start").then(std::move(b));
432 EXPECT_EQ(f.value(), "start;bind");
435 TEST(Future, value) {
436 auto f = makeFuture(std::unique_ptr<int>(new int(42)));
437 auto up = std::move(f.value());
440 EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
443 TEST(Future, isReady) {
445 auto f = p.getFuture();
446 EXPECT_FALSE(f.isReady());
448 EXPECT_TRUE(f.isReady());
451 TEST(Future, futureNotReady) {
453 Future<int> f = p.getFuture();
454 EXPECT_THROW(f.value(), eggs_t);
457 TEST(Future, hasException) {
458 EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
459 EXPECT_FALSE(makeFuture(42).getTry().hasException());
462 TEST(Future, hasValue) {
463 EXPECT_TRUE(makeFuture(42).getTry().hasValue());
464 EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
467 TEST(Future, makeFuture) {
468 EXPECT_TYPE(makeFuture(42), Future<int>);
469 EXPECT_EQ(42, makeFuture(42).value());
471 EXPECT_TYPE(makeFuture<float>(42), Future<float>);
472 EXPECT_EQ(42, makeFuture<float>(42).value());
474 auto fun = [] { return 42; };
475 EXPECT_TYPE(makeFutureWith(fun), Future<int>);
476 EXPECT_EQ(42, makeFutureWith(fun).value());
478 auto failfun = []() -> int { throw eggs; };
479 EXPECT_TYPE(makeFutureWith(failfun), Future<int>);
480 EXPECT_THROW(makeFutureWith(failfun).value(), eggs_t);
482 EXPECT_TYPE(makeFuture(), Future<void>);
485 TEST(Future, finish) {
486 auto x = std::make_shared<int>(0);
489 auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
491 // The callback hasn't executed
494 // The callback has a reference to x
495 EXPECT_EQ(2, x.use_count());
499 // the callback has executed
502 // the callback has been destructed
503 // and has released its reference to x
504 EXPECT_EQ(1, x.use_count());
507 TEST(Future, unwrap) {
511 auto fa = a.getFuture();
512 auto fb = b.getFuture();
517 // do a, then do b, and get the result of a + b.
518 Future<int> f = fa.then([&](Try<int>&& ta) {
519 auto va = ta.value();
521 return fb.then([va, &flag2](Try<int>&& tb) {
523 return va + tb.value();
529 EXPECT_FALSE(f.isReady());
534 EXPECT_FALSE(f.isReady());
539 EXPECT_EQ(7, f.value());
542 TEST(Future, throwCaughtInImmediateThen) {
543 // Neither of these should throw "Promise already satisfied"
545 [=](Try<void>&&) -> int { throw std::exception(); });
547 [=](Try<void>&&) -> Future<int> { throw std::exception(); });
550 TEST(Future, throwIfFailed) {
551 makeFuture<void>(eggs)
552 .then([=](Try<void>&& t) {
553 EXPECT_THROW(t.throwIfFailed(), eggs_t);
556 .then([=](Try<void>&& t) {
557 EXPECT_NO_THROW(t.throwIfFailed());
560 makeFuture<int>(eggs)
561 .then([=](Try<int>&& t) {
562 EXPECT_THROW(t.throwIfFailed(), eggs_t);
565 .then([=](Try<int>&& t) {
566 EXPECT_NO_THROW(t.throwIfFailed());
570 TEST(Future, getFutureAfterSetValue) {
573 EXPECT_EQ(42, p.getFuture().value());
576 TEST(Future, getFutureAfterSetException) {
578 p.setWith([]() -> void { throw std::logic_error("foo"); });
579 EXPECT_THROW(p.getFuture().value(), std::logic_error);
582 TEST(Future, detachRace) {
584 // This test is designed to detect a race that was in Core::detachOne()
585 // where detached_ was incremented and then tested, and that
586 // allowed a race where both Promise and Future would think they were the
587 // second and both try to delete. This showed up at scale but was very
588 // difficult to reliably repro in a test. As it is, this only fails about
589 // once in every 1,000 executions. Doing this 1,000 times is going to make a
590 // slow test so I won't do that but if it ever fails, take it seriously, and
591 // run the test binary with "--gtest_repeat=10000 --gtest_filter=*detachRace"
592 // (Don't forget to enable ASAN)
593 auto p = folly::make_unique<Promise<bool>>();
594 auto f = folly::make_unique<Future<bool>>(p->getFuture());
595 folly::Baton<> baton;
605 // Test of handling of a circular dependency. It's never recommended
606 // to have one because of possible memory leaks. Here we test that
607 // we can handle freeing of the Future while it is running.
608 TEST(Future, CircularDependencySharedPtrSelfReset) {
609 Promise<int64_t> promise;
610 auto ptr = std::make_shared<Future<int64_t>>(promise.getFuture());
613 [ptr] (folly::Try<int64_t>&& uid) mutable {
614 EXPECT_EQ(1, ptr.use_count());
616 // Leaving no references to ourselves.
618 EXPECT_EQ(0, ptr.use_count());
622 EXPECT_EQ(2, ptr.use_count());
626 promise.setWith([]{return 1l;});
629 TEST(Future, Constructor) {
630 auto f1 = []() -> Future<int> { return Future<int>(3); }();
631 EXPECT_EQ(f1.value(), 3);
632 auto f2 = []() -> Future<void> { return Future<void>(); }();
633 EXPECT_NO_THROW(f2.value());
636 TEST(Future, ImplicitConstructor) {
637 auto f1 = []() -> Future<int> { return 3; }();
638 EXPECT_EQ(f1.value(), 3);
639 // Unfortunately, the C++ standard does not allow the
640 // following implicit conversion to work:
641 //auto f2 = []() -> Future<void> { }();
644 TEST(Future, thenDynamic) {
645 // folly::dynamic has a constructor that takes any T, this test makes
646 // sure that we call the then lambda with folly::dynamic and not
647 // Try<folly::dynamic> because that then fails to compile
648 Promise<folly::dynamic> p;
649 Future<folly::dynamic> f = p.getFuture().then(
650 [](const folly::dynamic& d) {
651 return folly::dynamic(d.asInt() + 3);
655 EXPECT_EQ(f.get(), 5);