Files
2024-02-15 17:01:50 +00:00

95 lines
3.1 KiB
Python

from unittest import TestCase, mock
import pytest
from sentry.utils.retries import ConditionalRetryPolicy, RetryException, TimedRetryPolicy
class ConditionalRetryPolicyTestCase(TestCase):
bomb = Exception("Boom!")
def test_policy_success(self) -> None:
callable = mock.MagicMock(side_effect=[self.bomb, mock.sentinel.OK])
always_retry = lambda i, e: True
assert ConditionalRetryPolicy(always_retry)(callable) is mock.sentinel.OK
assert callable.call_count == 2
def test_poilcy_failure(self) -> None:
callable = mock.MagicMock(side_effect=self.bomb)
never_retry = lambda i, e: False
with pytest.raises(Exception) as e:
ConditionalRetryPolicy(never_retry)(callable)
assert callable.call_count == 1
assert e.value is self.bomb
def test_policy_counter(self) -> None:
callable = mock.MagicMock(side_effect=self.bomb)
retry_once = lambda i, e: i < 2
with pytest.raises(Exception) as e:
ConditionalRetryPolicy(retry_once)(callable)
assert callable.call_count == 2
assert e.value is self.bomb
def test_policy_exception_filtering(self) -> None:
errors = [Exception(), Exception(), Exception()]
callable = mock.MagicMock(side_effect=errors)
sometimes_retry = lambda i, e: e is not errors[-1]
with pytest.raises(Exception) as e:
ConditionalRetryPolicy(sometimes_retry)(callable)
assert e.value is errors[-1]
assert callable.call_count == 3
class TimedRetryPolicyTestCase(TestCase):
def test_policy_success(self):
bomb = Exception("Boom!")
callable = mock.MagicMock(side_effect=[bomb, mock.sentinel.OK])
retry = TimedRetryPolicy(0.3, delay=lambda i: 0.1)
retry.clock = mock.Mock()
retry.clock.sleep = mock.MagicMock()
retry.clock.time = mock.MagicMock(side_effect=[0, 0.15])
assert retry(callable) is mock.sentinel.OK
assert callable.call_count == 2
def test_policy_failure(self):
bomb = Exception("Boom!")
callable = mock.MagicMock(side_effect=bomb)
retry = TimedRetryPolicy(0.3, delay=lambda i: 0.1)
retry.clock = mock.Mock()
retry.clock.sleep = mock.MagicMock()
retry.clock.time = mock.MagicMock(side_effect=[0, 0.15, 0.25])
try:
retry(callable)
except RetryException as exception:
assert exception.exception is bomb
else:
self.fail(f"Expected {RetryException!r}!")
assert callable.call_count == 2
def test_decorator(self):
bomb = Exception("Boom!")
callable = mock.MagicMock(side_effect=[bomb, mock.sentinel.OK])
@TimedRetryPolicy.wrap(0.3, delay=lambda i: 0.1)
def retrying_func():
return callable()
retrying_func.clock = mock.Mock()
retrying_func.clock.sleep = mock.MagicMock()
retrying_func.clock.time = mock.MagicMock(side_effect=[0, 0.15, 0.25])
assert retrying_func() is mock.sentinel.OK
assert callable.call_count == 2