class ServerConn: def __init__(self): client_h2_config = H2Configuration( client_side=True, header_encoding='ascii', ) self.client_h2c = H2Connection(client_h2_config) self.to_client_transport = TransportStub(self.client_h2c) self.client_h2c.initiate_connection() server_config = H2Configuration( client_side=False, header_encoding='ascii', ) self.server_proto = H2Protocol( DummyHandler(), Configuration().__for_test__(), server_config, ) self.server_proto.connection_made(self.to_client_transport) # complete settings exchange and clear events buffer self.client_flush() self.to_client_transport.events() def client_flush(self): self.server_proto.data_received(self.client_h2c.data_to_send())
async def test_recv_data_larger_than_window_size(loop): client_h2c, server_h2c = create_connections() to_client_transport = TransportStub(client_h2c) server_conn = Connection(server_h2c, to_client_transport, loop=loop) to_server_transport = TransportStub(server_h2c) client_conn = Connection(client_h2c, to_server_transport, loop=loop) client_processor = EventsProcessor(DummyHandler(), client_conn) client_stream = client_conn.create_stream() request = Request(method='POST', scheme='http', path='/', content_type='application/grpc+proto', authority='test.com') await client_stream.send_request(request.to_headers(), _processor=client_processor) initial_window = server_h2c.local_settings.initial_window_size assert (client_h2c.local_flow_control_window( client_stream.id) == initial_window) # data should be bigger than window size data = b'0' * (initial_window + 1) size = len(data) # sending less than a full message await client_stream.send_data(data[:initial_window - 1]) # let server process it's events server_processor = EventsProcessor(DummyHandler(), server_conn) for event in to_server_transport.events(): server_processor.process(event) # checking window size was decreased assert client_h2c.local_flow_control_window(client_stream.id) == 1 # simulate that server is waiting for the size of a message and should # acknowledge that size as soon as it will be received server_stream, = server_processor.streams.values() recv_task = loop.create_task(server_stream.recv_data(size)) await asyncio.wait([recv_task], timeout=.01, loop=loop) assert server_stream.__buffer__._read_size == size assert server_stream.__buffer__._size == initial_window - 1 # check that server acknowledged received partial data assert client_h2c.local_flow_control_window(client_stream.id) > 1 # sending remaining data and recv_task should finish await client_stream.send_data(data[initial_window - 1:]) for event in to_server_transport.events(): server_processor.process(event) await asyncio.wait_for(recv_task, 0.01, loop=loop) assert server_stream.__buffer__._size == 0
class ServerStub: def __init__(self, protocol): self.connection = H2Connection( H2Configuration(client_side=False, header_encoding='utf-8')) self._transport = TransportStub(self.connection) self._protocol = protocol self._protocol.connection_made(self._transport) def events(self): return self._transport.events() def flush(self): self._protocol.data_received(self.connection.data_to_send())