Exemplo n.º 1
0
    def test_run_application_sendfile(self):
        mock_file = unittest.mock.Mock()

        mock_app = unittest.mock.AsyncMock()
        mock_app.return_value = wsgi.FileWrapper(mock_file)

        session = wsgi.HttpSession(None, mock_app, {})
        context = wsgi._ApplicationContext()

        run_task = tasks.spawn(session._run_application(context, {}))
        get_task = tasks.spawn(self.get_body_chunks(context))

        kernels.run(timeout=0.01)

        self.assertTrue(context._chunks.is_closed())

        self.assertTrue(run_task.is_completed())
        run_task.get_result_nonblocking()

        self.assertTrue(get_task.is_completed())
        self.assertEqual(get_task.get_result_nonblocking(), [])

        self.assertIs(context.file, mock_file)
        # `close` is not called because ownership is transferred to
        # context.
        mock_file.close.assert_not_called()
Exemplo n.º 2
0
        def do_test(s0, s1):
            m0 = nng.Message(b'hello world')
            t0 = tasks.spawn(s0.sendmsg(m0))
            t1 = tasks.spawn(s1.recv())
            kernels.run(timeout=1)
            self.assertTrue(t0.is_completed())
            self.assertTrue(t1.is_completed())
            self.assertEqual(t1.get_result_nonblocking(), b'hello world')

            # Ownership is transferred on success.
            self.assertIsNone(m0._msg_p)
Exemplo n.º 3
0
        def do_test(s0, s1):
            t0 = tasks.spawn(s0.send(b'hello world'))
            t1 = tasks.spawn(s1.recv())
            kernels.run(timeout=1)
            self.assertTrue(t0.is_completed())
            self.assertTrue(t1.is_completed())
            self.assertEqual(t1.get_result_nonblocking(), b'hello world')

            t2 = tasks.spawn(s1.send(b'spam egg'))
            t3 = tasks.spawn(s0.recv())
            kernels.run(timeout=1)
            self.assertTrue(t2.is_completed())
            self.assertTrue(t3.is_completed())
            self.assertEqual(t3.get_result_nonblocking(), b'spam egg')
Exemplo n.º 4
0
    async def _handle_request(self, environ, keep_alive):
        # Check if client disables Keep-Alive explicitly.
        connection = environ.get('HTTP_CONNECTION')
        if connection is not None:
            keep_alive = 'keep-alive' in connection.lower()

        # At the moment we do not check any expectations (except those
        # already in _RequestQueue), and just return HTTP 100 here.
        if environ.get('HTTP_EXPECT', '').lower() == '100-continue':
            await self._put_short_response(
                http.HTTPStatus.CONTINUE, keep_alive
            )
            if not keep_alive:
                raise _SessionExit
            return

        context = _ApplicationContext()
        async with tasks.joining(
            tasks.spawn(self._send_response(context, environ, keep_alive)),
            always_cancel=True,
            log_error=False,  # We handle and log error below.
        ) as send_task, tasks.joining(
            tasks.spawn(self._run_application(context, environ)),
            always_cancel=True,
            log_error=False,  # We handle and log error below.
        ) as run_task:
            async for task in tasks.as_completed([send_task, run_task]):
                try:
                    task.get_result_nonblocking()
                except self._EXIT_EXC_TYPES:
                    raise
                except Exception:
                    if self._response_queue.has_begun():
                        LOG.exception(
                            'task crash after response starts sending: %r',
                            task,
                        )
                        raise _SessionExit from None
                    LOG.warning(
                        'task crash before response starts sending: %r',
                        task,
                        exc_info=True,
                    )
                    await self._put_short_response(
                        http.HTTPStatus.INTERNAL_SERVER_ERROR, keep_alive
                    )
                    if not keep_alive:
                        raise _SessionExit from None
                    break
Exemplo n.º 5
0
    def test_timeout(self):
        with clients.Client(Request, Response, WIRE_DATA) as client:
            client.socket.send_timeout = 1  # Unit: milliseconds.
            client.socket.dial('inproc://%s' % uuid.uuid4())

            task = tasks.spawn(client.m.greet(name='world'))
            kernels.run(timeout=0.01)
            self.assertTrue(task.is_completed())
            with self.assertRaises(clients.ServerTimeoutError):
                task.get_result_nonblocking()

            task = tasks.spawn(
                client.m.greet.on_timeout_return(42)(name='world'))
            kernels.run(timeout=0.01)
            self.assertTrue(task.is_completed())
            self.assertEqual(task.get_result_nonblocking(), 42)
Exemplo n.º 6
0
 def test_timeout_other(self):
     t = tasks.spawn(timers.sleep(100))
     timers.timeout_after(0, task=t)
     kernels.run(timeout=1)
     self.assertTrue(t.is_completed())
     with self.assertRaises(timers.Timeout):
         t.get_result_nonblocking()
Exemplo n.º 7
0
def main(_):
    logging.basicConfig(level=logging.INFO)
    start = time.perf_counter()
    task = tasks.spawn(to_be_cancelled)
    kernels.run(cancel_task(task))
    elapsed = time.perf_counter() - start
    print('total elapsed time: %.3f seconds' % elapsed)
    return 0
Exemplo n.º 8
0
def main(_):
    start = time.perf_counter()
    ts = [tasks.spawn(compute(i + 1)) for i in range(10)]
    total = kernels.run(accumulate(ts))
    elapsed = time.perf_counter() - start
    print('result: %d' % total)
    print('total elapsed time: %.3f seconds' % elapsed)
    return 0
Exemplo n.º 9
0
 def test_already_closed_output(self):
     q1 = queues.Queue()
     q_out = queues.Queue()
     q_out.close()
     multiplexer_task = tasks.spawn(more_queues.multiplex([q1], q_out))
     kernels.run(timeout=0.01)
     self.assertTrue(multiplexer_task.is_completed())
     self.assertIsNone(multiplexer_task.get_result_nonblocking())
Exemplo n.º 10
0
    def test_body_chunks(self):

        chunks = []

        async def get_body_chunks():
            while True:
                chunk = await self.context.get_body_chunk()
                if not chunk:
                    break
                chunks.append(chunk)

        async def put_body_chunks():
            await self.context.put_body_chunk(b'a')
            await self.context.put_body_chunk(b'')
            await self.context.put_body_chunk(b'b')
            await self.context.put_body_chunk(b'')
            await self.context.put_body_chunk(b'c')

        put_task = tasks.spawn(put_body_chunks())
        with self.assertRaises(kernels.KernelTimeout):
            kernels.run(timeout=0.01)
        self.assertEqual(chunks, [])
        self.assertFalse(put_task.is_completed())

        get_task = tasks.spawn(get_body_chunks())
        with self.assertRaises(kernels.KernelTimeout):
            kernels.run(timeout=0.01)
        self.assertEqual(chunks, [b'a', b'b', b'c'])
        self.assertTrue(put_task.is_completed())
        self.assertFalse(get_task.is_completed())

        self.context.end_body_chunks()
        kernels.run(timeout=0.01)
        self.assertEqual(chunks, [b'a', b'b', b'c'])
        self.assertTrue(put_task.is_completed())
        self.assertTrue(get_task.is_completed())

        put_task.get_result_nonblocking()
        get_task.get_result_nonblocking()

        with self.assertRaisesRegex(
                AssertionError,
                r'expect .*UNDECIDED.*, not .*SEND:',
        ):
            self.context.sendfile('foo')
Exemplo n.º 11
0
 async def _try_cache(self, cache, key, revalidate, request, kwargs):
     task = cache.get(key)
     if task is None:
         task = cache[key] = tasks.spawn(self(request, **kwargs))
         result = 'miss'
     elif revalidate:
         task = cache[key] = tasks.spawn(self(request, **kwargs))
         result = 'revalidate'
     else:
         result = 'hit'
     LOG.debug(
         'send: cache %s: key=%r, %r, kwargs=%r', \
         result, key, request, kwargs,
     )
     # Here is a risk that, if all task waiting for this task get
     # cancelled before this task completes, this task might not
     # be joined, but this risk is probably too small.
     return await task.get_result()
Exemplo n.º 12
0
    def test_pubsub(self):
        with contextlib.ExitStack() as stack:
            wiredata = jsons.JsonWireData()
            p_queue = queues.Queue()
            s1_queue = queues.Queue()
            s2_queue = queues.Queue()
            publisher = stack.enter_context(
                publishers.Publisher(p_queue, wiredata))
            subscriber1 = stack.enter_context(
                subscribers.Subscriber(Message, s1_queue, wiredata))
            subscriber2 = stack.enter_context(
                subscribers.Subscriber(Message, s2_queue, wiredata))
            publisher.socket.listen('inproc://test_pubsub')
            subscriber1.socket.dial('inproc://test_pubsub')
            subscriber2.socket.dial('inproc://test_pubsub')
            p_task = tasks.spawn(publisher.serve())
            s1_task = tasks.spawn(subscriber1.serve())
            s2_task = tasks.spawn(subscriber2.serve())
            with self.assertRaises(kernels.KernelTimeout):
                # Unfortunately this test is a somehow timing sensitive.
                # If we remove this kernels.run call, the subscribers
                # might sometimes not receive all messages.
                kernels.run(timeout=0.01)
            expect = (Message(content='hello'), Message(content='world'))
            for message in expect:
                publisher.publish_nonblocking(message)
            self.assertFalse(s1_queue)
            self.assertFalse(s2_queue)
            with self.assertRaises(kernels.KernelTimeout):
                kernels.run(timeout=0.01)
            self.assertEqual(len(s1_queue), 2)
            self.assertEqual(len(s2_queue), 2)
            for message in expect:
                self.assertEqual(s1_queue.get_nonblocking(), message)
                self.assertEqual(s2_queue.get_nonblocking(), message)

            publisher.shutdown()
            subscriber1.shutdown()
            subscriber2.shutdown()
            kernels.run(timeout=0.01)
            self.assertIsNone(p_task.get_result_nonblocking())
            self.assertIsNone(s1_task.get_result_nonblocking())
            self.assertIsNone(s2_task.get_result_nonblocking())
Exemplo n.º 13
0
    def test_run_application_non_aiter(self):
        mock_app = unittest.mock.AsyncMock()
        mock_app.return_value = [b'x', b'', b'', b'', b'y']

        session = wsgi.HttpSession(None, mock_app, {})
        context = wsgi._ApplicationContext()

        run_task = tasks.spawn(session._run_application(context, {}))
        get_task = tasks.spawn(self.get_body_chunks(context))

        kernels.run(timeout=0.01)

        self.assertTrue(context._chunks.is_closed())

        self.assertTrue(run_task.is_completed())
        run_task.get_result_nonblocking()

        self.assertTrue(get_task.is_completed())
        self.assertEqual(get_task.get_result_nonblocking(), [b'x', b'y'])
Exemplo n.º 14
0
 def do_test(s0):
     m0 = nng.Message(b'hello world')
     t0 = tasks.spawn(s0.sendmsg(m0))
     t0.cancel()
     kernels.run(timeout=1)
     self.assertTrue(t0.is_completed())
     self.assertIsInstance(t0.get_exception_nonblocking(),
                           tasks.Cancelled)
     # Ownership was not transferred.
     self.assertIsNotNone(m0._msg_p)
Exemplo n.º 15
0
    def test_dialer_start(self):
        with contextlib.ExitStack() as stack:
            url = 'inproc://%s' % uuid.uuid4()

            s1 = stack.enter_context(asyncs.Socket(nng.Protocols.REP0))
            s1.listen(url)

            s0 = stack.enter_context(asyncs.Socket(nng.Protocols.REQ0))
            d = s0.dial(url, create_only=True)
            d.start()

            t0 = tasks.spawn(s0.send(b'hello world'))
            t1 = tasks.spawn(s1.recv())
            kernels.run(timeout=1)
            self.assertTrue(t0.is_completed())
            self.assertTrue(t1.is_completed())
            self.assertEqual(t1.get_result_nonblocking(), b'hello world')

            d = s0.dial('inproc://%s' % uuid.uuid4())
            with self.assertRaises(nng.Errors.ESTATE):
                d.start()
Exemplo n.º 16
0
 def test_closed_output(self):
     q1 = queues.Queue()
     q_out = queues.Queue()
     multiplexer_task = tasks.spawn(more_queues.multiplex([q1], q_out))
     with self.assertRaises(kernels.KernelTimeout):
         kernels.run(timeout=0.01)
     q1.put_nonblocking('x')
     q_out.close()
     kernels.run(timeout=0.01)
     self.assertEqual(get_many(q1), ['x'])
     self.assertEqual(get_many(q_out), [])
     self.assertTrue(multiplexer_task.is_completed())
     self.assertIsNone(multiplexer_task.get_result_nonblocking())
Exemplo n.º 17
0
    def do_test_headers_sent_blocking(self, make_coro):
        def assert_begin_but_not_sent():
            self.assertEqual(self.response_queue.has_begun(), True)
            self.assertEqual(self.response_queue._has_begun, True)
            self.assertEqual(self.response_queue._headers_sent.is_set(), False)

        block_send = locks.Event()

        async def mock_send(data):
            del data  # Unused.
            await block_send.wait()
            return 1

        self.mock_sock.send.side_effect = mock_send
        self.mock_sock.sendfile.side_effect = mock_send

        begin_task = tasks.spawn(
            self.response_queue.begin(http.HTTPStatus.OK, []))
        with self.assertRaises(kernels.KernelTimeout):
            kernels.run(timeout=0.01)
        assert_begin_but_not_sent()
        self.assertFalse(begin_task.is_completed())

        send_task = tasks.spawn(make_coro())
        with self.assertRaises(kernels.KernelTimeout):
            kernels.run(timeout=0.01)
        assert_begin_but_not_sent()
        self.assertFalse(begin_task.is_completed())
        self.assertFalse(send_task.is_completed())

        block_send.set()

        kernels.run(timeout=0.01)
        self.assert_begin(True)
        self.assertTrue(begin_task.is_completed())
        self.assertTrue(send_task.is_completed())
        begin_task.get_result_nonblocking()
        send_task.get_result_nonblocking()
Exemplo n.º 18
0
    def test_run_application_aiter(self):
        class MockBody:
            def __init__(self):
                self._iter = iter([b'x', b'', b'', b'', b'y'])
                self.closed = False

            def __aiter__(self):
                return self

            async def __anext__(self):
                try:
                    return next(self._iter)
                except StopIteration:
                    raise StopAsyncIteration from None

            def close(self):
                self.closed = True

        mock_body = MockBody()
        mock_app = unittest.mock.AsyncMock()
        mock_app.side_effect = [mock_body]

        session = wsgi.HttpSession(None, mock_app, {})
        context = wsgi._ApplicationContext()

        run_task = tasks.spawn(session._run_application(context, {}))
        get_task = tasks.spawn(self.get_body_chunks(context))

        kernels.run(timeout=0.01)

        self.assertTrue(mock_body.closed)
        self.assertTrue(context._chunks.is_closed())

        self.assertTrue(run_task.is_completed())
        run_task.get_result_nonblocking()

        self.assertTrue(get_task.is_completed())
        self.assertEqual(get_task.get_result_nonblocking(), [b'x', b'y'])
Exemplo n.º 19
0
def main(
    args: asyncs.LABELS.args,
    stub: LABELS.stub.stub,
    supervise_agents: g1.asyncs.agents.parts.LABELS.supervise_agents,
    graceful_exit: g1.asyncs.agents.parts.LABELS.graceful_exit,
):
    supervisor_task = tasks.spawn(supervise_agents)
    request = clients.Request('GET', args.url)
    response = kernels.run(stub.send(request, priority=0))
    for link in response.html().xpath('//a'):
        print(link.get('href'))
    graceful_exit.set()
    kernels.run(supervisor_task.get_result())
    return 0
Exemplo n.º 20
0
        def do_test(client, server, server_serve):
            url = 'inproc://%s' % uuid.uuid4()
            server.socket.listen(url)
            client.socket.dial(url)

            server_task = tasks.spawn(server_serve)

            client_task = tasks.spawn(client.m.greet(name='world'))

            with self.assertRaises(kernels.KernelTimeout):
                kernels.run(timeout=0.005)

            self.assertTrue(client_task.is_completed())
            self.assertEqual(client_task.get_result_nonblocking(),
                             'Hello, world')

            self.assertFalse(server_task.is_completed())

            server.socket.close()
            kernels.run(timeout=1)

            self.assertTrue(server_task.is_completed())
            self.assertIsNone(server_task.get_result_nonblocking())
Exemplo n.º 21
0
    def test_linger_on(self):

        quit_handler = locks.Event()
        handler_completed = locks.Event()

        async def handler(request, response):
            del request
            response.headers['Content-Type'] = 'text/plain'
            await response.write(b'hello world')
            response.close()
            await quit_handler.wait()
            handler_completed.set()

        async def get_content(content_iterator):
            content = []
            async for data in content_iterator:
                content.append(data)
            if not content:
                return None
            else:
                return b''.join(content)

        app = wsgi_apps.Application(handler)
        app_task = tasks.spawn(app(self.ENVIRON, self.start_response_mock))
        with self.assertRaises(kernels.KernelTimeout):
            kernels.run(timeout=0.01)
        self.assertTrue(app_task.is_completed())
        self.assertFalse(handler_completed.is_set())

        self.start_response_mock.assert_called_once_with(
            '200 OK',
            [('Content-Type', 'text/plain')],
        )
        self.assertEqual(
            kernels.run(
                get_content(app_task.get_result_nonblocking()),
                timeout=0.01,
            ),
            b'hello world',
        )
        # Handler lingers on after application completes.
        self.assertFalse(handler_completed.is_set())

        quit_handler.set()
        kernels.run(timeout=0.01)
        self.assertTrue(handler_completed.is_set())

        app.shutdown()
        kernels.run(app.serve(), timeout=0.01)
Exemplo n.º 22
0
 def test_grace_period_exceeded(self):
     self.graceful_exit.set()
     sleep_task = self.agent_queue.spawn(timers.sleep(99))
     self.assert_state(False, 1, True, [])
     self.main_task = tasks.spawn(
         agents.supervise_agents(self.agent_queue, self.graceful_exit, 0))
     kernels.run(timeout=0.01)
     self.assert_state(True, 0, True, [r'graceful exit: requested by user'])
     with self.assertRaisesRegex(
             agents.SupervisorError,
             r'grace period exceeded',
     ):
         self.main_task.get_result_nonblocking()
     with self.assertRaises(tasks.Cancelled):
         sleep_task.get_result_nonblocking()
     self.assertFalse(tasks.get_all_tasks())
Exemplo n.º 23
0
    def test_invalid_response(self):
        with clients.Client(Request, Response, WIRE_DATA) as client:
            with nng.Socket(nng.Protocols.REP0) as socket:
                url = 'inproc://%s' % uuid.uuid4()
                socket.listen(url)
                client.socket.dial(url)

                task = tasks.spawn(client.m.greet(name='world'))
                with self.assertRaises(kernels.KernelTimeout):
                    kernels.run(timeout=0)

                socket.recv()
                socket.send(b'{"result": {"greet": 42}, "error": null}')

                kernels.run(timeout=1)
                self.assertTrue(task.is_completed())
                with self.assertRaisesRegex(AssertionError, r'expect.*str'):
                    task.get_result_nonblocking()
Exemplo n.º 24
0
    def test_multiplex(self):
        q1 = queues.Queue()
        q2 = queues.Queue()
        q_out = queues.Queue()
        multiplexer_task = tasks.spawn(more_queues.multiplex([q1, q2], q_out))

        q1.put_nonblocking('x')
        with self.assertRaises(kernels.KernelTimeout):
            kernels.run(timeout=0.01)
        self.assertEqual(get_many(q_out), ['x'])

        q2.put_nonblocking('a')
        q1.put_nonblocking('y')
        q2.put_nonblocking('b')
        with self.assertRaises(kernels.KernelTimeout):
            kernels.run(timeout=0.01)
        # Hmmm... The order of q_out items depends on the internal
        # implementation of multiplex.  I am not sure whether this is a
        # good test case.
        self.assertEqual(get_many(q_out), ['a', 'y', 'b'])

        q2.put_nonblocking('c')
        q2.put_nonblocking('d')
        q2.put_nonblocking('e')
        with self.assertRaises(kernels.KernelTimeout):
            kernels.run(timeout=0.01)
        self.assertEqual(get_many(q_out), ['c', 'd', 'e'])

        q2.close()
        q1.put_nonblocking('z')
        with self.assertRaises(kernels.KernelTimeout):
            kernels.run(timeout=0.01)
        self.assertEqual(get_many(q_out), ['z'])
        self.assertFalse(multiplexer_task.is_completed())

        q1.put_nonblocking('w')
        q1.close()
        kernels.run(timeout=0.01)
        self.assertEqual(get_many(q_out), ['w'])
        self.assertTrue(q_out.is_closed())
        self.assertTrue(multiplexer_task.is_completed())
        self.assertIsNone(multiplexer_task.get_result_nonblocking())
Exemplo n.º 25
0
    def test_success(self):
        with clients.Client(Request, Response, WIRE_DATA) as client:
            with nng.Socket(nng.Protocols.REP0) as socket:
                url = 'inproc://%s' % uuid.uuid4()
                socket.listen(url)
                client.socket.dial(url)

                task = tasks.spawn(client.m.greet(name='world'))
                with self.assertRaises(kernels.KernelTimeout):
                    kernels.run(timeout=0)

                request = WIRE_DATA.to_upper(Request, socket.recv())
                self.assertEqual(request.args, Request.m.greet(name='world'))

                response = Response(result=Response.Result(
                    greet='hello world'))
                socket.send(WIRE_DATA.to_lower(response))

                kernels.run(timeout=1)
                self.assertTrue(task.is_completed())
                self.assertEqual(task.get_result_nonblocking(), 'hello world')
Exemplo n.º 26
0
 def test_cancel(self):
     q1 = queues.Queue()
     q2 = queues.Queue()
     q_out = queues.Queue(1)
     multiplexer_task = tasks.spawn(more_queues.multiplex([q1, q2], q_out))
     q1.put_nonblocking('x')
     q1.put_nonblocking('y')
     q2.put_nonblocking('a')
     q2.put_nonblocking('b')
     with self.assertRaises(kernels.KernelTimeout):
         kernels.run(timeout=0.01)
     multiplexer_task.cancel()
     kernels.run(timeout=0.01)
     self.assertTrue(multiplexer_task.is_completed())
     self.assertIsInstance(multiplexer_task.get_exception_nonblocking(),
                           tasks.Cancelled)
     self.assertTrue(q_out.is_closed())
     # No input item is lost.
     self.assertEqual(get_many(q1), ['y'])
     self.assertEqual(get_many(q2), ['a', 'b'])
     self.assertEqual(get_many(q_out), ['x'])
Exemplo n.º 27
0
    def test_send_response_put_body_chunks(self):
        def make_context(status, headers, *body_chunks):
            context = wsgi._ApplicationContext()
            context._status = status
            context._headers = headers
            context._chunks = queues.Queue()  # Unset capacity for test.
            for chunk in body_chunks:
                context._chunks.put_nonblocking(chunk)
            context.end_body_chunks()
            return context

        session = wsgi.HttpSession(self.mock_sock, None, {})
        for (
                context,
                keep_alive,
                expect_data_per_call,
                expect_not_session_exit,
        ) in [
                # header: none ; body: none ; omit_body: false
            (
                make_context(http.HTTPStatus.OK, []),
                True,
                [
                    b'HTTP/1.1 200 OK\r\n'
                    b'Connection: keep-alive\r\n'
                    b'Content-Length: 0\r\n'
                    b'\r\n',
                ],
                True,
            ),
                # header: custom ; body: one chunk ; omit_body: false
            (
                make_context(http.HTTPStatus.NOT_FOUND, [(b'x', b'y')],
                             b'foo bar'),
                False,
                [
                    b'HTTP/1.1 404 Not Found\r\n'
                    b'x: y\r\n'
                    b'Connection: close\r\n'
                    b'Content-Length: 7\r\n'
                    b'\r\n',
                    b'foo bar',
                ],
                False,
            ),
                # header: connection ; body: multiple chunks ; omit_body: false
            (
                make_context(
                    http.HTTPStatus.OK,
                    [(b'connection', b'KeeP-Alive')],
                    b'spam',
                    b' ',
                    b'egg',
                ),
                False,
                [
                    b'HTTP/1.1 200 OK\r\n'
                    b'connection: KeeP-Alive\r\n'
                    b'Content-Length: 8\r\n'
                    b'\r\n',
                    b'spam',
                    b' ',
                    b'egg',
                ],
                True,
            ),
                # header: connection, content-length ; body: multiple chunks
                # omit_body: false
            (
                make_context(
                    http.HTTPStatus.OK,
                    [(b'Connection', b'close'), (b'cOnTeNt-LeNgTh', b'8')],
                    b'spam',
                    b' ',
                    b'egg',
                ),
                True,
                [
                    b'HTTP/1.1 200 OK\r\n'
                    b'Connection: close\r\n'
                    b'cOnTeNt-LeNgTh: 8\r\n'
                    b'\r\n',
                    b'spam',
                    b' ',
                    b'egg',
                ],
                False,
            ),
                # header: none ; body: multiple chunks
                # omit_body: true
            (
                make_context(http.HTTPStatus.NOT_MODIFIED, [], b'x', b' ',
                             b'y'),
                True,
                [
                    b'HTTP/1.1 304 Not Modified\r\n'
                    b'Connection: keep-alive\r\n'
                    b'Content-Length: 3\r\n'
                    b'\r\n',
                ],
                True,
            ),
                # header: wrong content-length; body: multiple chunks
                # omit_body: false
            (
                make_context(
                    http.HTTPStatus.OK,
                    [(b'content-length', b'8')],
                    b'a',
                    b' ',
                    b'b',
                ),
                True,
                [
                    b'HTTP/1.1 200 OK\r\n'
                    b'content-length: 8\r\n'
                    b'Connection: keep-alive\r\n'
                    b'\r\n',
                    b'a',
                    b' ',
                    b'b',
                ],
                False,
            ),
        ]:
            with self.subTest((
                    context,
                    keep_alive,
                    expect_data_per_call,
                    expect_not_session_exit,
            )):
                self.mock_sock.send.reset_mock()

                send_task = tasks.spawn(
                    session._send_response(context, {}, keep_alive))
                kernels.run(timeout=0.01)

                self.assertTrue(send_task.is_completed())
                if expect_not_session_exit:
                    send_task.get_result_nonblocking()
                else:
                    with self.assertRaises(wsgi._SessionExit):
                        send_task.get_result_nonblocking()

                self.assertTrue(context._is_committed)
                self.assertFalse(session._response_queue._has_begun)
                self.assertFalse(
                    session._response_queue._headers_sent.is_set())
                self.assert_send(*expect_data_per_call)
                self.mock_sock.sendfile.assert_not_called()
Exemplo n.º 28
0
    def test_send_response_sendfile(self, mock_os):

        mock_file = unittest.mock.Mock()
        mock_os.fstat.return_value.st_size = 99
        self.mock_sock.sendfile.return_value = 99

        def make_context(status, headers):
            context = wsgi._ApplicationContext()
            context._status = status
            context._headers = headers
            context.sendfile(mock_file)
            context.end_body_chunks()
            return context

        session = wsgi.HttpSession(self.mock_sock, None, {})
        for (
                context,
                expect_headers,
                expect_not_session_exit,
        ) in [
                # header: none
            (
                make_context(http.HTTPStatus.OK, []),
                b'HTTP/1.1 200 OK\r\n'
                b'Connection: keep-alive\r\n'
                b'Content-Length: 99\r\n\r\n',
                True,
            ),
                # header: content-length
            (
                make_context(http.HTTPStatus.OK, [(b'cOnTeNt-LeNgTh', b'99')]),
                b'HTTP/1.1 200 OK\r\n'
                b'cOnTeNt-LeNgTh: 99\r\n'
                b'Connection: keep-alive\r\n\r\n',
                True,
            ),
                # header: wrong content-length
            (
                make_context(http.HTTPStatus.OK, [(b'cOnTeNt-LeNgTh', b'10')]),
                b'HTTP/1.1 200 OK\r\n'
                b'cOnTeNt-LeNgTh: 10\r\n'
                b'Connection: keep-alive\r\n\r\n',
                False,
            ),
        ]:
            with self.subTest((
                    context,
                    expect_headers,
                    expect_not_session_exit,
            )):
                self.mock_sock.reset_mock()
                mock_file.reset_mock()

                send_task = tasks.spawn(
                    session._send_response(context, {}, True))
                kernels.run(timeout=0.01)

                self.assertTrue(send_task.is_completed())
                if expect_not_session_exit:
                    send_task.get_result_nonblocking()
                else:
                    with self.assertRaises(wsgi._SessionExit):
                        send_task.get_result_nonblocking()

                self.assertTrue(context._is_committed)
                self.assertFalse(session._response_queue._has_begun)
                self.assertFalse(
                    session._response_queue._headers_sent.is_set())
                self.mock_sock.assert_has_calls([
                    unittest.mock.call.send(expect_headers),
                    unittest.mock.call.sendfile(mock_file),
                ])
                mock_file.close.assert_called_once()
Exemplo n.º 29
0
 async def serve(self):
     async for tagged_item in more_queues.select(
             cluster_stub._queue for cluster_stub in self._cluster_stubs):
         request, kwargs, future = tagged_item.item
         future.set_result(
             tasks.spawn(self._base_session.send(request, **kwargs)))
Exemplo n.º 30
0
    def test_state_transition(self):

        def is_committed():
            return (
                self.response._precommit is None
                and not self.response._body.is_closed()
            )

        def is_closed():
            return self.response._body.is_closed()

        self.assertTrue(self.response._send_mechanism_decided.is_set())
        self.assertIsNone(self.response.file)

        with self.assertRaisesRegex(
            AssertionError,
            r'expect .*UNDECIDED:.*, not .*SEND:',
        ):
            self.response.sendfile('foo')
        self.assertIsNone(self.response.file)

        self.assertTrue(self.response.is_uncommitted())
        self.assertFalse(is_committed())
        self.assertFalse(is_closed())

        self.start_response_mock.assert_not_called()

        # Write to pre-commit buffer.
        kernels.run(self.response.write(b'hello world'))

        read_task = tasks.spawn(self.response.read)
        with self.assertRaises(kernels.KernelTimeout):
            kernels.run(timeout=0.01)
        self.assertFalse(read_task.is_completed())

        with self.assertRaisesRegex(AssertionError, r'expect false-value'):
            self.response.err_after_commit(None)

        self.response.commit()

        self.assertFalse(self.response.is_uncommitted())
        self.assertTrue(is_committed())
        self.assertFalse(is_closed())
        self.start_response_mock.assert_called_once_with('200 OK', [])

        kernels.run(timeout=0.01)
        self.assertTrue(read_task.is_completed())
        self.assertEqual(
            read_task.get_result_nonblocking(),
            b'hello world',
        )

        # Repeated calls to commit has no effect.
        self.start_response_mock.reset_mock()
        self.response.commit()
        self.start_response_mock.assert_not_called()

        kernels.run(self.response.write(b'foo bar'))
        self.assertEqual(
            kernels.run(self.response.read, timeout=0.01),
            b'foo bar',
        )

        self.response.close()
        self.assertFalse(self.response.is_uncommitted())
        self.assertFalse(is_committed())
        self.assertTrue(is_closed())

        with self.assertRaisesRegex(ValueError, r'response is closed'):
            kernels.run(self.response.write(b'spam egg'))