(Wangle) Clean up tests
[folly.git] / folly / futures / test / FutureTest.cpp
1 /*
2  * Copyright 2015 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 <gtest/gtest.h>
18
19 #include <folly/futures/Future.h>
20 #include <folly/Memory.h>
21 #include <folly/Executor.h>
22 #include <folly/dynamic.h>
23 #include <folly/Baton.h>
24
25 #include <algorithm>
26 #include <atomic>
27 #include <memory>
28 #include <string>
29 #include <thread>
30 #include <type_traits>
31 #include <unistd.h>
32
33 using namespace folly;
34
35 #define EXPECT_TYPE(x, T) \
36   EXPECT_TRUE((std::is_same<decltype(x), T>::value))
37
38 typedef FutureException eggs_t;
39 static eggs_t eggs("eggs");
40
41 // Future
42
43 TEST(Future, onError) {
44   bool theFlag = false;
45   auto flag = [&]{ theFlag = true; };
46 #define EXPECT_FLAG() \
47   do { \
48     EXPECT_TRUE(theFlag); \
49     theFlag = false; \
50   } while(0);
51
52 #define EXPECT_NO_FLAG() \
53   do { \
54     EXPECT_FALSE(theFlag); \
55     theFlag = false; \
56   } while(0);
57
58   // By reference
59   {
60     auto f = makeFuture()
61       .then([] { throw eggs; })
62       .onError([&] (eggs_t& e) { flag(); });
63     EXPECT_FLAG();
64     EXPECT_NO_THROW(f.value());
65   }
66
67   {
68     auto f = makeFuture()
69       .then([] { throw eggs; })
70       .onError([&] (eggs_t& e) { flag(); return makeFuture(); });
71     EXPECT_FLAG();
72     EXPECT_NO_THROW(f.value());
73   }
74
75   // By value
76   {
77     auto f = makeFuture()
78       .then([] { throw eggs; })
79       .onError([&] (eggs_t e) { flag(); });
80     EXPECT_FLAG();
81     EXPECT_NO_THROW(f.value());
82   }
83
84   {
85     auto f = makeFuture()
86       .then([] { throw eggs; })
87       .onError([&] (eggs_t e) { flag(); return makeFuture(); });
88     EXPECT_FLAG();
89     EXPECT_NO_THROW(f.value());
90   }
91
92   // Polymorphic
93   {
94     auto f = makeFuture()
95       .then([] { throw eggs; })
96       .onError([&] (std::exception& e) { flag(); });
97     EXPECT_FLAG();
98     EXPECT_NO_THROW(f.value());
99   }
100
101   {
102     auto f = makeFuture()
103       .then([] { throw eggs; })
104       .onError([&] (std::exception& e) { flag(); return makeFuture(); });
105     EXPECT_FLAG();
106     EXPECT_NO_THROW(f.value());
107   }
108
109   // Non-exceptions
110   {
111     auto f = makeFuture()
112       .then([] { throw -1; })
113       .onError([&] (int e) { flag(); });
114     EXPECT_FLAG();
115     EXPECT_NO_THROW(f.value());
116   }
117
118   {
119     auto f = makeFuture()
120       .then([] { throw -1; })
121       .onError([&] (int e) { flag(); return makeFuture(); });
122     EXPECT_FLAG();
123     EXPECT_NO_THROW(f.value());
124   }
125
126   // Mutable lambda
127   {
128     auto f = makeFuture()
129       .then([] { throw eggs; })
130       .onError([&] (eggs_t& e) mutable { flag(); });
131     EXPECT_FLAG();
132     EXPECT_NO_THROW(f.value());
133   }
134
135   {
136     auto f = makeFuture()
137       .then([] { throw eggs; })
138       .onError([&] (eggs_t& e) mutable { flag(); return makeFuture(); });
139     EXPECT_FLAG();
140     EXPECT_NO_THROW(f.value());
141   }
142
143   // No throw
144   {
145     auto f = makeFuture()
146       .then([] { return 42; })
147       .onError([&] (eggs_t& e) { flag(); return -1; });
148     EXPECT_NO_FLAG();
149     EXPECT_EQ(42, f.value());
150   }
151
152   {
153     auto f = makeFuture()
154       .then([] { return 42; })
155       .onError([&] (eggs_t& e) { flag(); return makeFuture<int>(-1); });
156     EXPECT_NO_FLAG();
157     EXPECT_EQ(42, f.value());
158   }
159
160   // Catch different exception
161   {
162     auto f = makeFuture()
163       .then([] { throw eggs; })
164       .onError([&] (std::runtime_error& e) { flag(); });
165     EXPECT_NO_FLAG();
166     EXPECT_THROW(f.value(), eggs_t);
167   }
168
169   {
170     auto f = makeFuture()
171       .then([] { throw eggs; })
172       .onError([&] (std::runtime_error& e) { flag(); return makeFuture(); });
173     EXPECT_NO_FLAG();
174     EXPECT_THROW(f.value(), eggs_t);
175   }
176
177   // Returned value propagates
178   {
179     auto f = makeFuture()
180       .then([] { throw eggs; return 0; })
181       .onError([&] (eggs_t& e) { return 42; });
182     EXPECT_EQ(42, f.value());
183   }
184
185   // Returned future propagates
186   {
187     auto f = makeFuture()
188       .then([] { throw eggs; return 0; })
189       .onError([&] (eggs_t& e) { return makeFuture<int>(42); });
190     EXPECT_EQ(42, f.value());
191   }
192
193   // Throw in callback
194   {
195     auto f = makeFuture()
196       .then([] { throw eggs; return 0; })
197       .onError([&] (eggs_t& e) { throw e; return -1; });
198     EXPECT_THROW(f.value(), eggs_t);
199   }
200
201   {
202     auto f = makeFuture()
203       .then([] { throw eggs; return 0; })
204       .onError([&] (eggs_t& e) { throw e; return makeFuture<int>(-1); });
205     EXPECT_THROW(f.value(), eggs_t);
206   }
207
208   // exception_wrapper, return Future<T>
209   {
210     auto f = makeFuture()
211       .then([] { throw eggs; })
212       .onError([&] (exception_wrapper e) { flag(); return makeFuture(); });
213     EXPECT_FLAG();
214     EXPECT_NO_THROW(f.value());
215   }
216
217   // exception_wrapper, return Future<T> but throw
218   {
219     auto f = makeFuture()
220       .then([]{ throw eggs; return 0; })
221       .onError([&] (exception_wrapper e) {
222         flag();
223         throw eggs;
224         return makeFuture<int>(-1);
225       });
226     EXPECT_FLAG();
227     EXPECT_THROW(f.value(), eggs_t);
228   }
229
230   // exception_wrapper, return T
231   {
232     auto f = makeFuture()
233       .then([]{ throw eggs; return 0; })
234       .onError([&] (exception_wrapper e) {
235         flag();
236         return -1;
237       });
238     EXPECT_FLAG();
239     EXPECT_EQ(-1, f.value());
240   }
241
242   // exception_wrapper, return T but throw
243   {
244     auto f = makeFuture()
245       .then([]{ throw eggs; return 0; })
246       .onError([&] (exception_wrapper e) {
247         flag();
248         throw eggs;
249         return -1;
250       });
251     EXPECT_FLAG();
252     EXPECT_THROW(f.value(), eggs_t);
253   }
254
255   // const exception_wrapper&
256   {
257     auto f = makeFuture()
258       .then([] { throw eggs; })
259       .onError([&] (const exception_wrapper& e) {
260         flag();
261         return makeFuture();
262       });
263     EXPECT_FLAG();
264     EXPECT_NO_THROW(f.value());
265   }
266
267 }
268
269 TEST(Future, special) {
270   EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
271   EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
272   EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
273   EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
274 }
275
276 TEST(Future, then) {
277   auto f = makeFuture<std::string>("0")
278     .then([](){
279       return makeFuture<std::string>("1"); })
280     .then([](Try<std::string>&& t) {
281       return makeFuture(t.value() + ";2"); })
282     .then([](const Try<std::string>&& t) {
283       return makeFuture(t.value() + ";3"); })
284     .then([](Try<std::string>& t) {
285       return makeFuture(t.value() + ";4"); })
286     .then([](const Try<std::string>& t) {
287       return makeFuture(t.value() + ";5"); })
288     .then([](Try<std::string> t) {
289       return makeFuture(t.value() + ";6"); })
290     .then([](const Try<std::string> t) {
291       return makeFuture(t.value() + ";7"); })
292     .then([](std::string&& s) {
293       return makeFuture(s + ";8"); })
294     .then([](const std::string&& s) {
295       return makeFuture(s + ";9"); })
296     .then([](std::string& s) {
297       return makeFuture(s + ";10"); })
298     .then([](const std::string& s) {
299       return makeFuture(s + ";11"); })
300     .then([](std::string s) {
301       return makeFuture(s + ";12"); })
302     .then([](const std::string s) {
303       return makeFuture(s + ";13"); })
304   ;
305   EXPECT_EQ(f.value(), "1;2;3;4;5;6;7;8;9;10;11;12;13");
306 }
307
308 TEST(Future, thenTry) {
309   bool flag = false;
310
311   makeFuture<int>(42).then([&](Try<int>&& t) {
312                               flag = true;
313                               EXPECT_EQ(42, t.value());
314                             });
315   EXPECT_TRUE(flag); flag = false;
316
317   makeFuture<int>(42)
318     .then([](Try<int>&& t) { return t.value(); })
319     .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
320   EXPECT_TRUE(flag); flag = false;
321
322   makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
323   EXPECT_TRUE(flag); flag = false;
324
325   Promise<void> p;
326   auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
327   EXPECT_FALSE(flag);
328   EXPECT_FALSE(f.isReady());
329   p.setValue();
330   EXPECT_TRUE(flag);
331   EXPECT_TRUE(f.isReady());
332 }
333
334 TEST(Future, thenValue) {
335   bool flag = false;
336   makeFuture<int>(42).then([&](int i){
337     EXPECT_EQ(42, i);
338     flag = true;
339   });
340   EXPECT_TRUE(flag); flag = false;
341
342   makeFuture<int>(42)
343     .then([](int i){ return i; })
344     .then([&](int i) { flag = true; EXPECT_EQ(42, i); });
345   EXPECT_TRUE(flag); flag = false;
346
347   makeFuture().then([&]{
348     flag = true;
349   });
350   EXPECT_TRUE(flag); flag = false;
351
352   auto f = makeFuture<int>(eggs).then([&](int i){});
353   EXPECT_THROW(f.value(), eggs_t);
354
355   f = makeFuture<void>(eggs).then([&]{});
356   EXPECT_THROW(f.value(), eggs_t);
357 }
358
359 TEST(Future, thenValueFuture) {
360   bool flag = false;
361   makeFuture<int>(42)
362     .then([](int i){ return makeFuture<int>(std::move(i)); })
363     .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
364   EXPECT_TRUE(flag); flag = false;
365
366   makeFuture()
367     .then([]{ return makeFuture(); })
368     .then([&](Try<void>&& t) { flag = true; });
369   EXPECT_TRUE(flag); flag = false;
370 }
371
372 static std::string doWorkStatic(Try<std::string>&& t) {
373   return t.value() + ";static";
374 }
375
376 TEST(Future, thenFunction) {
377   struct Worker {
378     std::string doWork(Try<std::string>&& t) {
379       return t.value() + ";class";
380     }
381     static std::string doWorkStatic(Try<std::string>&& t) {
382       return t.value() + ";class-static";
383     }
384   } w;
385
386   auto f = makeFuture<std::string>("start")
387     .then(doWorkStatic)
388     .then(Worker::doWorkStatic)
389     .then(&Worker::doWork, &w);
390
391   EXPECT_EQ(f.value(), "start;static;class-static;class");
392 }
393
394 static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
395   return makeFuture(t.value() + ";static");
396 }
397
398 TEST(Future, thenFunctionFuture) {
399   struct Worker {
400     Future<std::string> doWorkFuture(Try<std::string>&& t) {
401       return makeFuture(t.value() + ";class");
402     }
403     static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
404       return makeFuture(t.value() + ";class-static");
405     }
406   } w;
407
408   auto f = makeFuture<std::string>("start")
409     .then(doWorkStaticFuture)
410     .then(Worker::doWorkStaticFuture)
411     .then(&Worker::doWorkFuture, &w);
412
413   EXPECT_EQ(f.value(), "start;static;class-static;class");
414 }
415
416 TEST(Future, thenBind) {
417   auto l = []() {
418     return makeFuture("bind");
419   };
420   auto b = std::bind(l);
421   auto f = makeFuture().then(std::move(b));
422   EXPECT_EQ(f.value(), "bind");
423 }
424
425 TEST(Future, thenBindTry) {
426   auto l = [](Try<std::string>&& t) {
427     return makeFuture(t.value() + ";bind");
428   };
429   auto b = std::bind(l, std::placeholders::_1);
430   auto f = makeFuture<std::string>("start").then(std::move(b));
431
432   EXPECT_EQ(f.value(), "start;bind");
433 }
434
435 TEST(Future, value) {
436   auto f = makeFuture(std::unique_ptr<int>(new int(42)));
437   auto up = std::move(f.value());
438   EXPECT_EQ(42, *up);
439
440   EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
441 }
442
443 TEST(Future, isReady) {
444   Promise<int> p;
445   auto f = p.getFuture();
446   EXPECT_FALSE(f.isReady());
447   p.setValue(42);
448   EXPECT_TRUE(f.isReady());
449   }
450
451 TEST(Future, futureNotReady) {
452   Promise<int> p;
453   Future<int> f = p.getFuture();
454   EXPECT_THROW(f.value(), eggs_t);
455 }
456
457 TEST(Future, hasException) {
458   EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
459   EXPECT_FALSE(makeFuture(42).getTry().hasException());
460 }
461
462 TEST(Future, hasValue) {
463   EXPECT_TRUE(makeFuture(42).getTry().hasValue());
464   EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
465 }
466
467 TEST(Future, makeFuture) {
468   EXPECT_TYPE(makeFuture(42), Future<int>);
469   EXPECT_EQ(42, makeFuture(42).value());
470
471   EXPECT_TYPE(makeFuture<float>(42), Future<float>);
472   EXPECT_EQ(42, makeFuture<float>(42).value());
473
474   auto fun = [] { return 42; };
475   EXPECT_TYPE(makeFutureWith(fun), Future<int>);
476   EXPECT_EQ(42, makeFutureWith(fun).value());
477
478   auto failfun = []() -> int { throw eggs; };
479   EXPECT_TYPE(makeFutureWith(failfun), Future<int>);
480   EXPECT_THROW(makeFutureWith(failfun).value(), eggs_t);
481
482   EXPECT_TYPE(makeFuture(), Future<void>);
483 }
484
485 TEST(Future, finish) {
486   auto x = std::make_shared<int>(0);
487   {
488     Promise<int> p;
489     auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
490
491     // The callback hasn't executed
492     EXPECT_EQ(0, *x);
493
494     // The callback has a reference to x
495     EXPECT_EQ(2, x.use_count());
496
497     p.setValue(42);
498
499     // the callback has executed
500     EXPECT_EQ(42, *x);
501   }
502   // the callback has been destructed
503   // and has released its reference to x
504   EXPECT_EQ(1, x.use_count());
505 }
506
507 TEST(Future, unwrap) {
508   Promise<int> a;
509   Promise<int> b;
510
511   auto fa = a.getFuture();
512   auto fb = b.getFuture();
513
514   bool flag1 = false;
515   bool flag2 = false;
516
517   // do a, then do b, and get the result of a + b.
518   Future<int> f = fa.then([&](Try<int>&& ta) {
519     auto va = ta.value();
520     flag1 = true;
521     return fb.then([va, &flag2](Try<int>&& tb) {
522       flag2 = true;
523       return va + tb.value();
524     });
525   });
526
527   EXPECT_FALSE(flag1);
528   EXPECT_FALSE(flag2);
529   EXPECT_FALSE(f.isReady());
530
531   a.setValue(3);
532   EXPECT_TRUE(flag1);
533   EXPECT_FALSE(flag2);
534   EXPECT_FALSE(f.isReady());
535
536   b.setValue(4);
537   EXPECT_TRUE(flag1);
538   EXPECT_TRUE(flag2);
539   EXPECT_EQ(7, f.value());
540 }
541
542 TEST(Future, throwCaughtInImmediateThen) {
543   // Neither of these should throw "Promise already satisfied"
544   makeFuture().then(
545     [=](Try<void>&&) -> int { throw std::exception(); });
546   makeFuture().then(
547     [=](Try<void>&&) -> Future<int> { throw std::exception(); });
548 }
549
550 TEST(Future, throwIfFailed) {
551   makeFuture<void>(eggs)
552     .then([=](Try<void>&& t) {
553       EXPECT_THROW(t.throwIfFailed(), eggs_t);
554     });
555   makeFuture()
556     .then([=](Try<void>&& t) {
557       EXPECT_NO_THROW(t.throwIfFailed());
558     });
559
560   makeFuture<int>(eggs)
561     .then([=](Try<int>&& t) {
562       EXPECT_THROW(t.throwIfFailed(), eggs_t);
563     });
564   makeFuture<int>(42)
565     .then([=](Try<int>&& t) {
566       EXPECT_NO_THROW(t.throwIfFailed());
567     });
568 }
569
570 TEST(Future, getFutureAfterSetValue) {
571   Promise<int> p;
572   p.setValue(42);
573   EXPECT_EQ(42, p.getFuture().value());
574 }
575
576 TEST(Future, getFutureAfterSetException) {
577   Promise<void> p;
578   p.setWith([]() -> void { throw std::logic_error("foo"); });
579   EXPECT_THROW(p.getFuture().value(), std::logic_error);
580 }
581
582 TEST(Future, detachRace) {
583   // Task #5438209
584   // This test is designed to detect a race that was in Core::detachOne()
585   // where detached_ was incremented and then tested, and that
586   // allowed a race where both Promise and Future would think they were the
587   // second and both try to delete. This showed up at scale but was very
588   // difficult to reliably repro in a test. As it is, this only fails about
589   // once in every 1,000 executions. Doing this 1,000 times is going to make a
590   // slow test so I won't do that but if it ever fails, take it seriously, and
591   // run the test binary with "--gtest_repeat=10000 --gtest_filter=*detachRace"
592   // (Don't forget to enable ASAN)
593   auto p = folly::make_unique<Promise<bool>>();
594   auto f = folly::make_unique<Future<bool>>(p->getFuture());
595   folly::Baton<> baton;
596   std::thread t1([&]{
597     baton.post();
598     p.reset();
599   });
600   baton.wait();
601   f.reset();
602   t1.join();
603 }
604
605 // Test of handling of a circular dependency. It's never recommended
606 // to have one because of possible memory leaks. Here we test that
607 // we can handle freeing of the Future while it is running.
608 TEST(Future, CircularDependencySharedPtrSelfReset) {
609   Promise<int64_t> promise;
610   auto ptr = std::make_shared<Future<int64_t>>(promise.getFuture());
611
612   ptr->then(
613     [ptr] (folly::Try<int64_t>&& uid) mutable {
614       EXPECT_EQ(1, ptr.use_count());
615
616       // Leaving no references to ourselves.
617       ptr.reset();
618       EXPECT_EQ(0, ptr.use_count());
619     }
620   );
621
622   EXPECT_EQ(2, ptr.use_count());
623
624   ptr.reset();
625
626   promise.setWith([]{return 1l;});
627 }
628
629 TEST(Future, Constructor) {
630   auto f1 = []() -> Future<int> { return Future<int>(3); }();
631   EXPECT_EQ(f1.value(), 3);
632   auto f2 = []() -> Future<void> { return Future<void>(); }();
633   EXPECT_NO_THROW(f2.value());
634 }
635
636 TEST(Future, ImplicitConstructor) {
637   auto f1 = []() -> Future<int> { return 3; }();
638   EXPECT_EQ(f1.value(), 3);
639   // Unfortunately, the C++ standard does not allow the
640   // following implicit conversion to work:
641   //auto f2 = []() -> Future<void> { }();
642 }
643
644 TEST(Future, thenDynamic) {
645   // folly::dynamic has a constructor that takes any T, this test makes
646   // sure that we call the then lambda with folly::dynamic and not
647   // Try<folly::dynamic> because that then fails to compile
648   Promise<folly::dynamic> p;
649   Future<folly::dynamic> f = p.getFuture().then(
650       [](const folly::dynamic& d) {
651         return folly::dynamic(d.asInt() + 3);
652       }
653   );
654   p.setValue(2);
655   EXPECT_EQ(f.get(), 5);
656 }