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 <folly/futures/Future.h>
21 #include <gtest/gtest.h>
24 using namespace std::chrono;
25 using namespace folly;
27 TEST(RetryingTest, has_op_call) {
28 using ew = exception_wrapper;
29 auto policy_raw = [](size_t n, const ew&) { return n < 3; };
30 auto policy_fut = [](size_t n, const ew&) { return makeFuture(n < 3); };
31 using namespace futures::detail;
32 EXPECT_TRUE(retrying_policy_traits<decltype(policy_raw)>::is_raw::value);
33 EXPECT_TRUE(retrying_policy_traits<decltype(policy_fut)>::is_fut::value);
36 TEST(RetryingTest, basic) {
37 auto r = futures::retrying(
38 [](size_t n, const exception_wrapper&) { return n < 3; },
41 ? makeFuture<size_t>(runtime_error("ha"))
45 EXPECT_EQ(2, r.value());
48 TEST(RetryingTest, policy_future) {
49 atomic<size_t> sleeps {0};
50 auto r = futures::retrying(
51 [&](size_t n, const exception_wrapper&) {
53 ? makeFuture(++sleeps).then([] { return true; })
58 ? makeFuture<size_t>(runtime_error("ha"))
62 EXPECT_EQ(2, r.value());
66 TEST(RetryingTest, policy_basic) {
67 auto r = futures::retrying(
68 futures::retryingPolicyBasic(3),
71 ? makeFuture<size_t>(runtime_error("ha"))
75 EXPECT_EQ(2, r.value());
78 TEST(RetryingTest, policy_capped_jittered_exponential_backoff) {
79 using ms = milliseconds;
80 auto start = steady_clock::now();
81 auto r = futures::retrying(
82 futures::retryingPolicyCappedJitteredExponentialBackoff(
83 3, ms(100), ms(1000), 0.1, mt19937_64(0),
84 [](size_t, const exception_wrapper&) { return true; }),
87 ? makeFuture<size_t>(runtime_error("ha"))
91 auto finish = steady_clock::now();
92 auto duration = duration_cast<milliseconds>(finish - start);
93 EXPECT_EQ(2, r.value());
95 milliseconds(300).count(),
97 milliseconds(25).count());
100 TEST(RetryingTest, policy_sleep_defaults) {
101 // To ensure that this compiles with default params.
102 using ms = milliseconds;
103 auto start = steady_clock::now();
104 auto r = futures::retrying(
105 futures::retryingPolicyCappedJitteredExponentialBackoff(
106 3, ms(100), ms(1000), 0.1),
109 ? makeFuture<size_t>(runtime_error("ha"))
113 auto finish = steady_clock::now();
114 auto duration = duration_cast<milliseconds>(finish - start);
115 EXPECT_EQ(2, r.value());
117 milliseconds(300).count(),
119 milliseconds(100).count());
123 TEST(RetryingTest, policy_sleep_cancel) {
125 using ms = milliseconds;
126 auto start = steady_clock::now();
127 auto r = futures::retrying(
128 futures::retryingPolicyCappedJitteredExponentialBackoff(
129 5, ms(100), ms(1000), 0.1, rng,
130 [](size_t n, const exception_wrapper&) { return true; }),
133 ? makeFuture<size_t>(runtime_error("ha"))
139 auto finish = steady_clock::now();
140 auto duration = duration_cast<milliseconds>(finish - start);
141 EXPECT_EQ(2, r.value());
143 milliseconds(0).count(),
145 milliseconds(10).count());