2 * Copyright 2014 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>
20 #include "folly/wangle/ManualExecutor.h"
21 #include "folly/wangle/InlineExecutor.h"
22 #include "folly/wangle/Later.h"
24 using namespace folly::wangle;
27 explicit ManualWaiter(std::shared_ptr<ManualExecutor> ex) : ex(ex) {}
34 std::shared_ptr<ManualExecutor> ex;
37 struct LaterFixture : public testing::Test {
39 westExecutor(new ManualExecutor),
40 eastExecutor(new ManualExecutor),
41 waiter(new ManualWaiter(westExecutor)),
45 ManualWaiter eastWaiter(eastExecutor);
47 eastWaiter.makeProgress();
53 eastExecutor->add([=]() { });
58 std::shared_ptr<ManualExecutor> westExecutor;
59 std::shared_ptr<ManualExecutor> eastExecutor;
60 std::shared_ptr<ManualWaiter> waiter;
61 InlineExecutor inlineExecutor;
66 TEST(Later, construct_and_launch) {
67 bool fulfilled = false;
68 auto later = Later<void>().then([&](Try<void>&& t) {
70 return makeFuture<int>(1);
73 // has not started yet.
74 EXPECT_FALSE(fulfilled);
76 EXPECT_EQ(later.launch().value(), 1);
77 EXPECT_TRUE(fulfilled);
80 TEST(Later, then_value) {
81 auto future = Later<int>(std::move(1))
82 .then([](Try<int>&& t) {
83 return t.value() == 1;
87 EXPECT_TRUE(future.value());
90 TEST(Later, then_future) {
91 auto future = Later<int>(1)
92 .then([](Try<int>&& t) {
93 return makeFuture(t.value() == 1);
96 EXPECT_TRUE(future.value());
99 TEST_F(LaterFixture, thread_hops) {
100 auto westThreadId = std::this_thread::get_id();
101 auto future = later.via(eastExecutor.get()).then([=](Try<void>&& t) {
102 EXPECT_NE(std::this_thread::get_id(), westThreadId);
103 return makeFuture<int>(1);
104 }).via(westExecutor.get()
105 ).then([=](Try<int>&& t) {
106 EXPECT_EQ(std::this_thread::get_id(), westThreadId);
109 while (!future.isReady()) {
110 waiter->makeProgress();
112 EXPECT_EQ(future.value(), 1);
115 TEST_F(LaterFixture, chain_laters) {
116 auto westThreadId = std::this_thread::get_id();
117 auto future = later.via(eastExecutor.get()).then([=](Try<void>&& t) {
118 EXPECT_NE(std::this_thread::get_id(), westThreadId);
119 return makeFuture<int>(1);
120 }).then([=](Try<int>&& t) {
122 return Later<int>(std::move(val)).via(westExecutor.get())
123 .then([=](Try<int>&& t) mutable {
124 EXPECT_EQ(std::this_thread::get_id(), westThreadId);
127 }).then([=](Try<int>&& t) {
128 EXPECT_EQ(std::this_thread::get_id(), westThreadId);
132 while (!future.isReady()) {
133 waiter->makeProgress();
135 EXPECT_EQ(future.value(), 1);
138 TEST_F(LaterFixture, fire_and_forget) {
139 auto west = westExecutor.get();
140 later.via(eastExecutor.get()).then([=](Try<void>&& t) {
143 waiter->makeProgress();