Adds writer test case for RCU
[folly.git] / folly / futures / test / PromiseTest.cpp
1 /*
2  * Copyright 2015-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/portability/GTest.h>
19
20 #include <memory>
21
22 using namespace folly;
23 using std::string;
24
25 using std::unique_ptr;
26 typedef FutureException eggs_t;
27 static eggs_t eggs("eggs");
28
29 TEST(Promise, makeEmpty) {
30   auto p = Promise<int>::makeEmpty();
31   EXPECT_TRUE(p.isFulfilled());
32 }
33
34 TEST(Promise, special) {
35   EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
36   EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
37   EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
38   EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
39 }
40
41 TEST(Promise, getSemiFuture) {
42   Promise<int> p;
43   SemiFuture<int> f = p.getSemiFuture();
44   EXPECT_FALSE(f.isReady());
45 }
46
47 TEST(Promise, getFuture) {
48   Promise<int> p;
49   Future<int> f = p.getFuture();
50   EXPECT_FALSE(f.isReady());
51 }
52
53 TEST(Promise, setValueUnit) {
54   Promise<Unit> p;
55   p.setValue();
56 }
57
58 TEST(Promise, setValueSemiFuture) {
59   Promise<int> fund;
60   auto ffund = fund.getSemiFuture();
61   fund.setValue(42);
62   EXPECT_EQ(42, ffund.value());
63
64   struct Foo {
65     string name;
66     int value;
67   };
68
69   Promise<Foo> pod;
70   auto fpod = pod.getSemiFuture();
71   Foo f = {"the answer", 42};
72   pod.setValue(f);
73   Foo f2 = fpod.value();
74   EXPECT_EQ(f.name, f2.name);
75   EXPECT_EQ(f.value, f2.value);
76
77   pod = Promise<Foo>();
78   fpod = pod.getSemiFuture();
79   pod.setValue(std::move(f2));
80   Foo f3 = fpod.value();
81   EXPECT_EQ(f.name, f3.name);
82   EXPECT_EQ(f.value, f3.value);
83
84   Promise<unique_ptr<int>> mov;
85   auto fmov = mov.getSemiFuture();
86   mov.setValue(std::make_unique<int>(42));
87   unique_ptr<int> ptr = std::move(fmov.value());
88   EXPECT_EQ(42, *ptr);
89
90   Promise<Unit> v;
91   auto fv = v.getSemiFuture();
92   v.setValue();
93   EXPECT_TRUE(fv.isReady());
94 }
95
96 TEST(Promise, setValue) {
97   Promise<int> fund;
98   auto ffund = fund.getFuture();
99   fund.setValue(42);
100   EXPECT_EQ(42, ffund.value());
101
102   struct Foo {
103     string name;
104     int value;
105   };
106
107   Promise<Foo> pod;
108   auto fpod = pod.getFuture();
109   Foo f = {"the answer", 42};
110   pod.setValue(f);
111   Foo f2 = fpod.value();
112   EXPECT_EQ(f.name, f2.name);
113   EXPECT_EQ(f.value, f2.value);
114
115   pod = Promise<Foo>();
116   fpod = pod.getFuture();
117   pod.setValue(std::move(f2));
118   Foo f3 = fpod.value();
119   EXPECT_EQ(f.name, f3.name);
120   EXPECT_EQ(f.value, f3.value);
121
122   Promise<unique_ptr<int>> mov;
123   auto fmov = mov.getFuture();
124   mov.setValue(std::make_unique<int>(42));
125   unique_ptr<int> ptr = std::move(fmov.value());
126   EXPECT_EQ(42, *ptr);
127
128   Promise<Unit> v;
129   auto fv = v.getFuture();
130   v.setValue();
131   EXPECT_TRUE(fv.isReady());
132 }
133
134 TEST(Promise, setException) {
135   {
136     Promise<Unit> p;
137     auto f = p.getFuture();
138     p.setException(eggs);
139     EXPECT_THROW(f.value(), eggs_t);
140   }
141   {
142     Promise<Unit> p;
143     auto f = p.getFuture();
144     // Calling setException() with an exception_ptr is deprecated,
145     // but don't complain about this in the test for this function.
146     FOLLY_PUSH_WARNING
147     FOLLY_GCC_DISABLE_WARNING("-Wdeprecated-declarations")
148     p.setException(std::make_exception_ptr(eggs));
149     FOLLY_POP_WARNING
150     EXPECT_THROW(f.value(), eggs_t);
151   }
152   {
153     Promise<Unit> p;
154     auto f = p.getFuture();
155     p.setException(exception_wrapper(eggs));
156     EXPECT_THROW(f.value(), eggs_t);
157   }
158 }
159
160 TEST(Promise, setWith) {
161   {
162     Promise<int> p;
163     auto f = p.getFuture();
164     p.setWith([] { return 42; });
165     EXPECT_EQ(42, f.value());
166   }
167   {
168     Promise<int> p;
169     auto f = p.getFuture();
170     p.setWith([]() -> int { throw eggs; });
171     EXPECT_THROW(f.value(), eggs_t);
172   }
173 }
174
175 TEST(Promise, isFulfilled) {
176   Promise<int> p;
177
178   EXPECT_FALSE(p.isFulfilled());
179   p.setValue(42);
180   EXPECT_TRUE(p.isFulfilled());
181 }
182
183 TEST(Promise, isFulfilledWithFuture) {
184   Promise<int> p;
185   auto f = p.getFuture(); // so core_ will become null
186
187   EXPECT_FALSE(p.isFulfilled());
188   p.setValue(42); // after here
189   EXPECT_TRUE(p.isFulfilled());
190 }
191
192 TEST(Promise, brokenOnDelete) {
193   auto p = std::make_unique<Promise<int>>();
194   auto f = p->getFuture();
195
196   EXPECT_FALSE(f.isReady());
197
198   p.reset();
199
200   EXPECT_TRUE(f.isReady());
201
202   auto t = f.getTry();
203
204   EXPECT_TRUE(t.hasException<BrokenPromise>());
205 }
206
207 TEST(Promise, brokenPromiseHasTypeInfo) {
208   auto pInt = std::make_unique<Promise<int>>();
209   auto fInt = pInt->getFuture();
210
211   auto pFloat = std::make_unique<Promise<float>>();
212   auto fFloat = pFloat->getFuture();
213
214   pInt.reset();
215   pFloat.reset();
216
217   auto whatInt = fInt.getTry().exception().what();
218   auto whatFloat = fFloat.getTry().exception().what();
219
220   EXPECT_NE(whatInt, whatFloat);
221 }