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.
18 #include <folly/small_vector.h>
19 #include <gtest/gtest.h>
22 #include <type_traits>
24 #include "folly/wangle/Executor.h"
25 #include "folly/wangle/Future.h"
27 using namespace folly::wangle;
30 using std::unique_ptr;
33 #define EXPECT_TYPE(x, T) \
34 EXPECT_TRUE((std::is_same<decltype(x), T>::value))
36 typedef WangleException eggs_t;
37 static eggs_t eggs("eggs");
54 Try<A> t_a(std::move(a));
58 EXPECT_EQ(5, t_a.value().x());
61 TEST(Future, special) {
62 EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
63 EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
64 EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
65 EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
71 makeFuture<int>(42).then([&](Try<int>&& t) {
73 EXPECT_EQ(42, t.value());
75 EXPECT_TRUE(flag); flag = false;
78 .then([](Try<int>&& t) { return t.value(); })
79 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
80 EXPECT_TRUE(flag); flag = false;
82 makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
83 EXPECT_TRUE(flag); flag = false;
86 auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
88 EXPECT_FALSE(f.isReady());
91 EXPECT_TRUE(f.isReady());
95 auto f = makeFuture(unique_ptr<int>(new int(42)));
96 auto up = std::move(f.value());
99 EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
102 TEST(Future, isReady) {
104 auto f = p.getFuture();
105 EXPECT_FALSE(f.isReady());
107 EXPECT_TRUE(f.isReady());
110 TEST(Future, hasException) {
111 EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
112 EXPECT_FALSE(makeFuture(42).getTry().hasException());
115 TEST(Future, hasValue) {
116 EXPECT_TRUE(makeFuture(42).getTry().hasValue());
117 EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
120 TEST(Future, makeFuture) {
121 EXPECT_TYPE(makeFuture(42), Future<int>);
122 EXPECT_EQ(42, makeFuture(42).value());
124 EXPECT_TYPE(makeFuture<float>(42), Future<float>);
125 EXPECT_EQ(42, makeFuture<float>(42).value());
127 auto fun = [] { return 42; };
128 EXPECT_TYPE(makeFutureTry(fun), Future<int>);
129 EXPECT_EQ(42, makeFutureTry(fun).value());
131 auto failfun = []() -> int { throw eggs; };
132 EXPECT_TYPE(makeFutureTry(failfun), Future<int>);
133 EXPECT_THROW(makeFutureTry(failfun).value(), eggs_t);
135 EXPECT_TYPE(makeFuture(), Future<void>);
140 TEST(Promise, special) {
141 EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
142 EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
143 EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
144 EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
147 TEST(Promise, getFuture) {
149 Future<int> f = p.getFuture();
150 EXPECT_FALSE(f.isReady());
153 TEST(Promise, setValue) {
155 auto ffund = fund.getFuture();
157 EXPECT_EQ(42, ffund.value());
165 auto fpod = pod.getFuture();
166 Foo f = {"the answer", 42};
168 Foo f2 = fpod.value();
169 EXPECT_EQ(f.name, f2.name);
170 EXPECT_EQ(f.value, f2.value);
172 pod = Promise<Foo>();
173 fpod = pod.getFuture();
175 pod.setValue(std::move(f2));
176 Foo f3 = fpod.value();
177 EXPECT_EQ(f.name, f3.name);
178 EXPECT_EQ(f.value, f3.value);
179 EXPECT_NE(f.name, f2.name);
183 Promise<unique_ptr<int>> mov;
184 auto fmov = mov.getFuture();
185 mov.setValue(unique_ptr<int>(new int(42)));
186 unique_ptr<int> ptr = std::move(fmov.value());
190 auto fv = v.getFuture();
192 EXPECT_TRUE(fv.isReady());
195 TEST(Promise, setException) {
198 auto f = p.getFuture();
199 p.setException(eggs);
200 EXPECT_THROW(f.value(), eggs_t);
204 auto f = p.getFuture();
208 p.setException(std::current_exception());
210 EXPECT_THROW(f.value(), eggs_t);
214 TEST(Promise, fulfil) {
217 auto f = p.getFuture();
218 p.fulfil([] { return 42; });
219 EXPECT_EQ(42, f.value());
223 auto f = p.getFuture();
224 p.fulfil([]() -> int { throw eggs; });
225 EXPECT_THROW(f.value(), eggs_t);
229 TEST(Future, finish) {
230 auto x = std::make_shared<int>(0);
232 auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
234 // The continuation hasn't executed
237 // The continuation has a reference to x
238 EXPECT_EQ(2, x.use_count());
242 // the continuation has executed
245 // the continuation has been destructed
246 // and has released its reference to x
247 EXPECT_EQ(1, x.use_count());
250 TEST(Future, unwrap) {
254 auto fa = a.getFuture();
255 auto fb = b.getFuture();
260 // do a, then do b, and get the result of a + b.
261 Future<int> f = fa.then([&](Try<int>&& ta) {
262 auto va = ta.value();
264 return fb.then([va, &flag2](Try<int>&& tb) {
266 return va + tb.value();
272 EXPECT_FALSE(f.isReady());
277 EXPECT_FALSE(f.isReady());
282 EXPECT_EQ(7, f.value());
285 TEST(Future, whenAll) {
286 // returns a vector variant
288 vector<Promise<int>> promises(10);
289 vector<Future<int>> futures;
291 for (auto& p : promises)
292 futures.push_back(p.getFuture());
294 auto allf = whenAll(futures.begin(), futures.end());
296 random_shuffle(promises.begin(), promises.end());
297 for (auto& p : promises) {
298 EXPECT_FALSE(allf.isReady());
302 EXPECT_TRUE(allf.isReady());
303 auto& results = allf.value();
304 for (auto& t : results) {
305 EXPECT_EQ(42, t.value());
309 // check error semantics
311 vector<Promise<int>> promises(4);
312 vector<Future<int>> futures;
314 for (auto& p : promises)
315 futures.push_back(p.getFuture());
317 auto allf = whenAll(futures.begin(), futures.end());
320 promises[0].setValue(42);
321 promises[1].setException(eggs);
323 EXPECT_FALSE(allf.isReady());
325 promises[2].setValue(42);
327 EXPECT_FALSE(allf.isReady());
329 promises[3].setException(eggs);
331 EXPECT_TRUE(allf.isReady());
332 EXPECT_FALSE(allf.getTry().hasException());
334 auto& results = allf.value();
335 EXPECT_EQ(42, results[0].value());
336 EXPECT_TRUE(results[1].hasException());
337 EXPECT_EQ(42, results[2].value());
338 EXPECT_TRUE(results[3].hasException());
341 // check that futures are ready in then()
343 vector<Promise<void>> promises(10);
344 vector<Future<void>> futures;
346 for (auto& p : promises)
347 futures.push_back(p.getFuture());
349 auto allf = whenAll(futures.begin(), futures.end())
350 .then([](Try<vector<Try<void>>>&& ts) {
351 for (auto& f : ts.value())
355 random_shuffle(promises.begin(), promises.end());
356 for (auto& p : promises)
358 EXPECT_TRUE(allf.isReady());
363 TEST(Future, whenAny) {
365 vector<Promise<int>> promises(10);
366 vector<Future<int>> futures;
368 for (auto& p : promises)
369 futures.push_back(p.getFuture());
371 for (auto& f : futures) {
372 EXPECT_FALSE(f.isReady());
375 auto anyf = whenAny(futures.begin(), futures.end());
377 /* futures were moved in, so these are invalid now */
378 EXPECT_FALSE(anyf.isReady());
380 promises[7].setValue(42);
381 EXPECT_TRUE(anyf.isReady());
382 auto& idx_fut = anyf.value();
384 auto i = idx_fut.first;
387 auto& f = idx_fut.second;
388 EXPECT_EQ(42, f.value());
393 vector<Promise<void>> promises(10);
394 vector<Future<void>> futures;
396 for (auto& p : promises)
397 futures.push_back(p.getFuture());
399 for (auto& f : futures) {
400 EXPECT_FALSE(f.isReady());
403 auto anyf = whenAny(futures.begin(), futures.end());
405 EXPECT_FALSE(anyf.isReady());
407 promises[3].setException(eggs);
408 EXPECT_TRUE(anyf.isReady());
409 EXPECT_TRUE(anyf.value().second.hasException());
414 vector<Promise<int>> promises(10);
415 vector<Future<int>> futures;
417 for (auto& p : promises)
418 futures.push_back(p.getFuture());
420 auto anyf = whenAny(futures.begin(), futures.end())
421 .then([](Try<pair<size_t, Try<int>>>&& f) {
422 EXPECT_EQ(42, f.value().second.value());
425 promises[3].setValue(42);
426 EXPECT_TRUE(anyf.isReady());
431 TEST(when, already_completed) {
433 vector<Future<void>> fs;
434 for (int i = 0; i < 10; i++)
435 fs.push_back(makeFuture());
437 whenAll(fs.begin(), fs.end())
438 .then([&](Try<vector<Try<void>>>&& t) {
439 EXPECT_EQ(fs.size(), t.value().size());
443 vector<Future<int>> fs;
444 for (int i = 0; i < 10; i++)
445 fs.push_back(makeFuture(i));
447 whenAny(fs.begin(), fs.end())
448 .then([&](Try<pair<size_t, Try<int>>>&& t) {
450 EXPECT_EQ(p.first, p.second.value());
456 vector<Promise<void>> promises(10);
457 vector<Future<void>> futures;
459 for (auto& p : promises)
460 futures.push_back(p.getFuture());
464 whenN(futures.begin(), futures.end(), n)
465 .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
468 EXPECT_EQ(n, v.size());
470 EXPECT_TRUE(tt.second.hasValue());
473 promises[0].setValue();
475 promises[1].setValue();
477 promises[2].setValue();
481 /* Ensure that we can compile when_{all,any} with folly::small_vector */
482 TEST(when, small_vector) {
483 using folly::small_vector;
485 small_vector<Future<void>> futures;
487 for (int i = 0; i < 10; i++)
488 futures.push_back(makeFuture());
490 auto anyf = whenAny(futures.begin(), futures.end());
494 small_vector<Future<void>> futures;
496 for (int i = 0; i < 10; i++)
497 futures.push_back(makeFuture());
499 auto allf = whenAll(futures.begin(), futures.end());
503 TEST(Future, whenAllVariadic) {
506 Future<bool> fb = pb.getFuture();
507 Future<int> fi = pi.getFuture();
509 whenAll(std::move(fb), std::move(fi))
510 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
512 EXPECT_TRUE(t.hasValue());
513 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
514 EXPECT_EQ(std::get<0>(t.value()).value(), true);
515 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
516 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
524 TEST(Future, whenAllVariadicReferences) {
527 Future<bool> fb = pb.getFuture();
528 Future<int> fi = pi.getFuture();
531 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
533 EXPECT_TRUE(t.hasValue());
534 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
535 EXPECT_EQ(std::get<0>(t.value()).value(), true);
536 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
537 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
545 TEST(Future, whenAll_none) {
546 vector<Future<int>> fs;
547 auto f = whenAll(fs.begin(), fs.end());
548 EXPECT_TRUE(f.isReady());
551 TEST(Future, throwCaughtInImmediateThen) {
552 // Neither of these should throw "Promise already satisfied"
554 [=](Try<void>&&) -> int { throw std::exception(); });
556 [=](Try<void>&&) -> Future<int> { throw std::exception(); });
559 TEST(Future, throwIfFailed) {
560 makeFuture<void>(eggs)
561 .then([=](Try<void>&& t) {
562 EXPECT_THROW(t.throwIfFailed(), eggs_t);
565 .then([=](Try<void>&& t) {
566 EXPECT_NO_THROW(t.throwIfFailed());
569 makeFuture<int>(eggs)
570 .then([=](Try<int>&& t) {
571 EXPECT_THROW(t.throwIfFailed(), eggs_t);
574 .then([=](Try<int>&& t) {
575 EXPECT_NO_THROW(t.throwIfFailed());