async def test_lifespan_default_callbacks_start_are_used_when_nothing_is_provided( mocked_on_start): send_data = [] called_once = False async def receive_start_up(): nonlocal called_once if not called_once: called_once = True return {"type": "lifespan.startup"} else: await asyncio.sleep(10) async def send_mocked(arg): send_data.append(arg) server = build_server(handler_identity, on_start=awaitable_mock(mocked_on_start)) lifecycle_handler = server({"type": "lifespan"}) from asyncio import TimeoutError as AsyncTimeoutError with pytest.raises(AsyncTimeoutError): await asyncio.wait_for(asyncio.ensure_future( lifecycle_handler(receive_start_up, send_mocked)), timeout=0.3) mocked_on_start.assert_called_once() assert send_data == [{"type": "lifespan.startup.complete"}]
async def test_server_coerces_header_list_into_dict(): headers = [(b"a", b"asdff"), (b"ccccccccc" * 1024, b"zu777/&!&/"), (b"double", b"123"), (b"double", b"asdf")] server = build_server(handler_identity) handler_func = server({"headers": headers, "type": "http"}) result = await handler_func(receive_none, send_none) assert { "a": "asdff", "ccccccccc" * 1024: "zu777/&!&/", "double": "123,asdf" } == result['headers']
async def test_slow_body_receiver(): async def noop_handler(request): return {"status": 200, "body": b"asdf"} def slow_body_receiver(timeout_s): async def slow_body(x): await asyncio.sleep(timeout_s) return slow_body handle_http = build_server(noop_handler, max_responde_timeout_s=0.1) with pytest.raises(TimeoutError): await handle_http({"type": "http"})(noop_receive, slow_body_receiver(0.9))
async def test_slow_body_request(): def slow_body_reader(timeout_s): async def slow_body(): await asyncio.sleep(timeout_s) return {"body": b"body content.", "more_body": True} return slow_body handle_http = build_server(lambda x, y: 1, max_receive_timeout_s=0.2) with pytest.raises(TimeoutError): await handle_http({"type": "http"})(slow_body_reader(0.1), noop_sender) with pytest.raises(TimeoutError): await handle_http({"type": "http"})(slow_body_reader(1.1), noop_sender)
async def test_lifespan_default_callbacks_stops_are_used_when_nothing_is_provided( mocked_on_stop): send_data = [] async def receive_shutdown(): return {"type": "lifespan.shutdown"} async def send_mocked(arg): send_data.append(arg) server = build_server(handler_identity, on_stop=awaitable_mock(mocked_on_stop)) lifecycle_handler = server({"type": "lifespan"}) await lifecycle_handler(receive_shutdown, send_mocked) mocked_on_stop.assert_called_once() assert send_data == [{"type": "lifespan.shutdown.complete"}]
async def test_requests_are_stacked_when_startup_is_not_completed(): server = build_server(handler_identity) lifespan_channel = asyncio.Queue() application_events = asyncio.Queue() request_channel = asyncio.Queue() startup_handler = server({"type": "lifespan"}) http_handler = server({"type": "http"}) http = http_handler(request_channel.get, application_events.put) startup = startup_handler(lifespan_channel.get, application_events.put) http_f = asyncio.ensure_future(http) startup_f = asyncio.ensure_future(startup) assert not http_f.done() assert not startup_f.done() await request_channel.put({"type": "http", "more_body": False}) assert not http_f.done() await lifespan_channel.put({"type": "lifespan.startup"}) await asyncio.sleep(0.01) assert not startup_f.done() assert http_f.done() acc = [] for _ in range(application_events.qsize()): acc.append(await application_events.get()) assert acc == [{ "type": "lifespan.startup.complete" }, { 'type': 'http.response.start', 'status': 200, 'headers': [] }, { 'type': 'http.response.body', 'body': b'', 'more_body': False }] startup_f.cancel()
async def test_lifespan_shutdown_failed_is_used_when_start_down_func_raises(): send_data = [] async def receive_shutdown(): return {"type": "lifespan.shutdown"} async def send_mocked(arg): send_data.append(arg) async def raise_on_shutdown(context): raise Exception("On shutdown it happend!") server = build_server(handler_identity, on_stop=raise_on_shutdown) lifecycle_handler = server({"type": "lifespan"}) with pytest.raises(Exception): await lifecycle_handler(receive_shutdown, send_mocked) assert send_data == [{ "type": "lifespan.shutdown.failed", "message": "On shutdown it happend!" }]
async def test_lifespan_startup_failed_is_used_when_start_up_func_raises(): send_data = [] async def receive_start_up(): return {"type": "lifespan.startup"} async def send_mocked(arg): send_data.append(arg) async def raise_on_startup(context): raise Exception("On startup something bad happend!") server = build_server(handler_identity, on_start=raise_on_startup) lifecycle_handler = server({"type": "lifespan"}) with pytest.raises(Exception): await lifecycle_handler(receive_start_up, send_mocked) assert send_data == [{ "type": "lifespan.startup.failed", "message": "On startup something bad happend!" }]
async def test_server_implements_a_handler_for_lifecycle_protocol(): server = build_server(handler_identity) lifecycle_handler = server({"type": "lifespan"}) assert lifecycle_handler.func.__name__ == lifespan_handler.__name__
async def test_server_raises_not_implemented_error_when_no_type_key_in_scope(): server = build_server(handler_identity) with pytest.raises(NotImplementedError): server({})
async def test_server_ignores_unknown_types_in_scope(): server = build_server(handler_identity) lifecycle_handler = server({"type": "unknown"}) assert lifecycle_handler.__name__ == noop.__name__
async def test_server_has_no_problems_with_empty_headers(): server = build_server(handler_identity) handler_func = server({"type": "http"}) result = await handler_func(receive_none, send_none) assert {} == result['headers']
def test_server_func_returns_handler_func_or_partial_for_request(): server = build_server(lambda x: x) handler_func = server({"type": "http"}) assert inspect.isfunction(handler_func) or isinstance( handler_func, partial)
def test_ring_server_yields_function(): server = build_server(lambda x: x) assert inspect.isfunction(server)
async def test_websockets_have_an_empty_config_if_startup_does_nothing(): server = build_server(handler_identity) ws_handler = server({"type": "websocket"}) result = await ws_handler(receive_none, send_none) assert result["config"] == {}
async def test_every_request_has_an_empty_config_if_startup_does_nothing(): server = build_server(handler_identity) http_handler = server({"type": "http"}) result = await http_handler(receive_none, send_none) assert result["config"] == {}