15 #include <aws/core/utils/Outcome.h> 17 #include <gtest/gtest.h> 24 typedef Aws::Utils::Outcome<int, Aws::Client::AWSError<DummyClientErrors>>
DummyOutcome;
31 throttled_function_call_count_++;
34 mutable std::atomic<int> throttled_function_call_count_{0};
47 throttled_function_call_count_++;
51 return MakeCall<DummyOutcome, int, DummyClientErrors>(
55 mutable std::atomic<int> throttled_function_call_count_{0};
58 TEST(ThrottlingManagerTest, simpleThrottling)
60 double max_tps = 100.0;
61 int api_call_count = 100;
63 for (
int idx = 0; idx < api_call_count; idx++) {
65 ASSERT_TRUE(outcome.IsSuccess());
66 std::this_thread::sleep_for(std::chrono::milliseconds(
int(1000.0 / max_tps)));
71 int succesful_outcomes = 0;
72 for (
int idx = 0; idx < api_call_count; idx++) {
73 int call_count_before = throttled_client.BaseClient::throttled_function_call_count_;
75 if (outcome.IsSuccess()) {
80 std::this_thread::sleep_for(std::chrono::milliseconds(
int(1000.0 / max_tps)));
82 ASSERT_NEAR(succesful_outcomes, api_call_count / 2.0, 3);
90 std::chrono::microseconds sleep_duration)
92 auto now = std::chrono::steady_clock::now();
93 auto prev_now = now - sleep_duration;
94 auto end = std::chrono::steady_clock::now() + duration;
99 if (now - prev_now > sleep_duration) {
100 std::this_thread::sleep_for(sleep_duration - (now - prev_now - sleep_duration));
102 std::this_thread::sleep_for(sleep_duration);
105 now = std::chrono::steady_clock::now();
113 TEST(ThrottlingManagerTest, multiThreadedClientThrottling)
115 const int milliseconds_to_run = 3500, sleep_duration_in_us = 150, max_tps = 125;
116 int threads_to_spawn = std::max(2u, std::thread::hardware_concurrency());
118 std::vector<std::thread> threads;
119 threads.reserve(threads_to_spawn);
120 for (
int tid = 0; tid < threads_to_spawn; tid++) {
121 threads.emplace_back(
MakeCalls, &throttled_client,
122 std::chrono::milliseconds(milliseconds_to_run),
123 std::chrono::microseconds(sleep_duration_in_us));
125 for (
auto & t : threads) {
128 int expected_non_throttled_call_count = std::ceil(max_tps * milliseconds_to_run / static_cast<float>(1000));
129 ASSERT_LE(throttled_client.BaseClient::throttled_function_call_count_,
130 expected_non_throttled_call_count);
133 int main(
int argc,
char ** argv)
135 testing::InitGoogleTest(&argc, argv);
136 return RUN_ALL_TESTS();
ThrottledClient(double max_api_tps)
DummyOutcome ThrottledFunction() const
int main(int argc, char **argv)
TEST(ThrottlingManagerTest, simpleThrottling)
virtual DummyOutcome ThrottledFunction(int number) const
void MakeCalls(ThrottledClient *throttled_client, std::chrono::milliseconds duration, std::chrono::microseconds sleep_duration)
Aws::Utils::Outcome< int, Aws::Client::AWSError< DummyClientErrors > > DummyOutcome
void SetMaxApiTps(const std::string &api, double tps)