Ejemplo n.º 1
0
def test_circuitbreaker_should_clear_last_exception_on_success_call():
    cb = CircuitBreaker(name='Foobar')
    cb._last_failure = IOError()
    assert isinstance(cb.last_failure, IOError)

    cb.call(lambda: True)

    assert cb.last_failure is None
Ejemplo n.º 2
0
def test_circuitbreaker_error__str__():
    cb = CircuitBreaker(name='Foobar')
    cb._last_failure = Exception()
    error = CircuitBreakerError(cb)

    assert str(error).startswith('Circuit "Foobar" OPEN until ')
    assert str(error).endswith(
        '(0 failures, 30 sec remaining) (last_failure: Exception())')
Ejemplo n.º 3
0
def test_circuitbreaker_should_save_last_exception_on_failure_call():
    cb = CircuitBreaker(name='Foobar')

    func = Mock(side_effect=IOError)

    with raises(IOError):
        cb.call(func)

    assert isinstance(cb.last_failure, IOError)
Ejemplo n.º 4
0
def test_circuitbreaker_should_call_fallback_function_if_open():
    fallback = Mock(return_value=True)

    func = Mock(return_value=False)

    CircuitBreaker.opened = lambda self: True

    cb = CircuitBreaker(name='WithFallback', fallback_function=fallback)
    cb.call(func)
    fallback.assert_called_once_with()
Ejemplo n.º 5
0
    def next(self, service_type):
        cache_status = SUCCESS

        sleep(0.3)  #give some time for processing previous request
        cache = CacheDriver()

        service1 = None
        service2 = None

        try:
            service1 = cache.do("custom", 'rpoplpush', [
                "services-" + str(service_type),
                "services-" + str(service_type)
            ])
        except Exception as e:
            test_logger.error(
                "ERROR: Custom cache rpoplpush command failed on" + str([
                    "services-" + str(service_type), "services-" +
                    str(service_type)
                ]))
            test_logger.error(str(e))
            cache_status = CUSTOM_CACHE_FAILED

        try:
            service2 = cache.do("redis", 'rpoplpush', [
                "services-" + str(service_type),
                "services-" + str(service_type)
            ])
            if service2 is not None:
                service2 = service2.decode('utf-8')

        except Exception as e:
            test_logger.error(
                "ERROR: Redis cache rpoplpush command failed on" + str([
                    "services-" + str(service_type), "services-" +
                    str(service_type)
                ]))
            test_logger.error(str(e))
            cache_status = REDIS_CACHE_FAILED if SUCCESS else BOTH_CACHES_FAILED

        if cache_status == BOTH_CACHES_FAILED:
            test_logger.error(
                "ERROR: Alert! Both caches rpoplpush command failed on " +
                str([
                    "services-" + str(service_type), "services-" +
                    str(service_type)
                ]))

        if service1 is not None:
            circuitbreaker = CircuitBreaker(service1, service_type)
        elif service2 is not None:
            circuitbreaker = CircuitBreaker(service2, service_type)

        return circuitbreaker
 def __init__(self,
              name,
              failure_threshold=5,
              recovery_timeout=60,
              expected_exception=RequestException):
     self.breaker = CircuitBreaker(failure_threshold, recovery_timeout,
                                   expected_exception, name)
Ejemplo n.º 7
0
import requests
from rest_framework.views import APIView, Response
from uuid import UUID
import logging
from .baseview import BaseView
from circuitbreaker import CircuitBreaker, CircuitBreakerError
from requests.exceptions import RequestException

RCB = CircuitBreaker(failure_threshold=5,
                     recovery_timeout=30,
                     expected_exception=RequestException)


class Room(BaseView):

    URL = 'http://localhost:8001/api/room/'
    URL1 = 'http://localhost:8002/api/guest/'
    URL2 = 'http://localhost:8003/api/menus/'

    @RCB
    def get_room(self, request, n_uuid):
        self.info(request)
        response = requests.get(self.URL + f'{n_uuid}')
        return Response(self.safeResponse(response),
                        status=response.status_code)

    @RCB
    def patch_room(self, request, n_uuid):
        self.info(request)
        response = requests.patch(self.URL + f'{n_uuid}', request.data)
        return Response(self.safeResponse(response),
Ejemplo n.º 8
0
def test_circuitbreaker__str__():
    cb = CircuitBreaker(name='Foobar')
    assert str(cb) == 'Foobar'
Ejemplo n.º 9
0
class TestIntent(unittest.TestCase):
    def setUp(self):
        request = SimpleNamespace()
        request.json = {
            "context": {
                "attributes": {},
                "intent": "TELEKOM_Demo_Intent",
                "locale": "de",
                "tokens": {}
            },
            "session": {
                "new": True,
                "id": "12345",
                "attributes": {
                    "key-1": "value-1",
                    "key-2": "value-2"
                }
            },
        }
        request.headers = {}
        self.ctx = Context(request)
        self.ctx.tracer = Tracer(request)

    @patch.object(logging.Logger, 'warning')
    def test_init_exceptions(self, warn_mock):
        with self.assertRaises(TypeError):
            Intent({})
        with self.assertRaises(ValueError):
            Intent('', None)
        with self.assertRaises(ValueError):
            Intent('demo_intent', 'random.does_not_exist')

    @patch('random.randint', return_value=1)
    def test_call_bad_return_type(self, mock_gde):
        mock_gde.__name__ = 'mock_gde'
        intent = Intent('TELEKOM_Demo_Intent', random.randint)
        with self.assertRaises(ValueError):
            intent(self.ctx).dict(self.ctx)

    @patch('random.randint', return_value=ErrorResponse(999, 'some error'))
    def test_call_error_999(self, mock_gde):
        mock_gde.__name__ = 'mock_gde'
        intent = Intent('TELEKOM_Demo_Intent', random.randint)
        self.assertIsInstance(intent(self.ctx), ErrorResponse)

    @patch('random.randint', side_effect=RequestException())
    def test_call_requests_error(self, mock_gde):
        mock_gde.__name__ = 'mock_gde'
        intent = Intent('TELEKOM_Demo_Intent', random.randint)
        response = intent(self.ctx)
        self.assertIsInstance(response, Response)
        self.assertEqual(response.text, 'GENERIC_HTTP_ERROR_RESPONSE')

    @patch('random.randint', side_effect=CircuitBreakerError(CircuitBreaker()))
    def test_call_circuit_breaker_open(self, mock_gde):
        mock_gde.__name__ = 'mock_gde'
        intent = Intent('TELEKOM_Demo_Intent', random.randint)
        response = intent(self.ctx)
        self.assertIsInstance(response, Response)
        self.assertEqual(response.text, 'GENERIC_HTTP_ERROR_RESPONSE')

    @patch('random.randint',
           return_value=Response(text='some text', type_=RESPONSE_TYPE_TELL))
    def test_append_push_messages_empty(self, mock_gde):
        mock_gde.__name__ = 'mock_gde'
        context = create_context('TELEKOM_Demo_Intent')
        intent = Intent('TELEKOM_Demo_Intent', random.randint)
        response = intent(context)
        response = intent._append_push_messages(context, response)
        self.assertEqual(response.push_notification, None)

    @patch('random.randint',
           return_value=Response(text='some text', type_=RESPONSE_TYPE_TELL))
    def test_append_push_messages_one(self, mock_gde):
        mock_gde.__name__ = 'mock_gde'
        context = create_context('TELEKOM_Demo_Intent')
        intent = Intent('TELEKOM_Demo_Intent', random.randint)
        response = intent(context)
        context.push_messages = {'device': [{'payload': 1}]}
        response = intent._append_push_messages(context, response)
        self.assertEqual(response.push_notification, {
            'targetName': 'device',
            'messagePayload': {
                'payload': 1
            }
        })

    @patch('random.randint',
           return_value=Response(text='some text', type_=RESPONSE_TYPE_TELL))
    def test_append_push_messages_two_messages(self, mock_gde):
        mock_gde.__name__ = 'mock_gde'
        context = create_context('TELEKOM_Demo_Intent')
        intent = Intent('TELEKOM_Demo_Intent', random.randint)
        response = intent(context)
        context.push_messages = {'device': [{'payload': 1}, {'payload': 2}]}
        with self.assertRaises(ValueError):
            _ = intent._append_push_messages(context, response)

    @patch('random.randint',
           return_value=Response(text='some text', type_=RESPONSE_TYPE_TELL))
    def test_append_push_messages_two_devices(self, mock_gde):
        mock_gde.__name__ = 'mock_gde'
        context = create_context('TELEKOM_Demo_Intent')
        intent = Intent('TELEKOM_Demo_Intent', random.randint)
        response = intent(context)
        context.push_messages = {
            'device': [{
                'payload': 1
            }],
            'device2': [{
                'payload': 2
            }]
        }
        with self.assertRaises(ValueError):
            _ = intent._append_push_messages(context, response)

    def test_repr(self):
        self.assertIn('TELEKOM_Demo_Intent',
                      repr(Intent('TELEKOM_Demo_Intent', random.randint)))

    def test_response_returns_message(self):
        """ Test if context._ returns l10n.Message
        """
        l10n.translations = {'de': l10n.Translations()}
        context = create_context('TELEKOM_Demo_Intent')
        with patch('random.randint',
                   return_value=Response(
                       text=context._('some text'))) as mock_gde:
            mock_gde.__name__ = 'mock_gde'
            intent = Intent('TELEKOM_Demo_Intent', random.randint)
            response = intent(context)
            self.assertIsInstance(response.text, l10n.Message)
Ejemplo n.º 10
0
    def __init__(self, service, config, signer, type_mapping, **kwargs):
        validate_config(config, signer=signer)
        self.signer = signer

        # Default to true (is a regional client) if there is nothing explicitly set. Regional
        # clients allow us to call set_region and that'll also set the endpoint. For non-regional
        # clients we require an endpoint
        self.regional_client = kwargs.get('regional_client', True)

        self._endpoint = None
        self._base_path = kwargs.get('base_path')
        self.service_endpoint_template = kwargs.get(
            'service_endpoint_template')
        self.endpoint_service_name = kwargs.get('endpoint_service_name')

        if self.regional_client:
            if kwargs.get('service_endpoint'):
                self.endpoint = kwargs.get('service_endpoint')
            else:
                region_to_use = None
                if 'region' in config and config['region']:
                    region_to_use = config.get('region')
                elif hasattr(signer, 'region'):
                    region_to_use = signer.region

                self.endpoint = regions.endpoint_for(
                    service,
                    service_endpoint_template=self.service_endpoint_template,
                    region=region_to_use,
                    endpoint=config.get('endpoint'),
                    endpoint_service_name=self.endpoint_service_name)
        else:
            if not kwargs.get('service_endpoint'):
                raise exceptions.MissingEndpointForNonRegionalServiceClientError(
                    'An endpoint must be provided for a non-regional service client'
                )
            self.endpoint = kwargs.get('service_endpoint')

        self.service = service
        self.complex_type_mappings = type_mapping
        self.type_mappings = merge_type_mappings(self.primitive_type_map,
                                                 type_mapping)
        self.session = requests.Session()

        # If the user doesn't specify timeout explicitly we would use default timeout.
        self.timeout = kwargs.get('timeout') if 'timeout' in kwargs else (
            DEFAULT_CONNECTION_TIMEOUT, DEFAULT_READ_TIMEOUT)

        self.user_agent = build_user_agent(
            get_config_value_or_default(config, "additional_user_agent"))

        self.logger = logging.getLogger("{}.{}".format(__name__, id(self)))
        self.logger.addHandler(logging.NullHandler())
        if get_config_value_or_default(config, "log_requests"):
            self.logger.disabled = False
            self.logger.setLevel(logging.DEBUG)
            is_http_log_enabled(True)
        else:
            self.logger.disabled = True
            is_http_log_enabled(False)

        self.skip_deserialization = kwargs.get('skip_deserialization')

        # Circuit Breaker at client level
        self.circuit_breaker_strategy = kwargs.get('circuit_breaker_strategy')
        self.circuit_breaker_name = None
        # Log if Circuit Breaker Strategy is not enabled or if using Default Circuit breaker Strategy
        if self.circuit_breaker_strategy is None or isinstance(
                self.circuit_breaker_strategy, NoCircuitBreakerStrategy):
            self.logger.debug('No circuit breaker strategy enabled!')
        else:
            # Enable Circuit breaker if a valid circuit breaker strategy is available
            if not isinstance(self.circuit_breaker_strategy,
                              CircuitBreakerStrategy):
                raise TypeError('Invalid Circuit Breaker Strategy!')
            self.circuit_breaker_name = str(
                uuid.uuid4()
            ) if self.circuit_breaker_strategy.name is None else self.circuit_breaker_strategy.name
            # Re-use Circuit breaker if sharing a Circuit Breaker Strategy.
            circuit_breaker = CircuitBreakerMonitor.get(
                self.circuit_breaker_name)
            if circuit_breaker is None:
                circuit_breaker = CircuitBreaker(
                    failure_threshold=self.circuit_breaker_strategy.
                    failure_threshold,
                    recovery_timeout=self.circuit_breaker_strategy.
                    recovery_timeout,
                    expected_exception=self.circuit_breaker_strategy.
                    expected_exception,
                    name=self.circuit_breaker_name)
            # Equivalent to decorating the request function with Circuit Breaker
            self.request = circuit_breaker(self.request)
        self.logger.debug('Endpoint: {}'.format(self._endpoint))
Ejemplo n.º 11
0
 def test_init_with_circuit_breaker(self):
     cb = CircuitBreaker()
     zcbs = CircuitBreakerSession(circuit_breaker=cb)
     self.assertEqual(zcbs.internal, False)
     self.assertEqual(zcbs.circuit_breaker, cb)
     self.assertTrue(isinstance(zcbs, Session))