2 * Copyright 2017 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <folly/Baton.h>
20 #include <folly/futures/Future.h>
21 #include <folly/io/async/EventBase.h>
22 #include <folly/portability/GTest.h>
24 using namespace folly;
26 using std::chrono::milliseconds;
28 TEST(Wait, waitImmediate) {
30 auto done = makeFuture(42).wait().value();
34 auto done_v = makeFuture(v).wait().value();
35 EXPECT_EQ(v.size(), done_v.size());
38 vector<Future<Unit>> v_f;
39 v_f.push_back(makeFuture());
40 v_f.push_back(makeFuture());
41 auto done_v_f = collectAll(v_f).wait().value();
42 EXPECT_EQ(2, done_v_f.size());
44 vector<Future<bool>> v_fb;
45 v_fb.push_back(makeFuture(true));
46 v_fb.push_back(makeFuture(false));
47 auto fut = collectAll(v_fb);
48 auto done_v_fb = std::move(fut.wait().value());
49 EXPECT_EQ(2, done_v_fb.size());
54 Future<int> f = p.getFuture();
55 std::atomic<bool> flag{false};
56 std::atomic<int> result{1};
57 std::atomic<std::thread::id> id;
59 std::thread t([&](Future<int>&& tf){
60 auto n = tf.then([&](Try<int> && t) {
61 id = std::this_thread::get_id();
65 result.store(n.wait().value());
70 EXPECT_EQ(result.load(), 1);
73 // validate that the callback ended up executing in this thread, which
74 // is more to ensure that this test actually tests what it should
75 EXPECT_EQ(id, std::this_thread::get_id());
76 EXPECT_EQ(result.load(), 42);
81 MoveFlag& operator=(const MoveFlag&) = delete;
82 MoveFlag(const MoveFlag&) = delete;
83 MoveFlag(MoveFlag&& other) noexcept {
89 TEST(Wait, waitReplacesSelf) {
93 auto f1 = makeFuture(MoveFlag());
95 EXPECT_FALSE(f1.value().moved);
98 auto f2 = makeFuture(MoveFlag()).wait();
99 EXPECT_FALSE(f2.value().moved);
105 auto f1 = makeFuture(MoveFlag());
106 f1.wait(milliseconds(1));
107 EXPECT_FALSE(f1.value().moved);
110 auto f2 = makeFuture(MoveFlag()).wait(milliseconds(1));
111 EXPECT_FALSE(f2.value().moved);
118 auto f1 = makeFuture(MoveFlag());
120 EXPECT_FALSE(f1.value().moved);
123 auto f2 = makeFuture(MoveFlag()).waitVia(&eb);
124 EXPECT_FALSE(f2.value().moved);
128 TEST(Wait, waitWithDuration) {
131 Future<int> f = p.getFuture();
132 f.wait(milliseconds(1));
133 EXPECT_FALSE(f.isReady());
135 EXPECT_TRUE(f.isReady());
139 Future<int> f = p.getFuture();
141 f.wait(milliseconds(1));
142 EXPECT_TRUE(f.isReady());
145 vector<Future<bool>> v_fb;
146 v_fb.push_back(makeFuture(true));
147 v_fb.push_back(makeFuture(false));
148 auto f = collectAll(v_fb);
149 f.wait(milliseconds(1));
150 EXPECT_TRUE(f.isReady());
151 EXPECT_EQ(2, f.value().size());
154 vector<Future<bool>> v_fb;
157 v_fb.push_back(p1.getFuture());
158 v_fb.push_back(p2.getFuture());
159 auto f = collectAll(v_fb);
160 f.wait(milliseconds(1));
161 EXPECT_FALSE(f.isReady());
163 EXPECT_FALSE(f.isReady());
165 EXPECT_TRUE(f.isReady());
168 auto f = makeFuture().wait(milliseconds(1));
169 EXPECT_TRUE(f.isReady());
174 auto start = std::chrono::steady_clock::now();
175 auto f = p.getFuture().wait(milliseconds(100));
176 auto elapsed = std::chrono::steady_clock::now() - start;
177 EXPECT_GE(elapsed, milliseconds(100));
178 EXPECT_FALSE(f.isReady());
180 EXPECT_TRUE(f.isReady());
184 // Try to trigger the race where the resultant Future is not yet complete
185 // even if we didn't hit the timeout, and make sure we deal with it properly
188 auto t = std::thread([&]{
190 /* sleep override */ std::this_thread::sleep_for(milliseconds(100));
194 auto f = p.getFuture().wait(std::chrono::seconds(3600));
195 EXPECT_TRUE(f.isReady());
200 TEST(Wait, multipleWait) {
201 auto f = futures::sleep(milliseconds(100));
202 for (size_t i = 0; i < 5; ++i) {
203 EXPECT_FALSE(f.isReady());
204 f.wait(milliseconds(3));
206 EXPECT_FALSE(f.isReady());
208 EXPECT_TRUE(f.isReady());
210 EXPECT_TRUE(f.isReady());