proxygen
WhileDoTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015-present Facebook, Inc.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 #include <memory>
18 #include <mutex>
19 #include <queue>
20 
21 #include <folly/futures/Future.h>
22 #include <folly/futures/Promise.h>
24 
25 using namespace folly;
26 
28  std::queue<std::shared_ptr<Promise<Unit>>>& ps,
29  std::mutex& ps_mutex) {
30  ps_mutex.lock();
31  auto p = ps.front();
32  ps.pop();
33  ps_mutex.unlock();
34  p->setValue();
35 }
36 
37 inline std::function<Future<Unit>(void)> makeThunk(
38  std::queue<std::shared_ptr<Promise<Unit>>>& ps,
39  int& interrupt,
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; });
45  ps_mutex.lock();
46  ps.push(p);
47  ps_mutex.unlock();
48 
49  return p->getFuture();
50  };
51 }
52 
53 inline std::function<bool(void)> makePred(int& i) {
54  return [&]() {
55  bool res = i < 3;
56  ++i;
57  return res;
58  };
59 }
60 
61 TEST(WhileDo, success) {
62  std::queue<std::shared_ptr<Promise<Unit>>> ps;
63  std::mutex ps_mutex;
64  int i = 0;
65  int interrupt = 0;
66  bool complete = false;
67  bool failure = false;
68 
69  auto pred = makePred(i);
70  auto thunk = makeThunk(ps, interrupt, ps_mutex);
71  auto f = folly::whileDo(pred, thunk)
72  .thenValue([&](auto&&) mutable { complete = true; })
73  .onError([&](FutureException& /* e */) { failure = true; });
74 
75  popAndFulfillPromise(ps, ps_mutex);
76  EXPECT_FALSE(complete);
77  EXPECT_FALSE(failure);
78 
79  popAndFulfillPromise(ps, ps_mutex);
80  EXPECT_FALSE(complete);
81  EXPECT_FALSE(failure);
82 
83  popAndFulfillPromise(ps, ps_mutex);
84  EXPECT_TRUE(f.isReady());
85  EXPECT_TRUE(complete);
86  EXPECT_FALSE(failure);
87 }
88 
89 TEST(WhileDo, failure) {
90  std::queue<std::shared_ptr<Promise<Unit>>> ps;
91  std::mutex ps_mutex;
92  int i = 0;
93  int interrupt = 0;
94  bool complete = false;
95  bool failure = false;
96 
97  auto pred = makePred(i);
98  auto thunk = makeThunk(ps, interrupt, ps_mutex);
99  auto f = folly::whileDo(pred, thunk)
100  .thenValue([&](auto&&) mutable { complete = true; })
101  .onError([&](FutureException& /* e */) { failure = true; });
102 
103  popAndFulfillPromise(ps, ps_mutex);
104  EXPECT_FALSE(complete);
105  EXPECT_FALSE(failure);
106 
107  ps_mutex.lock();
108  auto p2 = ps.front();
109  ps.pop();
110  ps_mutex.unlock();
111  FutureException eggs("eggs");
112  p2->setException(eggs);
113 
114  EXPECT_TRUE(f.isReady());
115  EXPECT_FALSE(complete);
116  EXPECT_TRUE(failure);
117 }
118 
119 TEST(WhileDo, interrupt) {
120  std::queue<std::shared_ptr<Promise<Unit>>> ps;
121  std::mutex ps_mutex;
122  int interrupt = 0;
123  bool complete = false;
124  bool failure = false;
125 
126  int i = 0;
127  auto pred = makePred(i);
128  auto thunk = makeThunk(ps, interrupt, ps_mutex);
129  auto f = folly::whileDo(pred, thunk)
130  .thenValue([&](auto&&) mutable { complete = true; })
131  .onError([&](FutureException& /* e */) { failure = true; });
132 
133  EXPECT_EQ(0, interrupt);
134 
135  FutureException eggs("eggs");
136  f.raise(eggs);
137 
138  for (int j = 1; j <= 3; ++j) {
139  EXPECT_EQ(1, interrupt);
140  popAndFulfillPromise(ps, ps_mutex);
141  }
142 }
auto f
Future< Unit > whileDo(P &&predicate, F &&thunk)
Definition: Future-inl.h:2335
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::function< Future< Unit >void)> makeThunk(std::queue< std::shared_ptr< Promise< Unit >>> &ps, int &interrupt, std::mutex &ps_mutex)
Definition: WhileDoTest.cpp:37
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
static eggs_t eggs("eggs")
std::mutex mutex
void popAndFulfillPromise(std::queue< std::shared_ptr< Promise< Unit >>> &ps, std::mutex &ps_mutex)
Definition: WhileDoTest.cpp:27
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST(SequencedExecutor, CPUThreadPoolExecutor)
std::function< bool(void)> makePred(int &i)
Definition: WhileDoTest.cpp:53