72 lines
3.2 KiB
Python
72 lines
3.2 KiB
Python
from tests import unittest
|
|
|
|
|
|
from botocore.retries import throttling
|
|
|
|
|
|
class TestCubicCalculator(unittest.TestCase):
|
|
def create_cubic_calculator(self, starting_max_rate=10, beta=0.7,
|
|
scale_constant=0.4):
|
|
return throttling.CubicCalculator(starting_max_rate=starting_max_rate,
|
|
scale_constant=scale_constant,
|
|
start_time=0, beta=beta)
|
|
|
|
# For these tests, rather than duplicate the formulas in the tests,
|
|
# I want to check against a fixed set of inputs with by-hand verified
|
|
# values to ensure we're doing the calculations correctly.
|
|
|
|
def test_starting_params(self):
|
|
cubic = self.create_cubic_calculator(starting_max_rate=10)
|
|
self.assertAlmostEqual(
|
|
cubic.get_params_snapshot().k, 1.9574338205844317
|
|
)
|
|
|
|
def test_success_responses_until_max_hit(self):
|
|
# For this test we're interested in the behavior less so than
|
|
# the specific numbers. There's a few cases we care about:
|
|
#
|
|
cubic = self.create_cubic_calculator(starting_max_rate=10)
|
|
params = cubic.get_params_snapshot()
|
|
start_k = params.k
|
|
start_w_max = params.w_max
|
|
# Before we get to t == start_k, our throttle is below our
|
|
# max w_max
|
|
assertLessEqual = self.assertLessEqual
|
|
assertLessEqual(cubic.success_received(start_k / 3.0), start_w_max)
|
|
assertLessEqual(cubic.success_received(start_k / 2.0), start_w_max)
|
|
assertLessEqual(cubic.success_received(start_k / 1.1), start_w_max)
|
|
# At t == start_k, we should be at w_max.
|
|
self.assertAlmostEqual(cubic.success_received(timestamp=start_k), 10.0)
|
|
# And once we pass start_k, we'll be above w_max.
|
|
self.assertGreaterEqual(
|
|
cubic.success_received(start_k * 1.1), start_w_max)
|
|
self.assertGreaterEqual(
|
|
cubic.success_received(start_k * 2.0), start_w_max)
|
|
|
|
def test_error_response_decreases_rate_by_beta(self):
|
|
# This is the default value here so we're just being explicit.
|
|
cubic = self.create_cubic_calculator(starting_max_rate=10, beta=0.7)
|
|
|
|
# So let's say we made it up to 8 TPS before we were throttled.
|
|
rate_when_throttled = 8
|
|
new_rate = cubic.error_received(current_rate=rate_when_throttled,
|
|
timestamp=1)
|
|
self.assertAlmostEqual(new_rate, rate_when_throttled * 0.7)
|
|
|
|
new_params = cubic.get_params_snapshot()
|
|
self.assertEqual(
|
|
new_params,
|
|
throttling.CubicParams(w_max=rate_when_throttled,
|
|
k=1.8171205928321397,
|
|
last_fail=1)
|
|
)
|
|
|
|
def test_t_0_should_match_beta_decrease(self):
|
|
# So if I have beta of 0.6
|
|
cubic = self.create_cubic_calculator(starting_max_rate=10, beta=0.6)
|
|
# When I get throttled I should decrease my rate by 60%.
|
|
new_rate = cubic.error_received(current_rate=10, timestamp=1)
|
|
self.assertEqual(new_rate, 6.0)
|
|
# And my starting rate at time t=1 should start at that new rate.
|
|
self.assertAlmostEqual(cubic.success_received(timestamp=1), 6.0)
|