Ejemplo n.º 1
0
async def test_exit_and_connection_was_broken(loop):
    client_h2c, server_h2c = create_connections()

    to_client_transport = TransportStub(client_h2c)
    to_server_transport = TransportStub(server_h2c)

    client_conn = Connection(client_h2c, to_server_transport, loop=loop)
    server_conn = Connection(server_h2c, to_client_transport, loop=loop)

    server_proc = EventsProcessor(DummyHandler(), server_conn)
    client_proc = EventsProcessor(DummyHandler(), client_conn)

    request = Request(method='POST', scheme='http', path='/',
                      content_type='application/grpc+proto',
                      authority='test.com')
    client_h2_stream = client_conn.create_stream()
    await client_h2_stream.send_request(request.to_headers(),
                                        _processor=client_proc)

    request = DummyRequest(value='ping')
    await send_message(client_h2_stream, ProtoCodec(), request, DummyRequest,
                       end=True)
    to_server_transport.process(server_proc)

    server_h2_stream = server_proc.handler.stream
    request_metadata = decode_metadata(server_proc.handler.headers)

    with pytest.raises(WriteError):
        async with Stream(server_h2_stream, Cardinality.UNARY_UNARY,
                          ProtoCodec(), DummyRequest, DummyReply,
                          metadata=request_metadata) as server_stream:
            await server_stream.recv_message()

            # simulate broken connection
            to_client_transport.__raise_on_write__(WriteError)
Ejemplo n.º 2
0
async def test_send_trailing_metadata_on_closed_stream(loop):
    client_h2c, server_h2c = create_connections()

    to_client_transport = TransportStub(client_h2c)
    to_server_transport = TransportStub(server_h2c)

    client_conn = Connection(client_h2c, to_server_transport, loop=loop)
    server_conn = Connection(server_h2c, to_client_transport, loop=loop)

    server_proc = EventsProcessor(DummyHandler(), server_conn)
    client_proc = EventsProcessor(DummyHandler(), client_conn)

    request = Request(method='POST', scheme='http', path='/',
                      content_type='application/grpc+proto',
                      authority='test.com')
    client_h2_stream = client_conn.create_stream()
    await client_h2_stream.send_request(request.to_headers(),
                                        _processor=client_proc)

    request = DummyRequest(value='ping')
    await send_message(client_h2_stream, ProtoCodec(), request, DummyRequest,
                       end=True)
    to_server_transport.process(server_proc)

    server_h2_stream = server_proc.handler.stream
    request_metadata = decode_metadata(server_proc.handler.headers)

    send_trailing_metadata_done = False
    async with Stream(server_h2_stream, Cardinality.UNARY_UNARY, ProtoCodec(),
                      DummyRequest, DummyReply,
                      metadata=request_metadata) as server_stream:
        await server_stream.send_trailing_metadata(status=Status.UNKNOWN)
        send_trailing_metadata_done = True

    assert send_trailing_metadata_done
Ejemplo n.º 3
0
async def test_exit_and_connection_was_closed(loop):
    client_h2c, server_h2c = create_connections()

    to_client_transport = TransportStub(client_h2c)
    to_server_transport = TransportStub(server_h2c)

    client_conn = Connection(client_h2c, to_server_transport, loop=loop)
    server_conn = Connection(server_h2c, to_client_transport, loop=loop)

    server_proc = EventsProcessor(DummyHandler(), server_conn)
    client_proc = EventsProcessor(DummyHandler(), client_conn)

    request = Request('POST', 'http', '/',
                      content_type='application/grpc+proto',
                      authority='test.com')
    client_h2_stream = client_conn.create_stream()
    await client_h2_stream.send_request(request.to_headers(),
                                        _processor=client_proc)

    request = DummyRequest(value='ping')
    await send_message(client_h2_stream, ProtoCodec(), request, DummyRequest,
                       end=True)
    to_server_transport.process(server_proc)

    server_h2_stream = server_proc.handler.stream
    request_metadata = Metadata.from_headers(server_proc.handler.headers)

    async with Stream(server_h2_stream, Cardinality.UNARY_UNARY, ProtoCodec(),
                      DummyRequest, DummyReply,
                      metadata=request_metadata) as server_stream:
        await server_stream.recv_message()
        client_h2c.close_connection()
        to_server_transport.process(server_proc)

        raise ServerError()  # should be suppressed
Ejemplo n.º 4
0
async def test_deadline(loop):
    stream = H2StreamStub(loop=loop)
    headers = [
        (':method', 'POST'),
        (':path', '/package.Service/Method'),
        ('te', 'trailers'),
        ('content-type', 'application/grpc'),
        ('grpc-timeout', '10m'),
    ]

    async def _method(stream_):
        await asyncio.sleep(1)

    methods = {'/package.Service/Method': Handler(
        _method,
        Cardinality.UNARY_UNARY,
        DummyRequest,
        DummyReply,
    )}
    task = loop.create_task(
        request_handler(methods, stream, headers, ProtoCodec(), release_stream)
    )
    await asyncio.wait_for(task, 0.1, loop=loop)
    assert stream.__events__ == [
        SendHeaders(headers=[
            (':status', '200'),
            ('grpc-status', '4'),  # DEADLINE_EXCEEDED
        ], end_stream=True),
        Reset(ErrorCodes.NO_ERROR),
    ]
Ejemplo n.º 5
0
async def test_exit_and_connection_was_closed(loop):
    client_h2c, server_h2c = create_connections()

    to_client_transport = TransportStub(client_h2c)
    to_server_transport = TransportStub(server_h2c)

    client_conn = Connection(client_h2c, to_server_transport, loop=loop)
    server_conn = Connection(server_h2c, to_client_transport, loop=loop)

    server_proc = EventsProcessor(DummyHandler(), server_conn)
    client_proc = EventsProcessor(DummyHandler(), client_conn)

    client_h2_stream = client_conn.create_stream()
    await client_h2_stream.send_request(create_headers(),
                                        _processor=client_proc)

    request = DummyRequest(value='ping')
    await send_message(client_h2_stream,
                       ProtoCodec(),
                       request,
                       DummyRequest,
                       end=True)
    to_server_transport.process(server_proc)

    server_h2_stream = server_proc.handler.stream
    request_metadata = decode_metadata(server_proc.handler.headers)

    async with mk_stream(server_h2_stream, request_metadata) as server_stream:
        await server_stream.recv_message()
        client_h2c.close_connection()
        to_server_transport.process(server_proc)

        raise ServerError()  # should be suppressed
Ejemplo n.º 6
0
async def test_exit_and_connection_was_broken(loop):
    client_h2c, server_h2c = create_connections()

    to_client_transport = TransportStub(client_h2c)
    to_server_transport = TransportStub(server_h2c)

    client_conn = Connection(client_h2c, to_server_transport, loop=loop)
    server_conn = Connection(server_h2c, to_client_transport, loop=loop)

    server_proc = EventsProcessor(DummyHandler(), server_conn)
    client_proc = EventsProcessor(DummyHandler(), client_conn)

    client_h2_stream = client_conn.create_stream()
    await client_h2_stream.send_request(create_headers(),
                                        _processor=client_proc)

    request = DummyRequest(value='ping')
    await send_message(client_h2_stream,
                       ProtoCodec(),
                       request,
                       DummyRequest,
                       end=True)
    to_server_transport.process(server_proc)

    server_h2_stream = server_proc.handler.stream
    request_metadata = decode_metadata(server_proc.handler.headers)

    with pytest.raises(WriteError):
        async with mk_stream(server_h2_stream,
                             request_metadata) as server_stream:
            server_stream.metadata = request_metadata
            await server_stream.recv_message()
            # simulate broken connection
            to_client_transport.__raise_on_write__(WriteError)
Ejemplo n.º 7
0
async def test_send_trailing_metadata_on_closed_stream(loop):
    client_h2c, server_h2c = create_connections()

    to_client_transport = TransportStub(client_h2c)
    to_server_transport = TransportStub(server_h2c)

    client_conn = Connection(client_h2c, to_server_transport, loop=loop)
    server_conn = Connection(server_h2c, to_client_transport, loop=loop)

    server_proc = EventsProcessor(DummyHandler(), server_conn)
    client_proc = EventsProcessor(DummyHandler(), client_conn)

    client_h2_stream = client_conn.create_stream()
    await client_h2_stream.send_request(create_headers(),
                                        _processor=client_proc)

    request = DummyRequest(value='ping')
    await send_message(client_h2_stream,
                       ProtoCodec(),
                       request,
                       DummyRequest,
                       end=True)
    to_server_transport.process(server_proc)

    server_h2_stream = server_proc.handler.stream
    request_metadata = decode_metadata(server_proc.handler.headers)

    send_trailing_metadata_done = False
    async with mk_stream(server_h2_stream, request_metadata) as server_stream:
        await server_stream.send_trailing_metadata(status=Status.UNKNOWN)
        send_trailing_metadata_done = True

    assert send_trailing_metadata_done
Ejemplo n.º 8
0
def _stream_streaming(stub):
    stream = Stream(stub, '/svc/Method', Cardinality.UNARY_STREAM,
                    DummyRequest, DummyReply,
                    codec=ProtoCodec(), status_details_codec=None,
                    dispatch=_DispatchServerEvents())
    stream.metadata = MultiDict()
    return stream
Ejemplo n.º 9
0
async def test_exit_and_stream_was_closed(loop):
    client_h2c, server_h2c = create_connections()

    to_client_transport = TransportStub(client_h2c)
    to_server_transport = TransportStub(server_h2c)

    client_conn = Connection(client_h2c, to_server_transport, loop=loop)
    server_conn = Connection(server_h2c, to_client_transport, loop=loop)

    server_proc = EventsProcessor(DummyHandler(), server_conn)
    client_proc = EventsProcessor(DummyHandler(), client_conn)

    client_h2_stream = client_conn.create_stream()
    await client_h2_stream.send_request(create_headers(),
                                        _processor=client_proc)

    request = DummyRequest(value='ping')
    await send_message(client_h2_stream, ProtoCodec(), request, DummyRequest,
                       end=True)
    to_server_transport.process(server_proc)

    server_h2_stream = server_proc.handler.stream
    request_metadata = decode_metadata(server_proc.handler.headers)

    async with mk_stream(server_h2_stream, request_metadata) as server_stream:
        await server_stream.recv_message()

        # simulating client closing stream
        await client_h2_stream.reset()
        to_server_transport.process(server_proc)

        # we should fail here on this attempt to send something
        await server_stream.send_message(DummyReply(value='pong'))
Ejemplo n.º 10
0
def mk_stream(h2_stream, metadata):
    stream = Stream(h2_stream, '/svc/Method', Cardinality.UNARY_UNARY,
                    DummyRequest, DummyReply, codec=ProtoCodec(),
                    status_details_codec=None,
                    dispatch=_DispatchServerEvents())
    stream.metadata = metadata
    return stream
Ejemplo n.º 11
0
    def __init__(self, *, loop, server_conn=None,
                 recv_type=None, send_type=None, path='/foo/bar',
                 content_type='application/grpc+proto',
                 codec=ProtoCodec(), deadline=None, metadata=None):
        self.server_conn = server_conn or ServerConn(loop=loop)

        self.stream_id = (self.server_conn.client_h2c
                          .get_next_available_stream_id())
        self.server_conn.client_h2c.send_headers(self.stream_id, [
            (':method', 'POST'),
            (':scheme', 'http'),
            (':path', path),
            (':authority', 'test.com'),
            ('te', 'trailers'),
            ('content-type', content_type),
        ])
        self.server_conn.client_flush()

        self.server_h2s = self.server_conn.server_proto.processor.handler.stream
        assert self.server_h2s

        self.server_stream = server.Stream(
            self.server_h2s,
            Cardinality.UNARY_UNARY,
            codec,
            recv_type,
            send_type,
            metadata=metadata or {},
            deadline=deadline,
        )
Ejemplo n.º 12
0
    def __init__(self,
                 *,
                 loop,
                 client_conn=None,
                 send_type=None,
                 recv_type=None,
                 path='/foo/bar',
                 codec=ProtoCodec(),
                 cardinality=Cardinality.UNARY_UNARY,
                 connect_time=None,
                 timeout=None,
                 deadline=None,
                 metadata=None):
        self.client_conn = client_conn or ClientConn(loop=loop)

        channel = client.Channel(port=-1, loop=loop, codec=codec)
        self.client_stream = channel.request(
            path,
            cardinality,
            send_type,
            recv_type,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )
        self.client_stream._channel = ChannelStub(
            self.client_conn.client_proto, connect_time=connect_time)
Ejemplo n.º 13
0
async def test_invalid_method(loop):
    stream = H2StreamStub(loop=loop)
    headers = [(':method', 'GET')]
    await request_handler({}, stream, headers, ProtoCodec(), release_stream)
    assert stream.__events__ == [
        SendHeaders(headers=[(':status', '405')], end_stream=True),
        Reset(ErrorCodes.NO_ERROR),
    ]
Ejemplo n.º 14
0
def mk_stream(h2_stream, metadata):
    stream = Stream(h2_stream,
                    Cardinality.UNARY_UNARY,
                    DummyRequest,
                    DummyReply,
                    codec=ProtoCodec(),
                    dispatch=_DispatchServerEvents())
    stream.metadata = metadata
    return stream
Ejemplo n.º 15
0
def _stream_streaming(stub):
    stream = Stream(stub,
                    Cardinality.UNARY_STREAM,
                    DummyRequest,
                    DummyReply,
                    codec=ProtoCodec(),
                    dispatch=_DispatchServerEvents())
    stream.metadata = MultiDict()
    return stream
Ejemplo n.º 16
0
def _stream(stub):
    stream = Stream(stub,
                    '/svc/Method',
                    Cardinality.UNARY_UNARY,
                    DummyRequest,
                    DummyReply,
                    codec=ProtoCodec(),
                    dispatch=_DispatchServerEvents())
    stream.metadata = MultiDict()
    return stream
Ejemplo n.º 17
0
async def test_connection_error():
    class BrokenChannel:
        def __connect__(self):
            raise IOError('Intentionally broken connection')

    stream = Stream(BrokenChannel(), '/foo/bar', MultiDict(),
                    Cardinality.UNARY_UNARY, DummyRequest, DummyReply,
                    codec=ProtoCodec(), dispatch=_DispatchChannelEvents())

    with pytest.raises(IOError) as err:
        async with stream:
            await stream.send_request()
    err.match('Intentionally broken connection')
Ejemplo n.º 18
0
async def test_send_trailing_metadata(loop, svc_type):
    async with ChannelFor(
        [svc_type()],
            codec=ProtoCodec(),
            status_details_codec=ProtoStatusDetailsCodec(),
    ) as channel:
        stub = DummyServiceStub(channel)
        with pytest.raises(GRPCError) as error:
            await stub.UnaryUnary(DummyRequest(value='ping'))
    assert error.value.status is Status.DATA_LOSS
    assert error.value.message == 'Some data loss occurred'
    assert error.value.details == [
        Help(links=[Help.Link(url='https://example.com')]),
    ]
Ejemplo n.º 19
0
async def test_missing_content_type(loop):
    stream = H2StreamStub(loop=loop)
    headers = [
        (':method', 'POST'),
    ]
    await request_handler({}, stream, headers, ProtoCodec(), release_stream)
    assert stream.__events__ == [
        SendHeaders(headers=[
            (':status', '415'),
            ('grpc-status', '2'),  # UNKNOWN
            ('grpc-message', 'Missing content-type header'),
        ], end_stream=True),
        Reset(ErrorCodes.NO_ERROR),
    ]
Ejemplo n.º 20
0
async def test_missing_te_header(loop):
    stream = H2StreamStub(loop=loop)
    headers = [
        (':method', 'POST'),
        ('content-type', 'application/grpc'),
    ]
    await request_handler({}, stream, headers, ProtoCodec(), release_stream)
    assert stream.__events__ == [
        SendHeaders(headers=[
            (':status', '400'),
            ('grpc-status', '2'),  # UNKNOWN
            ('grpc-message', 'Required "te: trailers" header is missing'),
        ], end_stream=True),
        Reset(ErrorCodes.NO_ERROR),
    ]
Ejemplo n.º 21
0
async def test_connection_error():
    request = Request('POST', 'http', '/foo/bar',
                      content_type='application/grpc+proto',
                      authority='test.com')

    class BrokenChannel:
        def __connect__(self):
            raise IOError('Intentionally broken connection')

    stream = Stream(BrokenChannel(), request, ProtoCodec(),
                    DummyRequest, DummyReply)

    with pytest.raises(IOError) as err:
        async with stream:
            await stream.send_request()
    err.match('Intentionally broken connection')
Ejemplo n.º 22
0
async def test_missing_method(loop):
    stream = H2StreamStub(loop=loop)
    headers = [
        (':method', 'POST'),
        (':path', '/missing.Service/MissingMethod'),
        ('te', 'trailers'),
        ('content-type', 'application/grpc'),
    ]
    await request_handler({}, stream, headers, ProtoCodec(), release_stream)
    assert stream.__events__ == [
        SendHeaders(headers=[
            (':status', '200'),
            ('grpc-status', '12'),  # UNIMPLEMENTED
            ('grpc-message', 'Method not found'),
        ], end_stream=True),
        Reset(ErrorCodes.NO_ERROR),
    ]
Ejemplo n.º 23
0
async def test_invalid_grpc_timeout(loop):
    stream = H2StreamStub(loop=loop)
    headers = [
        (':method', 'POST'),
        (':path', '/package.Service/Method'),
        ('te', 'trailers'),
        ('content-type', 'application/grpc'),
        ('grpc-timeout', 'invalid'),
    ]
    methods = {'/package.Service/Method': object()}
    await request_handler(methods, stream, headers, ProtoCodec(),
                          release_stream)
    assert stream.__events__ == [
        SendHeaders(headers=[
            (':status', '200'),
            ('grpc-status', '2'),  # UNKNOWN
            ('grpc-message', 'Invalid grpc-timeout header'),
        ], end_stream=True),
        Reset(ErrorCodes.NO_ERROR),
    ]
Ejemplo n.º 24
0
def grpc_decode(message_bin, message_type=None, codec=ProtoCodec()):
    message_len = struct.unpack('>I', message_bin[1:5])[0]
    assert len(message_bin) == message_len + 5
    message = codec.decode(message_bin[5:], message_type)
    return message
Ejemplo n.º 25
0
def grpc_encode(message, message_type=None, codec=ProtoCodec()):
    message_bin = codec.encode(message, message_type)
    header = struct.pack('?', False) + struct.pack('>I', len(message_bin))
    return header + message_bin
Ejemplo n.º 26
0
def test_proto_invalid_type():
    codec = ProtoCodec()
    assert codec.encode(DummyRequest(value='42'), DummyRequest) == \
        DummyRequest(value='42').SerializeToString()
    with pytest.raises(TypeError, match='Message must be of type'):
        codec.encode(1, DummyRequest)
Ejemplo n.º 27
0
def _stream_streaming(stub):
    return Stream(stub, Cardinality.UNARY_STREAM, ProtoCodec(),
                  DummyRequest, DummyReply, metadata=Metadata([]))
Ejemplo n.º 28
0
async def call_handler(mapping, stream, headers):
    await request_handler(mapping, stream, headers, ProtoCodec(), None,
                          _DispatchServerEvents(), release_stream)