proxygen
FutureTest.cpp File Reference
#include <folly/futures/Future.h>
#include <folly/Executor.h>
#include <folly/Memory.h>
#include <folly/Unit.h>
#include <folly/dynamic.h>
#include <folly/executors/ManualExecutor.h>
#include <folly/portability/GTest.h>
#include <folly/synchronization/Baton.h>
#include <algorithm>
#include <atomic>
#include <memory>
#include <numeric>
#include <queue>
#include <string>
#include <thread>
#include <type_traits>

Go to the source code of this file.

Macros

#define EXPECT_TYPE(x, T)   EXPECT_TRUE((std::is_same<decltype(x), T>::value))
 
#define DOIT(CREATION_EXPR)
 
#define DOIT(CREATION_EXPR)
 
#define DOIT(STMT)
 
#define DOIT(STMT)
 
#define DOIT(STMT)
 
#define DOIT(CTOR, STMT)
 
#define EXPECT_FLAG()
 
#define EXPECT_NO_FLAG()
 
#define EXPECT_FLAG()
 
#define EXPECT_NO_FLAG()
 

Typedefs

typedef FutureException eggs_t
 

Functions

 TEST (Future, makeEmpty)
 
 TEST (Future, futureDefaultCtor)
 
 TEST (Future, futureToUnit)
 
 TEST (Future, voidFutureToUnit)
 
 TEST (Future, unitFutureToUnitIdentity)
 
 TEST (Future, toUnitWhileInProgress)
 
 TEST (Future, makeFutureWithUnit)
 
 TEST (Future, getRequiresOnlyMoveCtor)
 
 TEST (Future, ctorPostconditionValid)
 
 TEST (Future, ctorPostconditionInvalid)
 
 TEST (Future, lacksPreconditionValid)
 
 TEST (Future, hasPreconditionValid)
 
 TEST (Future, hasPostconditionValid)
 
 TEST (Future, hasPostconditionInvalid)
 
 TEST (Future, onError)
 
 TEST (Future, thenError)
 
 TEST (Future, special)
 
 TEST (Future, then)
 
static folly::Future< std::stringdoWorkStaticTry (Try< std::string > &&t)
 
 TEST (Future, thenTrythenValue)
 
 TEST (Future, thenTry)
 
 TEST (Future, thenValue)
 
 TEST (Future, thenValueFuture)
 
static std::string doWorkStatic (Try< std::string > &&t)
 
static std::string doWorkStaticValue (std::string &&t)
 
 TEST (Future, thenFunction)
 
static Future< std::stringdoWorkStaticFuture (Try< std::string > &&t)
 
 TEST (Future, thenFunctionFuture)
 
 TEST (Future, thenStdFunction)
 
 TEST (Future, thenBind)
 
 TEST (Future, thenBindTry)
 
 TEST (Future, value)
 
 TEST (Future, isReady)
 
 TEST (Future, futureNotReady)
 
 TEST (Future, hasException)
 
 TEST (Future, hasValue)
 
 TEST (Future, makeFuture)
 
 TEST (Future, finish)
 
 TEST (Future, finishBigLambda)
 
 TEST (Future, unwrap)
 
 TEST (Future, throwCaughtInImmediateThen)
 
 TEST (Future, throwIfFailed)
 
 TEST (Future, getFutureAfterSetValue)
 
 TEST (Future, getFutureAfterSetException)
 
 TEST (Future, detachRace)
 
 TEST (Future, CircularDependencySharedPtrSelfReset)
 
 TEST (Future, Constructor)
 
 TEST (Future, ImplicitConstructor)
 
 TEST (Future, InPlaceConstructor)
 
 TEST (Future, thenDynamic)
 
 TEST (Future, RequestContext)
 
 TEST (Future, makeFutureNoThrow)
 
 TEST (Future, invokeCallbackReturningValueAsRvalue)
 
 TEST (Future, invokeCallbackReturningFutureAsRvalue)
 
 TEST (Future, futureWithinCtxCleanedUpWhenTaskFinishedInTime)
 
 TEST (Future, futureWithinNoValueReferenceWhenTimeOut)
 
 TEST (Future, makePromiseContract)
 
Future< bool > call (int depth, Executor *executor)
 
Future< int > recursion (Executor *executor, int depth)
 
 TEST (Future, ThenRecursion)
 

Variables

static eggs_t eggs ("eggs")
 

Macro Definition Documentation

#define DOIT (   CREATION_EXPR)
Value:
do { \
auto f1 = (CREATION_EXPR); \
EXPECT_TRUE(f1.valid()); \
auto f2 = std::move(f1); \
EXPECT_FALSE(f1.valid()); \
EXPECT_TRUE(f2.valid()); \
} while (false)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862

Referenced by TEST().

#define DOIT (   CREATION_EXPR)
Value:
do { \
auto f1 = (CREATION_EXPR); \
EXPECT_FALSE(f1.valid()); \
auto f2 = std::move(f1); \
EXPECT_FALSE(f1.valid()); \
EXPECT_FALSE(f2.valid()); \
} while (false)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
#define DOIT (   STMT)
Value:
do { \
auto f = makeValid(); \
{ STMT; } \
} while (false)
auto f
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72
#define DOIT (   STMT)
Value:
do { \
auto f = makeValid(); \
} while (false)
auto f
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72
#define DOIT (   STMT)
Value:
do { \
auto f = makeValid(); \
EXPECT_TRUE(f.valid()); \
} while (false)
auto f
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define DOIT (   CTOR,
  STMT 
)
Value:
do { \
auto f = (CTOR); \
EXPECT_FALSE(f.valid()); \
} while (false)
auto f
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
#define EXPECT_FLAG ( )
Value:
do { \
EXPECT_TRUE(theFlag); \
theFlag = false; \
} while (0);
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859

Referenced by TEST().

#define EXPECT_FLAG ( )
Value:
do { \
EXPECT_TRUE(theFlag); \
theFlag = false; \
} while (0);
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_NO_FLAG ( )
Value:
do { \
EXPECT_FALSE(theFlag); \
theFlag = false; \
} while (0);
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862

Referenced by TEST().

#define EXPECT_NO_FLAG ( )
Value:
do { \
EXPECT_FALSE(theFlag); \
theFlag = false; \
} while (0);
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
#define EXPECT_TYPE (   x,
  T 
)    EXPECT_TRUE((std::is_same<decltype(x), T>::value))

Definition at line 37 of file FutureTest.cpp.

Referenced by TEST().

Typedef Documentation

Definition at line 39 of file FutureTest.cpp.

Function Documentation

static std::string doWorkStatic ( Try< std::string > &&  t)
static

Definition at line 1066 of file FutureTest.cpp.

References folly::pushmi::detail::t.

Referenced by TEST().

1066  {
1067  return t.value() + ";static";
1068 }
T & value()&
Definition: Try-inl.h:140
static Future<std::string> doWorkStaticFuture ( Try< std::string > &&  t)
static

Definition at line 1094 of file FutureTest.cpp.

References folly::makeFuture(), and folly::pushmi::detail::t.

Referenced by TEST().

1094  {
1095  return makeFuture(t.value() + ";static");
1096 }
T & value()&
Definition: Try-inl.h:140
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
static folly::Future<std::string> doWorkStaticTry ( Try< std::string > &&  t)
static

Definition at line 956 of file FutureTest.cpp.

References folly::makeFuture(), and folly::pushmi::detail::t.

Referenced by TEST().

956  {
957  return makeFuture(t.value() + ";7");
958 }
T & value()&
Definition: Try-inl.h:140
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
static std::string doWorkStaticValue ( std::string &&  t)
static

Definition at line 1070 of file FutureTest.cpp.

References folly::pushmi::detail::t.

Referenced by TEST().

1070  {
1071  return t + ";value";
1072 }
Future<int> recursion ( Executor executor,
int  depth 
)

Definition at line 1610 of file FutureTest.cpp.

References call(), and folly::makeFuture().

Referenced by TEST().

1610  {
1611  return makeFuture().thenValue([=](auto) {
1612  return call(depth, executor).thenValue([=](auto result) {
1613  if (result) {
1614  return folly::makeFuture(42);
1615  }
1616 
1617  return recursion(executor, depth - 1);
1618  });
1619  });
1620 }
Future< int > recursion(Executor *executor, int depth)
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
Future< bool > call(int depth, Executor *executor)
TEST ( Future  ,
makeEmpty   
)

Definition at line 44 of file FutureTest.cpp.

References EXPECT_THROW, f, and folly::Future< T >::makeEmpty().

44  {
45  auto f = Future<int>::makeEmpty();
46  EXPECT_THROW(f.isReady(), FutureInvalid);
47 }
auto f
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
TEST ( Future  ,
futureDefaultCtor   
)

Definition at line 49 of file FutureTest.cpp.

49  {
50  Future<Unit>();
51 }
TEST ( Future  ,
futureToUnit   
)

Definition at line 53 of file FutureTest.cpp.

References eggs, EXPECT_TRUE, folly::makeFuture(), folly::unit, and folly::futures::detail::FutureBase< T >::value().

53  {
54  Future<Unit> fu = makeFuture(42).unit();
55  fu.value();
56  EXPECT_TRUE(makeFuture<int>(eggs).unit().hasException());
57 }
static eggs_t eggs("eggs")
constexpr Unit unit
Definition: Unit.h:45
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
voidFutureToUnit   
)

Definition at line 59 of file FutureTest.cpp.

References eggs, EXPECT_TRUE, folly::makeFuture(), folly::unit, and folly::futures::detail::FutureBase< T >::value().

59  {
60  Future<Unit> fu = makeFuture().unit();
61  fu.value();
62  EXPECT_TRUE(makeFuture<Unit>(eggs).unit().hasException());
63 }
static eggs_t eggs("eggs")
constexpr Unit unit
Definition: Unit.h:45
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
unitFutureToUnitIdentity   
)

Definition at line 65 of file FutureTest.cpp.

References eggs, EXPECT_TRUE, folly::makeFuture(), folly::unit, and folly::futures::detail::FutureBase< T >::value().

65  {
66  Future<Unit> fu = makeFuture(Unit{}).unit();
67  fu.value();
68  EXPECT_TRUE(makeFuture<Unit>(eggs).unit().hasException());
69 }
static eggs_t eggs("eggs")
constexpr Unit unit
Definition: Unit.h:45
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
toUnitWhileInProgress   
)

Definition at line 71 of file FutureTest.cpp.

References EXPECT_FALSE, EXPECT_TRUE, folly::Promise< T >::getFuture(), folly::futures::detail::FutureBase< T >::isReady(), and folly::Promise< T >::setValue().

71  {
72  Promise<int> p;
73  Future<Unit> fu = p.getFuture().unit();
74  EXPECT_FALSE(fu.isReady());
75  p.setValue(42);
76  EXPECT_TRUE(fu.isReady());
77 }
Future< T > getFuture()
Definition: Promise-inl.h:97
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST ( Future  ,
makeFutureWithUnit   
)

Definition at line 79 of file FutureTest.cpp.

References count, EXPECT_EQ, and folly::makeFutureWith().

79  {
80  int count = 0;
81  Future<Unit> fu = makeFutureWith([&] { count++; });
82  EXPECT_EQ(1, count);
83 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
int * count
std::enable_if< isFuture< invoke_result_t< F > >::value, invoke_result_t< F > >::type makeFutureWith(F &&func)
Definition: Future-inl.h:1322
TEST ( Future  ,
getRequiresOnlyMoveCtor   
)

Definition at line 85 of file FutureTest.cpp.

References EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, f, folly::Future< T >::makeEmpty(), and folly::gen::move.

85  {
86  struct MoveCtorOnly {
87  explicit MoveCtorOnly(int id) : id_(id) {}
88  MoveCtorOnly(const MoveCtorOnly&) = delete;
89  MoveCtorOnly(MoveCtorOnly&&) = default;
90  void operator=(MoveCtorOnly const&) = delete;
91  void operator=(MoveCtorOnly&&) = delete;
92  int id_;
93  };
94  {
95  auto f = makeFuture<MoveCtorOnly>(MoveCtorOnly(42));
96  EXPECT_TRUE(f.valid());
97  EXPECT_TRUE(f.isReady());
98  auto v = std::move(f).get();
99  EXPECT_EQ(v.id_, 42);
100  }
101  {
102  auto f = makeFuture<MoveCtorOnly>(MoveCtorOnly(42));
103  EXPECT_TRUE(f.valid());
104  EXPECT_TRUE(f.isReady());
105  auto v = std::move(f).get();
106  EXPECT_EQ(v.id_, 42);
107  }
108  {
109  auto f = makeFuture<MoveCtorOnly>(MoveCtorOnly(42));
110  EXPECT_TRUE(f.valid());
111  EXPECT_TRUE(f.isReady());
112  auto v = std::move(f).get(std::chrono::milliseconds(10));
113  EXPECT_EQ(v.id_, 42);
114  }
115  {
116  auto f = makeFuture<MoveCtorOnly>(MoveCtorOnly(42));
117  EXPECT_TRUE(f.valid());
118  EXPECT_TRUE(f.isReady());
119  auto v = std::move(f).get(std::chrono::milliseconds(10));
120  EXPECT_EQ(v.id_, 42);
121  }
122 }
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( Future  ,
ctorPostconditionValid   
)

Definition at line 137 of file FutureTest.cpp.

References DOIT, and folly::makeFuture().

137  {
138  // Ctors/factories that promise valid -- postcondition: valid()
139 
140 #define DOIT(CREATION_EXPR) \
141  do { \
142  auto f1 = (CREATION_EXPR); \
143  EXPECT_TRUE(f1.valid()); \
144  auto f2 = std::move(f1); \
145  EXPECT_FALSE(f1.valid()); \
146  EXPECT_TRUE(f2.valid()); \
147  } while (false)
148 
149  auto const except = std::logic_error("foo");
150  auto const ewrap = folly::exception_wrapper(except);
151 
152  DOIT(makeValid());
153  DOIT(Future<int>(42));
154  DOIT(Future<int>{42});
155  DOIT(Future<Unit>());
156  DOIT(Future<Unit>{});
157  DOIT(makeFuture());
158  DOIT(makeFuture(Unit{}));
159  DOIT(makeFuture<Unit>(Unit{}));
160  DOIT(makeFuture(42));
161  DOIT(makeFuture<int>(42));
162  DOIT(makeFuture<int>(except));
163  DOIT(makeFuture<int>(ewrap));
164  DOIT(makeFuture(Try<int>(42)));
165  DOIT(makeFuture<int>(Try<int>(42)));
166  DOIT(makeFuture<int>(Try<int>(ewrap)));
167 
168 #undef DOIT
169 }
#define DOIT(CREATION_EXPR)
Definition: Try.h:51
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
ctorPostconditionInvalid   
)

Definition at line 171 of file FutureTest.cpp.

References DOIT.

171  {
172  // Ctors/factories that promise invalid -- postcondition: !valid()
173 
174 #define DOIT(CREATION_EXPR) \
175  do { \
176  auto f1 = (CREATION_EXPR); \
177  EXPECT_FALSE(f1.valid()); \
178  auto f2 = std::move(f1); \
179  EXPECT_FALSE(f1.valid()); \
180  EXPECT_FALSE(f2.valid()); \
181  } while (false)
182 
183  DOIT(makeInvalid());
185 
186 #undef DOIT
187 }
#define DOIT(CREATION_EXPR)
TEST ( Future  ,
lacksPreconditionValid   
)

Definition at line 189 of file FutureTest.cpp.

References folly::copy(), DOIT, f, and folly::gen::move.

189  {
190  // Ops that don't throw FutureInvalid if !valid() --
191  // without precondition: valid()
192 
193 #define DOIT(STMT) \
194  do { \
195  auto f = makeValid(); \
196  { STMT; } \
197  copy(std::move(f)); \
198  EXPECT_NO_THROW(STMT); \
199  } while (false)
200 
201  // .valid() itself
202  DOIT(f.valid());
203 
204  // move-ctor - move-copy to local, copy(), pass-by-move-value
205  DOIT(auto other = std::move(f));
206  DOIT(copy(std::move(f)));
207  DOIT(([](auto) {})(std::move(f)));
208 
209  // move-assignment into either {valid | invalid}
210  DOIT({
211  auto other = makeValid();
212  other = std::move(f);
213  });
214  DOIT({
215  auto other = makeInvalid();
216  other = std::move(f);
217  });
218 
219 #undef DOIT
220 }
#define DOIT(CREATION_EXPR)
auto f
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72
TEST ( Future  ,
hasPreconditionValid   
)

Definition at line 222 of file FutureTest.cpp.

References DOIT, f, and folly::gen::move.

222  {
223  // Ops that require validity; precondition: valid();
224  // throw FutureInvalid if !valid()
225 
226 #define DOIT(STMT) \
227  do { \
228  auto f = makeValid(); \
229  EXPECT_NO_THROW(STMT); \
230  copy(std::move(f)); \
231  EXPECT_THROW(STMT, FutureInvalid); \
232  } while (false)
233 
234  DOIT(f.isReady());
235  DOIT(f.result());
236  DOIT(std::move(f).get());
237  DOIT(std::move(f).get(std::chrono::milliseconds(10)));
238  DOIT(f.getTry());
239  DOIT(f.hasValue());
240  DOIT(f.hasException());
241  DOIT(f.value());
242  DOIT(f.poll());
243  DOIT(std::move(f).then());
244  DOIT(std::move(f).then([](auto&&) {}));
245 
246 #undef DOIT
247 }
#define DOIT(CREATION_EXPR)
auto f
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
TEST ( Future  ,
hasPostconditionValid   
)

Definition at line 249 of file FutureTest.cpp.

References DOIT, f, and folly::gen::move.

249  {
250  // Ops that preserve validity -- postcondition: valid()
251 
252 #define DOIT(STMT) \
253  do { \
254  auto f = makeValid(); \
255  EXPECT_NO_THROW(STMT); \
256  EXPECT_TRUE(f.valid()); \
257  } while (false)
258 
259  auto const swallow = [](auto) {};
260 
261  DOIT(swallow(f.valid())); // f.valid() itself preserves validity
262  DOIT(swallow(f.isReady()));
263  DOIT(swallow(f.hasValue()));
264  DOIT(swallow(f.hasException()));
265  DOIT(swallow(f.value()));
266  DOIT(swallow(f.getTry()));
267  DOIT(swallow(f.poll()));
268  DOIT(f.raise(std::logic_error("foo")));
269  DOIT(f.cancel());
270  DOIT(swallow(f.getTry()));
271  DOIT(f.wait());
272  DOIT(std::move(f.wait()));
273 
274 #undef DOIT
275 }
#define DOIT(CREATION_EXPR)
auto f
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
TEST ( Future  ,
hasPostconditionInvalid   
)

Definition at line 277 of file FutureTest.cpp.

References DOIT, f, folly::makeFuture(), folly::gen::move, and folly::detail::distributed_mutex::wait().

277  {
278  // Ops that consume *this -- postcondition: !valid()
279 
280 #define DOIT(CTOR, STMT) \
281  do { \
282  auto f = (CTOR); \
283  EXPECT_NO_THROW(STMT); \
284  EXPECT_FALSE(f.valid()); \
285  } while (false)
286 
287  // move-ctor of {valid|invalid}
288  DOIT(makeValid(), { auto other{std::move(f)}; });
289  DOIT(makeInvalid(), { auto other{std::move(f)}; });
290 
291  // move-assignment of {valid|invalid} into {valid|invalid}
292  DOIT(makeValid(), {
293  auto other = makeValid();
294  other = std::move(f);
295  });
296  DOIT(makeValid(), {
297  auto other = makeInvalid();
298  other = std::move(f);
299  });
300  DOIT(makeInvalid(), {
301  auto other = makeValid();
302  other = std::move(f);
303  });
304  DOIT(makeInvalid(), {
305  auto other = makeInvalid();
306  other = std::move(f);
307  });
308 
309  // pass-by-value of {valid|invalid}
310  DOIT(makeValid(), {
311  auto const byval = [](auto) {};
312  byval(std::move(f));
313  });
314  DOIT(makeInvalid(), {
315  auto const byval = [](auto) {};
316  byval(std::move(f));
317  });
318 
319  // other consuming ops
320  auto const swallow = [](auto) {};
321  DOIT(makeValid(), swallow(std::move(f).wait()));
322  DOIT(makeValid(), swallow(std::move(f.wait())));
323  DOIT(makeValid(), swallow(std::move(f).get()));
324  DOIT(makeValid(), swallow(std::move(f).get(std::chrono::milliseconds(10))));
325  DOIT(makeValid(), swallow(std::move(f).semi()));
326 
327 #undef DOIT
328 }
#define DOIT(CREATION_EXPR)
auto f
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
bool wait(Waiter *waiter, bool shouldSleep, Waiter *&next)
TEST ( Future  ,
onError   
)

Definition at line 342 of file FutureTest.cpp.

References eggs, EXPECT_EQ, EXPECT_FLAG, EXPECT_NO_FLAG, EXPECT_NO_THROW, EXPECT_THROW, f, flag, and folly::makeFuture().

342  {
343  bool theFlag = false;
344  auto flag = [&] { theFlag = true; };
345 #define EXPECT_FLAG() \
346  do { \
347  EXPECT_TRUE(theFlag); \
348  theFlag = false; \
349  } while (0);
350 
351 #define EXPECT_NO_FLAG() \
352  do { \
353  EXPECT_FALSE(theFlag); \
354  theFlag = false; \
355  } while (0);
356 
357  // By reference
358  {
359  auto f = makeFuture()
360  .thenValue([](auto&&) { throw eggs; })
361  .onError([&](eggs_t& /* e */) { flag(); });
362  EXPECT_FLAG();
363  EXPECT_NO_THROW(f.value());
364  }
365 
366  {
367  auto f = makeFuture()
368  .thenValue([](auto&&) { throw eggs; })
369  .onError([&](eggs_t& /* e */) {
370  flag();
371  return makeFuture();
372  });
373  EXPECT_FLAG();
374  EXPECT_NO_THROW(f.value());
375  }
376 
377  // By value
378  {
379  auto f = makeFuture()
380  .thenValue([](auto&&) { throw eggs; })
381  .onError([&](eggs_t /* e */) { flag(); });
382  EXPECT_FLAG();
383  EXPECT_NO_THROW(f.value());
384  }
385 
386  {
387  auto f = makeFuture()
388  .thenValue([](auto&&) { throw eggs; })
389  .onError([&](eggs_t /* e */) {
390  flag();
391  return makeFuture();
392  });
393  EXPECT_FLAG();
394  EXPECT_NO_THROW(f.value());
395  }
396 
397  // Polymorphic
398  {
399  auto f = makeFuture()
400  .thenValue([](auto&&) { throw eggs; })
401  .onError([&](std::exception& /* e */) { flag(); });
402  EXPECT_FLAG();
403  EXPECT_NO_THROW(f.value());
404  }
405 
406  {
407  auto f = makeFuture()
408  .thenValue([](auto&&) { throw eggs; })
409  .onError([&](std::exception& /* e */) {
410  flag();
411  return makeFuture();
412  });
413  EXPECT_FLAG();
414  EXPECT_NO_THROW(f.value());
415  }
416 
417  // Non-exceptions
418  {
419  auto f = makeFuture()
420  .thenValue([](auto&&) { throw - 1; })
421  .onError([&](int /* e */) { flag(); });
422  EXPECT_FLAG();
423  EXPECT_NO_THROW(f.value());
424  }
425 
426  {
427  auto f = makeFuture()
428  .thenValue([](auto&&) { throw - 1; })
429  .onError([&](int /* e */) {
430  flag();
431  return makeFuture();
432  });
433  EXPECT_FLAG();
434  EXPECT_NO_THROW(f.value());
435  }
436 
437  // Mutable lambda
438  {
439  auto f = makeFuture()
440  .thenValue([](auto&&) { throw eggs; })
441  .onError([&](eggs_t& /* e */) mutable { flag(); });
442  EXPECT_FLAG();
443  EXPECT_NO_THROW(f.value());
444  }
445 
446  {
447  auto f = makeFuture()
448  .thenValue([](auto&&) { throw eggs; })
449  .onError([&](eggs_t& /* e */) mutable {
450  flag();
451  return makeFuture();
452  });
453  EXPECT_FLAG();
454  EXPECT_NO_THROW(f.value());
455  }
456 
457  // Function pointer
458  {
459  auto f = makeFuture()
460  .thenValue([](auto &&) -> int { throw eggs; })
461  .onError(onErrorHelperEggs)
462  .onError(onErrorHelperGeneric);
463  EXPECT_EQ(10, f.value());
464  }
465  {
466  auto f =
467  makeFuture()
468  .thenValue([](auto &&) -> int { throw std::runtime_error("test"); })
469  .onError(onErrorHelperEggs)
470  .onError(onErrorHelperGeneric);
471  EXPECT_EQ(20, f.value());
472  }
473  {
474  auto f =
475  makeFuture()
476  .thenValue([](auto &&) -> int { throw std::runtime_error("test"); })
477  .onError(onErrorHelperEggs);
478  EXPECT_THROW(f.value(), std::runtime_error);
479  }
480  {
481  auto f = makeFuture()
482  .thenValue([](auto &&) -> int { throw eggs; })
483  .thenError<eggs_t>(onErrorHelperEggs)
484  .thenError<std::exception>(onErrorHelperGeneric);
485  EXPECT_EQ(10, f.value());
486  }
487  {
488  auto f =
489  makeFuture()
490  .thenValue([](auto &&) -> int { throw std::runtime_error("test"); })
491  .thenError<eggs_t>(onErrorHelperEggs)
492  .thenError(onErrorHelperWrapper);
493  EXPECT_EQ(30, f.value());
494  }
495  {
496  auto f =
497  makeFuture()
498  .thenValue([](auto &&) -> int { throw std::runtime_error("test"); })
499  .thenError<eggs_t>(onErrorHelperEggs);
500  EXPECT_THROW(f.value(), std::runtime_error);
501  }
502 
503  // No throw
504  {
505  auto f = makeFuture()
506  .thenValue([](auto&&) { return 42; })
507  .onError([&](eggs_t& /* e */) {
508  flag();
509  return -1;
510  });
511  EXPECT_NO_FLAG();
512  EXPECT_EQ(42, f.value());
513  }
514 
515  {
516  auto f = makeFuture()
517  .thenValue([](auto&&) { return 42; })
518  .onError([&](eggs_t& /* e */) {
519  flag();
520  return makeFuture<int>(-1);
521  });
522  EXPECT_NO_FLAG();
523  EXPECT_EQ(42, f.value());
524  }
525 
526  // Catch different exception
527  {
528  auto f = makeFuture()
529  .thenValue([](auto&&) { throw eggs; })
530  .onError([&](std::runtime_error& /* e */) { flag(); });
531  EXPECT_NO_FLAG();
532  EXPECT_THROW(f.value(), eggs_t);
533  }
534 
535  {
536  auto f = makeFuture()
537  .thenValue([](auto&&) { throw eggs; })
538  .onError([&](std::runtime_error& /* e */) {
539  flag();
540  return makeFuture();
541  });
542  EXPECT_NO_FLAG();
543  EXPECT_THROW(f.value(), eggs_t);
544  }
545 
546  // Returned value propagates
547  {
548  auto f = makeFuture()
549  .thenValue([](auto &&) -> int { throw eggs; })
550  .onError([&](eggs_t& /* e */) { return 42; });
551  EXPECT_EQ(42, f.value());
552  }
553 
554  // Returned future propagates
555  {
556  auto f = makeFuture()
557  .thenValue([](auto &&) -> int { throw eggs; })
558  .onError([&](eggs_t& /* e */) { return makeFuture<int>(42); });
559  EXPECT_EQ(42, f.value());
560  }
561 
562  // Throw in callback
563  {
564  auto f = makeFuture()
565  .thenValue([](auto &&) -> int { throw eggs; })
566  .onError([&](eggs_t& e) -> int { throw e; });
567  EXPECT_THROW(f.value(), eggs_t);
568  }
569 
570  {
571  auto f = makeFuture()
572  .thenValue([](auto &&) -> int { throw eggs; })
573  .onError([&](eggs_t& e) -> Future<int> { throw e; });
574  EXPECT_THROW(f.value(), eggs_t);
575  }
576 
577  // exception_wrapper, return Future<T>
578  {
579  auto f = makeFuture()
580  .thenValue([](auto&&) { throw eggs; })
581  .onError([&](exception_wrapper /* e */) {
582  flag();
583  return makeFuture();
584  });
585  EXPECT_FLAG();
586  EXPECT_NO_THROW(f.value());
587  }
588 
589  // exception_wrapper, return Future<T> but throw
590  {
591  auto f = makeFuture()
592  .thenValue([](auto &&) -> int { throw eggs; })
593  .onError([&](exception_wrapper /* e */) -> Future<int> {
594  flag();
595  throw eggs;
596  });
597  EXPECT_FLAG();
598  EXPECT_THROW(f.value(), eggs_t);
599  }
600 
601  // exception_wrapper, return T
602  {
603  auto f = makeFuture()
604  .thenValue([](auto &&) -> int { throw eggs; })
605  .onError([&](exception_wrapper /* e */) {
606  flag();
607  return -1;
608  });
609  EXPECT_FLAG();
610  EXPECT_EQ(-1, f.value());
611  }
612 
613  // exception_wrapper, return T but throw
614  {
615  auto f = makeFuture()
616  .thenValue([](auto &&) -> int { throw eggs; })
617  .onError([&](exception_wrapper /* e */) -> int {
618  flag();
619  throw eggs;
620  });
621  EXPECT_FLAG();
622  EXPECT_THROW(f.value(), eggs_t);
623  }
624 
625  // const exception_wrapper&
626  {
627  auto f = makeFuture()
628  .thenValue([](auto&&) { throw eggs; })
629  .onError([&](const exception_wrapper& /* e */) {
630  flag();
631  return makeFuture();
632  });
633  EXPECT_FLAG();
634  EXPECT_NO_THROW(f.value());
635  }
636 #undef EXPECT_FLAG
637 #undef EXPECT_NO_FLAG
638 }
#define EXPECT_NO_FLAG()
auto f
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define EXPECT_FLAG()
static once_flag flag
Definition: Random.cpp:75
FutureException eggs_t
Definition: FutureTest.cpp:39
static eggs_t eggs("eggs")
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
thenError   
)

Definition at line 640 of file FutureTest.cpp.

References eggs, EXPECT_EQ, EXPECT_FLAG, EXPECT_NO_FLAG, EXPECT_NO_THROW, EXPECT_THROW, f, flag, and folly::makeFuture().

640  {
641  bool theFlag = false;
642  auto flag = [&] { theFlag = true; };
643 #define EXPECT_FLAG() \
644  do { \
645  EXPECT_TRUE(theFlag); \
646  theFlag = false; \
647  } while (0);
648 
649 #define EXPECT_NO_FLAG() \
650  do { \
651  EXPECT_FALSE(theFlag); \
652  theFlag = false; \
653  } while (0);
654 
655  // By reference
656  {
657  auto f = makeFuture()
658  .thenValue([](auto&&) { throw eggs; })
659  .thenError<eggs_t>([&](const eggs_t& /* e */) { flag(); });
660  EXPECT_FLAG();
661  EXPECT_NO_THROW(f.value());
662  }
663 
664  // By auto reference
665  {
666  auto f = makeFuture()
667  .thenValue([](auto&&) { throw eggs; })
668  .thenError<eggs_t>([&](auto const& /* e */) { flag(); });
669  EXPECT_FLAG();
670  EXPECT_NO_THROW(f.value());
671  }
672 
673  {
674  auto f = makeFuture()
675  .thenValue([](auto&&) { throw eggs; })
676  .onError([&](eggs_t& /* e */) {
677  flag();
678  return makeFuture();
679  });
680  EXPECT_FLAG();
681  EXPECT_NO_THROW(f.value());
682  }
683 
684  // By value
685  {
686  auto f = makeFuture()
687  .thenValue([](auto&&) { throw eggs; })
688  .onError([&](eggs_t /* e */) { flag(); });
689  EXPECT_FLAG();
690  EXPECT_NO_THROW(f.value());
691  }
692 
693  {
694  auto f = makeFuture()
695  .thenValue([](auto&&) { throw eggs; })
696  .onError([&](eggs_t /* e */) {
697  flag();
698  return makeFuture();
699  });
700  EXPECT_FLAG();
701  EXPECT_NO_THROW(f.value());
702  }
703 
704  // Polymorphic
705  {
706  auto f = makeFuture()
707  .thenValue([](auto&&) { throw eggs; })
708  .onError([&](std::exception& /* e */) { flag(); });
709  EXPECT_FLAG();
710  EXPECT_NO_THROW(f.value());
711  }
712 
713  {
714  auto f = makeFuture()
715  .thenValue([](auto&&) { throw eggs; })
716  .onError([&](std::exception& /* e */) {
717  flag();
718  return makeFuture();
719  });
720  EXPECT_FLAG();
721  EXPECT_NO_THROW(f.value());
722  }
723 
724  // Non-exceptions
725  {
726  auto f = makeFuture()
727  .thenValue([](auto&&) { throw - 1; })
728  .onError([&](int /* e */) { flag(); });
729  EXPECT_FLAG();
730  EXPECT_NO_THROW(f.value());
731  }
732 
733  {
734  auto f = makeFuture()
735  .thenValue([](auto&&) { throw - 1; })
736  .onError([&](int /* e */) {
737  flag();
738  return makeFuture();
739  });
740  EXPECT_FLAG();
741  EXPECT_NO_THROW(f.value());
742  }
743 
744  // Mutable lambda
745  {
746  auto f = makeFuture()
747  .thenValue([](auto&&) { throw eggs; })
748  .onError([&](eggs_t& /* e */) mutable { flag(); });
749  EXPECT_FLAG();
750  EXPECT_NO_THROW(f.value());
751  }
752 
753  {
754  auto f = makeFuture()
755  .thenValue([](auto&&) { throw eggs; })
756  .onError([&](eggs_t& /* e */) mutable {
757  flag();
758  return makeFuture();
759  });
760  EXPECT_FLAG();
761  EXPECT_NO_THROW(f.value());
762  }
763 
764  // Function pointer
765  {
766  auto f = makeFuture()
767  .thenValue([](auto &&) -> int { throw eggs; })
768  .onError(onErrorHelperEggs)
769  .onError(onErrorHelperGeneric);
770  EXPECT_EQ(10, f.value());
771  }
772  {
773  auto f =
774  makeFuture()
775  .thenValue([](auto &&) -> int { throw std::runtime_error("test"); })
776  .onError(onErrorHelperEggs)
777  .onError(onErrorHelperGeneric);
778  EXPECT_EQ(20, f.value());
779  }
780  {
781  auto f =
782  makeFuture()
783  .thenValue([](auto &&) -> int { throw std::runtime_error("test"); })
784  .onError(onErrorHelperEggs);
785  EXPECT_THROW(f.value(), std::runtime_error);
786  }
787 
788  // No throw
789  {
790  auto f = makeFuture()
791  .thenValue([](auto&&) { return 42; })
792  .onError([&](eggs_t& /* e */) {
793  flag();
794  return -1;
795  });
796  EXPECT_NO_FLAG();
797  EXPECT_EQ(42, f.value());
798  }
799 
800  {
801  auto f = makeFuture()
802  .thenValue([](auto&&) { return 42; })
803  .onError([&](eggs_t& /* e */) {
804  flag();
805  return makeFuture<int>(-1);
806  });
807  EXPECT_NO_FLAG();
808  EXPECT_EQ(42, f.value());
809  }
810 
811  // Catch different exception
812  {
813  auto f = makeFuture()
814  .thenValue([](auto&&) { throw eggs; })
815  .onError([&](std::runtime_error& /* e */) { flag(); });
816  EXPECT_NO_FLAG();
817  EXPECT_THROW(f.value(), eggs_t);
818  }
819 
820  {
821  auto f = makeFuture()
822  .thenValue([](auto&&) { throw eggs; })
823  .onError([&](std::runtime_error& /* e */) {
824  flag();
825  return makeFuture();
826  });
827  EXPECT_NO_FLAG();
828  EXPECT_THROW(f.value(), eggs_t);
829  }
830 
831  // Returned value propagates
832  {
833  auto f = makeFuture()
834  .thenValue([](auto &&) -> int { throw eggs; })
835  .onError([&](eggs_t& /* e */) { return 42; });
836  EXPECT_EQ(42, f.value());
837  }
838 
839  // Returned future propagates
840  {
841  auto f = makeFuture()
842  .thenValue([](auto &&) -> int { throw eggs; })
843  .onError([&](eggs_t& /* e */) { return makeFuture<int>(42); });
844  EXPECT_EQ(42, f.value());
845  }
846 
847  // Throw in callback
848  {
849  auto f = makeFuture()
850  .thenValue([](auto &&) -> int { throw eggs; })
851  .onError([&](eggs_t& e) -> int { throw e; });
852  EXPECT_THROW(f.value(), eggs_t);
853  }
854 
855  {
856  auto f = makeFuture()
857  .thenValue([](auto &&) -> int { throw eggs; })
858  .onError([&](eggs_t& e) -> Future<int> { throw e; });
859  EXPECT_THROW(f.value(), eggs_t);
860  }
861 
862  // exception_wrapper, return Future<T>
863  {
864  auto f = makeFuture()
865  .thenValue([](auto&&) { throw eggs; })
866  .onError([&](exception_wrapper /* e */) {
867  flag();
868  return makeFuture();
869  });
870  EXPECT_FLAG();
871  EXPECT_NO_THROW(f.value());
872  }
873 
874  // exception_wrapper, return Future<T> but throw
875  {
876  auto f = makeFuture()
877  .thenValue([](auto &&) -> int { throw eggs; })
878  .onError([&](exception_wrapper /* e */) -> Future<int> {
879  flag();
880  throw eggs;
881  });
882  EXPECT_FLAG();
883  EXPECT_THROW(f.value(), eggs_t);
884  }
885 
886  // exception_wrapper, return T
887  {
888  auto f = makeFuture()
889  .thenValue([](auto &&) -> int { throw eggs; })
890  .onError([&](exception_wrapper /* e */) {
891  flag();
892  return -1;
893  });
894  EXPECT_FLAG();
895  EXPECT_EQ(-1, f.value());
896  }
897 
898  // exception_wrapper, return T but throw
899  {
900  auto f = makeFuture()
901  .thenValue([](auto &&) -> int { throw eggs; })
902  .onError([&](exception_wrapper /* e */) -> int {
903  flag();
904  throw eggs;
905  });
906  EXPECT_FLAG();
907  EXPECT_THROW(f.value(), eggs_t);
908  }
909 
910  // const exception_wrapper&
911  {
912  auto f = makeFuture()
913  .thenValue([](auto&&) { throw eggs; })
914  .onError([&](const exception_wrapper& /* e */) {
915  flag();
916  return makeFuture();
917  });
918  EXPECT_FLAG();
919  EXPECT_NO_THROW(f.value());
920  }
921 #undef EXPECT_FLAG
922 #undef EXPECT_NO_FLAG
923 }
#define EXPECT_NO_FLAG()
auto f
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define EXPECT_FLAG()
static once_flag flag
Definition: Random.cpp:75
FutureException eggs_t
Definition: FutureTest.cpp:39
static eggs_t eggs("eggs")
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
special   
)

Definition at line 925 of file FutureTest.cpp.

References EXPECT_FALSE, EXPECT_TRUE, and folly::value().

925  {
926  EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
927  EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
928  EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
929  EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
930 }
static const char *const value
Definition: Conv.cpp:50
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST ( Future  ,
then   
)

Definition at line 932 of file FutureTest.cpp.

References EXPECT_EQ, f, folly::makeFuture(), s, string, folly::pushmi::detail::t, and folly::Try< T >::value().

932  {
933  auto f =
934  makeFuture<std::string>("0")
935  .thenValue([](auto&&) { return makeFuture<std::string>("1"); })
936  .then(
937  [](Try<std::string>&& t) { return makeFuture(t.value() + ";2"); })
938  .then([](const Try<std::string>&& t) {
939  return makeFuture(t.value() + ";3");
940  })
941  .then([](const Try<std::string>& t) {
942  return makeFuture(t.value() + ";4");
943  })
944  .then([](Try<std::string> t) { return makeFuture(t.value() + ";5"); })
945  .then([](const Try<std::string> t) {
946  return makeFuture(t.value() + ";6");
947  })
948  .then([](std::string&& s) { return makeFuture(s + ";7"); })
949  .then([](const std::string&& s) { return makeFuture(s + ";8"); })
950  .then([](const std::string& s) { return makeFuture(s + ";9"); })
951  .then([](std::string s) { return makeFuture(s + ";10"); })
952  .then([](const std::string s) { return makeFuture(s + ";11"); });
953  EXPECT_EQ(f.value(), "1;2;3;4;5;6;7;8;9;10;11");
954 }
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Definition: Try.h:51
const char * string
Definition: Conv.cpp:212
static set< string > s
T & value()&
Definition: Try-inl.h:140
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
thenTrythenValue   
)

Definition at line 960 of file FutureTest.cpp.

References doWorkStaticTry(), EXPECT_EQ, f, folly::makeFuture(), s, string, folly::pushmi::detail::t, and folly::Try< T >::value().

960  {
961  auto f =
962  makeFuture()
963  .thenTry([](auto&&) { return makeFuture<std::string>("1"); })
964  .thenTry(
965  [](Try<std::string>&& t) { return makeFuture(t.value() + ";2"); })
966  .thenTry([](const Try<std::string>&& t) {
967  return makeFuture(t.value() + ";3");
968  })
969  .thenTry([](const Try<std::string>& t) {
970  return makeFuture(t.value() + ";4");
971  })
972  .thenTry(
973  [](Try<std::string> t) { return makeFuture(t.value() + ";5"); })
974  .thenTry([](const Try<std::string> t) {
975  return makeFuture(t.value() + ";6");
976  })
977  .thenTry(doWorkStaticTry)
978  .thenValue([](std::string&& s) { return makeFuture(s + ";8"); })
979  .thenValue([](const std::string&& s) { return makeFuture(s + ";9"); })
980  .thenValue([](const std::string& s) { return makeFuture(s + ";10"); })
981  .thenValue([](std::string s) { return makeFuture(s + ";11"); })
982  .thenValue([](const std::string s) { return makeFuture(s + ";12"); });
983  EXPECT_EQ(f.value(), "1;2;3;4;5;6;7;8;9;10;11;12");
984 }
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static folly::Future< std::string > doWorkStaticTry(Try< std::string > &&t)
Definition: FutureTest.cpp:956
Definition: Try.h:51
const char * string
Definition: Conv.cpp:212
static set< string > s
T & value()&
Definition: Try-inl.h:140
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
thenTry   
)

Definition at line 986 of file FutureTest.cpp.

References EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, f, flag, folly::Promise< T >::getFuture(), folly::makeFuture(), folly::Promise< T >::setValue(), and folly::pushmi::detail::t.

986  {
987  bool flag = false;
988 
989  makeFuture<int>(42).then([&](Try<int>&& t) {
990  flag = true;
991  EXPECT_EQ(42, t.value());
992  });
993  EXPECT_TRUE(flag);
994  flag = false;
995 
996  makeFuture<int>(42)
997  .then([](Try<int>&& t) { return t.value(); })
998  .then([&](Try<int>&& t) {
999  flag = true;
1000  EXPECT_EQ(42, t.value());
1001  });
1002  EXPECT_TRUE(flag);
1003  flag = false;
1004 
1005  makeFuture().then([&](Try<Unit>&& t) {
1006  flag = true;
1007  t.value();
1008  });
1009  EXPECT_TRUE(flag);
1010  flag = false;
1011 
1012  Promise<Unit> p;
1013  auto f = p.getFuture().then([&](Try<Unit>&& /* t */) { flag = true; });
1014  EXPECT_FALSE(flag);
1015  EXPECT_FALSE(f.isReady());
1016  p.setValue();
1017  EXPECT_TRUE(flag);
1018  EXPECT_TRUE(f.isReady());
1019 }
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static once_flag flag
Definition: Random.cpp:75
Future< T > getFuture()
Definition: Promise-inl.h:97
Definition: Try.h:51
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
thenValue   
)

Definition at line 1021 of file FutureTest.cpp.

References eggs, EXPECT_EQ, EXPECT_THROW, EXPECT_TRUE, f, flag, i, and folly::makeFuture().

1021  {
1022  bool flag = false;
1023  makeFuture<int>(42).then([&](int i) {
1024  EXPECT_EQ(42, i);
1025  flag = true;
1026  });
1027  EXPECT_TRUE(flag);
1028  flag = false;
1029 
1030  makeFuture<int>(42).then([](int i) { return i; }).then([&](int i) {
1031  flag = true;
1032  EXPECT_EQ(42, i);
1033  });
1034  EXPECT_TRUE(flag);
1035  flag = false;
1036 
1037  makeFuture().thenValue([&](auto&&) { flag = true; });
1038  EXPECT_TRUE(flag);
1039  flag = false;
1040 
1041  auto f = makeFuture<int>(eggs).thenValue([&](int /* i */) {});
1042  EXPECT_THROW(f.value(), eggs_t);
1043 
1044  f = makeFuture<Unit>(eggs).thenValue([&](auto&&) {});
1045  EXPECT_THROW(f.value(), eggs_t);
1046 }
auto f
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static once_flag flag
Definition: Random.cpp:75
FutureException eggs_t
Definition: FutureTest.cpp:39
static eggs_t eggs("eggs")
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
thenValueFuture   
)

Definition at line 1048 of file FutureTest.cpp.

References EXPECT_EQ, EXPECT_TRUE, flag, i, folly::makeFuture(), folly::gen::move, and folly::pushmi::detail::t.

1048  {
1049  bool flag = false;
1050  makeFuture<int>(42)
1051  .then([](int i) { return makeFuture<int>(std::move(i)); })
1052  .then([&](Try<int>&& t) {
1053  flag = true;
1054  EXPECT_EQ(42, t.value());
1055  });
1056  EXPECT_TRUE(flag);
1057  flag = false;
1058 
1059  makeFuture()
1060  .thenValue([](auto&&) { return makeFuture(); })
1061  .then([&](Try<Unit>&& /* t */) { flag = true; });
1062  EXPECT_TRUE(flag);
1063  flag = false;
1064 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static once_flag flag
Definition: Random.cpp:75
Definition: Try.h:51
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
thenFunction   
)

Definition at line 1074 of file FutureTest.cpp.

References doWork(), doWorkStatic(), doWorkStaticValue(), EXPECT_EQ, f, string, and folly::pushmi::detail::t.

1074  {
1075  struct Worker {
1077  return t.value() + ";class";
1078  }
1080  return t.value() + ";class-static";
1081  }
1082  } w;
1083 
1084  auto f = makeFuture<std::string>("start")
1085  .then(doWorkStatic)
1086  .then(Worker::doWorkStatic)
1087  .then(&Worker::doWork, &w)
1088  .then(doWorkStaticValue)
1089  .thenValue(doWorkStaticValue);
1090 
1091  EXPECT_EQ(f.value(), "start;static;class-static;class;value;value");
1092 }
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static std::string doWorkStaticValue(std::string &&t)
void doWork(int work)
Definition: Try.h:51
const char * string
Definition: Conv.cpp:212
static std::string doWorkStatic(Try< std::string > &&t)
TEST ( Future  ,
thenFunctionFuture   
)

Definition at line 1098 of file FutureTest.cpp.

References doWorkStaticFuture(), EXPECT_EQ, f, folly::makeFuture(), and folly::pushmi::detail::t.

1098  {
1099  struct Worker {
1100  Future<std::string> doWorkFuture(Try<std::string>&& t) {
1101  return makeFuture(t.value() + ";class");
1102  }
1104  return makeFuture(t.value() + ";class-static");
1105  }
1106  } w;
1107 
1108  auto f = makeFuture<std::string>("start")
1109  .then(doWorkStaticFuture)
1111  .then(&Worker::doWorkFuture, &w);
1112 
1113  EXPECT_EQ(f.value(), "start;static;class-static;class");
1114 }
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Definition: Try.h:51
static Future< std::string > doWorkStaticFuture(Try< std::string > &&t)
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
thenStdFunction   
)

Definition at line 1116 of file FutureTest.cpp.

References EXPECT_EQ, EXPECT_TRUE, f, flag, i, folly::makeFuture(), folly::gen::move, folly::pushmi::detail::t, and folly::Try< T >::value().

1116  {
1117  {
1118  std::function<int(folly::Unit)> fn = [](folly::Unit) { return 42; };
1119  auto f = makeFuture().then(std::move(fn));
1120  EXPECT_EQ(f.value(), 42);
1121  }
1122  {
1123  std::function<int(int)> fn = [](int i) { return i + 23; };
1124  auto f = makeFuture(19).then(std::move(fn));
1125  EXPECT_EQ(f.value(), 42);
1126  }
1127  {
1128  std::function<int(int)> fn = [](int i) { return i + 23; };
1129  auto f = makeFuture(19).thenValue(std::move(fn));
1130  EXPECT_EQ(f.value(), 42);
1131  }
1132  {
1133  std::function<int(Try<int>)> fn = [](Try<int> t) { return t.value() + 2; };
1134  auto f = makeFuture(1).then(std::move(fn));
1135  EXPECT_EQ(f.value(), 3);
1136  }
1137  {
1138  bool flag = false;
1139  std::function<void(folly::Unit)> fn = [&flag](folly::Unit) { flag = true; };
1140  auto f = makeFuture().then(std::move(fn));
1141  EXPECT_TRUE(f.isReady());
1142  EXPECT_TRUE(flag);
1143  }
1144 }
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static once_flag flag
Definition: Random.cpp:75
Definition: Try.h:51
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
T & value()&
Definition: Try-inl.h:140
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
thenBind   
)

Definition at line 1146 of file FutureTest.cpp.

References b, folly::netops::bind(), EXPECT_EQ, f, folly::makeFuture(), and folly::gen::move.

1146  {
1147  auto l = [](folly::Unit) { return makeFuture("bind"); };
1148  auto b = std::bind(l, std::placeholders::_1);
1149  auto f = makeFuture().thenValue(std::move(b));
1150  EXPECT_EQ(f.value(), "bind");
1151 }
auto f
char b
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
int bind(NetworkSocket s, const sockaddr *name, socklen_t namelen)
Definition: NetOps.cpp:76
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
thenBindTry   
)

Definition at line 1153 of file FutureTest.cpp.

References b, folly::netops::bind(), EXPECT_EQ, f, folly::makeFuture(), folly::gen::move, and folly::pushmi::detail::t.

1153  {
1154  auto l = [](Try<std::string>&& t) { return makeFuture(t.value() + ";bind"); };
1155  auto b = std::bind(l, std::placeholders::_1);
1156  auto f = makeFuture<std::string>("start").then(std::move(b));
1157 
1158  EXPECT_EQ(f.value(), "start;bind");
1159 }
auto f
char b
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Definition: Try.h:51
int bind(NetworkSocket s, const sockaddr *name, socklen_t namelen)
Definition: NetOps.cpp:76
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
value   
)

Definition at line 1161 of file FutureTest.cpp.

References eggs, EXPECT_EQ, EXPECT_THROW, f, folly::makeFuture(), folly::gen::move, and folly::value().

1161  {
1162  auto f = makeFuture(std::make_unique<int>(42));
1163  auto up = std::move(f.value());
1164  EXPECT_EQ(42, *up);
1165 
1166  EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
1167 }
auto f
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static eggs_t eggs("eggs")
static const char *const value
Definition: Conv.cpp:50
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
isReady   
)

Definition at line 1169 of file FutureTest.cpp.

References EXPECT_FALSE, EXPECT_TRUE, f, folly::Promise< T >::getFuture(), and folly::Promise< T >::setValue().

1169  {
1170  Promise<int> p;
1171  auto f = p.getFuture();
1172  EXPECT_FALSE(f.isReady());
1173  p.setValue(42);
1174  EXPECT_TRUE(f.isReady());
1175 }
auto f
Future< T > getFuture()
Definition: Promise-inl.h:97
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST ( Future  ,
futureNotReady   
)

Definition at line 1177 of file FutureTest.cpp.

References EXPECT_THROW, f, folly::Promise< T >::getFuture(), and folly::futures::detail::FutureBase< T >::value().

1177  {
1178  Promise<int> p;
1179  Future<int> f = p.getFuture();
1180  EXPECT_THROW(f.value(), eggs_t);
1181 }
auto f
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
FutureException eggs_t
Definition: FutureTest.cpp:39
Future< T > getFuture()
Definition: Promise-inl.h:97
TEST ( Future  ,
hasException   
)

Definition at line 1183 of file FutureTest.cpp.

References eggs, EXPECT_FALSE, EXPECT_TRUE, and folly::makeFuture().

1183  {
1184  EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
1185  EXPECT_FALSE(makeFuture(42).getTry().hasException());
1186 }
static eggs_t eggs("eggs")
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
hasValue   
)

Definition at line 1188 of file FutureTest.cpp.

References eggs, EXPECT_FALSE, EXPECT_TRUE, and folly::makeFuture().

1188  {
1189  EXPECT_TRUE(makeFuture(42).getTry().hasValue());
1190  EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
1191 }
static eggs_t eggs("eggs")
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
makeFuture   
)

Definition at line 1193 of file FutureTest.cpp.

References eggs, EXPECT_EQ, EXPECT_NO_THROW, EXPECT_THROW, EXPECT_TYPE, fun(), folly::makeFuture(), folly::makeFutureWith(), and folly::value().

1193  {
1195  EXPECT_EQ(42, makeFuture(42).value());
1196 
1197  EXPECT_TYPE(makeFuture<float>(42), Future<float>);
1198  EXPECT_EQ(42, makeFuture<float>(42).value());
1199 
1200  auto fun = [] { return 42; };
1203 
1204  auto funf = [] { return makeFuture<int>(43); };
1206  EXPECT_EQ(43, makeFutureWith(funf).value());
1207 
1208  auto failfun = []() -> int { throw eggs; };
1210  EXPECT_NO_THROW(makeFutureWith(failfun));
1211  EXPECT_THROW(makeFutureWith(failfun).value(), eggs_t);
1212 
1213  auto failfunf = []() -> Future<int> { throw eggs; };
1215  EXPECT_NO_THROW(makeFutureWith(failfunf));
1216  EXPECT_THROW(makeFutureWith(failfunf).value(), eggs_t);
1217 
1219 }
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static eggs_t eggs("eggs")
static const char *const value
Definition: Conv.cpp:50
void fun()
#define EXPECT_TYPE(x, T)
Definition: FutureTest.cpp:37
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
std::enable_if< isFuture< invoke_result_t< F > >::value, invoke_result_t< F > >::type makeFutureWith(F &&func)
Definition: Future-inl.h:1322
TEST ( Future  ,
finish   
)

Definition at line 1221 of file FutureTest.cpp.

References EXPECT_EQ, f, and folly::pushmi::detail::t.

1221  {
1222  auto x = std::make_shared<int>(0);
1223 
1224  Promise<int> p;
1225  auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
1226 
1227  // The callback hasn't executed
1228  EXPECT_EQ(0, *x);
1229 
1230  // The callback has a reference to x
1231  EXPECT_EQ(2, x.use_count());
1232 
1233  p.setValue(42);
1234 
1235  // the callback has executed
1236  EXPECT_EQ(42, *x);
1237 
1238  // the callback has been destructed
1239  // and has released its reference to x
1240  EXPECT_EQ(1, x.use_count());
1241 }
Definition: InvokeTest.cpp:58
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Definition: Try.h:51
TEST ( Future  ,
finishBigLambda   
)

Definition at line 1243 of file FutureTest.cpp.

References EXPECT_EQ, f, folly::Promise< T >::getFuture(), folly::Promise< T >::setValue(), and folly::pushmi::detail::t.

1243  {
1244  auto x = std::make_shared<int>(0);
1245 
1246  // bulk_data, to be captured in the lambda passed to Future::then.
1247  // This is meant to force that the lambda can't be stored inside
1248  // the Future object.
1249  std::array<char, sizeof(futures::detail::Core<int>)> bulk_data = {{0}};
1250 
1251  // suppress gcc warning about bulk_data not being used
1252  EXPECT_EQ(bulk_data[0], 0);
1253 
1254  Promise<int> p;
1255  auto f = p.getFuture().then([x, bulk_data](Try<int>&& t) {
1256  (void)bulk_data;
1257  *x = t.value();
1258  });
1259 
1260  // The callback hasn't executed
1261  EXPECT_EQ(0, *x);
1262 
1263  // The callback has a reference to x
1264  EXPECT_EQ(2, x.use_count());
1265 
1266  p.setValue(42);
1267 
1268  // the callback has executed
1269  EXPECT_EQ(42, *x);
1270 
1271  // the callback has been destructed
1272  // and has released its reference to x
1273  EXPECT_EQ(1, x.use_count());
1274 }
Definition: InvokeTest.cpp:58
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Future< T > getFuture()
Definition: Promise-inl.h:97
Definition: Try.h:51
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
TEST ( Future  ,
unwrap   
)

Definition at line 1276 of file FutureTest.cpp.

References a, b, EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, f, folly::Promise< T >::getFuture(), folly::futures::detail::FutureBase< T >::isReady(), folly::gen::move, folly::Promise< T >::setValue(), and folly::futures::detail::FutureBase< T >::value().

1276  {
1277  Promise<int> a;
1278  Promise<int> b;
1279 
1280  auto fa = a.getFuture();
1281  auto fb = b.getFuture();
1282 
1283  bool flag1 = false;
1284  bool flag2 = false;
1285 
1286  // do a, then do b, and get the result of a + b.
1287  Future<int> f = std::move(fa).then([&](Try<int>&& ta) {
1288  auto va = ta.value();
1289  flag1 = true;
1290  return std::move(fb).then([va, &flag2](Try<int>&& tb) {
1291  flag2 = true;
1292  return va + tb.value();
1293  });
1294  });
1295 
1296  EXPECT_FALSE(flag1);
1297  EXPECT_FALSE(flag2);
1298  EXPECT_FALSE(f.isReady());
1299 
1300  a.setValue(3);
1301  EXPECT_TRUE(flag1);
1302  EXPECT_FALSE(flag2);
1303  EXPECT_FALSE(f.isReady());
1304 
1305  b.setValue(4);
1306  EXPECT_TRUE(flag1);
1307  EXPECT_TRUE(flag2);
1308  EXPECT_EQ(7, f.value());
1309 }
auto f
char b
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Future< T > getFuture()
Definition: Promise-inl.h:97
char a
Definition: Try.h:51
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST ( Future  ,
throwCaughtInImmediateThen   
)

Definition at line 1311 of file FutureTest.cpp.

References folly::makeFuture().

1311  {
1312  // Neither of these should throw "Promise already satisfied"
1313  makeFuture().then([=](Try<Unit> &&) -> int { throw std::exception(); });
1314  makeFuture().then(
1315  [=](Try<Unit> &&) -> Future<int> { throw std::exception(); });
1316 }
Definition: Try.h:51
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
throwIfFailed   
)

Definition at line 1318 of file FutureTest.cpp.

References eggs, EXPECT_NO_THROW, EXPECT_THROW, folly::makeFuture(), and folly::pushmi::detail::t.

1318  {
1319  makeFuture<Unit>(eggs).then(
1320  [=](Try<Unit>&& t) { EXPECT_THROW(t.throwIfFailed(), eggs_t); });
1321  makeFuture().then([=](Try<Unit>&& t) { EXPECT_NO_THROW(t.throwIfFailed()); });
1322 
1323  makeFuture<int>(eggs).then(
1324  [=](Try<int>&& t) { EXPECT_THROW(t.throwIfFailed(), eggs_t); });
1325  makeFuture<int>(42).then(
1326  [=](Try<int>&& t) { EXPECT_NO_THROW(t.throwIfFailed()); });
1327 }
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
FutureException eggs_t
Definition: FutureTest.cpp:39
static eggs_t eggs("eggs")
Definition: Try.h:51
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
getFutureAfterSetValue   
)

Definition at line 1329 of file FutureTest.cpp.

References EXPECT_EQ, folly::Promise< T >::getFuture(), and folly::Promise< T >::setValue().

1329  {
1330  Promise<int> p;
1331  p.setValue(42);
1332  EXPECT_EQ(42, p.getFuture().value());
1333 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Future< T > getFuture()
Definition: Promise-inl.h:97
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
TEST ( Future  ,
getFutureAfterSetException   
)

Definition at line 1335 of file FutureTest.cpp.

References EXPECT_THROW, folly::Promise< T >::getFuture(), and folly::Promise< T >::setWith().

1335  {
1336  Promise<Unit> p;
1337  p.setWith([]() -> void { throw std::logic_error("foo"); });
1338  EXPECT_THROW(p.getFuture().value(), std::logic_error);
1339 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
void setWith(F &&func)
Definition: Promise-inl.h:137
Future< T > getFuture()
Definition: Promise-inl.h:97
TEST ( Future  ,
detachRace   
)

Definition at line 1341 of file FutureTest.cpp.

References f, and folly::Baton< MayBlock, Atom >::wait().

1341  {
1342  // Task #5438209
1343  // This test is designed to detect a race that was in Core::detachOne()
1344  // where detached_ was incremented and then tested, and that
1345  // allowed a race where both Promise and Future would think they were the
1346  // second and both try to delete. This showed up at scale but was very
1347  // difficult to reliably repro in a test. As it is, this only fails about
1348  // once in every 1,000 executions. Doing this 1,000 times is going to make a
1349  // slow test so I won't do that but if it ever fails, take it seriously, and
1350  // run the test binary with "--gtest_repeat=10000 --gtest_filter=*detachRace"
1351  // (Don't forget to enable ASAN)
1352  auto p = std::make_unique<Promise<bool>>();
1353  auto f = std::make_unique<Future<bool>>(p->getFuture());
1354  folly::Baton<> baton;
1355  std::thread t1([&] {
1356  baton.post();
1357  p.reset();
1358  });
1359  baton.wait();
1360  f.reset();
1361  t1.join();
1362 }
auto f
FOLLY_ALWAYS_INLINE void wait(const WaitOptions &opt=wait_options()) noexcept
Definition: Baton.h:170
TEST ( Future  ,
CircularDependencySharedPtrSelfReset   
)

Definition at line 1367 of file FutureTest.cpp.

References EXPECT_EQ, folly::Promise< T >::getFuture(), folly::gen::move, ptr, and folly::Promise< T >::setValue().

1367  {
1368  Promise<int64_t> promise;
1369  auto ptr = std::make_shared<Future<int64_t>>(promise.getFuture());
1370 
1371  std::move(*ptr).thenTry([ptr](folly::Try<int64_t>&& /* uid */) mutable {
1372  EXPECT_EQ(1, ptr.use_count());
1373 
1374  // Leaving no references to ourselves.
1375  ptr.reset();
1376  EXPECT_EQ(0, ptr.use_count());
1377  });
1378 
1379  EXPECT_EQ(2, ptr.use_count());
1380 
1381  ptr.reset();
1382 
1383  promise.setValue(1);
1384 }
void * ptr
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Future< T > getFuture()
Definition: Promise-inl.h:97
Definition: Try.h:51
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
TEST ( Future  ,
Constructor   
)

Definition at line 1386 of file FutureTest.cpp.

References EXPECT_EQ, EXPECT_NO_THROW, and folly::futures::detail::FutureBase< T >::value().

1386  {
1387  auto f1 = []() -> Future<int> { return Future<int>(3); }();
1388  EXPECT_EQ(f1.value(), 3);
1389  auto f2 = []() -> Future<Unit> { return Future<Unit>(); }();
1390  EXPECT_NO_THROW(f2.value());
1391 }
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
TEST ( Future  ,
ImplicitConstructor   
)

Definition at line 1393 of file FutureTest.cpp.

References EXPECT_EQ.

1393  {
1394  auto f1 = []() -> Future<int> { return 3; }();
1395  EXPECT_EQ(f1.value(), 3);
1396  // Unfortunately, the C++ standard does not allow the
1397  // following implicit conversion to work:
1398  // auto f2 = []() -> Future<Unit> { }();
1399 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
TEST ( Future  ,
InPlaceConstructor   
)

Definition at line 1401 of file FutureTest.cpp.

References EXPECT_EQ, f, and folly::in_place().

1401  {
1402  auto f = Future<std::pair<int, double>>(in_place, 5, 3.2);
1403  EXPECT_EQ(5, f.value().first);
1404 }
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
in_place_tag in_place(in_place_tag={})
Definition: Utility.h:235
TEST ( Future  ,
thenDynamic   
)

Definition at line 1406 of file FutureTest.cpp.

References folly::dynamic::asInt(), EXPECT_EQ, f, folly::Promise< T >::getFuture(), folly::gen::move, and folly::Promise< T >::setValue().

1406  {
1407  // folly::dynamic has a constructor that takes any T, this test makes
1408  // sure that we call the then lambda with folly::dynamic and not
1409  // Try<folly::dynamic> because that then fails to compile
1411  Future<folly::dynamic> f = p.getFuture().then(
1412  [](const folly::dynamic& d) { return folly::dynamic(d.asInt() + 3); });
1413  p.setValue(2);
1414  EXPECT_EQ(std::move(f).get(), 5);
1415 }
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Future< T > getFuture()
Definition: Promise-inl.h:97
int64_t asInt() const
Definition: dynamic-inl.h:524
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
TEST ( Future  ,
RequestContext   
)

Definition at line 1417 of file FutureTest.cpp.

References add, EXPECT_FALSE, EXPECT_TRUE, f, for_each(), folly::RequestContext::get(), folly::RequestContext::getContextData(), folly::Promise< T >::getFuture(), int8_t, folly::makeFuture(), folly::gen::move, folly::RequestContext::saveContext(), folly::RequestContext::setContextData(), folly::Promise< T >::setValue(), folly::pushmi::detail::t, uint8_t, and folly::value().

1417  {
1418  class NewThreadExecutor : public Executor {
1419  public:
1420  ~NewThreadExecutor() override {
1421  std::for_each(v_.begin(), v_.end(), [](std::thread& t) { t.join(); });
1422  }
1423  void add(Func f) override {
1424  if (throwsOnAdd_) {
1425  throw std::exception();
1426  }
1427  v_.emplace_back(std::move(f));
1428  }
1429  void addWithPriority(Func f, int8_t /* prio */) override {
1430  add(std::move(f));
1431  }
1432  uint8_t getNumPriorities() const override {
1433  return numPriorities_;
1434  }
1435 
1436  void setHandlesPriorities() {
1437  numPriorities_ = 2;
1438  }
1439  void setThrowsOnAdd() {
1440  throwsOnAdd_ = true;
1441  }
1442 
1443  private:
1444  std::vector<std::thread> v_;
1445  uint8_t numPriorities_ = 1;
1446  bool throwsOnAdd_ = false;
1447  };
1448 
1449  struct MyRequestData : RequestData {
1450  MyRequestData(bool value_ = false) : value(value_) {}
1451 
1452  bool hasCallback() override {
1453  return false;
1454  }
1455 
1456  bool value;
1457  };
1458 
1459  Promise<int> p1, p2;
1460  NewThreadExecutor e;
1461  {
1463  RequestContext::get()->setContextData(
1464  "key", std::make_unique<MyRequestData>(true));
1465  auto checker = [](int lineno) {
1466  return [lineno](Try<int>&& /* t */) {
1467  auto d = static_cast<MyRequestData*>(
1468  RequestContext::get()->getContextData("key"));
1469  EXPECT_TRUE(d && d->value) << "on line " << lineno;
1470  };
1471  };
1472 
1473  makeFuture(1).via(&e).then(checker(__LINE__));
1474 
1475  e.setHandlesPriorities();
1476  makeFuture(2).via(&e).then(checker(__LINE__));
1477 
1478  p1.getFuture().then(checker(__LINE__));
1479 
1480  e.setThrowsOnAdd();
1481  p2.getFuture().via(&e).then(checker(__LINE__));
1482  }
1483  // Assert that no RequestContext is set
1484  EXPECT_FALSE(RequestContext::saveContext());
1485  p1.setValue(3);
1486  p2.setValue(4);
1487 }
auto f
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
virtual void add(Func)=0
virtual uint8_t getNumPriorities() const
Definition: Executor.h:44
Function< void()> Func
Definition: Executor.h:27
virtual void addWithPriority(Func, int8_t priority)
Definition: Executor.cpp:25
Future< T > getFuture()
Definition: Promise-inl.h:97
static const char *const value
Definition: Conv.cpp:50
Definition: Try.h:51
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
void for_each(T const &range, Function< void(typename T::value_type const &) const > const &func)
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
PUSHMI_INLINE_VAR constexpr detail::get_fn< T > get
Definition: submit.h:391
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
makeFutureNoThrow   
)

Definition at line 1489 of file FutureTest.cpp.

References folly::makeFuture().

1489  {
1490  makeFuture().value();
1491 }
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( Future  ,
invokeCallbackReturningValueAsRvalue   
)

Definition at line 1493 of file FutureTest.cpp.

References EXPECT_EQ, folly::foo, and folly::value().

1493  {
1494  struct Foo {
1495  int operator()(int x) & {
1496  return x + 1;
1497  }
1498  int operator()(int x) const& {
1499  return x + 2;
1500  }
1501  int operator()(int x) && {
1502  return x + 3;
1503  }
1504  };
1505 
1506  Foo foo;
1507  Foo const cfoo;
1508 
1509  // The continuation will be forward-constructed - copied if given as & and
1510  // moved if given as && - everywhere construction is required.
1511  // The continuation will be invoked with the same cvref as it is passed.
1512  EXPECT_EQ(101, makeFuture<int>(100).then(foo).value());
1513  EXPECT_EQ(202, makeFuture<int>(200).then(cfoo).value());
1514  EXPECT_EQ(303, makeFuture<int>(300).then(Foo()).value());
1515 }
Definition: InvokeTest.cpp:58
Foo(std::atomic< int > &d)
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static const char *const value
Definition: Conv.cpp:50
TEST ( Future  ,
invokeCallbackReturningFutureAsRvalue   
)

Definition at line 1517 of file FutureTest.cpp.

References EXPECT_EQ, folly::foo, and folly::value().

1517  {
1518  struct Foo {
1519  Future<int> operator()(int x) & {
1520  return x + 1;
1521  }
1522  Future<int> operator()(int x) const& {
1523  return x + 2;
1524  }
1525  Future<int> operator()(int x) && {
1526  return x + 3;
1527  }
1528  };
1529 
1530  Foo foo;
1531  Foo const cfoo;
1532 
1533  // The continuation will be forward-constructed - copied if given as & and
1534  // moved if given as && - everywhere construction is required.
1535  // The continuation will be invoked with the same cvref as it is passed.
1536  EXPECT_EQ(101, makeFuture<int>(100).then(foo).value());
1537  EXPECT_EQ(202, makeFuture<int>(200).then(cfoo).value());
1538  EXPECT_EQ(303, makeFuture<int>(300).then(Foo()).value());
1539 
1540  EXPECT_EQ(101, makeFuture<int>(100).thenValue(foo).value());
1541  EXPECT_EQ(202, makeFuture<int>(200).thenValue(cfoo).value());
1542  EXPECT_EQ(303, makeFuture<int>(300).thenValue(Foo()).value());
1543 }
Definition: InvokeTest.cpp:58
Foo(std::atomic< int > &d)
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static const char *const value
Definition: Conv.cpp:50
TEST ( Future  ,
futureWithinCtxCleanedUpWhenTaskFinishedInTime   
)

Definition at line 1545 of file FutureTest.cpp.

References EXPECT_EQ, folly::Promise< T >::getFuture(), and folly::Promise< T >::setValue().

1545  {
1546  // Used to track the use_count of callbackInput even outside of its scope
1547  std::weak_ptr<int> target;
1548  {
1550  auto input = std::make_shared<int>(1);
1551  auto longEnough = std::chrono::milliseconds(1000);
1552 
1553  promise.getFuture()
1554  .within(longEnough)
1555  .then([&target](
1556  folly::Try<std::shared_ptr<int>>&& callbackInput) mutable {
1557  target = callbackInput.value();
1558  });
1559  promise.setValue(input);
1560  }
1561  // After promise's life cycle is finished, make sure no one is holding the
1562  // input anymore, in other words, ctx should have been cleaned up.
1563  EXPECT_EQ(0, target.use_count());
1564 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Future< T > getFuture()
Definition: Promise-inl.h:97
Definition: Try.h:51
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
TEST ( Future  ,
futureWithinNoValueReferenceWhenTimeOut   
)

Definition at line 1566 of file FutureTest.cpp.

References EXPECT_EQ, and folly::Promise< T >::getFuture().

1566  {
1568  auto veryShort = std::chrono::milliseconds(1);
1569 
1570  promise.getFuture().within(veryShort).then(
1571  [](folly::Try<std::shared_ptr<int>>&& callbackInput) {
1572  // Timeout is fired. Verify callbackInput is not referenced
1573  EXPECT_EQ(0, callbackInput.value().use_count());
1574  });
1575 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Future< T > getFuture()
Definition: Promise-inl.h:97
Definition: Try.h:51
TEST ( Future  ,
makePromiseContract   
)

Definition at line 1577 of file FutureTest.cpp.

References testing::_, add, ASSERT_TRUE, c, folly::ManualExecutor::drain(), EXPECT_EQ, EXPECT_FALSE, f, and folly::gen::move.

1577  {
1578  class ManualExecutor : public Executor {
1579  private:
1580  std::queue<Func> queue_;
1581 
1582  public:
1583  void add(Func f) override {
1584  queue_.push(std::move(f));
1585  }
1586  void drain() {
1587  while (!queue_.empty()) {
1588  auto f = std::move(queue_.front());
1589  queue_.pop();
1590  f();
1591  }
1592  }
1593  };
1594 
1595  ManualExecutor e;
1596  auto c = makePromiseContract<int>(&e);
1597  c.second = std::move(c.second).then([](int _) { return _ + 1; });
1598  EXPECT_FALSE(c.second.isReady());
1599  c.first.setValue(3);
1600  EXPECT_FALSE(c.second.isReady());
1601  e.drain();
1602  ASSERT_TRUE(c.second.isReady());
1603  EXPECT_EQ(4, std::move(c.second).get());
1604 }
auto f
auto add
Definition: BaseTest.cpp:70
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Function< void()> Func
Definition: Executor.h:27
const internal::AnythingMatcher _
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
char c
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
TEST ( Future  ,
ThenRecursion   
)

Definition at line 1622 of file FutureTest.cpp.

References folly::pushmi::executor, EXPECT_EQ, and recursion().

1622  {
1624 
1625  EXPECT_EQ(42, recursion(&executor, 100000).getVia(&executor));
1626 }
Future< int > recursion(Executor *executor, int depth)
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor

Variable Documentation

eggs_t eggs("eggs")
static

Referenced by TEST().