1 | /* |
2 | * Copyright 2017-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/executors/ThreadedExecutor.h> |
18 | |
19 | #include <folly/Conv.h> |
20 | #include <folly/futures/Future.h> |
21 | #include <folly/gen/Base.h> |
22 | #include <folly/portability/GTest.h> |
23 | |
24 | namespace { |
25 | |
26 | class ThreadedExecutorTest : public testing::Test {}; |
27 | } // namespace |
28 | |
29 | TEST_F(ThreadedExecutorTest, example) { |
30 | folly::ThreadedExecutor x; |
31 | auto ret = folly::via(&x) |
32 | .thenValue([&](auto&&) { return 42; }) |
33 | .thenValue([&](int n) { return folly::to<std::string>(n); }) |
34 | .get(); |
35 | |
36 | EXPECT_EQ("42" , ret); |
37 | } |
38 | |
39 | TEST_F(ThreadedExecutorTest, dtor_waits) { |
40 | constexpr auto kDelay = std::chrono::milliseconds(100); |
41 | auto x = std::make_unique<folly::ThreadedExecutor>(); |
42 | auto fut = folly::via(&*x, [&] { /* sleep override */ |
43 | std::this_thread::sleep_for(kDelay); |
44 | }); |
45 | x = nullptr; |
46 | |
47 | EXPECT_TRUE(fut.isReady()); |
48 | } |
49 | |
50 | TEST_F(ThreadedExecutorTest, many) { |
51 | constexpr auto kNumTasks = 1024; |
52 | folly::ThreadedExecutor x; |
53 | auto rets = |
54 | folly::collect( |
55 | folly::gen::range<size_t>(0, kNumTasks) | |
56 | folly::gen::map([&](size_t i) { |
57 | return folly::via(&x) |
58 | .thenValue([=](auto&&) { return i; }) |
59 | .thenValue([](size_t k) { return folly::to<std::string>(k); }); |
60 | }) | |
61 | folly::gen::as<std::vector>()) |
62 | .get(); |
63 | |
64 | EXPECT_EQ("42" , rets[42]); |
65 | } |
66 | |
67 | TEST_F(ThreadedExecutorTest, many_sleeping_constant_time) { |
68 | constexpr auto kNumTasks = 256; |
69 | constexpr auto kDelay = std::chrono::milliseconds(100); |
70 | folly::ThreadedExecutor x; |
71 | auto rets = |
72 | folly::collect( |
73 | folly::gen::range<size_t>(0, kNumTasks) | |
74 | folly::gen::map([&](size_t i) { |
75 | return folly::via(&x) |
76 | .thenValue([=](auto&&) { |
77 | /* sleep override */ std::this_thread::sleep_for(kDelay); |
78 | }) |
79 | .thenValue([=](auto&&) { return i; }) |
80 | .thenValue([](size_t k) { return folly::to<std::string>(k); }); |
81 | }) | |
82 | folly::gen::as<std::vector>()) |
83 | .get(); |
84 | |
85 | EXPECT_EQ("42" , rets[42]); |
86 | } |
87 | |
88 | TEST_F(ThreadedExecutorTest, many_sleeping_decreasing_time) { |
89 | constexpr auto kNumTasks = 256; |
90 | constexpr auto kDelay = std::chrono::milliseconds(100); |
91 | folly::ThreadedExecutor x; |
92 | auto rets = |
93 | folly::collect( |
94 | folly::gen::range<size_t>(0, kNumTasks) | |
95 | folly::gen::map([&](size_t i) { |
96 | return folly::via(&x) |
97 | .thenValue([=](auto&&) { |
98 | auto delay = kDelay * (kNumTasks - i) / kNumTasks; |
99 | /* sleep override */ std::this_thread::sleep_for(delay); |
100 | }) |
101 | .thenValue([=](auto&&) { return i; }) |
102 | .thenValue([](size_t k) { return folly::to<std::string>(k); }); |
103 | }) | |
104 | folly::gen::as<std::vector>()) |
105 | .get(); |
106 | |
107 | EXPECT_EQ("42" , rets[42]); |
108 | } |
109 | |