folly: build with -Wunused-parameter
[folly.git] / folly / futures / test / TimesTest.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 <memory>
18 #include <mutex>
19 #include <queue>
20
21 #include <gtest/gtest.h>
22 #include <glog/logging.h>
23
24 #include <folly/futures/Future.h>
25 #include <folly/futures/Promise.h>
26
27 using namespace folly;
28
29 inline void popAndFulfillPromise(
30     std::queue<std::shared_ptr<Promise<Unit>>>& ps,
31     std::mutex& ps_mutex) {
32   ps_mutex.lock();
33   auto p = ps.front();
34   ps.pop();
35   ps_mutex.unlock();
36   p->setValue();
37 }
38
39 inline std::function<Future<Unit>(void)> makeThunk(
40     std::queue<std::shared_ptr<Promise<Unit>>>& ps,
41     int& interrupt,
42     std::mutex& ps_mutex) {
43   return [&]() mutable {
44     auto p = std::make_shared<Promise<Unit>>();
45     p->setInterruptHandler(
46         [&](exception_wrapper const& /* e */) { ++interrupt; });
47     ps_mutex.lock();
48     ps.push(p);
49     ps_mutex.unlock();
50
51     return p->getFuture();
52   };
53 }
54
55 inline std::function<bool(void)> makePred(int& i) {
56   return [&]() {
57     bool res = i < 3;
58     ++i;
59     return res;
60   };
61 }
62
63 TEST(Times, success) {
64   std::queue<std::shared_ptr<Promise<Unit>>> ps;
65   std::mutex ps_mutex;
66   int interrupt = 0;
67   bool complete = false;
68   bool failure = false;
69
70   auto thunk = makeThunk(ps, interrupt, ps_mutex);
71   auto f = folly::times(3, thunk).then([&]() mutable {
72     complete = true;
73   }).onError([&](FutureException& /* e */) { failure = true; });
74
75   popAndFulfillPromise(ps, ps_mutex);
76   EXPECT_FALSE(complete);
77   EXPECT_FALSE(failure);
78
79   popAndFulfillPromise(ps, ps_mutex);
80   EXPECT_FALSE(complete);
81   EXPECT_FALSE(failure);
82
83   popAndFulfillPromise(ps, ps_mutex);
84   EXPECT_TRUE(f.isReady());
85   EXPECT_TRUE(complete);
86   EXPECT_FALSE(failure);
87 }
88
89 TEST(Times, failure) {
90   std::queue<std::shared_ptr<Promise<Unit>>> ps;
91   std::mutex ps_mutex;
92   int interrupt = 0;
93   bool complete = false;
94   bool failure = false;
95
96   auto thunk = makeThunk(ps, interrupt, ps_mutex);
97   auto f = folly::times(3, thunk).then([&]() mutable {
98     complete = true;
99   }).onError([&](FutureException& /* e */) { failure = true; });
100
101   popAndFulfillPromise(ps, ps_mutex);
102   EXPECT_FALSE(complete);
103   EXPECT_FALSE(failure);
104
105   ps_mutex.lock();
106   auto p2 = ps.front();
107   ps.pop();
108   ps_mutex.unlock();
109   FutureException eggs("eggs");
110   p2->setException(eggs);
111
112   EXPECT_TRUE(f.isReady());
113   EXPECT_FALSE(complete);
114   EXPECT_TRUE(failure);
115 }
116
117 TEST(Times, interrupt) {
118   std::queue<std::shared_ptr<Promise<Unit>>> ps;
119   std::mutex ps_mutex;
120   int interrupt = 0;
121   bool complete = false;
122   bool failure = false;
123
124   auto thunk = makeThunk(ps, interrupt, ps_mutex);
125   auto f = folly::times(3, thunk).then([&]() mutable {
126     complete = true;
127   }).onError([&](FutureException& /* e */) { failure = true; });
128
129   EXPECT_EQ(0, interrupt);
130
131   FutureException eggs("eggs");
132   f.raise(eggs);
133
134   for (int i = 1; i <= 3; ++i) {
135     EXPECT_EQ(1, interrupt);
136     popAndFulfillPromise(ps, ps_mutex);
137   }
138 }