2 * Copyright 2015 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 <gtest/gtest.h>
21 #include <folly/futures/Future.h>
22 #include <folly/io/async/EventBase.h>
23 #include <folly/Baton.h>
25 using namespace folly;
27 using std::chrono::milliseconds;
29 TEST(Wait, waitImmediate) {
31 auto done = makeFuture(42).wait().value();
35 auto done_v = makeFuture(v).wait().value();
36 EXPECT_EQ(v.size(), done_v.size());
39 vector<Future<Unit>> v_f;
40 v_f.push_back(makeFuture());
41 v_f.push_back(makeFuture());
42 auto done_v_f = collectAll(v_f).wait().value();
43 EXPECT_EQ(2, done_v_f.size());
45 vector<Future<bool>> v_fb;
46 v_fb.push_back(makeFuture(true));
47 v_fb.push_back(makeFuture(false));
48 auto fut = collectAll(v_fb);
49 auto done_v_fb = std::move(fut.wait().value());
50 EXPECT_EQ(2, done_v_fb.size());
55 Future<int> f = p.getFuture();
56 std::atomic<bool> flag{false};
57 std::atomic<int> result{1};
58 std::atomic<std::thread::id> id;
60 std::thread t([&](Future<int>&& tf){
61 auto n = tf.then([&](Try<int> && t) {
62 id = std::this_thread::get_id();
66 result.store(n.wait().value());
71 EXPECT_EQ(result.load(), 1);
74 // validate that the callback ended up executing in this thread, which
75 // is more to ensure that this test actually tests what it should
76 EXPECT_EQ(id, std::this_thread::get_id());
77 EXPECT_EQ(result.load(), 42);
82 MoveFlag& operator=(const MoveFlag&) = delete;
83 MoveFlag(const MoveFlag&) = delete;
84 MoveFlag(MoveFlag&& other) noexcept {
90 TEST(Wait, waitReplacesSelf) {
94 auto f1 = makeFuture(MoveFlag());
96 EXPECT_FALSE(f1.value().moved);
99 auto f2 = makeFuture(MoveFlag()).wait();
100 EXPECT_FALSE(f2.value().moved);
106 auto f1 = makeFuture(MoveFlag());
107 f1.wait(milliseconds(1));
108 EXPECT_FALSE(f1.value().moved);
111 auto f2 = makeFuture(MoveFlag()).wait(milliseconds(1));
112 EXPECT_FALSE(f2.value().moved);
119 auto f1 = makeFuture(MoveFlag());
121 EXPECT_FALSE(f1.value().moved);
124 auto f2 = makeFuture(MoveFlag()).waitVia(&eb);
125 EXPECT_FALSE(f2.value().moved);
129 TEST(Wait, waitWithDuration) {
132 Future<int> f = p.getFuture();
133 f.wait(milliseconds(1));
134 EXPECT_FALSE(f.isReady());
136 EXPECT_TRUE(f.isReady());
140 Future<int> f = p.getFuture();
142 f.wait(milliseconds(1));
143 EXPECT_TRUE(f.isReady());
146 vector<Future<bool>> v_fb;
147 v_fb.push_back(makeFuture(true));
148 v_fb.push_back(makeFuture(false));
149 auto f = collectAll(v_fb);
150 f.wait(milliseconds(1));
151 EXPECT_TRUE(f.isReady());
152 EXPECT_EQ(2, f.value().size());
155 vector<Future<bool>> v_fb;
158 v_fb.push_back(p1.getFuture());
159 v_fb.push_back(p2.getFuture());
160 auto f = collectAll(v_fb);
161 f.wait(milliseconds(1));
162 EXPECT_FALSE(f.isReady());
164 EXPECT_FALSE(f.isReady());
166 EXPECT_TRUE(f.isReady());
169 auto f = makeFuture().wait(milliseconds(1));
170 EXPECT_TRUE(f.isReady());
175 auto start = std::chrono::steady_clock::now();
176 auto f = p.getFuture().wait(milliseconds(100));
177 auto elapsed = std::chrono::steady_clock::now() - start;
178 EXPECT_GE(elapsed, milliseconds(100));
179 EXPECT_FALSE(f.isReady());
181 EXPECT_TRUE(f.isReady());
185 // Try to trigger the race where the resultant Future is not yet complete
186 // even if we didn't hit the timeout, and make sure we deal with it properly
189 auto t = std::thread([&]{
191 /* sleep override */ std::this_thread::sleep_for(milliseconds(100));
195 auto f = p.getFuture().wait(std::chrono::seconds(3600));
196 EXPECT_TRUE(f.isReady());
201 TEST(Wait, multipleWait) {
202 auto f = futures::sleep(milliseconds(100));
203 for (size_t i = 0; i < 5; ++i) {
204 EXPECT_FALSE(f.isReady());
205 f.wait(milliseconds(3));
207 EXPECT_FALSE(f.isReady());
209 EXPECT_TRUE(f.isReady());
211 EXPECT_TRUE(f.isReady());