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.
17 #include <gtest/gtest.h>
19 #include <folly/futures/Future.h>
20 #include <folly/io/async/EventBase.h>
21 #include <folly/Baton.h>
23 using namespace folly;
25 using std::chrono::milliseconds;
27 TEST(Wait, waitImmediate) {
29 auto done = makeFuture(42).wait().value();
33 auto done_v = makeFuture(v).wait().value();
34 EXPECT_EQ(v.size(), done_v.size());
37 vector<Future<Unit>> v_f;
38 v_f.push_back(makeFuture());
39 v_f.push_back(makeFuture());
40 auto done_v_f = collectAll(v_f).wait().value();
41 EXPECT_EQ(2, done_v_f.size());
43 vector<Future<bool>> v_fb;
44 v_fb.push_back(makeFuture(true));
45 v_fb.push_back(makeFuture(false));
46 auto fut = collectAll(v_fb);
47 auto done_v_fb = std::move(fut.wait().value());
48 EXPECT_EQ(2, done_v_fb.size());
53 Future<int> f = p.getFuture();
54 std::atomic<bool> flag{false};
55 std::atomic<int> result{1};
56 std::atomic<std::thread::id> id;
58 std::thread t([&](Future<int>&& tf){
59 auto n = tf.then([&](Try<int> && t) {
60 id = std::this_thread::get_id();
64 result.store(n.wait().value());
69 EXPECT_EQ(result.load(), 1);
72 // validate that the callback ended up executing in this thread, which
73 // is more to ensure that this test actually tests what it should
74 EXPECT_EQ(id, std::this_thread::get_id());
75 EXPECT_EQ(result.load(), 42);
80 MoveFlag& operator=(const MoveFlag&) = delete;
81 MoveFlag(const MoveFlag&) = delete;
82 MoveFlag(MoveFlag&& other) noexcept {
88 TEST(Wait, waitReplacesSelf) {
92 auto f1 = makeFuture(MoveFlag());
94 EXPECT_FALSE(f1.value().moved);
97 auto f2 = makeFuture(MoveFlag()).wait();
98 EXPECT_FALSE(f2.value().moved);
104 auto f1 = makeFuture(MoveFlag());
105 f1.wait(milliseconds(1));
106 EXPECT_FALSE(f1.value().moved);
109 auto f2 = makeFuture(MoveFlag()).wait(milliseconds(1));
110 EXPECT_FALSE(f2.value().moved);
117 auto f1 = makeFuture(MoveFlag());
119 EXPECT_FALSE(f1.value().moved);
122 auto f2 = makeFuture(MoveFlag()).waitVia(&eb);
123 EXPECT_FALSE(f2.value().moved);
127 TEST(Wait, waitWithDuration) {
130 Future<int> f = p.getFuture();
131 f.wait(milliseconds(1));
132 EXPECT_FALSE(f.isReady());
134 EXPECT_TRUE(f.isReady());
138 Future<int> f = p.getFuture();
140 f.wait(milliseconds(1));
141 EXPECT_TRUE(f.isReady());
144 vector<Future<bool>> v_fb;
145 v_fb.push_back(makeFuture(true));
146 v_fb.push_back(makeFuture(false));
147 auto f = collectAll(v_fb);
148 f.wait(milliseconds(1));
149 EXPECT_TRUE(f.isReady());
150 EXPECT_EQ(2, f.value().size());
153 vector<Future<bool>> v_fb;
156 v_fb.push_back(p1.getFuture());
157 v_fb.push_back(p2.getFuture());
158 auto f = collectAll(v_fb);
159 f.wait(milliseconds(1));
160 EXPECT_FALSE(f.isReady());
162 EXPECT_FALSE(f.isReady());
164 EXPECT_TRUE(f.isReady());
167 auto f = makeFuture().wait(milliseconds(1));
168 EXPECT_TRUE(f.isReady());
173 auto start = std::chrono::steady_clock::now();
174 auto f = p.getFuture().wait(milliseconds(100));
175 auto elapsed = std::chrono::steady_clock::now() - start;
176 EXPECT_GE(elapsed, milliseconds(100));
177 EXPECT_FALSE(f.isReady());
179 EXPECT_TRUE(f.isReady());
183 // Try to trigger the race where the resultant Future is not yet complete
184 // even if we didn't hit the timeout, and make sure we deal with it properly
187 auto t = std::thread([&]{
189 /* sleep override */ std::this_thread::sleep_for(milliseconds(100));
193 auto f = p.getFuture().wait(std::chrono::seconds(3600));
194 EXPECT_TRUE(f.isReady());