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/wangle/Executor.h>
27 #include <folly/wangle/Future.h>
28 #include <folly/wangle/ManualExecutor.h>
30 using namespace folly::wangle;
33 using std::unique_ptr;
36 #define EXPECT_TYPE(x, T) \
37 EXPECT_TRUE((std::is_same<decltype(x), T>::value))
39 typedef WangleException eggs_t;
40 static eggs_t eggs("eggs");
57 Try<A> t_a(std::move(a));
61 EXPECT_EQ(5, t_a.value().x());
64 TEST(Future, special) {
65 EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
66 EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
67 EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
68 EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
74 makeFuture<int>(42).then([&](Try<int>&& t) {
76 EXPECT_EQ(42, t.value());
78 EXPECT_TRUE(flag); flag = false;
81 .then([](Try<int>&& t) { return t.value(); })
82 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
83 EXPECT_TRUE(flag); flag = false;
85 makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
86 EXPECT_TRUE(flag); flag = false;
89 auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
91 EXPECT_FALSE(f.isReady());
94 EXPECT_TRUE(f.isReady());
97 static string doWorkStatic(Try<string>&& t) {
98 return t.value() + ";static";
101 TEST(Future, thenFunction) {
103 string doWork(Try<string>&& t) {
104 return t.value() + ";class";
106 static string doWorkStatic(Try<string>&& t) {
107 return t.value() + ";class-static";
111 auto f = makeFuture<string>("start")
113 .then(Worker::doWorkStatic)
114 .then(&w, &Worker::doWork);
116 EXPECT_EQ(f.value(), "start;static;class-static;class");
119 static Future<string> doWorkStaticFuture(Try<string>&& t) {
120 return makeFuture(t.value() + ";static");
123 TEST(Future, thenFunctionFuture) {
125 Future<string> doWorkFuture(Try<string>&& t) {
126 return makeFuture(t.value() + ";class");
128 static Future<string> doWorkStaticFuture(Try<string>&& t) {
129 return makeFuture(t.value() + ";class-static");
133 auto f = makeFuture<string>("start")
134 .then(doWorkStaticFuture)
135 .then(Worker::doWorkStaticFuture)
136 .then(&w, &Worker::doWorkFuture);
138 EXPECT_EQ(f.value(), "start;static;class-static;class");
141 TEST(Future, value) {
142 auto f = makeFuture(unique_ptr<int>(new int(42)));
143 auto up = std::move(f.value());
146 EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
149 TEST(Future, isReady) {
151 auto f = p.getFuture();
152 EXPECT_FALSE(f.isReady());
154 EXPECT_TRUE(f.isReady());
157 TEST(Future, futureNotReady) {
159 Future<int> f = p.getFuture();
160 EXPECT_THROW(f.value(), eggs_t);
163 TEST(Future, hasException) {
164 EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
165 EXPECT_FALSE(makeFuture(42).getTry().hasException());
168 TEST(Future, hasValue) {
169 EXPECT_TRUE(makeFuture(42).getTry().hasValue());
170 EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
173 TEST(Future, makeFuture) {
174 EXPECT_TYPE(makeFuture(42), Future<int>);
175 EXPECT_EQ(42, makeFuture(42).value());
177 EXPECT_TYPE(makeFuture<float>(42), Future<float>);
178 EXPECT_EQ(42, makeFuture<float>(42).value());
180 auto fun = [] { return 42; };
181 EXPECT_TYPE(makeFutureTry(fun), Future<int>);
182 EXPECT_EQ(42, makeFutureTry(fun).value());
184 auto failfun = []() -> int { throw eggs; };
185 EXPECT_TYPE(makeFutureTry(failfun), Future<int>);
186 EXPECT_THROW(makeFutureTry(failfun).value(), eggs_t);
188 EXPECT_TYPE(makeFuture(), Future<void>);
193 TEST(Promise, special) {
194 EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
195 EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
196 EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
197 EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
200 TEST(Promise, getFuture) {
202 Future<int> f = p.getFuture();
203 EXPECT_FALSE(f.isReady());
206 TEST(Promise, setValue) {
208 auto ffund = fund.getFuture();
210 EXPECT_EQ(42, ffund.value());
218 auto fpod = pod.getFuture();
219 Foo f = {"the answer", 42};
221 Foo f2 = fpod.value();
222 EXPECT_EQ(f.name, f2.name);
223 EXPECT_EQ(f.value, f2.value);
225 pod = Promise<Foo>();
226 fpod = pod.getFuture();
227 pod.setValue(std::move(f2));
228 Foo f3 = fpod.value();
229 EXPECT_EQ(f.name, f3.name);
230 EXPECT_EQ(f.value, f3.value);
232 Promise<unique_ptr<int>> mov;
233 auto fmov = mov.getFuture();
234 mov.setValue(unique_ptr<int>(new int(42)));
235 unique_ptr<int> ptr = std::move(fmov.value());
239 auto fv = v.getFuture();
241 EXPECT_TRUE(fv.isReady());
244 TEST(Promise, setException) {
247 auto f = p.getFuture();
248 p.setException(eggs);
249 EXPECT_THROW(f.value(), eggs_t);
253 auto f = p.getFuture();
257 p.setException(std::current_exception());
259 EXPECT_THROW(f.value(), eggs_t);
263 TEST(Promise, fulfil) {
266 auto f = p.getFuture();
267 p.fulfil([] { return 42; });
268 EXPECT_EQ(42, f.value());
272 auto f = p.getFuture();
273 p.fulfil([]() -> int { throw eggs; });
274 EXPECT_THROW(f.value(), eggs_t);
278 TEST(Future, finish) {
279 auto x = std::make_shared<int>(0);
282 auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
284 // The callback hasn't executed
287 // The callback has a reference to x
288 EXPECT_EQ(2, x.use_count());
292 // the callback has executed
295 // the callback has been destructed
296 // and has released its reference to x
297 EXPECT_EQ(1, x.use_count());
300 TEST(Future, unwrap) {
304 auto fa = a.getFuture();
305 auto fb = b.getFuture();
310 // do a, then do b, and get the result of a + b.
311 Future<int> f = fa.then([&](Try<int>&& ta) {
312 auto va = ta.value();
314 return fb.then([va, &flag2](Try<int>&& tb) {
316 return va + tb.value();
322 EXPECT_FALSE(f.isReady());
327 EXPECT_FALSE(f.isReady());
332 EXPECT_EQ(7, f.value());
335 TEST(Future, whenAll) {
336 // returns a vector variant
338 vector<Promise<int>> promises(10);
339 vector<Future<int>> futures;
341 for (auto& p : promises)
342 futures.push_back(p.getFuture());
344 auto allf = whenAll(futures.begin(), futures.end());
346 random_shuffle(promises.begin(), promises.end());
347 for (auto& p : promises) {
348 EXPECT_FALSE(allf.isReady());
352 EXPECT_TRUE(allf.isReady());
353 auto& results = allf.value();
354 for (auto& t : results) {
355 EXPECT_EQ(42, t.value());
359 // check error semantics
361 vector<Promise<int>> promises(4);
362 vector<Future<int>> futures;
364 for (auto& p : promises)
365 futures.push_back(p.getFuture());
367 auto allf = whenAll(futures.begin(), futures.end());
370 promises[0].setValue(42);
371 promises[1].setException(eggs);
373 EXPECT_FALSE(allf.isReady());
375 promises[2].setValue(42);
377 EXPECT_FALSE(allf.isReady());
379 promises[3].setException(eggs);
381 EXPECT_TRUE(allf.isReady());
382 EXPECT_FALSE(allf.getTry().hasException());
384 auto& results = allf.value();
385 EXPECT_EQ(42, results[0].value());
386 EXPECT_TRUE(results[1].hasException());
387 EXPECT_EQ(42, results[2].value());
388 EXPECT_TRUE(results[3].hasException());
391 // check that futures are ready in then()
393 vector<Promise<void>> promises(10);
394 vector<Future<void>> futures;
396 for (auto& p : promises)
397 futures.push_back(p.getFuture());
399 auto allf = whenAll(futures.begin(), futures.end())
400 .then([](Try<vector<Try<void>>>&& ts) {
401 for (auto& f : ts.value())
405 random_shuffle(promises.begin(), promises.end());
406 for (auto& p : promises)
408 EXPECT_TRUE(allf.isReady());
413 TEST(Future, whenAny) {
415 vector<Promise<int>> promises(10);
416 vector<Future<int>> futures;
418 for (auto& p : promises)
419 futures.push_back(p.getFuture());
421 for (auto& f : futures) {
422 EXPECT_FALSE(f.isReady());
425 auto anyf = whenAny(futures.begin(), futures.end());
427 /* futures were moved in, so these are invalid now */
428 EXPECT_FALSE(anyf.isReady());
430 promises[7].setValue(42);
431 EXPECT_TRUE(anyf.isReady());
432 auto& idx_fut = anyf.value();
434 auto i = idx_fut.first;
437 auto& f = idx_fut.second;
438 EXPECT_EQ(42, f.value());
443 vector<Promise<void>> promises(10);
444 vector<Future<void>> futures;
446 for (auto& p : promises)
447 futures.push_back(p.getFuture());
449 for (auto& f : futures) {
450 EXPECT_FALSE(f.isReady());
453 auto anyf = whenAny(futures.begin(), futures.end());
455 EXPECT_FALSE(anyf.isReady());
457 promises[3].setException(eggs);
458 EXPECT_TRUE(anyf.isReady());
459 EXPECT_TRUE(anyf.value().second.hasException());
464 vector<Promise<int>> promises(10);
465 vector<Future<int>> futures;
467 for (auto& p : promises)
468 futures.push_back(p.getFuture());
470 auto anyf = whenAny(futures.begin(), futures.end())
471 .then([](Try<pair<size_t, Try<int>>>&& f) {
472 EXPECT_EQ(42, f.value().second.value());
475 promises[3].setValue(42);
476 EXPECT_TRUE(anyf.isReady());
481 TEST(when, already_completed) {
483 vector<Future<void>> fs;
484 for (int i = 0; i < 10; i++)
485 fs.push_back(makeFuture());
487 whenAll(fs.begin(), fs.end())
488 .then([&](Try<vector<Try<void>>>&& t) {
489 EXPECT_EQ(fs.size(), t.value().size());
493 vector<Future<int>> fs;
494 for (int i = 0; i < 10; i++)
495 fs.push_back(makeFuture(i));
497 whenAny(fs.begin(), fs.end())
498 .then([&](Try<pair<size_t, Try<int>>>&& t) {
500 EXPECT_EQ(p.first, p.second.value());
506 vector<Promise<void>> promises(10);
507 vector<Future<void>> futures;
509 for (auto& p : promises)
510 futures.push_back(p.getFuture());
514 whenN(futures.begin(), futures.end(), n)
515 .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
518 EXPECT_EQ(n, v.size());
520 EXPECT_TRUE(tt.second.hasValue());
523 promises[0].setValue();
525 promises[1].setValue();
527 promises[2].setValue();
531 /* Ensure that we can compile when_{all,any} with folly::small_vector */
532 TEST(when, small_vector) {
534 static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<void>),
535 "Futures should not be trivially copyable");
536 static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<int>),
537 "Futures should not be trivially copyable");
539 using folly::small_vector;
541 small_vector<Future<void>> futures;
543 for (int i = 0; i < 10; i++)
544 futures.push_back(makeFuture());
546 auto anyf = whenAny(futures.begin(), futures.end());
550 small_vector<Future<void>> futures;
552 for (int i = 0; i < 10; i++)
553 futures.push_back(makeFuture());
555 auto allf = whenAll(futures.begin(), futures.end());
559 TEST(Future, whenAllVariadic) {
562 Future<bool> fb = pb.getFuture();
563 Future<int> fi = pi.getFuture();
565 whenAll(std::move(fb), std::move(fi))
566 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
568 EXPECT_TRUE(t.hasValue());
569 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
570 EXPECT_EQ(std::get<0>(t.value()).value(), true);
571 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
572 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
580 TEST(Future, whenAllVariadicReferences) {
583 Future<bool> fb = pb.getFuture();
584 Future<int> fi = pi.getFuture();
587 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
589 EXPECT_TRUE(t.hasValue());
590 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
591 EXPECT_EQ(std::get<0>(t.value()).value(), true);
592 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
593 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
601 TEST(Future, whenAll_none) {
602 vector<Future<int>> fs;
603 auto f = whenAll(fs.begin(), fs.end());
604 EXPECT_TRUE(f.isReady());
607 TEST(Future, throwCaughtInImmediateThen) {
608 // Neither of these should throw "Promise already satisfied"
610 [=](Try<void>&&) -> int { throw std::exception(); });
612 [=](Try<void>&&) -> Future<int> { throw std::exception(); });
615 TEST(Future, throwIfFailed) {
616 makeFuture<void>(eggs)
617 .then([=](Try<void>&& t) {
618 EXPECT_THROW(t.throwIfFailed(), eggs_t);
621 .then([=](Try<void>&& t) {
622 EXPECT_NO_THROW(t.throwIfFailed());
625 makeFuture<int>(eggs)
626 .then([=](Try<int>&& t) {
627 EXPECT_THROW(t.throwIfFailed(), eggs_t);
630 .then([=](Try<int>&& t) {
631 EXPECT_NO_THROW(t.throwIfFailed());
635 TEST(Future, waitWithSemaphoreImmediate) {
636 waitWithSemaphore(makeFuture());
637 auto done = waitWithSemaphore(makeFuture(42)).value();
640 vector<int> v{1,2,3};
641 auto done_v = waitWithSemaphore(makeFuture(v)).value();
642 EXPECT_EQ(v.size(), done_v.size());
643 EXPECT_EQ(v, done_v);
645 vector<Future<void>> v_f;
646 v_f.push_back(makeFuture());
647 v_f.push_back(makeFuture());
648 auto done_v_f = waitWithSemaphore(whenAll(v_f.begin(), v_f.end())).value();
649 EXPECT_EQ(2, done_v_f.size());
651 vector<Future<bool>> v_fb;
652 v_fb.push_back(makeFuture(true));
653 v_fb.push_back(makeFuture(false));
654 auto fut = whenAll(v_fb.begin(), v_fb.end());
655 auto done_v_fb = std::move(waitWithSemaphore(std::move(fut)).value());
656 EXPECT_EQ(2, done_v_fb.size());
659 TEST(Future, waitWithSemaphore) {
661 Future<int> f = p.getFuture();
662 std::atomic<bool> flag{false};
663 std::atomic<int> result{1};
664 std::atomic<std::thread::id> id;
666 std::thread t([&](Future<int>&& tf){
667 auto n = tf.then([&](Try<int> && t) {
668 id = std::this_thread::get_id();
672 result.store(waitWithSemaphore(std::move(n)).value());
678 EXPECT_EQ(result.load(), 1);
681 // validate that the callback ended up executing in this thread, which
682 // is more to ensure that this test actually tests what it should
683 EXPECT_EQ(id, std::this_thread::get_id());
684 EXPECT_EQ(result.load(), 42);
687 TEST(Future, waitWithSemaphoreForTime) {
690 Future<int> f = p.getFuture();
691 auto t = waitWithSemaphore(std::move(f),
692 std::chrono::microseconds(1));
693 EXPECT_FALSE(t.isReady());
695 EXPECT_TRUE(t.isReady());
699 Future<int> f = p.getFuture();
701 auto t = waitWithSemaphore(std::move(f),
702 std::chrono::milliseconds(1));
703 EXPECT_TRUE(t.isReady());
706 vector<Future<bool>> v_fb;
707 v_fb.push_back(makeFuture(true));
708 v_fb.push_back(makeFuture(false));
709 auto f = whenAll(v_fb.begin(), v_fb.end());
710 auto t = waitWithSemaphore(std::move(f),
711 std::chrono::milliseconds(1));
712 EXPECT_TRUE(t.isReady());
713 EXPECT_EQ(2, t.value().size());
716 vector<Future<bool>> v_fb;
719 v_fb.push_back(p1.getFuture());
720 v_fb.push_back(p2.getFuture());
721 auto f = whenAll(v_fb.begin(), v_fb.end());
722 auto t = waitWithSemaphore(std::move(f),
723 std::chrono::milliseconds(1));
724 EXPECT_FALSE(t.isReady());
726 EXPECT_FALSE(t.isReady());
728 EXPECT_TRUE(t.isReady());
732 Future<int> f = p.getFuture();
733 auto begin = std::chrono::system_clock::now();
734 auto t = waitWithSemaphore(std::move(f),
735 std::chrono::milliseconds(1));
736 auto end = std::chrono::system_clock::now();
737 EXPECT_TRUE( end - begin < std::chrono::milliseconds(5));
738 EXPECT_FALSE(t.isReady());
741 auto t = waitWithSemaphore(makeFuture(),
742 std::chrono::milliseconds(1));
743 EXPECT_TRUE(t.isReady());
747 TEST(Future, callbackAfterActivate) {
749 auto f = p.getFuture();
753 f.then([&](Try<void>&&) { count++; });
762 TEST(Future, activateOnDestruct) {
764 auto f = p.getFuture();
768 f.then([&](Try<void>&&) { count++; });
773 f = makeFuture(); // force destruction of old f
777 TEST(Future, viaIsCold) {
781 auto fv = makeFuture().via(&x);
782 fv.then([&](Try<void>&&) { count++; });
788 EXPECT_EQ(1, x.run());
792 TEST(Future, getFuture_after_setValue) {
795 EXPECT_EQ(42, p.getFuture().value());
798 TEST(Future, getFuture_after_setException) {
800 p.fulfil([]() -> void { throw std::logic_error("foo"); });
801 EXPECT_THROW(p.getFuture().value(), std::logic_error);