2 * Copyright 2017 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.
21 #include <folly/futures/Future.h>
22 #include <folly/futures/Promise.h>
23 #include <folly/portability/GTest.h>
25 using namespace folly;
27 inline void popAndFulfillPromise(
28 std::queue<std::shared_ptr<Promise<Unit>>>& ps,
29 std::mutex& ps_mutex) {
37 inline std::function<Future<Unit>(void)> makeThunk(
38 std::queue<std::shared_ptr<Promise<Unit>>>& ps,
40 std::mutex& ps_mutex) {
41 return [&]() mutable {
42 auto p = std::make_shared<Promise<Unit>>();
43 p->setInterruptHandler(
44 [&](exception_wrapper const& /* e */) { ++interrupt; });
49 return p->getFuture();
53 inline std::function<bool(void)> makePred(int& i) {
61 TEST(Times, success) {
62 std::queue<std::shared_ptr<Promise<Unit>>> ps;
65 bool complete = false;
68 auto thunk = makeThunk(ps, interrupt, ps_mutex);
69 auto f = folly::times(3, thunk).then([&]() mutable {
71 }).onError([&](FutureException& /* e */) { failure = true; });
73 popAndFulfillPromise(ps, ps_mutex);
74 EXPECT_FALSE(complete);
75 EXPECT_FALSE(failure);
77 popAndFulfillPromise(ps, ps_mutex);
78 EXPECT_FALSE(complete);
79 EXPECT_FALSE(failure);
81 popAndFulfillPromise(ps, ps_mutex);
82 EXPECT_TRUE(f.isReady());
83 EXPECT_TRUE(complete);
84 EXPECT_FALSE(failure);
87 TEST(Times, failure) {
88 std::queue<std::shared_ptr<Promise<Unit>>> ps;
91 bool complete = false;
94 auto thunk = makeThunk(ps, interrupt, ps_mutex);
95 auto f = folly::times(3, thunk).then([&]() mutable {
97 }).onError([&](FutureException& /* e */) { failure = true; });
99 popAndFulfillPromise(ps, ps_mutex);
100 EXPECT_FALSE(complete);
101 EXPECT_FALSE(failure);
104 auto p2 = ps.front();
107 FutureException eggs("eggs");
108 p2->setException(eggs);
110 EXPECT_TRUE(f.isReady());
111 EXPECT_FALSE(complete);
112 EXPECT_TRUE(failure);
115 TEST(Times, interrupt) {
116 std::queue<std::shared_ptr<Promise<Unit>>> ps;
119 bool complete = false;
120 bool failure = false;
122 auto thunk = makeThunk(ps, interrupt, ps_mutex);
123 auto f = folly::times(3, thunk).then([&]() mutable {
125 }).onError([&](FutureException& /* e */) { failure = true; });
127 EXPECT_EQ(0, interrupt);
129 FutureException eggs("eggs");
132 for (int i = 1; i <= 3; ++i) {
133 EXPECT_EQ(1, interrupt);
134 popAndFulfillPromise(ps, ps_mutex);