test_retry.py (4323B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\common\script\util\test\test_retry.py 2 from __future__ import print_function 3 from eve.common.script.util.retry import retry_with_exponential_backoff 4 from mock import Mock 5 from stackless_response_router.exceptions import TimeoutException 6 from testsuites.testcases import ServerClientTestCase 7 8 class TestRetry(ServerClientTestCase): 9 10 def test_with_the_default_one_attempt_tries_once(self): 11 self._test_retry(retries_needed=1, max_attempts=1, expected_calls=1) 12 13 def test_with_the_default_one_attempt_tries_once_even_if_it_times_out(self): 14 self._test_retry(retries_needed=1, max_attempts=1, expected_calls=1, should_raise_exception_class=TimeoutException) 15 16 def test_with_the_default_one_attempt_tries_once_even_if_it_should_retry(self): 17 self._test_retry(retries_needed=1, max_attempts=1, expected_calls=1, force_retry=True) 18 19 def test_with_multiple_attempts_tries_once_if_enough(self): 20 self._test_retry(retries_needed=1, max_attempts=10, expected_calls=1) 21 22 def test_with_multiple_timeout_attempts_tries_twice_if_needed(self): 23 self._test_retry(retries_needed=2, max_attempts=10, expected_calls=2) 24 25 def test_with_multiple_timeout_attempts_tries_max_times_if_needed(self): 26 self._test_retry(retries_needed=10, max_attempts=10, expected_calls=10) 27 28 def test_with_multiple_timeout_attempts_times_out_if_more_than_max_attempts_needed(self): 29 self._test_retry(retries_needed=11, max_attempts=10, expected_calls=10, should_timeout=True) 30 31 def test_with_multiple_attempts_and_special_should_retry_tries_max_times_if_needed(self): 32 self._test_retry(retries_needed=10, max_attempts=10, expected_calls=10, force_retry=True) 33 34 def test_with_multiple_attempts_and_special_should_retry_stops_trying_if_more_than_max_attempts_needed(self): 35 self._test_retry(retries_needed=11, max_attempts=10, expected_calls=10, force_retry=True) 36 37 def test_with_the_default_one_attempt_propagates_exceptions_other_than_timeout(self): 38 self._test_retry(retries_needed=1, max_attempts=1, expected_calls=1, should_raise_exception_class=Exception) 39 40 def test_with_multiple_attempts_propagates_exceptions_other_than_timeout_right_away(self): 41 self._test_retry(retries_needed=1, max_attempts=10, expected_calls=1, should_raise_exception_class=Exception) 42 43 def _test_retry(self, retries_needed, max_attempts, expected_calls, force_retry = False, should_timeout = False, should_raise_exception_class = None): 44 retries_tracker = RetriesTracker(retries_needed, should_raise_exception_class, force_retry) 45 if should_timeout: 46 expected_exception = TimeoutException 47 else: 48 expected_exception = should_raise_exception_class 49 if expected_exception: 50 with self.assertRaises(expected_exception): 51 retry_with_exponential_backoff(func=retries_tracker.do, max_attempts=max_attempts, retry_delay_in_seconds=1, jitter=True, waiter=Mock(), should_retry=lambda result: force_retry or isinstance(result, TimeoutException)) 52 else: 53 retry_with_exponential_backoff(func=retries_tracker.do, max_attempts=max_attempts, retry_delay_in_seconds=1, jitter=True, waiter=Mock(), should_retry=lambda result: force_retry or isinstance(result, TimeoutException)) 54 print('retries_tracker.number_of_calls', retries_tracker.number_of_calls, 'expected', expected_calls) 55 self.assertEqual(retries_tracker.number_of_calls, expected_calls) 56 57 58 class RetriesTracker(object): 59 60 def __init__(self, retries_needed, should_raise_exception_class, force_retry): 61 self.retries_needed = retries_needed 62 self.should_raise_exception_class = should_raise_exception_class 63 self.force_retry = force_retry 64 self.number_of_calls = 0 65 66 def do(self): 67 self.number_of_calls += 1 68 if self.should_raise_exception_class: 69 raise self.should_raise_exception_class('RetriesTracker encountered an existential crisis') 70 if self.number_of_calls < self.retries_needed: 71 if self.force_retry: 72 return Mock() 73 raise TimeoutException('RetriesTracker went on vacation, try again later') 74 else: 75 return Mock()