2 * Copyright 2016 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 <glog/logging.h>
23 #include <folly/futures/Future.h>
24 #include <folly/futures/Promise.h>
25 #include <folly/portability/GTest.h>
27 using namespace folly;
29 inline void popAndFulfillPromise(
30 std::queue<std::shared_ptr<Promise<Unit>>>& ps,
31 std::mutex& ps_mutex) {
39 inline std::function<Future<Unit>(void)> makeThunk(
40 std::queue<std::shared_ptr<Promise<Unit>>>& ps,
42 std::mutex& ps_mutex) {
43 return [&]() mutable {
44 auto p = std::make_shared<Promise<Unit>>();
45 p->setInterruptHandler(
46 [&](exception_wrapper const& /* e */) { ++interrupt; });
51 return p->getFuture();
55 inline std::function<bool(void)> makePred(int& i) {
63 TEST(WhileDo, success) {
64 std::queue<std::shared_ptr<Promise<Unit>>> ps;
68 bool complete = false;
71 auto pred = makePred(i);
72 auto thunk = makeThunk(ps, interrupt, ps_mutex);
73 auto f = folly::whileDo(pred, thunk)
74 .then([&]() mutable { complete = true; })
75 .onError([&](FutureException& /* e */) { failure = true; });
77 popAndFulfillPromise(ps, ps_mutex);
78 EXPECT_FALSE(complete);
79 EXPECT_FALSE(failure);
81 popAndFulfillPromise(ps, ps_mutex);
82 EXPECT_FALSE(complete);
83 EXPECT_FALSE(failure);
85 popAndFulfillPromise(ps, ps_mutex);
86 EXPECT_TRUE(f.isReady());
87 EXPECT_TRUE(complete);
88 EXPECT_FALSE(failure);
91 TEST(WhileDo, failure) {
92 std::queue<std::shared_ptr<Promise<Unit>>> ps;
96 bool complete = false;
99 auto pred = makePred(i);
100 auto thunk = makeThunk(ps, interrupt, ps_mutex);
101 auto f = folly::whileDo(pred, thunk)
102 .then([&]() mutable { complete = true; })
103 .onError([&](FutureException& /* e */) { failure = true; });
105 popAndFulfillPromise(ps, ps_mutex);
106 EXPECT_FALSE(complete);
107 EXPECT_FALSE(failure);
110 auto p2 = ps.front();
113 FutureException eggs("eggs");
114 p2->setException(eggs);
116 EXPECT_TRUE(f.isReady());
117 EXPECT_FALSE(complete);
118 EXPECT_TRUE(failure);
121 TEST(WhileDo, interrupt) {
122 std::queue<std::shared_ptr<Promise<Unit>>> ps;
125 bool complete = false;
126 bool failure = false;
129 auto pred = makePred(i);
130 auto thunk = makeThunk(ps, interrupt, ps_mutex);
131 auto f = folly::whileDo(pred, thunk)
132 .then([&]() mutable { complete = true; })
133 .onError([&](FutureException& /* e */) { failure = true; });
135 EXPECT_EQ(0, interrupt);
137 FutureException eggs("eggs");
140 for (int j = 1; j <= 3; ++j) {
141 EXPECT_EQ(1, interrupt);
142 popAndFulfillPromise(ps, ps_mutex);