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"
29 using namespace folly::wangle;
32 using std::unique_ptr;
35 #define EXPECT_TYPE(x, T) \
36 EXPECT_TRUE((std::is_same<decltype(x), T>::value))
38 typedef WangleException eggs_t;
39 static eggs_t eggs("eggs");
56 Try<A> t_a(std::move(a));
60 EXPECT_EQ(5, t_a.value().x());
63 TEST(Future, special) {
64 EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
65 EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
66 EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
67 EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
73 makeFuture<int>(42).then([&](Try<int>&& t) {
75 EXPECT_EQ(42, t.value());
77 EXPECT_TRUE(flag); flag = false;
80 .then([](Try<int>&& t) { return t.value(); })
81 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
82 EXPECT_TRUE(flag); flag = false;
84 makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
85 EXPECT_TRUE(flag); flag = false;
88 auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
90 EXPECT_FALSE(f.isReady());
93 EXPECT_TRUE(f.isReady());
96 static string doWorkStatic(Try<string>&& t) {
97 return t.value() + ";static";
100 TEST(Future, thenFunction) {
102 string doWork(Try<string>&& t) {
103 return t.value() + ";class";
105 static string doWorkStatic(Try<string>&& t) {
106 return t.value() + ";class-static";
110 auto f = makeFuture<string>("start")
112 .then(Worker::doWorkStatic)
113 .then(&w, &Worker::doWork);
115 EXPECT_EQ(f.value(), "start;static;class-static;class");
118 static Future<string> doWorkStaticFuture(Try<string>&& t) {
119 return makeFuture(t.value() + ";static");
122 TEST(Future, thenFunctionFuture) {
124 Future<string> doWorkFuture(Try<string>&& t) {
125 return makeFuture(t.value() + ";class");
127 static Future<string> doWorkStaticFuture(Try<string>&& t) {
128 return makeFuture(t.value() + ";class-static");
132 auto f = makeFuture<string>("start")
133 .then(doWorkStaticFuture)
134 .then(Worker::doWorkStaticFuture)
135 .then(&w, &Worker::doWorkFuture);
137 EXPECT_EQ(f.value(), "start;static;class-static;class");
140 TEST(Future, value) {
141 auto f = makeFuture(unique_ptr<int>(new int(42)));
142 auto up = std::move(f.value());
145 EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
148 TEST(Future, isReady) {
150 auto f = p.getFuture();
151 EXPECT_FALSE(f.isReady());
153 EXPECT_TRUE(f.isReady());
156 TEST(Future, futureNotReady) {
158 Future<int> f = p.getFuture();
159 EXPECT_THROW(f.value(), eggs_t);
162 TEST(Future, hasException) {
163 EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
164 EXPECT_FALSE(makeFuture(42).getTry().hasException());
167 TEST(Future, hasValue) {
168 EXPECT_TRUE(makeFuture(42).getTry().hasValue());
169 EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
172 TEST(Future, makeFuture) {
173 EXPECT_TYPE(makeFuture(42), Future<int>);
174 EXPECT_EQ(42, makeFuture(42).value());
176 EXPECT_TYPE(makeFuture<float>(42), Future<float>);
177 EXPECT_EQ(42, makeFuture<float>(42).value());
179 auto fun = [] { return 42; };
180 EXPECT_TYPE(makeFutureTry(fun), Future<int>);
181 EXPECT_EQ(42, makeFutureTry(fun).value());
183 auto failfun = []() -> int { throw eggs; };
184 EXPECT_TYPE(makeFutureTry(failfun), Future<int>);
185 EXPECT_THROW(makeFutureTry(failfun).value(), eggs_t);
187 EXPECT_TYPE(makeFuture(), Future<void>);
192 TEST(Promise, special) {
193 EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
194 EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
195 EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
196 EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
199 TEST(Promise, getFuture) {
201 Future<int> f = p.getFuture();
202 EXPECT_FALSE(f.isReady());
205 TEST(Promise, setValue) {
207 auto ffund = fund.getFuture();
209 EXPECT_EQ(42, ffund.value());
217 auto fpod = pod.getFuture();
218 Foo f = {"the answer", 42};
220 Foo f2 = fpod.value();
221 EXPECT_EQ(f.name, f2.name);
222 EXPECT_EQ(f.value, f2.value);
224 pod = Promise<Foo>();
225 fpod = pod.getFuture();
226 pod.setValue(std::move(f2));
227 Foo f3 = fpod.value();
228 EXPECT_EQ(f.name, f3.name);
229 EXPECT_EQ(f.value, f3.value);
231 Promise<unique_ptr<int>> mov;
232 auto fmov = mov.getFuture();
233 mov.setValue(unique_ptr<int>(new int(42)));
234 unique_ptr<int> ptr = std::move(fmov.value());
238 auto fv = v.getFuture();
240 EXPECT_TRUE(fv.isReady());
243 TEST(Promise, setException) {
246 auto f = p.getFuture();
247 p.setException(eggs);
248 EXPECT_THROW(f.value(), eggs_t);
252 auto f = p.getFuture();
256 p.setException(std::current_exception());
258 EXPECT_THROW(f.value(), eggs_t);
262 TEST(Promise, fulfil) {
265 auto f = p.getFuture();
266 p.fulfil([] { return 42; });
267 EXPECT_EQ(42, f.value());
271 auto f = p.getFuture();
272 p.fulfil([]() -> int { throw eggs; });
273 EXPECT_THROW(f.value(), eggs_t);
277 TEST(Future, finish) {
278 auto x = std::make_shared<int>(0);
280 auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
282 // The continuation hasn't executed
285 // The continuation has a reference to x
286 EXPECT_EQ(2, x.use_count());
290 // the continuation has executed
293 // the continuation has been destructed
294 // and has released its reference to x
295 EXPECT_EQ(1, x.use_count());
298 TEST(Future, unwrap) {
302 auto fa = a.getFuture();
303 auto fb = b.getFuture();
308 // do a, then do b, and get the result of a + b.
309 Future<int> f = fa.then([&](Try<int>&& ta) {
310 auto va = ta.value();
312 return fb.then([va, &flag2](Try<int>&& tb) {
314 return va + tb.value();
320 EXPECT_FALSE(f.isReady());
325 EXPECT_FALSE(f.isReady());
330 EXPECT_EQ(7, f.value());
333 TEST(Future, whenAll) {
334 // returns a vector variant
336 vector<Promise<int>> promises(10);
337 vector<Future<int>> futures;
339 for (auto& p : promises)
340 futures.push_back(p.getFuture());
342 auto allf = whenAll(futures.begin(), futures.end());
344 random_shuffle(promises.begin(), promises.end());
345 for (auto& p : promises) {
346 EXPECT_FALSE(allf.isReady());
350 EXPECT_TRUE(allf.isReady());
351 auto& results = allf.value();
352 for (auto& t : results) {
353 EXPECT_EQ(42, t.value());
357 // check error semantics
359 vector<Promise<int>> promises(4);
360 vector<Future<int>> futures;
362 for (auto& p : promises)
363 futures.push_back(p.getFuture());
365 auto allf = whenAll(futures.begin(), futures.end());
368 promises[0].setValue(42);
369 promises[1].setException(eggs);
371 EXPECT_FALSE(allf.isReady());
373 promises[2].setValue(42);
375 EXPECT_FALSE(allf.isReady());
377 promises[3].setException(eggs);
379 EXPECT_TRUE(allf.isReady());
380 EXPECT_FALSE(allf.getTry().hasException());
382 auto& results = allf.value();
383 EXPECT_EQ(42, results[0].value());
384 EXPECT_TRUE(results[1].hasException());
385 EXPECT_EQ(42, results[2].value());
386 EXPECT_TRUE(results[3].hasException());
389 // check that futures are ready in then()
391 vector<Promise<void>> promises(10);
392 vector<Future<void>> futures;
394 for (auto& p : promises)
395 futures.push_back(p.getFuture());
397 auto allf = whenAll(futures.begin(), futures.end())
398 .then([](Try<vector<Try<void>>>&& ts) {
399 for (auto& f : ts.value())
403 random_shuffle(promises.begin(), promises.end());
404 for (auto& p : promises)
406 EXPECT_TRUE(allf.isReady());
411 TEST(Future, whenAny) {
413 vector<Promise<int>> promises(10);
414 vector<Future<int>> futures;
416 for (auto& p : promises)
417 futures.push_back(p.getFuture());
419 for (auto& f : futures) {
420 EXPECT_FALSE(f.isReady());
423 auto anyf = whenAny(futures.begin(), futures.end());
425 /* futures were moved in, so these are invalid now */
426 EXPECT_FALSE(anyf.isReady());
428 promises[7].setValue(42);
429 EXPECT_TRUE(anyf.isReady());
430 auto& idx_fut = anyf.value();
432 auto i = idx_fut.first;
435 auto& f = idx_fut.second;
436 EXPECT_EQ(42, f.value());
441 vector<Promise<void>> promises(10);
442 vector<Future<void>> futures;
444 for (auto& p : promises)
445 futures.push_back(p.getFuture());
447 for (auto& f : futures) {
448 EXPECT_FALSE(f.isReady());
451 auto anyf = whenAny(futures.begin(), futures.end());
453 EXPECT_FALSE(anyf.isReady());
455 promises[3].setException(eggs);
456 EXPECT_TRUE(anyf.isReady());
457 EXPECT_TRUE(anyf.value().second.hasException());
462 vector<Promise<int>> promises(10);
463 vector<Future<int>> futures;
465 for (auto& p : promises)
466 futures.push_back(p.getFuture());
468 auto anyf = whenAny(futures.begin(), futures.end())
469 .then([](Try<pair<size_t, Try<int>>>&& f) {
470 EXPECT_EQ(42, f.value().second.value());
473 promises[3].setValue(42);
474 EXPECT_TRUE(anyf.isReady());
479 TEST(when, already_completed) {
481 vector<Future<void>> fs;
482 for (int i = 0; i < 10; i++)
483 fs.push_back(makeFuture());
485 whenAll(fs.begin(), fs.end())
486 .then([&](Try<vector<Try<void>>>&& t) {
487 EXPECT_EQ(fs.size(), t.value().size());
491 vector<Future<int>> fs;
492 for (int i = 0; i < 10; i++)
493 fs.push_back(makeFuture(i));
495 whenAny(fs.begin(), fs.end())
496 .then([&](Try<pair<size_t, Try<int>>>&& t) {
498 EXPECT_EQ(p.first, p.second.value());
504 vector<Promise<void>> promises(10);
505 vector<Future<void>> futures;
507 for (auto& p : promises)
508 futures.push_back(p.getFuture());
512 whenN(futures.begin(), futures.end(), n)
513 .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
516 EXPECT_EQ(n, v.size());
518 EXPECT_TRUE(tt.second.hasValue());
521 promises[0].setValue();
523 promises[1].setValue();
525 promises[2].setValue();
529 /* Ensure that we can compile when_{all,any} with folly::small_vector */
530 TEST(when, small_vector) {
532 static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<void>),
533 "Futures should not be trivially copyable");
534 static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<int>),
535 "Futures should not be trivially copyable");
537 using folly::small_vector;
539 small_vector<Future<void>> futures;
541 for (int i = 0; i < 10; i++)
542 futures.push_back(makeFuture());
544 auto anyf = whenAny(futures.begin(), futures.end());
548 small_vector<Future<void>> futures;
550 for (int i = 0; i < 10; i++)
551 futures.push_back(makeFuture());
553 auto allf = whenAll(futures.begin(), futures.end());
557 TEST(Future, whenAllVariadic) {
560 Future<bool> fb = pb.getFuture();
561 Future<int> fi = pi.getFuture();
563 whenAll(std::move(fb), std::move(fi))
564 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
566 EXPECT_TRUE(t.hasValue());
567 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
568 EXPECT_EQ(std::get<0>(t.value()).value(), true);
569 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
570 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
578 TEST(Future, whenAllVariadicReferences) {
581 Future<bool> fb = pb.getFuture();
582 Future<int> fi = pi.getFuture();
585 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
587 EXPECT_TRUE(t.hasValue());
588 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
589 EXPECT_EQ(std::get<0>(t.value()).value(), true);
590 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
591 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
599 TEST(Future, whenAll_none) {
600 vector<Future<int>> fs;
601 auto f = whenAll(fs.begin(), fs.end());
602 EXPECT_TRUE(f.isReady());
605 TEST(Future, throwCaughtInImmediateThen) {
606 // Neither of these should throw "Promise already satisfied"
608 [=](Try<void>&&) -> int { throw std::exception(); });
610 [=](Try<void>&&) -> Future<int> { throw std::exception(); });
613 TEST(Future, throwIfFailed) {
614 makeFuture<void>(eggs)
615 .then([=](Try<void>&& t) {
616 EXPECT_THROW(t.throwIfFailed(), eggs_t);
619 .then([=](Try<void>&& t) {
620 EXPECT_NO_THROW(t.throwIfFailed());
623 makeFuture<int>(eggs)
624 .then([=](Try<int>&& t) {
625 EXPECT_THROW(t.throwIfFailed(), eggs_t);
628 .then([=](Try<int>&& t) {
629 EXPECT_NO_THROW(t.throwIfFailed());
633 TEST(Future, waitWithSemaphoreImmediate) {
634 waitWithSemaphore(makeFuture());
635 auto done = waitWithSemaphore(makeFuture(42)).value();
638 vector<int> v{1,2,3};
639 auto done_v = waitWithSemaphore(makeFuture(v)).value();
640 EXPECT_EQ(v.size(), done_v.size());
641 EXPECT_EQ(v, done_v);
643 vector<Future<void>> v_f;
644 v_f.push_back(makeFuture());
645 v_f.push_back(makeFuture());
646 auto done_v_f = waitWithSemaphore(whenAll(v_f.begin(), v_f.end())).value();
647 EXPECT_EQ(2, done_v_f.size());
649 vector<Future<bool>> v_fb;
650 v_fb.push_back(makeFuture(true));
651 v_fb.push_back(makeFuture(false));
652 auto fut = whenAll(v_fb.begin(), v_fb.end());
653 auto done_v_fb = std::move(waitWithSemaphore(std::move(fut)).value());
654 EXPECT_EQ(2, done_v_fb.size());
657 TEST(Future, waitWithSemaphore) {
659 Future<int> f = p.getFuture();
660 std::atomic<bool> flag{false};
661 std::atomic<int> result{1};
662 std::atomic<std::thread::id> id;
664 std::thread t([&](Future<int>&& tf){
665 auto n = tf.then([&](Try<int> && t) {
666 id = std::this_thread::get_id();
670 result.store(waitWithSemaphore(std::move(n)).value());
676 EXPECT_EQ(result.load(), 1);
679 // validate that the continuation ended up executing in this thread, which
680 // is more to ensure that this test actually tests what it should
681 EXPECT_EQ(id, std::this_thread::get_id());
682 EXPECT_EQ(result.load(), 42);
685 TEST(Future, waitWithSemaphoreForTime) {
688 Future<int> f = p.getFuture();
689 auto t = waitWithSemaphore(std::move(f),
690 std::chrono::microseconds(1));
691 EXPECT_FALSE(t.isReady());
693 EXPECT_TRUE(t.isReady());
697 Future<int> f = p.getFuture();
699 auto t = waitWithSemaphore(std::move(f),
700 std::chrono::milliseconds(1));
701 EXPECT_TRUE(t.isReady());
704 vector<Future<bool>> v_fb;
705 v_fb.push_back(makeFuture(true));
706 v_fb.push_back(makeFuture(false));
707 auto f = whenAll(v_fb.begin(), v_fb.end());
708 auto t = waitWithSemaphore(std::move(f),
709 std::chrono::milliseconds(1));
710 EXPECT_TRUE(t.isReady());
711 EXPECT_EQ(2, t.value().size());
714 vector<Future<bool>> v_fb;
717 v_fb.push_back(p1.getFuture());
718 v_fb.push_back(p2.getFuture());
719 auto f = whenAll(v_fb.begin(), v_fb.end());
720 auto t = waitWithSemaphore(std::move(f),
721 std::chrono::milliseconds(1));
722 EXPECT_FALSE(t.isReady());
724 EXPECT_FALSE(t.isReady());
726 EXPECT_TRUE(t.isReady());
730 Future<int> f = p.getFuture();
731 auto begin = std::chrono::system_clock::now();
732 auto t = waitWithSemaphore(std::move(f),
733 std::chrono::milliseconds(1));
734 auto end = std::chrono::system_clock::now();
735 EXPECT_TRUE( end - begin < std::chrono::milliseconds(2));
736 EXPECT_FALSE(t.isReady());
739 auto t = waitWithSemaphore(makeFuture(),
740 std::chrono::milliseconds(1));
741 EXPECT_TRUE(t.isReady());