NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

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()