2 * Copyright 2014 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.
19 #include <folly/small_vector.h>
20 #include <gtest/gtest.h>
24 #include <type_traits>
26 #include <folly/Memory.h>
27 #include <folly/wangle/Executor.h>
28 #include <folly/wangle/Future.h>
29 #include <folly/wangle/ManualExecutor.h>
31 using namespace folly::wangle;
34 using std::unique_ptr;
37 #define EXPECT_TYPE(x, T) \
38 EXPECT_TRUE((std::is_same<decltype(x), T>::value))
40 typedef WangleException eggs_t;
41 static eggs_t eggs("eggs");
58 Try<A> t_a(std::move(a));
62 EXPECT_EQ(5, t_a.value().x());
65 TEST(Future, special) {
66 EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
67 EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
68 EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
69 EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
72 TEST(Future, thenTry) {
75 makeFuture<int>(42).then([&](Try<int>&& t) {
77 EXPECT_EQ(42, t.value());
79 EXPECT_TRUE(flag); flag = false;
82 .then([](Try<int>&& t) { return t.value(); })
83 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
84 EXPECT_TRUE(flag); flag = false;
86 makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
87 EXPECT_TRUE(flag); flag = false;
90 auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
92 EXPECT_FALSE(f.isReady());
95 EXPECT_TRUE(f.isReady());
98 TEST(Future, thenValue) {
100 makeFuture<int>(42).then([&](int i){
104 EXPECT_TRUE(flag); flag = false;
107 .then([](int i){ return i; })
108 .then([&](int i) { flag = true; EXPECT_EQ(42, i); });
109 EXPECT_TRUE(flag); flag = false;
111 makeFuture().then([&]{
114 EXPECT_TRUE(flag); flag = false;
116 auto f = makeFuture<int>(eggs).then([&](int i){});
117 EXPECT_THROW(f.value(), eggs_t);
119 f = makeFuture<void>(eggs).then([&]{});
120 EXPECT_THROW(f.value(), eggs_t);
123 TEST(Future, thenValueFuture) {
126 .then([](int i){ return makeFuture<int>(std::move(i)); })
127 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
128 EXPECT_TRUE(flag); flag = false;
131 .then([]{ return makeFuture(); })
132 .then([&](Try<void>&& t) { flag = true; });
133 EXPECT_TRUE(flag); flag = false;
136 static string doWorkStatic(Try<string>&& t) {
137 return t.value() + ";static";
140 TEST(Future, thenFunction) {
142 string doWork(Try<string>&& t) {
143 return t.value() + ";class";
145 static string doWorkStatic(Try<string>&& t) {
146 return t.value() + ";class-static";
150 auto f = makeFuture<string>("start")
152 .then(Worker::doWorkStatic)
153 .then(&w, &Worker::doWork);
155 EXPECT_EQ(f.value(), "start;static;class-static;class");
158 static Future<string> doWorkStaticFuture(Try<string>&& t) {
159 return makeFuture(t.value() + ";static");
162 TEST(Future, thenFunctionFuture) {
164 Future<string> doWorkFuture(Try<string>&& t) {
165 return makeFuture(t.value() + ";class");
167 static Future<string> doWorkStaticFuture(Try<string>&& t) {
168 return makeFuture(t.value() + ";class-static");
172 auto f = makeFuture<string>("start")
173 .then(doWorkStaticFuture)
174 .then(Worker::doWorkStaticFuture)
175 .then(&w, &Worker::doWorkFuture);
177 EXPECT_EQ(f.value(), "start;static;class-static;class");
180 TEST(Future, value) {
181 auto f = makeFuture(unique_ptr<int>(new int(42)));
182 auto up = std::move(f.value());
185 EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
188 TEST(Future, isReady) {
190 auto f = p.getFuture();
191 EXPECT_FALSE(f.isReady());
193 EXPECT_TRUE(f.isReady());
196 TEST(Future, futureNotReady) {
198 Future<int> f = p.getFuture();
199 EXPECT_THROW(f.value(), eggs_t);
202 TEST(Future, hasException) {
203 EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
204 EXPECT_FALSE(makeFuture(42).getTry().hasException());
207 TEST(Future, hasValue) {
208 EXPECT_TRUE(makeFuture(42).getTry().hasValue());
209 EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
212 TEST(Future, makeFuture) {
213 EXPECT_TYPE(makeFuture(42), Future<int>);
214 EXPECT_EQ(42, makeFuture(42).value());
216 EXPECT_TYPE(makeFuture<float>(42), Future<float>);
217 EXPECT_EQ(42, makeFuture<float>(42).value());
219 auto fun = [] { return 42; };
220 EXPECT_TYPE(makeFutureTry(fun), Future<int>);
221 EXPECT_EQ(42, makeFutureTry(fun).value());
223 auto failfun = []() -> int { throw eggs; };
224 EXPECT_TYPE(makeFutureTry(failfun), Future<int>);
225 EXPECT_THROW(makeFutureTry(failfun).value(), eggs_t);
227 EXPECT_TYPE(makeFuture(), Future<void>);
232 TEST(Promise, special) {
233 EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
234 EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
235 EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
236 EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
239 TEST(Promise, getFuture) {
241 Future<int> f = p.getFuture();
242 EXPECT_FALSE(f.isReady());
245 TEST(Promise, setValue) {
247 auto ffund = fund.getFuture();
249 EXPECT_EQ(42, ffund.value());
257 auto fpod = pod.getFuture();
258 Foo f = {"the answer", 42};
260 Foo f2 = fpod.value();
261 EXPECT_EQ(f.name, f2.name);
262 EXPECT_EQ(f.value, f2.value);
264 pod = Promise<Foo>();
265 fpod = pod.getFuture();
266 pod.setValue(std::move(f2));
267 Foo f3 = fpod.value();
268 EXPECT_EQ(f.name, f3.name);
269 EXPECT_EQ(f.value, f3.value);
271 Promise<unique_ptr<int>> mov;
272 auto fmov = mov.getFuture();
273 mov.setValue(unique_ptr<int>(new int(42)));
274 unique_ptr<int> ptr = std::move(fmov.value());
278 auto fv = v.getFuture();
280 EXPECT_TRUE(fv.isReady());
283 TEST(Promise, setException) {
286 auto f = p.getFuture();
287 p.setException(eggs);
288 EXPECT_THROW(f.value(), eggs_t);
292 auto f = p.getFuture();
296 p.setException(std::current_exception());
298 EXPECT_THROW(f.value(), eggs_t);
302 TEST(Promise, fulfil) {
305 auto f = p.getFuture();
306 p.fulfil([] { return 42; });
307 EXPECT_EQ(42, f.value());
311 auto f = p.getFuture();
312 p.fulfil([]() -> int { throw eggs; });
313 EXPECT_THROW(f.value(), eggs_t);
317 TEST(Future, finish) {
318 auto x = std::make_shared<int>(0);
321 auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
323 // The callback hasn't executed
326 // The callback has a reference to x
327 EXPECT_EQ(2, x.use_count());
331 // the callback has executed
334 // the callback has been destructed
335 // and has released its reference to x
336 EXPECT_EQ(1, x.use_count());
339 TEST(Future, unwrap) {
343 auto fa = a.getFuture();
344 auto fb = b.getFuture();
349 // do a, then do b, and get the result of a + b.
350 Future<int> f = fa.then([&](Try<int>&& ta) {
351 auto va = ta.value();
353 return fb.then([va, &flag2](Try<int>&& tb) {
355 return va + tb.value();
361 EXPECT_FALSE(f.isReady());
366 EXPECT_FALSE(f.isReady());
371 EXPECT_EQ(7, f.value());
374 TEST(Future, whenAll) {
375 // returns a vector variant
377 vector<Promise<int>> promises(10);
378 vector<Future<int>> futures;
380 for (auto& p : promises)
381 futures.push_back(p.getFuture());
383 auto allf = whenAll(futures.begin(), futures.end());
385 random_shuffle(promises.begin(), promises.end());
386 for (auto& p : promises) {
387 EXPECT_FALSE(allf.isReady());
391 EXPECT_TRUE(allf.isReady());
392 auto& results = allf.value();
393 for (auto& t : results) {
394 EXPECT_EQ(42, t.value());
398 // check error semantics
400 vector<Promise<int>> promises(4);
401 vector<Future<int>> futures;
403 for (auto& p : promises)
404 futures.push_back(p.getFuture());
406 auto allf = whenAll(futures.begin(), futures.end());
409 promises[0].setValue(42);
410 promises[1].setException(eggs);
412 EXPECT_FALSE(allf.isReady());
414 promises[2].setValue(42);
416 EXPECT_FALSE(allf.isReady());
418 promises[3].setException(eggs);
420 EXPECT_TRUE(allf.isReady());
421 EXPECT_FALSE(allf.getTry().hasException());
423 auto& results = allf.value();
424 EXPECT_EQ(42, results[0].value());
425 EXPECT_TRUE(results[1].hasException());
426 EXPECT_EQ(42, results[2].value());
427 EXPECT_TRUE(results[3].hasException());
430 // check that futures are ready in then()
432 vector<Promise<void>> promises(10);
433 vector<Future<void>> futures;
435 for (auto& p : promises)
436 futures.push_back(p.getFuture());
438 auto allf = whenAll(futures.begin(), futures.end())
439 .then([](Try<vector<Try<void>>>&& ts) {
440 for (auto& f : ts.value())
444 random_shuffle(promises.begin(), promises.end());
445 for (auto& p : promises)
447 EXPECT_TRUE(allf.isReady());
452 TEST(Future, whenAny) {
454 vector<Promise<int>> promises(10);
455 vector<Future<int>> futures;
457 for (auto& p : promises)
458 futures.push_back(p.getFuture());
460 for (auto& f : futures) {
461 EXPECT_FALSE(f.isReady());
464 auto anyf = whenAny(futures.begin(), futures.end());
466 /* futures were moved in, so these are invalid now */
467 EXPECT_FALSE(anyf.isReady());
469 promises[7].setValue(42);
470 EXPECT_TRUE(anyf.isReady());
471 auto& idx_fut = anyf.value();
473 auto i = idx_fut.first;
476 auto& f = idx_fut.second;
477 EXPECT_EQ(42, f.value());
482 vector<Promise<void>> promises(10);
483 vector<Future<void>> futures;
485 for (auto& p : promises)
486 futures.push_back(p.getFuture());
488 for (auto& f : futures) {
489 EXPECT_FALSE(f.isReady());
492 auto anyf = whenAny(futures.begin(), futures.end());
494 EXPECT_FALSE(anyf.isReady());
496 promises[3].setException(eggs);
497 EXPECT_TRUE(anyf.isReady());
498 EXPECT_TRUE(anyf.value().second.hasException());
503 vector<Promise<int>> promises(10);
504 vector<Future<int>> futures;
506 for (auto& p : promises)
507 futures.push_back(p.getFuture());
509 auto anyf = whenAny(futures.begin(), futures.end())
510 .then([](Try<pair<size_t, Try<int>>>&& f) {
511 EXPECT_EQ(42, f.value().second.value());
514 promises[3].setValue(42);
515 EXPECT_TRUE(anyf.isReady());
520 TEST(when, already_completed) {
522 vector<Future<void>> fs;
523 for (int i = 0; i < 10; i++)
524 fs.push_back(makeFuture());
526 whenAll(fs.begin(), fs.end())
527 .then([&](Try<vector<Try<void>>>&& t) {
528 EXPECT_EQ(fs.size(), t.value().size());
532 vector<Future<int>> fs;
533 for (int i = 0; i < 10; i++)
534 fs.push_back(makeFuture(i));
536 whenAny(fs.begin(), fs.end())
537 .then([&](Try<pair<size_t, Try<int>>>&& t) {
539 EXPECT_EQ(p.first, p.second.value());
545 vector<Promise<void>> promises(10);
546 vector<Future<void>> futures;
548 for (auto& p : promises)
549 futures.push_back(p.getFuture());
553 whenN(futures.begin(), futures.end(), n)
554 .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
557 EXPECT_EQ(n, v.size());
559 EXPECT_TRUE(tt.second.hasValue());
562 promises[0].setValue();
564 promises[1].setValue();
566 promises[2].setValue();
570 /* Ensure that we can compile when_{all,any} with folly::small_vector */
571 TEST(when, small_vector) {
573 static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<void>),
574 "Futures should not be trivially copyable");
575 static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<int>),
576 "Futures should not be trivially copyable");
578 using folly::small_vector;
580 small_vector<Future<void>> futures;
582 for (int i = 0; i < 10; i++)
583 futures.push_back(makeFuture());
585 auto anyf = whenAny(futures.begin(), futures.end());
589 small_vector<Future<void>> futures;
591 for (int i = 0; i < 10; i++)
592 futures.push_back(makeFuture());
594 auto allf = whenAll(futures.begin(), futures.end());
598 TEST(Future, whenAllVariadic) {
601 Future<bool> fb = pb.getFuture();
602 Future<int> fi = pi.getFuture();
604 whenAll(std::move(fb), std::move(fi))
605 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
607 EXPECT_TRUE(t.hasValue());
608 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
609 EXPECT_EQ(std::get<0>(t.value()).value(), true);
610 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
611 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
619 TEST(Future, whenAllVariadicReferences) {
622 Future<bool> fb = pb.getFuture();
623 Future<int> fi = pi.getFuture();
626 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
628 EXPECT_TRUE(t.hasValue());
629 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
630 EXPECT_EQ(std::get<0>(t.value()).value(), true);
631 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
632 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
640 TEST(Future, whenAll_none) {
641 vector<Future<int>> fs;
642 auto f = whenAll(fs.begin(), fs.end());
643 EXPECT_TRUE(f.isReady());
646 TEST(Future, throwCaughtInImmediateThen) {
647 // Neither of these should throw "Promise already satisfied"
649 [=](Try<void>&&) -> int { throw std::exception(); });
651 [=](Try<void>&&) -> Future<int> { throw std::exception(); });
654 TEST(Future, throwIfFailed) {
655 makeFuture<void>(eggs)
656 .then([=](Try<void>&& t) {
657 EXPECT_THROW(t.throwIfFailed(), eggs_t);
660 .then([=](Try<void>&& 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, waitWithSemaphoreImmediate) {
675 waitWithSemaphore(makeFuture());
676 auto done = waitWithSemaphore(makeFuture(42)).value();
679 vector<int> v{1,2,3};
680 auto done_v = waitWithSemaphore(makeFuture(v)).value();
681 EXPECT_EQ(v.size(), done_v.size());
682 EXPECT_EQ(v, done_v);
684 vector<Future<void>> v_f;
685 v_f.push_back(makeFuture());
686 v_f.push_back(makeFuture());
687 auto done_v_f = waitWithSemaphore(whenAll(v_f.begin(), v_f.end())).value();
688 EXPECT_EQ(2, done_v_f.size());
690 vector<Future<bool>> v_fb;
691 v_fb.push_back(makeFuture(true));
692 v_fb.push_back(makeFuture(false));
693 auto fut = whenAll(v_fb.begin(), v_fb.end());
694 auto done_v_fb = std::move(waitWithSemaphore(std::move(fut)).value());
695 EXPECT_EQ(2, done_v_fb.size());
698 TEST(Future, waitWithSemaphore) {
700 Future<int> f = p.getFuture();
701 std::atomic<bool> flag{false};
702 std::atomic<int> result{1};
703 std::atomic<std::thread::id> id;
705 std::thread t([&](Future<int>&& tf){
706 auto n = tf.then([&](Try<int> && t) {
707 id = std::this_thread::get_id();
711 result.store(waitWithSemaphore(std::move(n)).value());
716 EXPECT_EQ(result.load(), 1);
719 // validate that the callback ended up executing in this thread, which
720 // is more to ensure that this test actually tests what it should
721 EXPECT_EQ(id, std::this_thread::get_id());
722 EXPECT_EQ(result.load(), 42);
725 TEST(Future, waitWithSemaphoreForTime) {
728 Future<int> f = p.getFuture();
729 auto t = waitWithSemaphore(std::move(f),
730 std::chrono::microseconds(1));
731 EXPECT_FALSE(t.isReady());
733 EXPECT_TRUE(t.isReady());
737 Future<int> f = p.getFuture();
739 auto t = waitWithSemaphore(std::move(f),
740 std::chrono::milliseconds(1));
741 EXPECT_TRUE(t.isReady());
744 vector<Future<bool>> v_fb;
745 v_fb.push_back(makeFuture(true));
746 v_fb.push_back(makeFuture(false));
747 auto f = whenAll(v_fb.begin(), v_fb.end());
748 auto t = waitWithSemaphore(std::move(f),
749 std::chrono::milliseconds(1));
750 EXPECT_TRUE(t.isReady());
751 EXPECT_EQ(2, t.value().size());
754 vector<Future<bool>> v_fb;
757 v_fb.push_back(p1.getFuture());
758 v_fb.push_back(p2.getFuture());
759 auto f = whenAll(v_fb.begin(), v_fb.end());
760 auto t = waitWithSemaphore(std::move(f),
761 std::chrono::milliseconds(1));
762 EXPECT_FALSE(t.isReady());
764 EXPECT_FALSE(t.isReady());
766 EXPECT_TRUE(t.isReady());
769 auto t = waitWithSemaphore(makeFuture(),
770 std::chrono::milliseconds(1));
771 EXPECT_TRUE(t.isReady());
775 TEST(Future, callbackAfterActivate) {
777 auto f = p.getFuture();
781 f.then([&](Try<void>&&) { count++; });
790 TEST(Future, activateOnDestruct) {
792 auto f = p.getFuture();
796 f.then([&](Try<void>&&) { count++; });
801 f = makeFuture(); // force destruction of old f
805 TEST(Future, viaActsCold) {
809 auto fv = makeFuture().via(&x);
810 fv.then([&](Try<void>&&) { count++; });
816 EXPECT_EQ(1, x.run());
820 TEST(Future, viaIsCold) {
822 EXPECT_FALSE(makeFuture().via(&x).isActive());
825 TEST(Future, viaRaces) {
828 auto tid = std::this_thread::get_id();
834 .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
835 .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
836 .then([&](Try<void>&&) { done = true; });
843 while (!done) x.run();
849 TEST(Future, viaRaces_2stage) {
852 auto tid = std::this_thread::get_id();
856 auto f2 = p.getFuture().via(&x);
857 f2.then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
858 .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
859 .then([&](Try<void>&&) { done = true; });
861 // the bug was in the promise being fulfilled before f2 is reactivated. we
862 // could sleep, but yielding should cause this to fail with reasonable
864 std::this_thread::yield();
872 while (!done) x.run();
877 TEST(Future, getFuture_after_setValue) {
880 EXPECT_EQ(42, p.getFuture().value());
883 TEST(Future, getFuture_after_setException) {
885 p.fulfil([]() -> void { throw std::logic_error("foo"); });
886 EXPECT_THROW(p.getFuture().value(), std::logic_error);
889 TEST(Future, detachRace) {
891 // This test is designed to detect a race that was in Core::detachOne()
892 // where detached_ was incremented and then tested, and that
893 // allowed a race where both Promise and Future would think they were the
894 // second and both try to delete. This showed up at scale but was very
895 // difficult to reliably repro in a test. As it is, this only fails about
896 // once in every 1,000 executions. Doing this 1,000 times is going to make a
897 // slow test so I won't do that but if it ever fails, take it seriously, and
898 // run the test binary with "--gtest_repeat=10000 --gtest_filter=*detachRace"
899 // (Don't forget to enable ASAN)
900 auto p = folly::make_unique<Promise<bool>>();
901 auto f = folly::make_unique<Future<bool>>(p->getFuture());
902 folly::Baton<> baton;