proxygen
SemiFutureTest.cpp File Reference
#include <folly/Executor.h>
#include <folly/Memory.h>
#include <folly/Unit.h>
#include <folly/dynamic.h>
#include <folly/executors/ManualExecutor.h>
#include <folly/futures/Future.h>
#include <folly/io/async/EventBase.h>
#include <folly/portability/GTest.h>
#include <folly/synchronization/Baton.h>
#include <algorithm>
#include <atomic>
#include <future>
#include <memory>
#include <numeric>
#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()
 

Typedefs

typedef FutureException eggs_t
 

Functions

 TEST (SemiFuture, makeEmpty)
 
 TEST (SemiFuture, futureDefaultCtor)
 
 TEST (SemiFuture, makeSemiFutureWithUnit)
 
 TEST (SemiFuture, ctorPostconditionValid)
 
 TEST (SemiFuture, ctorPostconditionInvalid)
 
 TEST (SemiFuture, lacksPreconditionValid)
 
 TEST (SemiFuture, hasPreconditionValid)
 
 TEST (SemiFuture, hasPostconditionValid)
 
 TEST (SemiFuture, hasPostconditionInvalid)
 
 TEST (SemiFuture, special)
 
 TEST (SemiFuture, value)
 
 TEST (SemiFuture, hasException)
 
 TEST (SemiFuture, hasValue)
 
 TEST (SemiFuture, makeSemiFuture)
 
 TEST (SemiFuture, Constructor)
 
 TEST (SemiFuture, ImplicitConstructor)
 
 TEST (SemiFuture, InPlaceConstructor)
 
 TEST (SemiFuture, makeSemiFutureNoThrow)
 
 TEST (SemiFuture, ViaThrowOnNull)
 
 TEST (SemiFuture, ConstructSemiFutureFromEmptyFuture)
 
 TEST (SemiFuture, ConstructSemiFutureFromFutureDefaultCtor)
 
 TEST (SemiFuture, MakeSemiFutureFromFutureWithUnit)
 
 TEST (SemiFuture, MakeSemiFutureFromFutureWithValue)
 
 TEST (SemiFuture, MakeSemiFutureFromReadyFuture)
 
 TEST (SemiFuture, MakeSemiFutureFromNotReadyFuture)
 
 TEST (SemiFuture, MakeFutureFromSemiFuture)
 
 TEST (SemiFuture, MakeFutureFromSemiFutureReturnFuture)
 
 TEST (SemiFuture, MakeFutureFromSemiFutureReturnSemiFuture)
 
 TEST (SemiFuture, MakeFutureFromSemiFutureLValue)
 
 TEST (SemiFuture, SimpleGet)
 
 TEST (SemiFuture, SimpleGetTry)
 
 TEST (SemiFuture, SimpleTimedGet)
 
 TEST (SemiFuture, SimpleTimedGetViaFromSemiFuture)
 
 TEST (SemiFuture, SimpleTimedGetTry)
 
 TEST (SemiFuture, SimpleTimedGetTryViaFromSemiFuture)
 
 TEST (SemiFuture, SimpleValue)
 
 TEST (SemiFuture, SimpleValueThrow)
 
 TEST (SemiFuture, SimpleResult)
 
 TEST (SemiFuture, SimpleResultThrow)
 
 TEST (SemiFuture, SimpleDefer)
 
 TEST (SemiFuture, DeferWithDelayedSetValue)
 
 TEST (SemiFuture, DeferWithViaAndDelayedSetValue)
 
 TEST (SemiFuture, DeferWithGetTimedGet)
 
 TEST (SemiFuture, DeferWithVia)
 
 TEST (SemiFuture, ChainingDefertoThen)
 
 TEST (SemiFuture, SimpleDeferWithValue)
 
 TEST (SemiFuture, SimpleDeferWithValueFunctionReference)
 
 TEST (SemiFuture, ChainingDefertoThenWithValue)
 
 TEST (SemiFuture, MakeSemiFutureFromFutureWithTry)
 
 TEST (SemiFuture, DeferWithinContinuation)
 
 TEST (SemiFuture, onError)
 
 TEST (SemiFuture, makePromiseContract)
 
 TEST (SemiFuture, invokeCallbackWithOriginalCVRef)
 
 TEST (SemiFuture, semiFutureWithinCtxCleanedUpWhenTaskFinishedInTime)
 
 TEST (SemiFuture, semiFutureWithinNoValueReferenceWhenTimeOut)
 
 TEST (SemiFuture, collectAllSemiFutureDeferredWork)
 
 TEST (SemiFuture, DeferWithNestedSemiFuture)
 

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_NO_FLAG ( )
Value:
do { \
EXPECT_FALSE(theFlag); \
theFlag = false; \
} while (0);
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862

Referenced by TEST().

#define EXPECT_TYPE (   x,
  T 
)    EXPECT_TRUE((std::is_same<decltype(x), T>::value))

Definition at line 37 of file SemiFutureTest.cpp.

Referenced by TEST().

Typedef Documentation

Definition at line 39 of file SemiFutureTest.cpp.

Function Documentation

TEST ( SemiFuture  ,
makeEmpty   
)

Definition at line 44 of file SemiFutureTest.cpp.

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

44  {
46  EXPECT_THROW(f.isReady(), FutureInvalid);
47 }
auto f
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
TEST ( SemiFuture  ,
futureDefaultCtor   
)

Definition at line 49 of file SemiFutureTest.cpp.

49  {
51 }
TEST ( SemiFuture  ,
makeSemiFutureWithUnit   
)

Definition at line 53 of file SemiFutureTest.cpp.

References count, EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, folly::SemiFuture< T >::makeEmpty(), and folly::makeSemiFutureWith().

53  {
54  int count = 0;
55  SemiFuture<Unit> fu = makeSemiFutureWith([&] { count++; });
56  EXPECT_EQ(1, count);
57 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::enable_if< isFutureOrSemiFuture< invoke_result_t< F > >::value, SemiFuture< typename invoke_result_t< F >::value_type > >::type makeSemiFutureWith(F &&func)
Definition: Future-inl.h:721
int * count
TEST ( SemiFuture  ,
ctorPostconditionValid   
)

Definition at line 72 of file SemiFutureTest.cpp.

References DOIT, and folly::makeSemiFuture().

72  {
73  // Ctors/factories that promise valid -- postcondition: valid()
74 
75 #define DOIT(CREATION_EXPR) \
76  do { \
77  auto f1 = (CREATION_EXPR); \
78  EXPECT_TRUE(f1.valid()); \
79  auto f2 = std::move(f1); \
80  EXPECT_FALSE(f1.valid()); \
81  EXPECT_TRUE(f2.valid()); \
82  } while (false)
83 
84  auto const except = std::logic_error("foo");
85  auto const ewrap = folly::exception_wrapper(except);
86 
87  DOIT(makeValid());
88  DOIT(SemiFuture<int>(42));
89  DOIT(SemiFuture<int>{42});
94  DOIT(makeSemiFuture<Unit>(Unit{}));
95  DOIT(makeSemiFuture(42));
96  DOIT(makeSemiFuture<int>(42));
97  DOIT(makeSemiFuture<int>(except));
98  DOIT(makeSemiFuture<int>(ewrap));
100  DOIT(makeSemiFuture<int>(Try<int>(42)));
101  DOIT(makeSemiFuture<int>(Try<int>(ewrap)));
102 
103 #undef DOIT
104 }
#define DOIT(CREATION_EXPR)
Definition: Try.h:51
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)
Definition: Future-inl.h:712
TEST ( SemiFuture  ,
ctorPostconditionInvalid   
)

Definition at line 106 of file SemiFutureTest.cpp.

References DOIT.

106  {
107  // Ctors/factories that promise invalid -- postcondition: !valid()
108 
109 #define DOIT(CREATION_EXPR) \
110  do { \
111  auto f1 = (CREATION_EXPR); \
112  EXPECT_FALSE(f1.valid()); \
113  auto f2 = std::move(f1); \
114  EXPECT_FALSE(f1.valid()); \
115  EXPECT_FALSE(f2.valid()); \
116  } while (false)
117 
118  DOIT(makeInvalid());
120 
121 #undef DOIT
122 }
#define DOIT(CREATION_EXPR)
TEST ( SemiFuture  ,
lacksPreconditionValid   
)

Definition at line 124 of file SemiFutureTest.cpp.

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

124  {
125  // Ops that don't throw FutureInvalid if !valid() --
126  // without precondition: valid()
127 
128 #define DOIT(STMT) \
129  do { \
130  auto f = makeValid(); \
131  { STMT; } \
132  copy(std::move(f)); \
133  EXPECT_NO_THROW(STMT); \
134  } while (false)
135 
136  // .valid() itself
137  DOIT(f.valid());
138 
139  // move-ctor - move-copy to local, copy(), pass-by-move-value
140  DOIT(auto other = std::move(f));
141  DOIT(copy(std::move(f)));
142  DOIT(([](auto) {})(std::move(f)));
143 
144  // move-assignment into either {valid | invalid}
145  DOIT({
146  auto other = makeValid();
147  other = std::move(f);
148  });
149  DOIT({
150  auto other = makeInvalid();
151  other = std::move(f);
152  });
153 
154 #undef DOIT
155 }
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
#define DOIT(CREATION_EXPR)
TEST ( SemiFuture  ,
hasPreconditionValid   
)

Definition at line 157 of file SemiFutureTest.cpp.

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

157  {
158  // Ops that require validity; precondition: valid();
159  // throw FutureInvalid if !valid()
160 
161 #define DOIT(STMT) \
162  do { \
163  auto f = makeValid(); \
164  EXPECT_NO_THROW(STMT); \
165  copy(std::move(f)); \
166  EXPECT_THROW(STMT, FutureInvalid); \
167  } while (false)
168 
169  DOIT(f.isReady());
170  DOIT(f.result());
171  DOIT(std::move(f).getTry());
172  DOIT(f.hasValue());
173  DOIT(f.hasException());
174  DOIT(f.value());
175 
176 #undef DOIT
177 }
auto f
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define DOIT(CREATION_EXPR)
TEST ( SemiFuture  ,
hasPostconditionValid   
)

Definition at line 179 of file SemiFutureTest.cpp.

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

179  {
180  // Ops that preserve validity -- postcondition: valid()
181 
182 #define DOIT(STMT) \
183  do { \
184  auto f = makeValid(); \
185  EXPECT_NO_THROW(STMT); \
186  EXPECT_TRUE(f.valid()); \
187  } while (false)
188 
189  auto const swallow = [](auto) {};
190 
191  DOIT(swallow(f.valid())); // f.valid() itself preserves validity
192  DOIT(swallow(f.isReady()));
193  DOIT(swallow(f.hasValue()));
194  DOIT(swallow(f.hasException()));
195  DOIT(swallow(f.value()));
196  DOIT(swallow(f.poll()));
197  DOIT(f.raise(std::logic_error("foo")));
198  DOIT(f.cancel());
199  DOIT(f.wait());
200  DOIT(std::move(f.wait()));
201 
202 #undef DOIT
203 }
auto f
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define DOIT(CREATION_EXPR)
TEST ( SemiFuture  ,
hasPostconditionInvalid   
)

Definition at line 205 of file SemiFutureTest.cpp.

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

205  {
206  // Ops that consume *this -- postcondition: !valid()
207 
208 #define DOIT(CTOR, STMT) \
209  do { \
210  auto f = (CTOR); \
211  EXPECT_NO_THROW(STMT); \
212  EXPECT_FALSE(f.valid()); \
213  } while (false)
214 
215  // move-ctor of {valid|invalid}
216  DOIT(makeValid(), { auto other{std::move(f)}; });
217  DOIT(makeInvalid(), { auto other{std::move(f)}; });
218 
219  // move-assignment of {valid|invalid} into {valid|invalid}
220  DOIT(makeValid(), {
221  auto other = makeValid();
222  other = std::move(f);
223  });
224  DOIT(makeValid(), {
225  auto other = makeInvalid();
226  other = std::move(f);
227  });
228  DOIT(makeInvalid(), {
229  auto other = makeValid();
230  other = std::move(f);
231  });
232  DOIT(makeInvalid(), {
233  auto other = makeInvalid();
234  other = std::move(f);
235  });
236 
237  // pass-by-value of {valid|invalid}
238  DOIT(makeValid(), {
239  auto const byval = [](auto) {};
240  byval(std::move(f));
241  });
242  DOIT(makeInvalid(), {
243  auto const byval = [](auto) {};
244  byval(std::move(f));
245  });
246 
247  // other consuming ops
248  auto const swallow = [](auto) {};
249  DOIT(makeValid(), swallow(std::move(f).get()));
250  DOIT(makeValid(), swallow(std::move(f).getTry()));
251  DOIT(makeValid(), swallow(std::move(f).wait()));
252  DOIT(makeValid(), swallow(std::move(f.wait())));
253 
254 #undef DOIT
255 }
auto f
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define DOIT(CREATION_EXPR)
bool wait(Waiter *waiter, bool shouldSleep, Waiter *&next)
TEST ( SemiFuture  ,
special   
)

Definition at line 266 of file SemiFutureTest.cpp.

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

266  {
267  EXPECT_FALSE(std::is_copy_constructible<SemiFuture<int>>::value);
268  EXPECT_FALSE(std::is_copy_assignable<SemiFuture<int>>::value);
269  EXPECT_TRUE(std::is_move_constructible<SemiFuture<int>>::value);
270  EXPECT_TRUE(std::is_move_assignable<SemiFuture<int>>::value);
271 }
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 ( SemiFuture  ,
value   
)

Definition at line 273 of file SemiFutureTest.cpp.

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

273  {
274  auto f = makeSemiFuture(std::make_unique<int>(42));
275  auto up = std::move(f.value());
276  EXPECT_EQ(42, *up);
277 
278  EXPECT_THROW(makeSemiFuture<int>(eggs).value(), eggs_t);
279 
280  EXPECT_TYPE(std::declval<SemiFuture<int>&>().value(), int&);
281  EXPECT_TYPE(std::declval<SemiFuture<int> const&>().value(), int const&);
282  EXPECT_TYPE(std::declval<SemiFuture<int>&&>().value(), int&&);
283  EXPECT_TYPE(std::declval<SemiFuture<int> const&&>().value(), int const&&);
284 }
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
#define EXPECT_TYPE(x, T)
static const char *const value
Definition: Conv.cpp:50
static eggs_t eggs("eggs")
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)
Definition: Future-inl.h:712
TEST ( SemiFuture  ,
hasException   
)

Definition at line 286 of file SemiFutureTest.cpp.

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

286  {
287  EXPECT_TRUE(makeSemiFuture<int>(eggs).getTry().hasException());
288  EXPECT_FALSE(makeSemiFuture(42).getTry().hasException());
289 }
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
static eggs_t eggs("eggs")
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)
Definition: Future-inl.h:712
TEST ( SemiFuture  ,
hasValue   
)

Definition at line 291 of file SemiFutureTest.cpp.

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

291  {
292  EXPECT_TRUE(makeSemiFuture(42).getTry().hasValue());
293  EXPECT_FALSE(makeSemiFuture<int>(eggs).getTry().hasValue());
294 }
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
static eggs_t eggs("eggs")
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)
Definition: Future-inl.h:712
TEST ( SemiFuture  ,
makeSemiFuture   
)

Definition at line 296 of file SemiFutureTest.cpp.

References eggs, EXPECT_EQ, EXPECT_NO_THROW, EXPECT_THROW, EXPECT_TYPE, fun(), folly::makeSemiFuture(), folly::makeSemiFutureWith(), and folly::value().

296  {
298  EXPECT_EQ(42, makeSemiFuture(42).value());
299 
300  EXPECT_TYPE(makeSemiFuture<float>(42), SemiFuture<float>);
301  EXPECT_EQ(42, makeSemiFuture<float>(42).value());
302 
303  auto fun = [] { return 42; };
306 
307  auto funf = [] { return makeSemiFuture<int>(43); };
309  EXPECT_EQ(43, makeSemiFutureWith(funf).value());
310 
311  auto failfun = []() -> int { throw eggs; };
315 
316  auto failfunf = []() -> SemiFuture<int> { throw eggs; };
320 
321  auto futurefun = [] { return makeFuture<int>(44); };
323  EXPECT_EQ(44, makeSemiFutureWith(futurefun).value());
324 
326 }
#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
std::enable_if< isFutureOrSemiFuture< invoke_result_t< F > >::value, SemiFuture< typename invoke_result_t< F >::value_type > >::type makeSemiFutureWith(F &&func)
Definition: Future-inl.h:721
#define EXPECT_TYPE(x, T)
static const char *const value
Definition: Conv.cpp:50
void fun()
static eggs_t eggs("eggs")
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)
Definition: Future-inl.h:712
TEST ( SemiFuture  ,
Constructor   
)

Definition at line 328 of file SemiFutureTest.cpp.

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

328  {
329  auto f1 = []() -> SemiFuture<int> { return SemiFuture<int>(3); }();
330  EXPECT_EQ(f1.value(), 3);
331  auto f2 = []() -> SemiFuture<Unit> { return SemiFuture<Unit>(); }();
332  EXPECT_NO_THROW(f2.value());
333 }
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
TEST ( SemiFuture  ,
ImplicitConstructor   
)

Definition at line 335 of file SemiFutureTest.cpp.

References EXPECT_EQ.

335  {
336  auto f1 = []() -> SemiFuture<int> { return 3; }();
337  EXPECT_EQ(f1.value(), 3);
338 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
TEST ( SemiFuture  ,
InPlaceConstructor   
)

Definition at line 340 of file SemiFutureTest.cpp.

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

340  {
342  EXPECT_EQ(5, f.value().first);
343 }
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
in_place_tag in_place(in_place_tag={})
Definition: Utility.h:235
TEST ( SemiFuture  ,
makeSemiFutureNoThrow   
)

Definition at line 345 of file SemiFutureTest.cpp.

References folly::makeSemiFuture().

345  {
346  makeSemiFuture().value();
347 }
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)
Definition: Future-inl.h:712
TEST ( SemiFuture  ,
ViaThrowOnNull   
)

Definition at line 349 of file SemiFutureTest.cpp.

References EXPECT_THROW, folly::makeSemiFuture(), and folly::via().

349  {
351 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
PUSHMI_INLINE_VAR constexpr detail::via_fn via
Definition: via.h:166
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)
Definition: Future-inl.h:712
TEST ( SemiFuture  ,
ConstructSemiFutureFromEmptyFuture   
)

Definition at line 353 of file SemiFutureTest.cpp.

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

353  {
355  EXPECT_THROW(f.isReady(), FutureInvalid);
356 }
auto f
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
TEST ( SemiFuture  ,
ConstructSemiFutureFromFutureDefaultCtor   
)

Definition at line 358 of file SemiFutureTest.cpp.

TEST ( SemiFuture  ,
MakeSemiFutureFromFutureWithUnit   
)

Definition at line 362 of file SemiFutureTest.cpp.

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

362  {
363  int count = 0;
364  SemiFuture<Unit> fu = SemiFuture<Unit>{makeFutureWith([&] { count++; })};
365  EXPECT_EQ(1, count);
366 }
#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 ( SemiFuture  ,
MakeSemiFutureFromFutureWithValue   
)

Definition at line 368 of file SemiFutureTest.cpp.

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

368  {
369  auto f =
370  SemiFuture<std::unique_ptr<int>>{makeFuture(std::make_unique<int>(42))};
371  auto up = std::move(f.value());
372  EXPECT_EQ(42, *up);
373 }
auto f
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( SemiFuture  ,
MakeSemiFutureFromReadyFuture   
)

Definition at line 375 of file SemiFutureTest.cpp.

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

375  {
376  Promise<int> p;
377  auto f = p.getSemiFuture();
378  EXPECT_FALSE(f.isReady());
379  p.setValue(42);
380  EXPECT_TRUE(f.isReady());
381 }
auto f
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST ( SemiFuture  ,
MakeSemiFutureFromNotReadyFuture   
)

Definition at line 383 of file SemiFutureTest.cpp.

References EXPECT_THROW, f, and folly::Promise< T >::getSemiFuture().

383  {
384  Promise<int> p;
385  auto f = p.getSemiFuture();
386  EXPECT_THROW(f.value(), eggs_t);
387 }
auto f
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
FutureException eggs_t
TEST ( SemiFuture  ,
MakeFutureFromSemiFuture   
)

Definition at line 389 of file SemiFutureTest.cpp.

References ASSERT_EQ, EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, f, folly::Promise< T >::getSemiFuture(), folly::EventBase::loopOnce(), folly::gen::move, folly::Promise< T >::setValue(), and folly::value().

389  {
391  Promise<int> p;
392  std::atomic<int> result{0};
393  auto f = p.getSemiFuture();
394  auto future = std::move(f).via(&e).then([&](int value) {
395  result = value;
396  return value;
397  });
398  e.loopOnce();
399  EXPECT_EQ(result, 0);
400  EXPECT_FALSE(future.isReady());
401  p.setValue(42);
402  e.loopOnce();
403  EXPECT_TRUE(future.isReady());
404  ASSERT_EQ(future.value(), 42);
405  ASSERT_EQ(result, 42);
406 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
bool loopOnce(int flags=0)
Definition: EventBase.cpp:271
static const char *const value
Definition: Conv.cpp:50
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST ( SemiFuture  ,
MakeFutureFromSemiFutureReturnFuture   
)

Definition at line 408 of file SemiFutureTest.cpp.

References ASSERT_EQ, EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, f, folly::Promise< T >::getSemiFuture(), folly::EventBase::loopOnce(), folly::makeFuture(), folly::gen::move, folly::Promise< T >::setValue(), and folly::value().

408  {
410  Promise<int> p;
411  int result{0};
412  auto f = p.getSemiFuture();
413  auto future = std::move(f).via(&e).then([&](int value) {
414  result = value;
415  return folly::makeFuture(std::move(value));
416  });
417  e.loopOnce();
418  EXPECT_EQ(result, 0);
419  EXPECT_FALSE(future.isReady());
420  p.setValue(42);
421  e.loopOnce();
422  EXPECT_TRUE(future.isReady());
423  ASSERT_EQ(future.value(), 42);
424  ASSERT_EQ(result, 42);
425 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
bool loopOnce(int flags=0)
Definition: EventBase.cpp:271
static const char *const value
Definition: Conv.cpp:50
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
TEST ( SemiFuture  ,
MakeFutureFromSemiFutureReturnSemiFuture   
)

Definition at line 427 of file SemiFutureTest.cpp.

References ASSERT_EQ, EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, f, folly::Promise< T >::getSemiFuture(), folly::EventBase::loopOnce(), folly::makeSemiFuture(), folly::gen::move, folly::Promise< T >::setValue(), and folly::value().

427  {
429  Promise<int> p;
430  int result{0};
431  auto f = p.getSemiFuture();
432  auto future = std::move(f)
433  .via(&e)
434  .then([&](int value) {
435  result = value;
436  return folly::makeSemiFuture(std::move(value));
437  })
438  .then([&](int value) {
439  return folly::makeSemiFuture(std::move(value));
440  });
441  e.loopOnce();
442  EXPECT_EQ(result, 0);
443  EXPECT_FALSE(future.isReady());
444  p.setValue(42);
445  e.loopOnce();
446  e.loopOnce();
447  EXPECT_TRUE(future.isReady());
448  ASSERT_EQ(future.value(), 42);
449  ASSERT_EQ(result, 42);
450 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
bool loopOnce(int flags=0)
Definition: EventBase.cpp:271
static const char *const value
Definition: Conv.cpp:50
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)
Definition: Future-inl.h:712
TEST ( SemiFuture  ,
MakeFutureFromSemiFutureLValue   
)

Definition at line 452 of file SemiFutureTest.cpp.

References ASSERT_EQ, EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, f, folly::Promise< T >::getSemiFuture(), folly::EventBase::loopOnce(), folly::gen::move, folly::Promise< T >::setValue(), and folly::value().

452  {
454  Promise<int> p;
455  std::atomic<int> result{0};
456  auto f = p.getSemiFuture();
457  auto future = std::move(f).via(&e).then([&](int value) {
458  result = value;
459  return value;
460  });
461  e.loopOnce();
462  EXPECT_EQ(result, 0);
463  EXPECT_FALSE(future.isReady());
464  p.setValue(42);
465  e.loopOnce();
466  EXPECT_TRUE(future.isReady());
467  ASSERT_EQ(future.value(), 42);
468  ASSERT_EQ(result, 42);
469 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
bool loopOnce(int flags=0)
Definition: EventBase.cpp:271
static const char *const value
Definition: Conv.cpp:50
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST ( SemiFuture  ,
SimpleGet   
)

Definition at line 471 of file SemiFutureTest.cpp.

References ASSERT_EQ, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

471  {
472  EventBase e2;
473  Promise<int> p;
474  auto sf = p.getSemiFuture();
475  p.setValue(3);
476  auto v = std::move(sf).get();
477  ASSERT_EQ(v, 3);
478 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleGetTry   
)

Definition at line 480 of file SemiFutureTest.cpp.

References ASSERT_EQ, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

480  {
481  EventBase e2;
482  Promise<int> p;
483  auto sf = p.getSemiFuture();
484  p.setValue(3);
485  auto v = std::move(sf).getTry();
486  ASSERT_EQ(v.value(), 3);
487 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleTimedGet   
)

Definition at line 489 of file SemiFutureTest.cpp.

References EXPECT_THROW, folly::Promise< T >::getSemiFuture(), and folly::gen::move.

489  {
491  auto sf = p.getSemiFuture();
492  EXPECT_THROW(
493  std::move(sf).get(std::chrono::milliseconds(100)), FutureTimeout);
494 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleTimedGetViaFromSemiFuture   
)

Definition at line 496 of file SemiFutureTest.cpp.

References EXPECT_THROW, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::via().

496  {
499  auto sf = p.getSemiFuture();
500  EXPECT_THROW(
501  std::move(sf).via(&e2).getVia(&e2, std::chrono::milliseconds(100)),
502  FutureTimeout);
503 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
PUSHMI_INLINE_VAR constexpr detail::via_fn via
Definition: via.h:166
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleTimedGetTry   
)

Definition at line 505 of file SemiFutureTest.cpp.

References EXPECT_THROW, folly::Promise< T >::getSemiFuture(), and folly::gen::move.

505  {
507  auto sf = p.getSemiFuture();
508  EXPECT_THROW(
509  std::move(sf).getTry(std::chrono::milliseconds(100)), FutureTimeout);
510 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleTimedGetTryViaFromSemiFuture   
)

Definition at line 512 of file SemiFutureTest.cpp.

References EXPECT_THROW, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::via().

512  {
515  auto sf = p.getSemiFuture();
516  EXPECT_THROW(
517  std::move(sf).via(&e2).getTryVia(&e2, std::chrono::milliseconds(100)),
518  FutureTimeout);
519 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
PUSHMI_INLINE_VAR constexpr detail::via_fn via
Definition: via.h:166
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleValue   
)

Definition at line 521 of file SemiFutureTest.cpp.

References ASSERT_EQ, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

521  {
522  Promise<int> p;
523  auto sf = p.getSemiFuture();
524  p.setValue(3);
525  auto v = std::move(sf).value();
526  ASSERT_EQ(v, 3);
527 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleValueThrow   
)

Definition at line 529 of file SemiFutureTest.cpp.

References EXPECT_THROW, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::value().

529  {
531  auto sf = p.getSemiFuture();
533 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static const char *const value
Definition: Conv.cpp:50
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleResult   
)

Definition at line 535 of file SemiFutureTest.cpp.

References ASSERT_EQ, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

535  {
536  EventBase e2;
537  Promise<int> p;
538  auto sf = p.getSemiFuture();
539  p.setValue(3);
540  auto v = std::move(sf).result();
541  ASSERT_EQ(v.value(), 3);
542 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleResultThrow   
)

Definition at line 544 of file SemiFutureTest.cpp.

References EXPECT_THROW, folly::Promise< T >::getSemiFuture(), and folly::gen::move.

544  {
545  EventBase e2;
547  auto sf = p.getSemiFuture();
548  EXPECT_THROW(std::move(sf).result(), FutureNotReady);
549 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleDefer   
)

Definition at line 551 of file SemiFutureTest.cpp.

References ASSERT_EQ, f, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

551  {
552  std::atomic<int> innerResult{0};
554  auto f = p.getSemiFuture().toUnsafeFuture();
555  auto sf = std::move(f).semi().defer([&](auto&&) { innerResult = 17; });
556  p.setValue();
557  // Run "F" here inline in the calling thread
558  std::move(sf).get();
559  ASSERT_EQ(innerResult, 17);
560 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
DeferWithDelayedSetValue   
)

Definition at line 562 of file SemiFutureTest.cpp.

References ASSERT_EQ, folly::async(), f, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

562  {
563  EventBase e2;
565  auto f = p.getSemiFuture().toUnsafeFuture();
566  auto sf = std::move(f).semi().defer([&](auto&&) { return 17; });
567 
568  // Start thread and have it blocking in the semifuture before we satisfy the
569  // promise
570  auto resultF =
571  std::async(std::launch::async, [&]() { return std::move(sf).get(); });
572 
573  // Check that future is not already satisfied before setting the promise
574  // Async task should be blocked on sf.
575  ASSERT_EQ(
576  resultF.wait_for(std::chrono::milliseconds(100)),
577  std::future_status::timeout);
578  p.setValue();
579  ASSERT_EQ(resultF.get(), 17);
580 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
auto async(F &&fn)
Definition: Async.h:24
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
DeferWithViaAndDelayedSetValue   
)

Definition at line 582 of file SemiFutureTest.cpp.

References ASSERT_EQ, folly::async(), f, folly::Promise< T >::getSemiFuture(), folly::EventBase::loopForever(), folly::gen::move, folly::Promise< T >::setValue(), folly::pushmi::detail::t, folly::EventBase::terminateLoopSoon(), and folly::via().

582  {
583  EventBase e2;
585  auto f = p.getSemiFuture().toUnsafeFuture();
586  auto sf = std::move(f).semi().defer([&](auto&&) { return 17; }).via(&e2);
587  // Start thread and have it blocking in the semifuture before we satisfy the
588  // promise.
589  auto resultF =
590  std::async(std::launch::async, [&]() { return std::move(sf).get(); });
591  std::thread t([&]() { e2.loopForever(); });
592  // Check that future is not already satisfied before setting the promise
593  // Async task should be blocked on sf.
594  ASSERT_EQ(
595  resultF.wait_for(std::chrono::milliseconds(100)),
596  std::future_status::timeout);
597  p.setValue();
598  e2.terminateLoopSoon();
599  t.join();
600  ASSERT_EQ(resultF.get(), 17);
601 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
auto async(F &&fn)
Definition: Async.h:24
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
PUSHMI_INLINE_VAR constexpr detail::via_fn via
Definition: via.h:166
void terminateLoopSoon()
Definition: EventBase.cpp:493
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
DeferWithGetTimedGet   
)

Definition at line 603 of file SemiFutureTest.cpp.

References ASSERT_EQ, EXPECT_THROW, f, folly::Promise< T >::getSemiFuture(), and folly::gen::move.

603  {
604  std::atomic<int> innerResult{0};
606  auto f = p.getSemiFuture().toUnsafeFuture();
607  auto sf = std::move(f).semi().defer([&](auto&&) { innerResult = 17; });
608  EXPECT_THROW(
609  std::move(sf).get(std::chrono::milliseconds(100)), FutureTimeout);
610  ASSERT_EQ(innerResult, 0);
611 }
auto f
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
DeferWithVia   
)

Definition at line 613 of file SemiFutureTest.cpp.

References ASSERT_EQ, f, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

613  {
614  std::atomic<int> innerResult{0};
615  EventBase e2;
617  auto f = p.getSemiFuture().toUnsafeFuture();
618  auto sf = std::move(f).semi().defer([&](auto&&) { innerResult = 17; });
619  // Run "F" here inline in the calling thread
620  auto tf = std::move(sf).via(&e2);
621  p.setValue();
622  tf.getVia(&e2);
623  ASSERT_EQ(innerResult, 17);
624 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
ChainingDefertoThen   
)

Definition at line 626 of file SemiFutureTest.cpp.

References ASSERT_EQ, f, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

626  {
627  std::atomic<int> innerResult{0};
628  std::atomic<int> result{0};
629  EventBase e2;
631  auto f = p.getSemiFuture().toUnsafeFuture();
632  auto sf = std::move(f).semi().defer([&](auto&&) { innerResult = 17; });
633  // Run "F" here inline in a task running on the eventbase
634  auto tf = std::move(sf).via(&e2).thenValue([&](auto&&) { result = 42; });
635  p.setValue();
636  tf.getVia(&e2);
637  ASSERT_EQ(innerResult, 17);
638  ASSERT_EQ(result, 42);
639 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleDeferWithValue   
)

Definition at line 641 of file SemiFutureTest.cpp.

References a, ASSERT_EQ, f, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

641  {
642  std::atomic<int> innerResult{0};
643  Promise<int> p;
644  auto f = p.getSemiFuture().toUnsafeFuture();
645  auto sf = std::move(f).semi().deferValue([&](int a) { innerResult = a; });
646  p.setValue(7);
647  // Run "F" here inline in the calling thread
648  std::move(sf).get();
649  ASSERT_EQ(innerResult, 7);
650 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
char a
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
SimpleDeferWithValueFunctionReference   
)

Definition at line 658 of file SemiFutureTest.cpp.

References ASSERT_EQ, f, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

658  {
659  Promise<int> p;
660  auto f = p.getSemiFuture().toUnsafeFuture();
661  auto sf = std::move(f).semi().deferValue(deferValueHelper);
662  p.setValue(7);
663  // Run "F" here inline in the calling thread
664  ASSERT_EQ(std::move(sf).get(), 7);
665 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
ChainingDefertoThenWithValue   
)

Definition at line 667 of file SemiFutureTest.cpp.

References a, ASSERT_EQ, f, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

667  {
668  std::atomic<int> innerResult{0};
669  std::atomic<int> result{0};
670  EventBase e2;
671  Promise<int> p;
672  auto f = p.getSemiFuture().toUnsafeFuture();
673  auto sf = std::move(f).semi().deferValue([&](int a) {
674  innerResult = a;
675  return a;
676  });
677  // Run "F" here inline in a task running on the eventbase
678  auto tf = std::move(sf).via(&e2).then([&](int a) { result = a; });
679  p.setValue(7);
680  tf.getVia(&e2);
681  ASSERT_EQ(innerResult, 7);
682  ASSERT_EQ(result, 7);
683 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
char a
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
MakeSemiFutureFromFutureWithTry   
)

Definition at line 685 of file SemiFutureTest.cpp.

References ASSERT_EQ, eggs, f, folly::Promise< T >::getSemiFuture(), folly::gen::move, folly::Promise< T >::setException(), folly::pushmi::detail::t, and folly::Try< T >::tryGetExceptionObject().

685  {
686  Promise<int> p;
687  auto f = p.getSemiFuture().toUnsafeFuture();
688  auto sf = std::move(f).semi().defer([&](Try<int> t) {
689  if (auto err = t.tryGetExceptionObject<std::logic_error>()) {
690  return Try<std::string>(err->what());
691  }
692  return Try<std::string>(
693  make_exception_wrapper<std::logic_error>("Exception"));
694  });
695  p.setException(make_exception_wrapper<std::logic_error>("Try"));
696  auto tryResult = std::move(sf).get();
697  ASSERT_EQ(tryResult.value(), "Try");
698 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void setException(exception_wrapper ew)
Definition: Promise-inl.h:111
std::exception * tryGetExceptionObject()
Definition: Try.h:292
Definition: Try.h:51
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
DeferWithinContinuation   
)

Definition at line 706 of file SemiFutureTest.cpp.

References ASSERT_EQ, f, folly::Promise< T >::getSemiFuture(), folly::gen::move, and folly::Promise< T >::setValue().

706  {
707  std::atomic<int> innerResult{0};
708  std::atomic<int> result{0};
709  EventBase e2;
710  Promise<int> p;
711  Promise<int> p2;
712  auto f = p.getSemiFuture().via(&e2);
713  auto resultF = std::move(f).then([&, p3 = std::move(p2)](int outer) mutable {
714  result = outer;
715  return makeSemiFuture<int>(std::move(outer))
716  .deferValue([&, p4 = std::move(p3)](int inner) mutable {
717  innerResult = inner;
718  p4.setValue(inner);
719  return inner;
720  });
721  });
722  p.setValue(7);
723  auto r = resultF.getVia(&e2);
724  ASSERT_EQ(r, 7);
725  ASSERT_EQ(innerResult, 7);
726  ASSERT_EQ(result, 7);
727 }
auto f
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
onError   
)

Definition at line 729 of file SemiFutureTest.cpp.

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

729  {
730  bool theFlag = false;
731  auto flag = [&] { theFlag = true; };
732 #define EXPECT_FLAG() \
733  do { \
734  EXPECT_TRUE(theFlag); \
735  theFlag = false; \
736  } while (0);
737 
738 #define EXPECT_NO_FLAG() \
739  do { \
740  EXPECT_FALSE(theFlag); \
741  theFlag = false; \
742  } while (0);
743 
744  // By reference
745  {
746  auto f = makeSemiFuture()
747  .defer([](auto&&) { throw eggs; })
748  .deferError<eggs_t>([&](eggs_t const& /* e */) { flag(); });
749  EXPECT_NO_THROW(std::move(f).get());
750  EXPECT_FLAG();
751  }
752 
753  {
754  auto f = makeSemiFuture()
755  .defer(deferHelper)
756  .deferError<eggs_t>([&](eggs_t const& /* e */) { flag(); });
757  EXPECT_NO_THROW(std::move(f).get());
758  EXPECT_FLAG();
759  }
760 
761  // By auto reference
762  {
763  auto f = makeSemiFuture()
764  .defer([](auto&&) { throw eggs; })
765  .deferError<eggs_t>([&](auto& /* e */) { flag(); });
766  EXPECT_NO_THROW(std::move(f).get());
767  EXPECT_FLAG();
768  }
769 
770  // By value
771  {
772  auto f = makeSemiFuture()
773  .defer([](auto&&) { throw eggs; })
774  .deferError<eggs_t>([&](eggs_t /* e */) { flag(); });
775  EXPECT_NO_THROW(std::move(f).get());
776  EXPECT_FLAG();
777  }
778 
779  // auto value
780  {
781  auto f = makeSemiFuture()
782  .defer([](auto&&) { throw eggs; })
783  .deferError<eggs_t>([&](auto /* e */) { flag(); });
784  EXPECT_NO_THROW(std::move(f).get());
785  EXPECT_FLAG();
786  }
787 
788  // Polymorphic
789  {
790  auto f =
792  .defer([](auto&&) { throw eggs; })
793  .deferError<std::exception>([&](auto const& /* e */) { flag(); });
794  EXPECT_NO_THROW(std::move(f).get());
795  EXPECT_FLAG();
796  }
797 
798  // Non-exceptions
799  {
800  auto f = makeSemiFuture()
801  .defer([](auto&&) { throw - 1; })
802  .deferError<int>([&](auto /* e */) { flag(); });
803  EXPECT_NO_THROW(std::move(f).get());
804  EXPECT_FLAG();
805  }
806 
807  // Mutable lambda
808  {
809  auto f =
811  .defer([](auto&&) { throw eggs; })
812  .deferError<eggs_t>([&](auto const& /* e */) mutable { flag(); });
813  EXPECT_NO_THROW(std::move(f).get());
814  EXPECT_FLAG();
815  }
816 
817  // Function pointer
818  {
819  auto f = makeSemiFuture()
820  .defer([](auto &&) -> int { throw eggs; })
821  .deferError<eggs_t>(onErrorHelperEggs)
822  .deferError(onErrorHelperGeneric);
823  EXPECT_EQ(10, std::move(f).get());
824  }
825  {
826  auto f =
828  .defer([](auto &&) -> int { throw std::runtime_error("test"); })
829  .deferError<eggs_t>(onErrorHelperEggs)
830  .deferError(onErrorHelperGeneric);
831  EXPECT_EQ(20, std::move(f).get());
832  }
833  {
834  auto f =
836  .defer([](auto &&) -> int { throw std::runtime_error("test"); })
837  .deferError<eggs_t>(onErrorHelperEggs);
838  EXPECT_THROW(std::move(f).get(), std::runtime_error);
839  }
840 
841  // No throw
842  {
843  auto f = makeSemiFuture()
844  .defer([](auto&&) { return 42; })
845  .deferError<eggs_t>([&](auto& /* e */) {
846  flag();
847  return -1;
848  });
849  EXPECT_NO_FLAG();
850  EXPECT_EQ(42, std::move(f).get());
851  EXPECT_NO_FLAG();
852  }
853 
854  // Catch different exception
855  {
856  auto f = makeSemiFuture()
857  .defer([](auto&&) { throw eggs; })
858  .deferError<std::runtime_error>(
859  [&](auto const& /* e */) { flag(); });
860  EXPECT_THROW(std::move(f).get(), eggs_t);
861  EXPECT_NO_FLAG();
862  }
863 
864  // Returned value propagates
865  {
866  auto f = makeSemiFuture()
867  .defer([](auto &&) -> int { throw eggs; })
868  .deferError<eggs_t>([&](auto const& /* e */) { return 42; });
869  EXPECT_EQ(42, std::move(f).get());
870  }
871 
872  // Throw in callback
873  {
874  auto f = makeSemiFuture()
875  .defer([](auto &&) -> int { throw eggs; })
876  .deferError<eggs_t>([&](auto const& e) -> int { throw e; });
877  EXPECT_THROW(std::move(f).get(), eggs_t);
878  }
879 
880  // exception_wrapper, return T
881  {
882  auto f = makeSemiFuture()
883  .defer([](auto &&) -> int { throw eggs; })
884  .deferError([&](exception_wrapper /* e */) {
885  flag();
886  return -1;
887  });
888  EXPECT_EQ(-1, std::move(f).get());
889  EXPECT_FLAG();
890  }
891 
892  // exception_wrapper, return T but throw
893  {
894  auto f = makeSemiFuture()
895  .defer([](auto &&) -> int { throw eggs; })
896  .deferError([&](exception_wrapper /* e */) -> int {
897  flag();
898  throw eggs;
899  });
900  EXPECT_THROW(std::move(f).get(), eggs_t);
901  EXPECT_FLAG();
902  }
903 
904  // const exception_wrapper&
905  {
906  auto f = makeSemiFuture()
907  .defer([](auto&&) { throw eggs; })
908  .deferError([&](const exception_wrapper& /* e */) { flag(); });
909  EXPECT_NO_THROW(std::move(f).get());
910  EXPECT_FLAG();
911  }
912 }
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
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define EXPECT_NO_FLAG()
static once_flag flag
Definition: Random.cpp:75
#define EXPECT_FLAG()
static eggs_t eggs("eggs")
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)
Definition: Future-inl.h:712
TEST ( SemiFuture  ,
makePromiseContract   
)

Definition at line 914 of file SemiFutureTest.cpp.

References testing::_, c, EXPECT_EQ, and folly::gen::move.

914  {
915  auto c = makePromiseContract<int>();
916  c.first.setValue(3);
917  c.second = std::move(c.second).deferValue([](int _) { return _ + 1; });
918  EXPECT_EQ(4, std::move(c.second).get());
919 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const internal::AnythingMatcher _
char c
TEST ( SemiFuture  ,
invokeCallbackWithOriginalCVRef   
)

Definition at line 921 of file SemiFutureTest.cpp.

References EXPECT_EQ, folly::foo, folly::value(), and folly::detail::distributed_mutex::wait().

921  {
922  struct Foo {
923  int operator()(int x) & {
924  return x + 1;
925  }
926  int operator()(int x) const& {
927  return x + 2;
928  }
929  int operator()(int x) && {
930  return x + 3;
931  }
932  };
933 
934  Foo foo;
935  Foo const cfoo;
936 
937  // The continuation will be forward-constructed - copied if given as & and
938  // moved if given as && - everywhere construction is required.
939  // The continuation will be invoked with the same cvref as it is passed.
940  EXPECT_EQ(101, makeSemiFuture<int>(100).deferValue(foo).wait().value());
941  EXPECT_EQ(202, makeSemiFuture<int>(200).deferValue(cfoo).wait().value());
942  EXPECT_EQ(303, makeSemiFuture<int>(300).deferValue(Foo()).wait().value());
943 }
Definition: InvokeTest.cpp:58
Foo(std::atomic< int > &d)
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
bool wait(Waiter *waiter, bool shouldSleep, Waiter *&next)
static const char *const value
Definition: Conv.cpp:50
TEST ( SemiFuture  ,
semiFutureWithinCtxCleanedUpWhenTaskFinishedInTime   
)

Definition at line 945 of file SemiFutureTest.cpp.

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

945  {
946  // Used to track the use_count of callbackInput even outside of its scope
947  std::weak_ptr<int> target;
948  {
950  auto input = std::make_shared<int>(1);
951  auto longEnough = std::chrono::milliseconds(1000);
952 
953  promise.getSemiFuture()
954  .within(longEnough)
955  .toUnsafeFuture()
956  .then([&target](
957  folly::Try<std::shared_ptr<int>>&& callbackInput) mutable {
958  target = callbackInput.value();
959  });
960  promise.setValue(input);
961  }
962  // After promise's life cycle is finished, make sure no one is holding the
963  // input anymore, in other words, ctx should have been cleaned up.
964  EXPECT_EQ(0, target.use_count());
965 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Definition: Try.h:51
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
semiFutureWithinNoValueReferenceWhenTimeOut   
)

Definition at line 967 of file SemiFutureTest.cpp.

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

967  {
969  auto veryShort = std::chrono::milliseconds(1);
970 
971  promise.getSemiFuture().within(veryShort).toUnsafeFuture().then(
972  [](folly::Try<std::shared_ptr<int>>&& callbackInput) {
973  // Timeout is fired. Verify callbackInput is not referenced
974  EXPECT_EQ(0, callbackInput.value().use_count());
975  });
976 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Definition: Try.h:51
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
TEST ( SemiFuture  ,
collectAllSemiFutureDeferredWork   
)

Definition at line 978 of file SemiFutureTest.cpp.

References folly::collectAllSemiFuture(), folly::pushmi::executor, EXPECT_EQ, EXPECT_TRUE, folly::Promise< T >::getSemiFuture(), folly::gen::guard(), folly::makeGuard(), folly::gen::move, folly::Promise< T >::setValue(), folly::value(), and x.

978  {
979  {
980  Promise<int> promise1;
981  Promise<int> promise2;
982 
983  auto future = collectAllSemiFuture(
984  promise1.getSemiFuture().deferValue([](int x) { return x * 2; }),
985  promise2.getSemiFuture().deferValue([](int x) { return x * 2; }));
986 
987  promise1.setValue(1);
988  promise2.setValue(2);
989 
990  auto result = std::move(future).getTry(std::chrono::milliseconds{100});
991 
992  EXPECT_TRUE(result.hasValue());
993 
994  EXPECT_EQ(2, *std::get<0>(*result));
995  EXPECT_EQ(4, *std::get<1>(*result));
996  }
997 
998  {
999  Promise<int> promise1;
1000  Promise<int> promise2;
1001 
1002  auto future = collectAllSemiFuture(
1003  promise1.getSemiFuture().deferValue([](int x) { return x * 2; }),
1004  promise2.getSemiFuture().deferValue([](int x) { return x * 2; }));
1005 
1006  promise1.setValue(1);
1007  promise2.setValue(2);
1008 
1010 
1011  auto value = std::move(future).via(&executor).getVia(&executor);
1012 
1013  EXPECT_EQ(2, *std::get<0>(value));
1014  EXPECT_EQ(4, *std::get<1>(value));
1015  }
1016 
1017  {
1018  Promise<int> promise1;
1019  Promise<int> promise2;
1020 
1021  std::vector<SemiFuture<int>> futures;
1022  futures.push_back(
1023  promise1.getSemiFuture().deferValue([](int x) { return x * 2; }));
1024  futures.push_back(
1025  promise2.getSemiFuture().deferValue([](int x) { return x * 2; }));
1026 
1027  auto future = collectAllSemiFuture(futures);
1028 
1029  promise1.setValue(1);
1030  promise2.setValue(2);
1031 
1032  EXPECT_TRUE(future.wait().isReady());
1033 
1034  auto value = std::move(future).get();
1035  EXPECT_EQ(2, *value[0]);
1036  EXPECT_EQ(4, *value[1]);
1037  }
1038 
1039  {
1040  bool deferredDestroyed = false;
1041 
1042  {
1043  Promise<int> promise;
1044  auto guard = makeGuard([&] { deferredDestroyed = true; });
1045  collectAllSemiFuture(promise.getSemiFuture().deferValue(
1046  [guard = std::move(guard)](int x) { return x; }));
1047  }
1048 
1049  EXPECT_TRUE(deferredDestroyed);
1050  }
1051 }
Definition: InvokeTest.cpp:58
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const int x
SemiFuture< std::tuple< Try< typename remove_cvref_t< Fs >::value_type >... > > collectAllSemiFuture(Fs &&...fs)
Definition: Future-inl.h:1441
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
GuardImpl guard(ErrorHandler &&handler)
Definition: Base.h:840
static const char *const value
Definition: Conv.cpp:50
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
FOLLY_NODISCARD detail::ScopeGuardImplDecay< F, true > makeGuard(F &&f) noexcept(noexcept(detail::ScopeGuardImplDecay< F, true >(static_cast< F && >(f))))
Definition: ScopeGuard.h:184
TEST ( SemiFuture  ,
DeferWithNestedSemiFuture   
)

Definition at line 1053 of file SemiFutureTest.cpp.

References EXPECT_GE, EXPECT_TRUE, now(), folly::futures::sleep(), and start.

1053  {
1055  auto future = futures::sleep(std::chrono::milliseconds{100})
1056  .semi()
1057  .deferValue([](auto&&) {
1058  return futures::sleep(std::chrono::milliseconds{200});
1059  });
1060  future.wait();
1061  EXPECT_TRUE(future.hasValue());
1062  EXPECT_GE(
1063  std::chrono::steady_clock::now() - start, std::chrono::milliseconds{300});
1064 }
Future< Unit > sleep(Duration dur, Timekeeper *tk)
Definition: Future.cpp:42
std::chrono::steady_clock::time_point now()
#define EXPECT_GE(val1, val2)
Definition: gtest.h:1932
auto start
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859

Variable Documentation

eggs_t eggs("eggs")
static

Referenced by TEST().