예제 #1
0
async def test_responders(method):
    class Resource:
        async def on_get(self, req, resp):
            resp.set_header('method', 'get')

        async def on_head(self, req, resp):
            resp.set_header('method', 'head')

        async def on_post(self, req, resp):
            resp.set_header('method', 'post')

        async def on_put(self, req, resp):
            resp.set_header('method', 'put')

        async def on_options(self, req, resp):
            resp.set_header('method', 'options')

        async def on_patch(self, req, resp):
            resp.set_header('method', 'patch')

        async def on_delete(self, req, resp):
            resp.set_header('method', 'delete')

    resource = Resource()

    app = App()
    app.add_route('/', resource)

    async with testing.ASGIConductor(app) as conductor:
        simulate = getattr(conductor, 'simulate_' + method)
        result = await simulate('/')
        assert result.headers['method'] == method
예제 #2
0
async def test_wsgi_not_supported():
    with pytest.raises(falcon.CompatibilityError):
        async with testing.TestClient(falcon.App()):
            pass

    with pytest.raises(falcon.CompatibilityError):
        async with testing.ASGIConductor(falcon.App()):
            pass
예제 #3
0
async def test_callback(callback_app, simple_resource, method, uri, expected):
    async with testing.ASGIConductor(callback_app) as conductor:
        resp = await conductor.simulate_request(method, uri)
        assert resp.status_code == 200
        assert resp.text == expected

        await asyncio.wait_for(simple_resource.event.wait(), 3.0)

        assert simple_resource.called == 1
예제 #4
0
    async def _test():
        conductor = testing.ASGIConductor(app)
        result = await conductor.simulate_get()
        assert 'data: whassup' in result.text

        async with testing.ASGIConductor(app) as conductor:
            async with conductor.simulate_get_stream() as sr:

                event_count = 0

                result_text = ''

                while event_count < 5:
                    chunk = (await sr.stream.read()).decode()
                    if not chunk:
                        continue

                    result_text += chunk
                    event_count += len(chunk.strip().split('\n\n'))

                assert result_text.startswith('data: whassup\n\n' * 5)
                assert event_count == 5
예제 #5
0
파일: test_ws.py 프로젝트: vmdhhh/falcon
def conductor():
    app = falcon.asgi.App()
    return testing.ASGIConductor(app)
예제 #6
0
파일: test_ws.py 프로젝트: vmdhhh/falcon
async def test_echo():  # noqa: C901
    consumer_sleep = 0.01
    producer_loop = 10
    producer_sleep_factor = consumer_sleep / (producer_loop / 2)

    class Resource:
        def __init__(self):
            self.caught_operation_not_allowed = False

        async def on_websocket(self, req, ws, p1, p2, injected):
            # NOTE(kgriffs): Normally the receiver task is not started
            #   until the websocket is started. But here we start it
            #   first in order to simulate a potential race condition
            #   that ASGIWebSocketSimulator._emit() guards against,
            #   in case it ever arises due to the way the target ASGI
            #   app may be implemented.
            ws._buffered_receiver.start()

            await asyncio.sleep(0)

            if ws.unaccepted:
                await ws.accept()

            try:
                await ws.accept()
            except falcon.OperationNotAllowed:
                self.caught_operation_not_allowed = True

            if ws.ready:
                await ws.send_text(
                    f'{p1}:{p2}:{req.context.message}:{injected}')

            messages = deque()
            sink_task = falcon.create_task(self._sink(ws, messages))

            while not sink_task.done():
                if not messages:
                    await asyncio.sleep(0)
                    continue

                try:
                    await ws.send_text(messages.popleft())
                except falcon.WebSocketDisconnected:
                    break

            sink_task.cancel()
            try:
                await sink_task
            except asyncio.CancelledError:
                pass

        async def _sink(self, ws, messages):
            while True:
                # NOTE(kgriffs): Throttle slightly to allow messages to
                #   fill up the buffer.
                await asyncio.sleep(consumer_sleep)

                try:
                    message = await ws.receive_text()
                except falcon.WebSocketDisconnected:
                    break

                if message != 'ignore':
                    messages.append(message)

    class MiddlewareA:
        async def process_resource_ws(self, req, ws, resource, params):
            assert isinstance(resource, Resource)
            assert isinstance(ws, falcon.asgi.WebSocket)
            params['injected'] = '42'

    class MiddlewareB:
        async def process_request_ws(self, req, ws):
            assert isinstance(ws, falcon.asgi.WebSocket)
            req.context.message = 'hello'

    resource = Resource()

    # NOTE(kgriffs): The two methods are split across different middleware
    #   classes so that we can test code paths that check for the existence
    #   of one WebSocket middleware method vs the other, and also so that
    #   we can make sure both the kwarg and the add_middlware() paths
    #   succeed.
    app = App(middleware=MiddlewareA())
    app.add_middleware(MiddlewareB())

    app.add_route('/{p1}/{p2}', resource)

    async with testing.ASGIConductor(app) as c:
        async with c.simulate_ws('/v1/v2', headers={}) as ws:
            assert (await ws.receive_text()) == 'v1:v2:hello:42'

            for i in range(producer_loop):
                message = str(
                    i
                ) if i else ''  # Test round-tripping the empty string as well

                for i in range(100):
                    await ws.send_text('ignore')

                # NOTE(kgriffs): For part of the time, cause the buffer on the
                #   server side to fill up, and for the remainder of the time
                #   for the buffer to be empty and wait on the client for
                #   additional messages.
                await asyncio.sleep(i * producer_sleep_factor)

                await ws.send_text(message)
                assert (await ws.receive_text()) == message

            await ws.close()

            assert ws.closed
            assert ws.close_code == CloseCode.NORMAL

    assert resource.caught_operation_not_allowed
예제 #7
0
 async def t():
     with pytest.raises(SomeException):
         async with testing.ASGIConductor(app):
             raise SomeException()