def test_wait_func(self): def wait_func(retry_state): return retry_state.attempt_number * retry_state.seconds_since_start r = Retrying(wait=wait_func) self.assertEqual(r.wait(make_retry_state(1, 5)), 5) self.assertEqual(r.wait(make_retry_state(2, 11)), 22) self.assertEqual(r.wait(make_retry_state(10, 100)), 1000)
def test_stop_backward_compat(self): r = Retrying(stop=lambda attempt, delay: attempt == delay) with reports_deprecation_warning(): self.assertFalse(r.stop(make_retry_state(1, 3))) with reports_deprecation_warning(): self.assertFalse(r.stop(make_retry_state(100, 99))) with reports_deprecation_warning(): self.assertTrue(r.stop(make_retry_state(101, 101)))
def test_stop_func_with_retry_state(self): def stop_func(retry_state): rs = retry_state return rs.attempt_number == rs.seconds_since_start r = Retrying(stop=stop_func) self.assertFalse(r.stop(make_retry_state(1, 3))) self.assertFalse(r.stop(make_retry_state(100, 99))) self.assertTrue(r.stop(make_retry_state(101, 101)))
def test_exponential_retry_backoff_not_greater_than_30s(previous_attempt_number): retry_state = make_retry_state( previous_attempt_number=previous_attempt_number, delay_since_first_attempt=0 ) with testing_retries() as func: # Expecting the wait to be somewhere between 22.5 (30*.75) and 30 assert 22.5 <= func.retry.wait(retry_state) <= 30
def test_wait_class_backward_compatibility(self): """Ensure builtin objects accept both old and new parameters.""" waitobj = tenacity.wait_fixed(5) self.assertEqual(waitobj(1, 0.1), 5) self.assertEqual( waitobj(1, 0.1, tenacity.Future.construct(1, 1, False)), 5) retry_state = make_retry_state(123, 456) self.assertEqual(retry_state.attempt_number, 123) self.assertEqual(retry_state.seconds_since_start, 456) self.assertEqual(waitobj(retry_state=retry_state), 5)
def test_wait_random_exponential(self): fn = tenacity.wait_random_exponential(0.5, 60.0) for _ in six.moves.range(1000): self._assert_inclusive_range(fn(make_retry_state(1, 0)), 0, 1.0) self._assert_inclusive_range(fn(make_retry_state(2, 0)), 0, 2.0) self._assert_inclusive_range(fn(make_retry_state(3, 0)), 0, 4.0) self._assert_inclusive_range(fn(make_retry_state(4, 0)), 0, 8.0) self._assert_inclusive_range(fn(make_retry_state(5, 0)), 0, 16.0) self._assert_inclusive_range(fn(make_retry_state(6, 0)), 0, 32.0) self._assert_inclusive_range(fn(make_retry_state(7, 0)), 0, 60.0) self._assert_inclusive_range(fn(make_retry_state(8, 0)), 0, 60.0) self._assert_inclusive_range(fn(make_retry_state(9, 0)), 0, 60.0) fn = tenacity.wait_random_exponential(10, 5) for _ in six.moves.range(1000): self._assert_inclusive_range(fn(make_retry_state(1, 0)), 0.00, 5.00) # Default arguments exist fn = tenacity.wait_random_exponential() fn(0, 0)
def test_wait_random_exponential_statistically(self): fn = tenacity.wait_random_exponential(0.5, 60.0) attempt = [] for i in six.moves.range(10): attempt.append( [fn(make_retry_state(i, 0)) for _ in six.moves.range(4000)]) def mean(lst): return float(sum(lst)) / float(len(lst)) # skipping attempt 0 self._assert_inclusive_epsilon(mean(attempt[1]), 0.50, 0.04) self._assert_inclusive_epsilon(mean(attempt[2]), 1, 0.08) self._assert_inclusive_epsilon(mean(attempt[3]), 2, 0.16) self._assert_inclusive_epsilon(mean(attempt[4]), 4, 0.32) self._assert_inclusive_epsilon(mean(attempt[5]), 8, 0.64) self._assert_inclusive_epsilon(mean(attempt[6]), 16, 1.28) self._assert_inclusive_epsilon(mean(attempt[7]), 30, 2.56) self._assert_inclusive_epsilon(mean(attempt[8]), 30, 2.56) self._assert_inclusive_epsilon(mean(attempt[9]), 30, 2.56)
def test_stop_after_attempt(self): r = Retrying(stop=tenacity.stop_after_attempt(3)) self.assertFalse(r.stop(make_retry_state(2, 6546))) self.assertTrue(r.stop(make_retry_state(3, 6546))) self.assertTrue(r.stop(make_retry_state(4, 6546)))
def s(*args): return stop(make_retry_state(*args))
def r(fut): retry_state = make_retry_state(1, 1.0, last_result=fut) return retry(retry_state)
def test_never_stop(self): r = Retrying() self.assertFalse(r.stop(make_retry_state(3, 6546)))
def test_stop_after_delay(self): r = Retrying(stop=tenacity.stop_after_delay(1)) self.assertFalse(r.stop(make_retry_state(2, 0.999))) self.assertTrue(r.stop(make_retry_state(2, 1))) self.assertTrue(r.stop(make_retry_state(2, 1.001)))
def test_maximum_attempt_time_exceeded(delay_since_first_attempt, stop): retry_state = make_retry_state( previous_attempt_number=0, delay_since_first_attempt=delay_since_first_attempt) with testing_retries() as func: assert func.retry.stop(retry_state) is stop
retry=retry_if_api_request_error(status_codes=status_codes), wait=tenacity.wait_fixed(0), stop=tenacity.stop_after_attempt(2), reraise=True, ) def _retry_enabled_function(callable=None): if callable: return callable() yield _retry_enabled_function @pytest.mark.parametrize( "retry_state,max_wait", [ (make_retry_state(previous_attempt_number=1, delay_since_first_attempt=0), 0.25), (make_retry_state(previous_attempt_number=2, delay_since_first_attempt=0), 0.5), (make_retry_state(previous_attempt_number=3, delay_since_first_attempt=0), 1), (make_retry_state(previous_attempt_number=4, delay_since_first_attempt=0), 2), (make_retry_state(previous_attempt_number=5, delay_since_first_attempt=0), 4), (make_retry_state(previous_attempt_number=6, delay_since_first_attempt=0), 8), (make_retry_state(previous_attempt_number=7, delay_since_first_attempt=0), 16), (make_retry_state(previous_attempt_number=8, delay_since_first_attempt=0), 30), ],