async def test_dispatch_success_but_skip_breaker(self, infuse_client, dispatch_success): service = get_service("testone") resp, status = await service.http_dispatch("GET", "/", include_status_code=True, skip_breaker=True) assert status == 222 assert resp == {"call_count": 1}
async def test_dispatch_breaker_skip_breaker(self, infuse_client, dispatch_fail, monkeypatch): monkeypatch.setattr(settings, "INFUSE_BREAKER_MAX_FAILURE", 3) monkeypatch.setattr(settings, "INFUSE_BREAKER_RESET_TIMEOUT", 1) service = get_service("testthree") for i in range(5): with pytest.raises(OSError) as e: resp, status = await service.http_dispatch( "POST", "/", include_status_code=True, skip_breaker=True) assert e.value.args[0]["call_count"] == i + 1
async def test_dont_open_for_client_errors(self, infuse_client, monkeypatch, dispatch_client_error): monkeypatch.setattr(settings, "INFUSE_BREAKER_MAX_FAILURE", 3) monkeypatch.setattr(settings, "INFUSE_BREAKER_RESET_TIMEOUT", 1) service = get_service("testthree") for i in range(10): with pytest.raises(APIException) as e: resp, status = await service.http_dispatch( "POST", "/", include_status_code=True, propagate_error=True, ) assert e.value.args[0]["call_count"] == i + 1
async def test_dispatch_breaker_tripped(self, infuse_client, dispatch_fail, monkeypatch): monkeypatch.setattr(settings, "INFUSE_BREAKER_MAX_FAILURE", 3) monkeypatch.setattr(settings, "INFUSE_BREAKER_RESET_TIMEOUT", 1) service = get_service("testthree") with pytest.raises(OSError) as e: resp, status = await service.http_dispatch( "POST", "/", include_status_code=True) assert e.value.args[0]["call_count"] == 1 with pytest.raises(OSError) as e: resp, status = await service.http_dispatch( "POST", "/", include_status_code=True) assert e.value.args[0]["call_count"] == 2 with pytest.raises(ServiceUnavailable503Error): resp, status = await service.http_dispatch( "POST", "/", include_status_code=True) assert e.value.args[0]["call_count"] == 3 # shouldn't be invoked with pytest.raises(ServiceUnavailable503Error): resp, status = await service.http_dispatch( "POST", "/", include_status_code=True) assert e.value.args[0]["call_count"] == 3 await asyncio.sleep(2) # trip again with pytest.raises(ServiceUnavailable503Error): resp, status = await service.http_dispatch( "POST", "/", include_status_code=True, ) assert e.value.args[0]["call_count"] == 4
async def get(self, request, *args, **kwargs): try: service = get_service("incendiary") resp, status = await service.http_dispatch( "GET", "/trace_error_2", include_status_code=True) segment = request.app.xray_recorder.current_segment() subsegment = segment.subsegments[0] try: assert subsegment.trace_id == segment.trace_id assert subsegment.error is True assert subsegment.http["response"]["status"] == 400 == status except AssertionError: traceback.print_exc() raise except Exception: traceback.print_exc() raise return json({}, status=204)
async def get(self, request, *args, **kwargs): start = time.time() try: depth = int(request.query_params.get("depth", 0)) except ValueError: depth = 0 if depth and len(settings.SERVICE_CONNECTIONS) > 0: ping_tasks = {} ping_responses = {} for s in settings.SERVICE_CONNECTIONS: try: service = get_service(s) except RuntimeError as e: ping_responses.update({s: {"error": e.args[0]}}) else: ping_tasks.update({ s: asyncio.ensure_future( response_time( service.http_dispatch, "GET", f"/{s}/ping/", query_params={"depth": depth - 1}, include_status_code=True, )) }) await asyncio.gather(*ping_tasks.values()) for k, v in ping_tasks.items(): ping_responses.update({k: v.result()}) resp = ping_responses else: resp = "pong" return json({ "response": resp, "process_time": f"{int((time.time()-start) * 1000)} ms", })
async def test_depth_connection_exists(self, monkeypatch, pong_server, ping_client): registry.reset() monkeypatch.setattr(settings, "SERVICE_CONNECTIONS", ["pong"]) pong_service = get_service("pong") pong_service.host = "127.0.0.1" pong_service.port = pong_server.port response = await ping_client.get( "/ping/ping/", params={"depth": 1}, # server_kwargs={"run_async": True} ) assert response.status == 200 response_body = await response.json() assert "response" in response_body assert "process_time" in response_body assert "response" in response_body assert "pong" in response_body["response"] assert response_body["response"]["pong"]["status_code"] == 200
async def test_task_context_service_anonymous_http_dispatch_injection( self, insanic_application, test_client, test_service_token_factory, monkeypatch, ): import aiotask_context import asyncio from insanic.loading import get_service monkeypatch.setattr(settings, "SERVICE_CONNECTIONS", ["userip"]) UserIPService = get_service("userip") class TokenView(InsanicView): permission_classes = [ AllowAny, ] async def get(self, request, *args, **kwargs): context_user = aiotask_context.get( settings.TASK_CONTEXT_REQUEST_USER) request_user = request.user handlers.jwt_decode_handler(request.auth) token = UserIPService.service_token assert token is not None jwt.decode( token, settings.SERVICE_TOKEN_KEY, verify=False, algorithms=[settings.JWT_SERVICE_AUTH_ALGORITHM], ) assert dict(request_user) == context_user return json({"user": dict(request_user)}) insanic_application.add_route(TokenView.as_view(), "/") client = await test_client(insanic_application) users = [] requests = [] for _ in range(10): user = AnonymousUser token = test_service_token_factory() requests.append( client.get( "/", headers={ "Authorization": token, settings.INTERNAL_REQUEST_USER_HEADER: to_header_value(user), }, )) users.append(user) responses = await asyncio.gather(*requests) for i in range(10): r = responses[i] resp = await r.json() assert r.status == 200, resp assert resp["user"]["id"] == users[i].id