d925644589ea254c2b15a5dd45bbb1331ccffea7
[folly.git] / folly / wangle / test / FutureTest.cpp
1 /*
2  * Copyright 2014 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 <algorithm>
18 #include <atomic>
19 #include <folly/small_vector.h>
20 #include <gtest/gtest.h>
21 #include <memory>
22 #include <string>
23 #include <thread>
24 #include <type_traits>
25 #include <unistd.h>
26 #include "folly/wangle/Executor.h"
27 #include "folly/wangle/Future.h"
28
29 using namespace folly::wangle;
30 using std::pair;
31 using std::string;
32 using std::unique_ptr;
33 using std::vector;
34
35 #define EXPECT_TYPE(x, T) \
36   EXPECT_TRUE((std::is_same<decltype(x), T>::value))
37
38 typedef WangleException eggs_t;
39 static eggs_t eggs("eggs");
40
41 // Future
42
43 TEST(Future, try) {
44   class A {
45    public:
46     A(int x) : x_(x) {}
47
48     int x() const {
49       return x_;
50     }
51    private:
52     int x_;
53   };
54
55   A a(5);
56   Try<A> t_a(std::move(a));
57
58   Try<void> t_void;
59
60   EXPECT_EQ(5, t_a.value().x());
61 }
62
63 TEST(Future, special) {
64   EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
65   EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
66   EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
67   EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
68 }
69
70 TEST(Future, then) {
71   bool flag = false;
72
73   makeFuture<int>(42).then([&](Try<int>&& t) {
74                               flag = true;
75                               EXPECT_EQ(42, t.value());
76                             });
77   EXPECT_TRUE(flag); flag = false;
78
79   makeFuture<int>(42)
80     .then([](Try<int>&& t) { return t.value(); })
81     .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
82   EXPECT_TRUE(flag); flag = false;
83
84   makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
85   EXPECT_TRUE(flag); flag = false;
86
87   Promise<void> p;
88   auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
89   EXPECT_FALSE(flag);
90   EXPECT_FALSE(f.isReady());
91   p.setValue();
92   EXPECT_TRUE(flag);
93   EXPECT_TRUE(f.isReady());
94 }
95
96 static string doWorkStatic(Try<string>&& t) {
97   return t.value() + ";static";
98 }
99
100 TEST(Future, thenFunction) {
101   struct Worker {
102     string doWork(Try<string>&& t) {
103       return t.value() + ";class";
104     }
105     static string doWorkStatic(Try<string>&& t) {
106       return t.value() + ";class-static";
107     }
108   } w;
109
110   auto f = makeFuture<string>("start")
111     .then(doWorkStatic)
112     .then(Worker::doWorkStatic)
113     .then(&w, &Worker::doWork);
114
115   EXPECT_EQ(f.value(), "start;static;class-static;class");
116 }
117
118 static Future<string> doWorkStaticFuture(Try<string>&& t) {
119   return makeFuture(t.value() + ";static");
120 }
121
122 TEST(Future, thenFunctionFuture) {
123   struct Worker {
124     Future<string> doWorkFuture(Try<string>&& t) {
125       return makeFuture(t.value() + ";class");
126     }
127     static Future<string> doWorkStaticFuture(Try<string>&& t) {
128       return makeFuture(t.value() + ";class-static");
129     }
130   } w;
131
132   auto f = makeFuture<string>("start")
133     .then(doWorkStaticFuture)
134     .then(Worker::doWorkStaticFuture)
135     .then(&w, &Worker::doWorkFuture);
136
137   EXPECT_EQ(f.value(), "start;static;class-static;class");
138 }
139
140 TEST(Future, value) {
141   auto f = makeFuture(unique_ptr<int>(new int(42)));
142   auto up = std::move(f.value());
143   EXPECT_EQ(42, *up);
144
145   EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
146 }
147
148 TEST(Future, isReady) {
149   Promise<int> p;
150   auto f = p.getFuture();
151   EXPECT_FALSE(f.isReady());
152   p.setValue(42);
153   EXPECT_TRUE(f.isReady());
154   }
155
156 TEST(Future, hasException) {
157   EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
158   EXPECT_FALSE(makeFuture(42).getTry().hasException());
159 }
160
161 TEST(Future, hasValue) {
162   EXPECT_TRUE(makeFuture(42).getTry().hasValue());
163   EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
164 }
165
166 TEST(Future, makeFuture) {
167   EXPECT_TYPE(makeFuture(42), Future<int>);
168   EXPECT_EQ(42, makeFuture(42).value());
169
170   EXPECT_TYPE(makeFuture<float>(42), Future<float>);
171   EXPECT_EQ(42, makeFuture<float>(42).value());
172
173   auto fun = [] { return 42; };
174   EXPECT_TYPE(makeFutureTry(fun), Future<int>);
175   EXPECT_EQ(42, makeFutureTry(fun).value());
176
177   auto failfun = []() -> int { throw eggs; };
178   EXPECT_TYPE(makeFutureTry(failfun), Future<int>);
179   EXPECT_THROW(makeFutureTry(failfun).value(), eggs_t);
180
181   EXPECT_TYPE(makeFuture(), Future<void>);
182 }
183
184 // Promise
185
186 TEST(Promise, special) {
187   EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
188   EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
189   EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
190   EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
191 }
192
193 TEST(Promise, getFuture) {
194   Promise<int> p;
195   Future<int> f = p.getFuture();
196   EXPECT_FALSE(f.isReady());
197 }
198
199 TEST(Promise, setValue) {
200   Promise<int> fund;
201   auto ffund = fund.getFuture();
202   fund.setValue(42);
203   EXPECT_EQ(42, ffund.value());
204
205   struct Foo {
206     string name;
207     int value;
208   };
209
210   Promise<Foo> pod;
211   auto fpod = pod.getFuture();
212   Foo f = {"the answer", 42};
213   pod.setValue(f);
214   Foo f2 = fpod.value();
215   EXPECT_EQ(f.name, f2.name);
216   EXPECT_EQ(f.value, f2.value);
217
218   pod = Promise<Foo>();
219   fpod = pod.getFuture();
220   pod.setValue(std::move(f2));
221   Foo f3 = fpod.value();
222   EXPECT_EQ(f.name, f3.name);
223   EXPECT_EQ(f.value, f3.value);
224
225   Promise<unique_ptr<int>> mov;
226   auto fmov = mov.getFuture();
227   mov.setValue(unique_ptr<int>(new int(42)));
228   unique_ptr<int> ptr = std::move(fmov.value());
229   EXPECT_EQ(42, *ptr);
230
231   Promise<void> v;
232   auto fv = v.getFuture();
233   v.setValue();
234   EXPECT_TRUE(fv.isReady());
235 }
236
237 TEST(Promise, setException) {
238   {
239     Promise<void> p;
240     auto f = p.getFuture();
241     p.setException(eggs);
242     EXPECT_THROW(f.value(), eggs_t);
243   }
244   {
245     Promise<void> p;
246     auto f = p.getFuture();
247     try {
248       throw eggs;
249     } catch (...) {
250       p.setException(std::current_exception());
251     }
252     EXPECT_THROW(f.value(), eggs_t);
253   }
254 }
255
256 TEST(Promise, fulfil) {
257   {
258     Promise<int> p;
259     auto f = p.getFuture();
260     p.fulfil([] { return 42; });
261     EXPECT_EQ(42, f.value());
262   }
263   {
264     Promise<int> p;
265     auto f = p.getFuture();
266     p.fulfil([]() -> int { throw eggs; });
267     EXPECT_THROW(f.value(), eggs_t);
268   }
269 }
270
271 TEST(Future, finish) {
272   auto x = std::make_shared<int>(0);
273   Promise<int> p;
274   auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
275
276   // The continuation hasn't executed
277   EXPECT_EQ(0, *x);
278
279   // The continuation has a reference to x
280   EXPECT_EQ(2, x.use_count());
281
282   p.setValue(42);
283
284   // the continuation has executed
285   EXPECT_EQ(42, *x);
286
287   // the continuation has been destructed
288   // and has released its reference to x
289   EXPECT_EQ(1, x.use_count());
290 }
291
292 TEST(Future, unwrap) {
293   Promise<int> a;
294   Promise<int> b;
295
296   auto fa = a.getFuture();
297   auto fb = b.getFuture();
298
299   bool flag1 = false;
300   bool flag2 = false;
301
302   // do a, then do b, and get the result of a + b.
303   Future<int> f = fa.then([&](Try<int>&& ta) {
304     auto va = ta.value();
305     flag1 = true;
306     return fb.then([va, &flag2](Try<int>&& tb) {
307       flag2 = true;
308       return va + tb.value();
309     });
310   });
311
312   EXPECT_FALSE(flag1);
313   EXPECT_FALSE(flag2);
314   EXPECT_FALSE(f.isReady());
315
316   a.setValue(3);
317   EXPECT_TRUE(flag1);
318   EXPECT_FALSE(flag2);
319   EXPECT_FALSE(f.isReady());
320
321   b.setValue(4);
322   EXPECT_TRUE(flag1);
323   EXPECT_TRUE(flag2);
324   EXPECT_EQ(7, f.value());
325 }
326
327 TEST(Future, whenAll) {
328   // returns a vector variant
329   {
330     vector<Promise<int>> promises(10);
331     vector<Future<int>> futures;
332
333     for (auto& p : promises)
334       futures.push_back(p.getFuture());
335
336     auto allf = whenAll(futures.begin(), futures.end());
337
338     random_shuffle(promises.begin(), promises.end());
339     for (auto& p : promises) {
340       EXPECT_FALSE(allf.isReady());
341       p.setValue(42);
342     }
343
344     EXPECT_TRUE(allf.isReady());
345     auto& results = allf.value();
346     for (auto& t : results) {
347       EXPECT_EQ(42, t.value());
348     }
349   }
350
351   // check error semantics
352   {
353     vector<Promise<int>> promises(4);
354     vector<Future<int>> futures;
355
356     for (auto& p : promises)
357       futures.push_back(p.getFuture());
358
359     auto allf = whenAll(futures.begin(), futures.end());
360
361
362     promises[0].setValue(42);
363     promises[1].setException(eggs);
364
365     EXPECT_FALSE(allf.isReady());
366
367     promises[2].setValue(42);
368
369     EXPECT_FALSE(allf.isReady());
370
371     promises[3].setException(eggs);
372
373     EXPECT_TRUE(allf.isReady());
374     EXPECT_FALSE(allf.getTry().hasException());
375
376     auto& results = allf.value();
377     EXPECT_EQ(42, results[0].value());
378     EXPECT_TRUE(results[1].hasException());
379     EXPECT_EQ(42, results[2].value());
380     EXPECT_TRUE(results[3].hasException());
381   }
382
383   // check that futures are ready in then()
384   {
385     vector<Promise<void>> promises(10);
386     vector<Future<void>> futures;
387
388     for (auto& p : promises)
389       futures.push_back(p.getFuture());
390
391     auto allf = whenAll(futures.begin(), futures.end())
392       .then([](Try<vector<Try<void>>>&& ts) {
393         for (auto& f : ts.value())
394           f.value();
395       });
396
397     random_shuffle(promises.begin(), promises.end());
398     for (auto& p : promises)
399       p.setValue();
400     EXPECT_TRUE(allf.isReady());
401   }
402 }
403
404
405 TEST(Future, whenAny) {
406   {
407     vector<Promise<int>> promises(10);
408     vector<Future<int>> futures;
409
410     for (auto& p : promises)
411       futures.push_back(p.getFuture());
412
413     for (auto& f : futures) {
414       EXPECT_FALSE(f.isReady());
415     }
416
417     auto anyf = whenAny(futures.begin(), futures.end());
418
419     /* futures were moved in, so these are invalid now */
420     EXPECT_FALSE(anyf.isReady());
421
422     promises[7].setValue(42);
423     EXPECT_TRUE(anyf.isReady());
424     auto& idx_fut = anyf.value();
425
426     auto i = idx_fut.first;
427     EXPECT_EQ(7, i);
428
429     auto& f = idx_fut.second;
430     EXPECT_EQ(42, f.value());
431   }
432
433   // error
434   {
435     vector<Promise<void>> promises(10);
436     vector<Future<void>> futures;
437
438     for (auto& p : promises)
439       futures.push_back(p.getFuture());
440
441     for (auto& f : futures) {
442       EXPECT_FALSE(f.isReady());
443     }
444
445     auto anyf = whenAny(futures.begin(), futures.end());
446
447     EXPECT_FALSE(anyf.isReady());
448
449     promises[3].setException(eggs);
450     EXPECT_TRUE(anyf.isReady());
451     EXPECT_TRUE(anyf.value().second.hasException());
452   }
453
454   // then()
455   {
456     vector<Promise<int>> promises(10);
457     vector<Future<int>> futures;
458
459     for (auto& p : promises)
460       futures.push_back(p.getFuture());
461
462     auto anyf = whenAny(futures.begin(), futures.end())
463       .then([](Try<pair<size_t, Try<int>>>&& f) {
464         EXPECT_EQ(42, f.value().second.value());
465       });
466
467     promises[3].setValue(42);
468     EXPECT_TRUE(anyf.isReady());
469   }
470 }
471
472
473 TEST(when, already_completed) {
474   {
475     vector<Future<void>> fs;
476     for (int i = 0; i < 10; i++)
477       fs.push_back(makeFuture());
478
479     whenAll(fs.begin(), fs.end())
480       .then([&](Try<vector<Try<void>>>&& t) {
481         EXPECT_EQ(fs.size(), t.value().size());
482       });
483   }
484   {
485     vector<Future<int>> fs;
486     for (int i = 0; i < 10; i++)
487       fs.push_back(makeFuture(i));
488
489     whenAny(fs.begin(), fs.end())
490       .then([&](Try<pair<size_t, Try<int>>>&& t) {
491         auto& p = t.value();
492         EXPECT_EQ(p.first, p.second.value());
493       });
494   }
495 }
496
497 TEST(when, whenN) {
498   vector<Promise<void>> promises(10);
499   vector<Future<void>> futures;
500
501   for (auto& p : promises)
502     futures.push_back(p.getFuture());
503
504   bool flag = false;
505   size_t n = 3;
506   whenN(futures.begin(), futures.end(), n)
507     .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
508       flag = true;
509       auto v = t.value();
510       EXPECT_EQ(n, v.size());
511       for (auto& tt : v)
512         EXPECT_TRUE(tt.second.hasValue());
513     });
514
515   promises[0].setValue();
516   EXPECT_FALSE(flag);
517   promises[1].setValue();
518   EXPECT_FALSE(flag);
519   promises[2].setValue();
520   EXPECT_TRUE(flag);
521 }
522
523 /* Ensure that we can compile when_{all,any} with folly::small_vector */
524 TEST(when, small_vector) {
525
526   static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<void>),
527                 "Futures should not be trivially copyable");
528   static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<int>),
529                 "Futures should not be trivially copyable");
530
531   using folly::small_vector;
532   {
533     small_vector<Future<void>> futures;
534
535     for (int i = 0; i < 10; i++)
536       futures.push_back(makeFuture());
537
538     auto anyf = whenAny(futures.begin(), futures.end());
539   }
540
541   {
542     small_vector<Future<void>> futures;
543
544     for (int i = 0; i < 10; i++)
545       futures.push_back(makeFuture());
546
547     auto allf = whenAll(futures.begin(), futures.end());
548   }
549 }
550
551 TEST(Future, whenAllVariadic) {
552   Promise<bool> pb;
553   Promise<int> pi;
554   Future<bool> fb = pb.getFuture();
555   Future<int> fi = pi.getFuture();
556   bool flag = false;
557   whenAll(std::move(fb), std::move(fi))
558     .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
559       flag = true;
560       EXPECT_TRUE(t.hasValue());
561       EXPECT_TRUE(std::get<0>(t.value()).hasValue());
562       EXPECT_EQ(std::get<0>(t.value()).value(), true);
563       EXPECT_TRUE(std::get<1>(t.value()).hasValue());
564       EXPECT_EQ(std::get<1>(t.value()).value(), 42);
565     });
566   pb.setValue(true);
567   EXPECT_FALSE(flag);
568   pi.setValue(42);
569   EXPECT_TRUE(flag);
570 }
571
572 TEST(Future, whenAllVariadicReferences) {
573   Promise<bool> pb;
574   Promise<int> pi;
575   Future<bool> fb = pb.getFuture();
576   Future<int> fi = pi.getFuture();
577   bool flag = false;
578   whenAll(fb, fi)
579     .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
580       flag = true;
581       EXPECT_TRUE(t.hasValue());
582       EXPECT_TRUE(std::get<0>(t.value()).hasValue());
583       EXPECT_EQ(std::get<0>(t.value()).value(), true);
584       EXPECT_TRUE(std::get<1>(t.value()).hasValue());
585       EXPECT_EQ(std::get<1>(t.value()).value(), 42);
586     });
587   pb.setValue(true);
588   EXPECT_FALSE(flag);
589   pi.setValue(42);
590   EXPECT_TRUE(flag);
591 }
592
593 TEST(Future, whenAll_none) {
594   vector<Future<int>> fs;
595   auto f = whenAll(fs.begin(), fs.end());
596   EXPECT_TRUE(f.isReady());
597 }
598
599 TEST(Future, throwCaughtInImmediateThen) {
600   // Neither of these should throw "Promise already satisfied"
601   makeFuture().then(
602     [=](Try<void>&&) -> int { throw std::exception(); });
603   makeFuture().then(
604     [=](Try<void>&&) -> Future<int> { throw std::exception(); });
605 }
606
607 TEST(Future, throwIfFailed) {
608   makeFuture<void>(eggs)
609     .then([=](Try<void>&& t) {
610       EXPECT_THROW(t.throwIfFailed(), eggs_t);
611     });
612   makeFuture()
613     .then([=](Try<void>&& t) {
614       EXPECT_NO_THROW(t.throwIfFailed());
615     });
616
617   makeFuture<int>(eggs)
618     .then([=](Try<int>&& t) {
619       EXPECT_THROW(t.throwIfFailed(), eggs_t);
620     });
621   makeFuture<int>(42)
622     .then([=](Try<int>&& t) {
623       EXPECT_NO_THROW(t.throwIfFailed());
624     });
625 }
626
627 TEST(Future, waitWithSemaphoreImmediate) {
628   waitWithSemaphore(makeFuture());
629   auto done = waitWithSemaphore(makeFuture(42));
630   EXPECT_EQ(done, 42);
631 }
632
633 TEST(Future, waitWithSemaphore) {
634   Promise<int> p;
635   Future<int> f = p.getFuture();
636   std::atomic<bool> flag{false};
637   std::atomic<int> result{1};
638   std::atomic<std::thread::id> id;
639
640   std::thread t([&](Future<int>&& tf){
641       auto n = tf.then([&](Try<int> && t) {
642           id = std::this_thread::get_id();
643           return t.value();
644         });
645       flag = true;
646       result.store(waitWithSemaphore(std::move(n)));
647       LOG(INFO) << result;
648     },
649     std::move(f)
650     );
651   while(!flag){}
652   EXPECT_EQ(result.load(), 1);
653   p.setValue(42);
654   t.join();
655   // validate that the continuation ended up executing in this thread, which
656   // is more to ensure that this test actually tests what it should
657   EXPECT_EQ(id, std::this_thread::get_id());
658   EXPECT_EQ(result.load(), 42);
659 }