def _perform_add_event(self, response_sequence): """ Given a sequence of functions that take an intent and returns a response (or raises an exception), perform :func:`add_event` and return the result. """ log = object() eff = add_event(self.event, 'tid', 'ord', log) uid = '00000000-0000-0000-0000-000000000000' svrq = service_request( ServiceType.CLOUD_FEEDS, 'POST', 'autoscale/events', headers={'content-type': ['application/vnd.rackspace.atom+json']}, data=self._get_request('INFO', uid, 'tid'), log=log, success_pred=has_code(201), json_response=False) seq = [ (TenantScope(mock.ANY, 'tid'), nested_sequence([ retry_sequence( Retry(effect=svrq, should_retry=ShouldDelayAndRetry( can_retry=mock.ANY, next_interval=exponential_backoff_interval(2))), response_sequence) ])) ] return perform_sequence(seq, eff)
def _perform_add_event(self, response_sequence): """ Given a sequence of functions that take an intent and returns a response (or raises an exception), perform :func:`add_event` and return the result. """ log = object() eff = add_event(self.event, 'tid', 'ord', log) uid = '00000000-0000-0000-0000-000000000000' svrq = service_request( ServiceType.CLOUD_FEEDS, 'POST', 'autoscale/events', headers={ 'content-type': ['application/vnd.rackspace.atom+json']}, data=self._get_request('INFO', uid, 'tid'), log=log, success_pred=has_code(201), json_response=False) seq = [ (TenantScope(mock.ANY, 'tid'), nested_sequence([ retry_sequence( Retry(effect=svrq, should_retry=ShouldDelayAndRetry( can_retry=mock.ANY, next_interval=exponential_backoff_interval(2))), response_sequence ) ])) ] return perform_sequence(seq, eff)
def test_can_have_a_different_should_retry_function(self): """ The ``should_retry`` function does not have to be a :obj:`ShouldDelayAndRetry`. """ expected = Retry(effect=Effect(1), should_retry=ANY) actual = Retry(effect=Effect(1), should_retry=lambda _: False) seq = [ retry_sequence(expected, [lambda _: raise_(Exception())]) ] self.assertRaises(Exception, perform_sequence, seq, Effect(actual))
def test_retry_sequence_fails_if_mismatch_sequence(self): """ Fail if the wrong number of performers are given. """ r = Retry( effect=Effect(1), should_retry=ShouldDelayAndRetry( can_retry=retry_times(5), next_interval=repeating_interval(10))) seq = [ retry_sequence(r, [lambda _: raise_(Exception()), lambda _: raise_(Exception())]) ] self.assertRaises(AssertionError, perform_sequence, seq, Effect(r))
def test_do_not_have_to_expect_an_exact_can_retry(self): """ The expected retry intent does not actually have to specify the exact ``can_retry`` function, since it might just be a lambda, which is hard to compare or hash. """ expected = Retry(effect=Effect(1), should_retry=ANY) actual = Retry(effect=Effect(1), should_retry=ShouldDelayAndRetry( can_retry=lambda _: False, next_interval=repeating_interval(10))) seq = [ retry_sequence(expected, [lambda _: raise_(Exception())]) ] self.assertRaises(Exception, perform_sequence, seq, Effect(actual))
def test_retry_sequence_retries_without_delays(self): """ Perform the wrapped effect with the performers given, without any delay even if the original intent had a delay. """ r = Retry( effect=Effect(1), should_retry=ShouldDelayAndRetry( can_retry=retry_times(5), next_interval=repeating_interval(10))) seq = [ retry_sequence(r, [lambda _: raise_(Exception()), lambda _: raise_(Exception()), lambda _: "yay done"]) ] self.assertEqual(perform_sequence(seq, Effect(r)), "yay done")
def test_fallback(self): """ Accept a ``fallback`` dispatcher that will be used if a performer returns an effect for an intent that is not covered by the base dispatcher. """ def dispatch_2(intent): if intent == 2: return sync_performer(lambda d, i: "yay done") r = Retry( effect=Effect(1), should_retry=ShouldDelayAndRetry( can_retry=retry_times(5), next_interval=repeating_interval(10))) seq = [ retry_sequence(r, [lambda _: Effect(2)], fallback_dispatcher=ComposedDispatcher( [dispatch_2, base_dispatcher])) ] self.assertEqual(perform_sequence(seq, Effect(r)), "yay done")