def test_asgi_request_event_emitter_hang(): # NOTE(kgriffs): This tests the ASGI server behavior that # ASGIRequestEventEmitter simulates when emit() is called # again after there are not more events available. expected_elasped_min = 1 disconnect_at = time.time() + expected_elasped_min emit = testing.ASGIRequestEventEmitter(disconnect_at=disconnect_at) async def t(): start = time.time() while True: event = await emit() if not event.get('more_body', False): break elapsed = time.time() - start assert elapsed < 0.1 start = time.time() await emit() elapsed = time.time() - start assert (elapsed + 0.1) > expected_elasped_min falcon.invoke_coroutine_sync(t)
def test_filelike(): s = asgi.BoundedStream(testing.ASGIRequestEventEmitter()) for __ in range(2): with pytest.raises(OSError): s.fileno() assert not s.isatty() assert s.readable() assert not s.seekable() assert not s.writable() s.close() assert s.closed # NOTE(kgriffs): Closing an already-closed stream is a noop. s.close() assert s.closed async def test_iteration(): with pytest.raises(ValueError): await s.read() with pytest.raises(ValueError): await s.readall() with pytest.raises(ValueError): await s.exhaust() with pytest.raises(ValueError): async for chunk in s: pass falcon.invoke_coroutine_sync(test_iteration)
def test_bounded_stream_alias(self): scope = testing.create_scope() req_event_emitter = testing.ASGIRequestEventEmitter(b'', disconnect_at=0) req = falcon.asgi.Request(scope, req_event_emitter) assert req.bounded_stream is req.stream
def test_request_repr(self): scope = testing.create_scope() req_event_emitter = testing.ASGIRequestEventEmitter(b'', disconnect_at=0) req = falcon.asgi.Request(scope, req_event_emitter) _repr = '<%s: %s %r>' % (req.__class__.__name__, req.method, req.url) assert req.__repr__() == _repr
async def t(): emitter = testing.ASGIRequestEventEmitter(b'123456798' * 1024, disconnect_at=(time.time() + 0.5)) s = asgi.BoundedStream(emitter) assert await s.read(1) == b'1' assert await s.read(2) == b'23' await asyncio.sleep(0.5) await s.exhaust() assert await s.read(1) == b'' assert await s.read(100) == b'' assert s.eof
async def test_exhaust(): emitter = testing.ASGIRequestEventEmitter(b'123456798' * 1024) stream = asgi.BoundedStream(emitter) assert await stream.read(1) == b'1' assert await stream.read(6) == b'234567' assert await stream.read(101) == b'98' + b'123456798' * 11 await stream.exhaust() assert await stream.read(1) == b'' assert await stream.read(6) == b'' assert await stream.read(101) == b'' assert stream.eof
async def test_content_length_smaller_than_body(self, body_length, content_length): body_in = os.urandom(body_length) scope = testing.create_scope(content_length=content_length) req_event_emitter = testing.ASGIRequestEventEmitter(body=body_in) req_event_emitter._emit_empty_chunks = False first_event = await req_event_emitter.emit() req = falcon.asgi.Request(scope, req_event_emitter, first_event=first_event) body_out = await req.bounded_stream.read() assert body_out == body_in[:content_length]
def _call_with_scope(scope): app = App() resource = testing.SimpleTestResourceAsync() app.add_route('/', resource) req_event_emitter = testing.ASGIRequestEventEmitter() resp_event_collector = testing.ASGIResponseEventCollector() falcon.invoke_coroutine_sync(app.__call__, scope, req_event_emitter, resp_event_collector) assert resource.called return resource
async def t(): emitter = testing.ASGIRequestEventEmitter( b'123456789' * 2, # NOTE(kgriffs): This must be small enough to create several events chunk_size=3, ) s = asgi.BoundedStream(emitter) assert await s.read(1) == b'1' assert await s.read(2) == b'23' emitter.disconnect(exhaust_body=False) await s.exhaust() assert await s.read(1) == b'' assert await s.read(100) == b'' assert s.eof
def test_deserialization(asgi, func, body, expected): handler = media.JSONHandler(loads=func) args = ['application/javacript', len(body)] if asgi: if not ASGI_SUPPORTED: pytest.skip('ASGI requires Python 3.6+') from falcon.asgi.stream import BoundedStream s = BoundedStream(testing.ASGIRequestEventEmitter(body)) args.insert(0, s) result = falcon.async_to_sync(handler.deserialize_async, *args) else: args.insert(0, io.BytesIO(body)) result = handler.deserialize(*args) assert result == expected
def _stream(body, content_length=None): emitter = testing.ASGIRequestEventEmitter(body) return asgi.BoundedStream(emitter, content_length=content_length)