proxygen
FutureTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2014-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <folly/futures/Future.h>
18 #include <folly/Executor.h>
19 #include <folly/Memory.h>
20 #include <folly/Unit.h>
21 #include <folly/dynamic.h>
25 
26 #include <algorithm>
27 #include <atomic>
28 #include <memory>
29 #include <numeric>
30 #include <queue>
31 #include <string>
32 #include <thread>
33 #include <type_traits>
34 
35 using namespace folly;
36 
37 #define EXPECT_TYPE(x, T) EXPECT_TRUE((std::is_same<decltype(x), T>::value))
38 
40 static eggs_t eggs("eggs");
41 
42 // Future
43 
44 TEST(Future, makeEmpty) {
45  auto f = Future<int>::makeEmpty();
46  EXPECT_THROW(f.isReady(), FutureInvalid);
47 }
48 
49 TEST(Future, futureDefaultCtor) {
50  Future<Unit>();
51 }
52 
53 TEST(Future, futureToUnit) {
54  Future<Unit> fu = makeFuture(42).unit();
55  fu.value();
56  EXPECT_TRUE(makeFuture<int>(eggs).unit().hasException());
57 }
58 
59 TEST(Future, voidFutureToUnit) {
60  Future<Unit> fu = makeFuture().unit();
61  fu.value();
62  EXPECT_TRUE(makeFuture<Unit>(eggs).unit().hasException());
63 }
64 
65 TEST(Future, unitFutureToUnitIdentity) {
66  Future<Unit> fu = makeFuture(Unit{}).unit();
67  fu.value();
68  EXPECT_TRUE(makeFuture<Unit>(eggs).unit().hasException());
69 }
70 
71 TEST(Future, toUnitWhileInProgress) {
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 }
78 
79 TEST(Future, makeFutureWithUnit) {
80  int count = 0;
81  Future<Unit> fu = makeFutureWith([&] { count++; });
82  EXPECT_EQ(1, count);
83 }
84 
85 TEST(Future, getRequiresOnlyMoveCtor) {
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 }
123 
124 namespace {
125 auto makeValid() {
126  auto valid = makeFuture<int>(42);
127  EXPECT_TRUE(valid.valid());
128  return valid;
129 }
130 auto makeInvalid() {
131  auto invalid = Future<int>::makeEmpty();
132  EXPECT_FALSE(invalid.valid());
133  return invalid;
134 }
135 } // namespace
136 
137 TEST(Future, ctorPostconditionValid) {
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 }
170 
171 TEST(Future, ctorPostconditionInvalid) {
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 }
188 
189 TEST(Future, lacksPreconditionValid) {
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 }
221 
222 TEST(Future, hasPreconditionValid) {
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 }
248 
249 TEST(Future, hasPostconditionValid) {
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 }
276 
277 TEST(Future, hasPostconditionInvalid) {
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 }
329 
330 namespace {
331 Future<int> onErrorHelperEggs(const eggs_t&) {
332  return makeFuture(10);
333 }
334 Future<int> onErrorHelperGeneric(const std::exception&) {
335  return makeFuture(20);
336 }
337 Future<int> onErrorHelperWrapper(folly::exception_wrapper&&) {
338  return makeFuture(30);
339 }
340 } // namespace
341 
342 TEST(Future, onError) {
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 }
639 
640 TEST(Future, thenError) {
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 }
924 
925 TEST(Future, special) {
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 }
931 
932 TEST(Future, then) {
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 }
955 
957  return makeFuture(t.value() + ";7");
958 }
959 
960 TEST(Future, thenTrythenValue) {
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 }
985 
986 TEST(Future, thenTry) {
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 }
1020 
1021 TEST(Future, thenValue) {
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 }
1047 
1048 TEST(Future, thenValueFuture) {
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 }
1065 
1067  return t.value() + ";static";
1068 }
1069 
1071  return t + ";value";
1072 }
1073 
1074 TEST(Future, thenFunction) {
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 }
1093 
1095  return makeFuture(t.value() + ";static");
1096 }
1097 
1098 TEST(Future, thenFunctionFuture) {
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 }
1115 
1116 TEST(Future, thenStdFunction) {
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 }
1145 
1146 TEST(Future, thenBind) {
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 }
1152 
1153 TEST(Future, thenBindTry) {
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 }
1160 
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 }
1168 
1169 TEST(Future, isReady) {
1170  Promise<int> p;
1171  auto f = p.getFuture();
1172  EXPECT_FALSE(f.isReady());
1173  p.setValue(42);
1174  EXPECT_TRUE(f.isReady());
1175 }
1176 
1177 TEST(Future, futureNotReady) {
1178  Promise<int> p;
1179  Future<int> f = p.getFuture();
1180  EXPECT_THROW(f.value(), eggs_t);
1181 }
1182 
1183 TEST(Future, hasException) {
1184  EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
1185  EXPECT_FALSE(makeFuture(42).getTry().hasException());
1186 }
1187 
1188 TEST(Future, hasValue) {
1189  EXPECT_TRUE(makeFuture(42).getTry().hasValue());
1190  EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
1191 }
1192 
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 }
1220 
1221 TEST(Future, finish) {
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 }
1242 
1243 TEST(Future, finishBigLambda) {
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 }
1275 
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 }
1310 
1311 TEST(Future, throwCaughtInImmediateThen) {
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 }
1317 
1318 TEST(Future, throwIfFailed) {
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 }
1328 
1329 TEST(Future, getFutureAfterSetValue) {
1330  Promise<int> p;
1331  p.setValue(42);
1332  EXPECT_EQ(42, p.getFuture().value());
1333 }
1334 
1335 TEST(Future, getFutureAfterSetException) {
1336  Promise<Unit> p;
1337  p.setWith([]() -> void { throw std::logic_error("foo"); });
1338  EXPECT_THROW(p.getFuture().value(), std::logic_error);
1339 }
1340 
1341 TEST(Future, detachRace) {
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 }
1363 
1364 // Test of handling of a circular dependency. It's never recommended
1365 // to have one because of possible memory leaks. Here we test that
1366 // we can handle freeing of the Future while it is running.
1367 TEST(Future, CircularDependencySharedPtrSelfReset) {
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 }
1385 
1386 TEST(Future, Constructor) {
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 }
1392 
1393 TEST(Future, ImplicitConstructor) {
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 }
1400 
1401 TEST(Future, InPlaceConstructor) {
1402  auto f = Future<std::pair<int, double>>(in_place, 5, 3.2);
1403  EXPECT_EQ(5, f.value().first);
1404 }
1405 
1406 TEST(Future, thenDynamic) {
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 }
1416 
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  {
1464  "key", std::make_unique<MyRequestData>(true));
1465  auto checker = [](int lineno) {
1466  return [lineno](Try<int>&& /* t */) {
1467  auto d = static_cast<MyRequestData*>(
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
1485  p1.setValue(3);
1486  p2.setValue(4);
1487 }
1488 
1489 TEST(Future, makeFutureNoThrow) {
1490  makeFuture().value();
1491 }
1492 
1493 TEST(Future, invokeCallbackReturningValueAsRvalue) {
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 }
1516 
1517 TEST(Future, invokeCallbackReturningFutureAsRvalue) {
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 }
1544 
1545 TEST(Future, futureWithinCtxCleanedUpWhenTaskFinishedInTime) {
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 }
1565 
1566 TEST(Future, futureWithinNoValueReferenceWhenTimeOut) {
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 }
1576 
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 }
1605 
1607  return makeFuture().then(executor, [=] { return depth == 0; });
1608 }
1609 
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 }
1621 
1622 TEST(Future, ThenRecursion) {
1624 
1625  EXPECT_EQ(42, recursion(&executor, 100000).getVia(&executor));
1626 }
Definition: InvokeTest.cpp:58
void * ptr
#define EXPECT_NO_FLAG()
#define DOIT(CREATION_EXPR)
auto f
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
Future< int > recursion(Executor *executor, int depth)
char b
auto add
Definition: BaseTest.cpp:70
void setContextData(const RequestToken &val, std::unique_ptr< RequestData > data)
Definition: Request.cpp:129
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
void setWith(F &&func)
Definition: Promise-inl.h:137
static std::string doWorkStaticValue(std::string &&t)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define EXPECT_FLAG()
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
in_place_tag in_place(in_place_tag={})
Definition: Utility.h:235
static once_flag flag
Definition: Random.cpp:75
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
void doWork(int work)
static folly::Future< std::string > doWorkStaticTry(Try< std::string > &&t)
Definition: FutureTest.cpp:956
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72
FOLLY_ALWAYS_INLINE void wait(const WaitOptions &opt=wait_options()) noexcept
Definition: Baton.h:170
static std::shared_ptr< RequestContext > saveContext()
Definition: Request.h:196
Function< void()> Func
Definition: Executor.h:27
auto const foo
Definition: LazyTest.cpp:49
FutureException eggs_t
Definition: FutureTest.cpp:39
static eggs_t eggs("eggs")
Future< T > getFuture()
Definition: Promise-inl.h:97
int64_t asInt() const
Definition: dynamic-inl.h:524
bool wait(Waiter *waiter, bool shouldSleep, Waiter *&next)
constexpr Unit unit
Definition: Unit.h:45
char a
Definition: Try.h:51
int * count
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
std::pair< Promise< T >, SemiFuture< T > > makePromiseContract()
Definition: Future.h:925
void fun()
const char * string
Definition: Conv.cpp:212
int bind(NetworkSocket s, const sockaddr *name, socklen_t namelen)
Definition: NetOps.cpp:76
static set< string > s
constexpr detail::Unwrap unwrap
Definition: Base-inl.h:2579
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
const internal::AnythingMatcher _
T & value()&
Definition: Try-inl.h:140
void for_each(T const &range, Function< void(typename T::value_type const &) const > const &func)
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
RequestData * getContextData(const RequestToken &val)
Definition: Request.cpp:151
static std::string doWorkStatic(Try< std::string > &&t)
static Future< std::string > doWorkStaticFuture(Try< std::string > &&t)
char c
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
#define EXPECT_TYPE(x, T)
Definition: FutureTest.cpp:37
TEST(SequencedExecutor, CPUThreadPoolExecutor)
static RequestContext * get()
Definition: Request.cpp:290
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310
Future< bool > call(int depth, Executor *executor)
std::enable_if< isFuture< invoke_result_t< F > >::value, invoke_result_t< F > >::type makeFutureWith(F &&func)
Definition: Future-inl.h:1322
static Future< T > makeEmpty()
Definition: Future-inl.h:951