예제 #1
0
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)
예제 #2
0
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)
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
    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
예제 #6
0
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
예제 #7
0
    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]
예제 #8
0
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
예제 #9
0
    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
예제 #10
0
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
예제 #11
0
def _stream(body, content_length=None):
    emitter = testing.ASGIRequestEventEmitter(body)
    return asgi.BoundedStream(emitter, content_length=content_length)