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/Executor.h>
28 #include <folly/wangle/futures/Future.h>
29 #include <folly/wangle/futures/ManualExecutor.h>
30 #include <folly/MPMCQueue.h>
32 #include <folly/io/async/Request.h>
34 using namespace folly;
35 using namespace folly::wangle;
38 using std::unique_ptr;
41 #define EXPECT_TYPE(x, T) \
42 EXPECT_TRUE((std::is_same<decltype(x), T>::value))
44 /// Simple executor that does work in another thread
45 class ThreadExecutor : public Executor {
46 folly::MPMCQueue<Func> funcs;
47 std::atomic<bool> done {false};
55 while (!funcs.isEmpty()) {
56 funcs.blockingRead(fn);
63 explicit ThreadExecutor(size_t n = 1024)
64 : funcs(n), worker(std::bind(&ThreadExecutor::work, this)) {}
72 void add(Func fn) override {
73 funcs.blockingWrite(std::move(fn));
76 void waitForStartup() {
81 typedef WangleException eggs_t;
82 static eggs_t eggs("eggs");
86 TEST(Future, onError) {
88 auto flag = [&]{ theFlag = true; };
89 #define EXPECT_FLAG() \
91 EXPECT_TRUE(theFlag); \
95 #define EXPECT_NO_FLAG() \
97 EXPECT_FALSE(theFlag); \
103 auto f = makeFuture()
104 .then([] { throw eggs; })
105 .onError([&] (eggs_t& e) { flag(); });
107 EXPECT_NO_THROW(f.value());
111 auto f = makeFuture()
112 .then([] { throw eggs; })
113 .onError([&] (eggs_t& e) { flag(); return makeFuture(); });
115 EXPECT_NO_THROW(f.value());
120 auto f = makeFuture()
121 .then([] { throw eggs; })
122 .onError([&] (eggs_t e) { flag(); });
124 EXPECT_NO_THROW(f.value());
128 auto f = makeFuture()
129 .then([] { throw eggs; })
130 .onError([&] (eggs_t e) { flag(); return makeFuture(); });
132 EXPECT_NO_THROW(f.value());
137 auto f = makeFuture()
138 .then([] { throw eggs; })
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) { flag(); return makeFuture(); });
149 EXPECT_NO_THROW(f.value());
154 auto f = makeFuture()
155 .then([] { throw -1; })
156 .onError([&] (int e) { flag(); });
158 EXPECT_NO_THROW(f.value());
162 auto f = makeFuture()
163 .then([] { throw -1; })
164 .onError([&] (int e) { flag(); return makeFuture(); });
166 EXPECT_NO_THROW(f.value());
171 auto f = makeFuture()
172 .then([] { throw eggs; })
173 .onError([&] (eggs_t& e) mutable { flag(); });
175 EXPECT_NO_THROW(f.value());
179 auto f = makeFuture()
180 .then([] { throw eggs; })
181 .onError([&] (eggs_t& e) mutable { flag(); return makeFuture(); });
183 EXPECT_NO_THROW(f.value());
188 auto f = makeFuture()
189 .then([] { return 42; })
190 .onError([&] (eggs_t& e) { flag(); return -1; });
192 EXPECT_EQ(42, f.value());
196 auto f = makeFuture()
197 .then([] { return 42; })
198 .onError([&] (eggs_t& e) { flag(); return makeFuture<int>(-1); });
200 EXPECT_EQ(42, f.value());
203 // Catch different exception
205 auto f = makeFuture()
206 .then([] { throw eggs; })
207 .onError([&] (std::runtime_error& e) { flag(); });
209 EXPECT_THROW(f.value(), eggs_t);
213 auto f = makeFuture()
214 .then([] { throw eggs; })
215 .onError([&] (std::runtime_error& e) { flag(); return makeFuture(); });
217 EXPECT_THROW(f.value(), eggs_t);
220 // Returned value propagates
222 auto f = makeFuture()
223 .then([] { throw eggs; return 0; })
224 .onError([&] (eggs_t& e) { return 42; });
225 EXPECT_EQ(42, f.value());
228 // Returned future propagates
230 auto f = makeFuture()
231 .then([] { throw eggs; return 0; })
232 .onError([&] (eggs_t& e) { return makeFuture<int>(42); });
233 EXPECT_EQ(42, f.value());
238 auto f = makeFuture()
239 .then([] { throw eggs; return 0; })
240 .onError([&] (eggs_t& e) { throw e; return -1; });
241 EXPECT_THROW(f.value(), eggs_t);
245 auto f = makeFuture()
246 .then([] { throw eggs; return 0; })
247 .onError([&] (eggs_t& e) { throw e; return makeFuture<int>(-1); });
248 EXPECT_THROW(f.value(), eggs_t);
265 Try<A> t_a(std::move(a));
269 EXPECT_EQ(5, t_a.value().x());
272 TEST(Future, special) {
273 EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
274 EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
275 EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
276 EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
279 TEST(Future, thenTry) {
282 makeFuture<int>(42).then([&](Try<int>&& t) {
284 EXPECT_EQ(42, t.value());
286 EXPECT_TRUE(flag); flag = false;
289 .then([](Try<int>&& t) { return t.value(); })
290 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
291 EXPECT_TRUE(flag); flag = false;
293 makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
294 EXPECT_TRUE(flag); flag = false;
297 auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
299 EXPECT_FALSE(f.isReady());
302 EXPECT_TRUE(f.isReady());
305 TEST(Future, thenValue) {
307 makeFuture<int>(42).then([&](int i){
311 EXPECT_TRUE(flag); flag = false;
314 .then([](int i){ return i; })
315 .then([&](int i) { flag = true; EXPECT_EQ(42, i); });
316 EXPECT_TRUE(flag); flag = false;
318 makeFuture().then([&]{
321 EXPECT_TRUE(flag); flag = false;
323 auto f = makeFuture<int>(eggs).then([&](int i){});
324 EXPECT_THROW(f.value(), eggs_t);
326 f = makeFuture<void>(eggs).then([&]{});
327 EXPECT_THROW(f.value(), eggs_t);
330 TEST(Future, thenValueFuture) {
333 .then([](int i){ return makeFuture<int>(std::move(i)); })
334 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
335 EXPECT_TRUE(flag); flag = false;
338 .then([]{ return makeFuture(); })
339 .then([&](Try<void>&& t) { flag = true; });
340 EXPECT_TRUE(flag); flag = false;
343 static string doWorkStatic(Try<string>&& t) {
344 return t.value() + ";static";
347 TEST(Future, thenFunction) {
349 string doWork(Try<string>&& t) {
350 return t.value() + ";class";
352 static string doWorkStatic(Try<string>&& t) {
353 return t.value() + ";class-static";
357 auto f = makeFuture<string>("start")
359 .then(Worker::doWorkStatic)
360 .then(&w, &Worker::doWork);
362 EXPECT_EQ(f.value(), "start;static;class-static;class");
365 static Future<string> doWorkStaticFuture(Try<string>&& t) {
366 return makeFuture(t.value() + ";static");
369 TEST(Future, thenFunctionFuture) {
371 Future<string> doWorkFuture(Try<string>&& t) {
372 return makeFuture(t.value() + ";class");
374 static Future<string> doWorkStaticFuture(Try<string>&& t) {
375 return makeFuture(t.value() + ";class-static");
379 auto f = makeFuture<string>("start")
380 .then(doWorkStaticFuture)
381 .then(Worker::doWorkStaticFuture)
382 .then(&w, &Worker::doWorkFuture);
384 EXPECT_EQ(f.value(), "start;static;class-static;class");
387 TEST(Future, value) {
388 auto f = makeFuture(unique_ptr<int>(new int(42)));
389 auto up = std::move(f.value());
392 EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
395 TEST(Future, isReady) {
397 auto f = p.getFuture();
398 EXPECT_FALSE(f.isReady());
400 EXPECT_TRUE(f.isReady());
403 TEST(Future, futureNotReady) {
405 Future<int> f = p.getFuture();
406 EXPECT_THROW(f.value(), eggs_t);
409 TEST(Future, hasException) {
410 EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
411 EXPECT_FALSE(makeFuture(42).getTry().hasException());
414 TEST(Future, hasValue) {
415 EXPECT_TRUE(makeFuture(42).getTry().hasValue());
416 EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
419 TEST(Future, makeFuture) {
420 EXPECT_TYPE(makeFuture(42), Future<int>);
421 EXPECT_EQ(42, makeFuture(42).value());
423 EXPECT_TYPE(makeFuture<float>(42), Future<float>);
424 EXPECT_EQ(42, makeFuture<float>(42).value());
426 auto fun = [] { return 42; };
427 EXPECT_TYPE(makeFutureTry(fun), Future<int>);
428 EXPECT_EQ(42, makeFutureTry(fun).value());
430 auto failfun = []() -> int { throw eggs; };
431 EXPECT_TYPE(makeFutureTry(failfun), Future<int>);
432 EXPECT_THROW(makeFutureTry(failfun).value(), eggs_t);
434 EXPECT_TYPE(makeFuture(), Future<void>);
439 TEST(Promise, special) {
440 EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
441 EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
442 EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
443 EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
446 TEST(Promise, getFuture) {
448 Future<int> f = p.getFuture();
449 EXPECT_FALSE(f.isReady());
452 TEST(Promise, setValue) {
454 auto ffund = fund.getFuture();
456 EXPECT_EQ(42, ffund.value());
464 auto fpod = pod.getFuture();
465 Foo f = {"the answer", 42};
467 Foo f2 = fpod.value();
468 EXPECT_EQ(f.name, f2.name);
469 EXPECT_EQ(f.value, f2.value);
471 pod = Promise<Foo>();
472 fpod = pod.getFuture();
473 pod.setValue(std::move(f2));
474 Foo f3 = fpod.value();
475 EXPECT_EQ(f.name, f3.name);
476 EXPECT_EQ(f.value, f3.value);
478 Promise<unique_ptr<int>> mov;
479 auto fmov = mov.getFuture();
480 mov.setValue(unique_ptr<int>(new int(42)));
481 unique_ptr<int> ptr = std::move(fmov.value());
485 auto fv = v.getFuture();
487 EXPECT_TRUE(fv.isReady());
490 TEST(Promise, setException) {
493 auto f = p.getFuture();
494 p.setException(eggs);
495 EXPECT_THROW(f.value(), eggs_t);
499 auto f = p.getFuture();
503 p.setException(std::current_exception());
505 EXPECT_THROW(f.value(), eggs_t);
509 TEST(Promise, fulfil) {
512 auto f = p.getFuture();
513 p.fulfil([] { return 42; });
514 EXPECT_EQ(42, f.value());
518 auto f = p.getFuture();
519 p.fulfil([]() -> int { throw eggs; });
520 EXPECT_THROW(f.value(), eggs_t);
524 TEST(Future, finish) {
525 auto x = std::make_shared<int>(0);
528 auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
530 // The callback hasn't executed
533 // The callback has a reference to x
534 EXPECT_EQ(2, x.use_count());
538 // the callback has executed
541 // the callback has been destructed
542 // and has released its reference to x
543 EXPECT_EQ(1, x.use_count());
546 TEST(Future, unwrap) {
550 auto fa = a.getFuture();
551 auto fb = b.getFuture();
556 // do a, then do b, and get the result of a + b.
557 Future<int> f = fa.then([&](Try<int>&& ta) {
558 auto va = ta.value();
560 return fb.then([va, &flag2](Try<int>&& tb) {
562 return va + tb.value();
568 EXPECT_FALSE(f.isReady());
573 EXPECT_FALSE(f.isReady());
578 EXPECT_EQ(7, f.value());
581 TEST(Future, whenAll) {
582 // returns a vector variant
584 vector<Promise<int>> promises(10);
585 vector<Future<int>> futures;
587 for (auto& p : promises)
588 futures.push_back(p.getFuture());
590 auto allf = whenAll(futures.begin(), futures.end());
592 random_shuffle(promises.begin(), promises.end());
593 for (auto& p : promises) {
594 EXPECT_FALSE(allf.isReady());
598 EXPECT_TRUE(allf.isReady());
599 auto& results = allf.value();
600 for (auto& t : results) {
601 EXPECT_EQ(42, t.value());
605 // check error semantics
607 vector<Promise<int>> promises(4);
608 vector<Future<int>> futures;
610 for (auto& p : promises)
611 futures.push_back(p.getFuture());
613 auto allf = whenAll(futures.begin(), futures.end());
616 promises[0].setValue(42);
617 promises[1].setException(eggs);
619 EXPECT_FALSE(allf.isReady());
621 promises[2].setValue(42);
623 EXPECT_FALSE(allf.isReady());
625 promises[3].setException(eggs);
627 EXPECT_TRUE(allf.isReady());
628 EXPECT_FALSE(allf.getTry().hasException());
630 auto& results = allf.value();
631 EXPECT_EQ(42, results[0].value());
632 EXPECT_TRUE(results[1].hasException());
633 EXPECT_EQ(42, results[2].value());
634 EXPECT_TRUE(results[3].hasException());
637 // check that futures are ready in then()
639 vector<Promise<void>> promises(10);
640 vector<Future<void>> futures;
642 for (auto& p : promises)
643 futures.push_back(p.getFuture());
645 auto allf = whenAll(futures.begin(), futures.end())
646 .then([](Try<vector<Try<void>>>&& ts) {
647 for (auto& f : ts.value())
651 random_shuffle(promises.begin(), promises.end());
652 for (auto& p : promises)
654 EXPECT_TRUE(allf.isReady());
659 TEST(Future, whenAny) {
661 vector<Promise<int>> promises(10);
662 vector<Future<int>> futures;
664 for (auto& p : promises)
665 futures.push_back(p.getFuture());
667 for (auto& f : futures) {
668 EXPECT_FALSE(f.isReady());
671 auto anyf = whenAny(futures.begin(), futures.end());
673 /* futures were moved in, so these are invalid now */
674 EXPECT_FALSE(anyf.isReady());
676 promises[7].setValue(42);
677 EXPECT_TRUE(anyf.isReady());
678 auto& idx_fut = anyf.value();
680 auto i = idx_fut.first;
683 auto& f = idx_fut.second;
684 EXPECT_EQ(42, f.value());
689 vector<Promise<void>> promises(10);
690 vector<Future<void>> futures;
692 for (auto& p : promises)
693 futures.push_back(p.getFuture());
695 for (auto& f : futures) {
696 EXPECT_FALSE(f.isReady());
699 auto anyf = whenAny(futures.begin(), futures.end());
701 EXPECT_FALSE(anyf.isReady());
703 promises[3].setException(eggs);
704 EXPECT_TRUE(anyf.isReady());
705 EXPECT_TRUE(anyf.value().second.hasException());
710 vector<Promise<int>> promises(10);
711 vector<Future<int>> futures;
713 for (auto& p : promises)
714 futures.push_back(p.getFuture());
716 auto anyf = whenAny(futures.begin(), futures.end())
717 .then([](Try<pair<size_t, Try<int>>>&& f) {
718 EXPECT_EQ(42, f.value().second.value());
721 promises[3].setValue(42);
722 EXPECT_TRUE(anyf.isReady());
727 TEST(when, already_completed) {
729 vector<Future<void>> fs;
730 for (int i = 0; i < 10; i++)
731 fs.push_back(makeFuture());
733 whenAll(fs.begin(), fs.end())
734 .then([&](Try<vector<Try<void>>>&& t) {
735 EXPECT_EQ(fs.size(), t.value().size());
739 vector<Future<int>> fs;
740 for (int i = 0; i < 10; i++)
741 fs.push_back(makeFuture(i));
743 whenAny(fs.begin(), fs.end())
744 .then([&](Try<pair<size_t, Try<int>>>&& t) {
746 EXPECT_EQ(p.first, p.second.value());
752 vector<Promise<void>> promises(10);
753 vector<Future<void>> futures;
755 for (auto& p : promises)
756 futures.push_back(p.getFuture());
760 whenN(futures.begin(), futures.end(), n)
761 .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
764 EXPECT_EQ(n, v.size());
766 EXPECT_TRUE(tt.second.hasValue());
769 promises[0].setValue();
771 promises[1].setValue();
773 promises[2].setValue();
777 /* Ensure that we can compile when_{all,any} with folly::small_vector */
778 TEST(when, small_vector) {
780 static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<void>),
781 "Futures should not be trivially copyable");
782 static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<int>),
783 "Futures should not be trivially copyable");
785 using folly::small_vector;
787 small_vector<Future<void>> futures;
789 for (int i = 0; i < 10; i++)
790 futures.push_back(makeFuture());
792 auto anyf = whenAny(futures.begin(), futures.end());
796 small_vector<Future<void>> futures;
798 for (int i = 0; i < 10; i++)
799 futures.push_back(makeFuture());
801 auto allf = whenAll(futures.begin(), futures.end());
805 TEST(Future, whenAllVariadic) {
808 Future<bool> fb = pb.getFuture();
809 Future<int> fi = pi.getFuture();
811 whenAll(std::move(fb), std::move(fi))
812 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
814 EXPECT_TRUE(t.hasValue());
815 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
816 EXPECT_EQ(std::get<0>(t.value()).value(), true);
817 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
818 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
826 TEST(Future, whenAllVariadicReferences) {
829 Future<bool> fb = pb.getFuture();
830 Future<int> fi = pi.getFuture();
833 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
835 EXPECT_TRUE(t.hasValue());
836 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
837 EXPECT_EQ(std::get<0>(t.value()).value(), true);
838 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
839 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
847 TEST(Future, whenAll_none) {
848 vector<Future<int>> fs;
849 auto f = whenAll(fs.begin(), fs.end());
850 EXPECT_TRUE(f.isReady());
853 TEST(Future, throwCaughtInImmediateThen) {
854 // Neither of these should throw "Promise already satisfied"
856 [=](Try<void>&&) -> int { throw std::exception(); });
858 [=](Try<void>&&) -> Future<int> { throw std::exception(); });
861 TEST(Future, throwIfFailed) {
862 makeFuture<void>(eggs)
863 .then([=](Try<void>&& t) {
864 EXPECT_THROW(t.throwIfFailed(), eggs_t);
867 .then([=](Try<void>&& t) {
868 EXPECT_NO_THROW(t.throwIfFailed());
871 makeFuture<int>(eggs)
872 .then([=](Try<int>&& t) {
873 EXPECT_THROW(t.throwIfFailed(), eggs_t);
876 .then([=](Try<int>&& t) {
877 EXPECT_NO_THROW(t.throwIfFailed());
881 TEST(Future, waitWithSemaphoreImmediate) {
882 waitWithSemaphore(makeFuture());
883 auto done = waitWithSemaphore(makeFuture(42)).value();
886 vector<int> v{1,2,3};
887 auto done_v = waitWithSemaphore(makeFuture(v)).value();
888 EXPECT_EQ(v.size(), done_v.size());
889 EXPECT_EQ(v, done_v);
891 vector<Future<void>> v_f;
892 v_f.push_back(makeFuture());
893 v_f.push_back(makeFuture());
894 auto done_v_f = waitWithSemaphore(whenAll(v_f.begin(), v_f.end())).value();
895 EXPECT_EQ(2, done_v_f.size());
897 vector<Future<bool>> v_fb;
898 v_fb.push_back(makeFuture(true));
899 v_fb.push_back(makeFuture(false));
900 auto fut = whenAll(v_fb.begin(), v_fb.end());
901 auto done_v_fb = std::move(waitWithSemaphore(std::move(fut)).value());
902 EXPECT_EQ(2, done_v_fb.size());
905 TEST(Future, waitWithSemaphore) {
907 Future<int> f = p.getFuture();
908 std::atomic<bool> flag{false};
909 std::atomic<int> result{1};
910 std::atomic<std::thread::id> id;
912 std::thread t([&](Future<int>&& tf){
913 auto n = tf.then([&](Try<int> && t) {
914 id = std::this_thread::get_id();
918 result.store(waitWithSemaphore(std::move(n)).value());
923 EXPECT_EQ(result.load(), 1);
926 // validate that the callback ended up executing in this thread, which
927 // is more to ensure that this test actually tests what it should
928 EXPECT_EQ(id, std::this_thread::get_id());
929 EXPECT_EQ(result.load(), 42);
932 TEST(Future, waitWithSemaphoreForTime) {
935 Future<int> f = p.getFuture();
936 auto t = waitWithSemaphore(std::move(f),
937 std::chrono::microseconds(1));
938 EXPECT_FALSE(t.isReady());
940 EXPECT_TRUE(t.isReady());
944 Future<int> f = p.getFuture();
946 auto t = waitWithSemaphore(std::move(f),
947 std::chrono::milliseconds(1));
948 EXPECT_TRUE(t.isReady());
951 vector<Future<bool>> v_fb;
952 v_fb.push_back(makeFuture(true));
953 v_fb.push_back(makeFuture(false));
954 auto f = whenAll(v_fb.begin(), v_fb.end());
955 auto t = waitWithSemaphore(std::move(f),
956 std::chrono::milliseconds(1));
957 EXPECT_TRUE(t.isReady());
958 EXPECT_EQ(2, t.value().size());
961 vector<Future<bool>> v_fb;
964 v_fb.push_back(p1.getFuture());
965 v_fb.push_back(p2.getFuture());
966 auto f = whenAll(v_fb.begin(), v_fb.end());
967 auto t = waitWithSemaphore(std::move(f),
968 std::chrono::milliseconds(1));
969 EXPECT_FALSE(t.isReady());
971 EXPECT_FALSE(t.isReady());
973 EXPECT_TRUE(t.isReady());
976 auto t = waitWithSemaphore(makeFuture(),
977 std::chrono::milliseconds(1));
978 EXPECT_TRUE(t.isReady());
982 TEST(Future, callbackAfterActivate) {
984 auto f = p.getFuture();
988 f.then([&](Try<void>&&) { count++; });
997 TEST(Future, activateOnDestruct) {
998 auto f = std::make_shared<Future<void>>(makeFuture());
1002 f->then([&](Try<void>&&) { count++; });
1003 EXPECT_EQ(0, count);
1006 EXPECT_EQ(1, count);
1009 TEST(Future, viaActsCold) {
1014 fv.then([&](Try<void>&&) { count++; });
1016 EXPECT_EQ(0, count);
1020 EXPECT_EQ(1, x.run());
1021 EXPECT_EQ(1, count);
1024 TEST(Future, viaIsCold) {
1026 EXPECT_FALSE(via(&x).isActive());
1029 TEST(Future, viaRaces) {
1032 auto tid = std::this_thread::get_id();
1035 std::thread t1([&] {
1038 .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
1039 .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
1040 .then([&](Try<void>&&) { done = true; });
1043 std::thread t2([&] {
1047 while (!done) x.run();
1053 TEST(Future, viaRaces_2stage) {
1056 auto tid = std::this_thread::get_id();
1059 std::thread t1([&] {
1060 auto f2 = p.getFuture().via(&x);
1061 f2.then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
1062 .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
1063 .then([&](Try<void>&&) { done = true; });
1065 // the bug was in the promise being fulfilled before f2 is reactivated. we
1066 // could sleep, but yielding should cause this to fail with reasonable
1068 std::this_thread::yield();
1072 std::thread t2([&] {
1076 while (!done) x.run();
1081 TEST(Future, getFuture_after_setValue) {
1084 EXPECT_EQ(42, p.getFuture().value());
1087 TEST(Future, getFuture_after_setException) {
1089 p.fulfil([]() -> void { throw std::logic_error("foo"); });
1090 EXPECT_THROW(p.getFuture().value(), std::logic_error);
1093 TEST(Future, detachRace) {
1095 // This test is designed to detect a race that was in Core::detachOne()
1096 // where detached_ was incremented and then tested, and that
1097 // allowed a race where both Promise and Future would think they were the
1098 // second and both try to delete. This showed up at scale but was very
1099 // difficult to reliably repro in a test. As it is, this only fails about
1100 // once in every 1,000 executions. Doing this 1,000 times is going to make a
1101 // slow test so I won't do that but if it ever fails, take it seriously, and
1102 // run the test binary with "--gtest_repeat=10000 --gtest_filter=*detachRace"
1103 // (Don't forget to enable ASAN)
1104 auto p = folly::make_unique<Promise<bool>>();
1105 auto f = folly::make_unique<Future<bool>>(p->getFuture());
1106 folly::Baton<> baton;
1116 class TestData : public RequestData {
1118 explicit TestData(int data) : data_(data) {}
1119 virtual ~TestData() {}
1123 TEST(Future, context) {
1125 // Start a new context
1126 RequestContext::create();
1128 EXPECT_EQ(nullptr, RequestContext::get()->getContextData("test"));
1130 // Set some test data
1131 RequestContext::get()->setContextData(
1133 std::unique_ptr<TestData>(new TestData(10)));
1137 auto future = p.getFuture().then([&]{
1138 // Check that the context followed the future
1139 EXPECT_TRUE(RequestContext::get() != nullptr);
1140 auto a = dynamic_cast<TestData*>(
1141 RequestContext::get()->getContextData("test"));
1142 auto data = a->data_;
1143 EXPECT_EQ(10, data);
1146 // Clear the context
1147 RequestContext::setContext(nullptr);
1149 EXPECT_EQ(nullptr, RequestContext::get()->getContextData("test"));
1151 // Fulfil the promise
1156 // This only fails about 1 in 1k times when the bug is present :(
1157 TEST(Future, t5506504) {
1161 auto promises = std::make_shared<vector<Promise<void>>>(4);
1162 vector<Future<void>> futures;
1164 for (auto& p : *promises) {
1165 futures.emplace_back(
1168 .then([](Try<void>&&){}));
1173 for (auto& p : *promises) p.setValue();
1176 return whenAll(futures.begin(), futures.end());
1179 waitWithSemaphore(fn());