def test_read_pipe(self): proto = MyReadPipeProto(loop=self.loop) rpipe, wpipe = os.pipe() pipeobj = io.open(rpipe, 'rb', 1024) @asyncio.coroutine def connect(): t, p = yield from self.loop.connect_read_pipe( lambda: proto, pipeobj) self.assertIs(p, proto) self.assertIs(t, proto.transport) self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) self.assertEqual(0, proto.nbytes) self.loop.run_until_complete(connect()) os.write(wpipe, b'1') tb.run_until(self.loop, lambda: proto.nbytes >= 1) self.assertEqual(1, proto.nbytes) os.write(wpipe, b'2345') tb.run_until(self.loop, lambda: proto.nbytes >= 5) self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) self.assertEqual(5, proto.nbytes) os.close(wpipe) self.loop.run_until_complete(proto.done) self.assertEqual( ['INITIAL', 'CONNECTED', 'EOF', 'CLOSED'], proto.state) # extra info is available self.assertIsNotNone(proto.transport.get_extra_info('pipe'))
def _test_create_datagram_endpoint_addrs(self, family, lc_addr): class TestMyDatagramProto(MyDatagramProto): def __init__(inner_self): super().__init__(loop=self.loop) def datagram_received(self, data, addr): super().datagram_received(data, addr) self.transport.sendto(b'resp:' + data, addr) coro = self.loop.create_datagram_endpoint( TestMyDatagramProto, local_addr=lc_addr, family=family) s_transport, server = self.loop.run_until_complete(coro) host, port, *_ = s_transport.get_extra_info('sockname') self.assertIsInstance(server, TestMyDatagramProto) self.assertEqual('INITIALIZED', server.state) self.assertIs(server.transport, s_transport) extra = {} if hasattr(socket, 'SO_REUSEPORT') and \ sys.version_info[:3] >= (3, 5, 1): extra['reuse_port'] = True coro = self.loop.create_datagram_endpoint( lambda: MyDatagramProto(loop=self.loop), family=family, remote_addr=(host, port), **extra) transport, client = self.loop.run_until_complete(coro) self.assertIsInstance(client, MyDatagramProto) self.assertEqual('INITIALIZED', client.state) self.assertIs(client.transport, transport) transport.sendto(b'xxx') tb.run_until(self.loop, lambda: server.nbytes) self.assertEqual(3, server.nbytes) tb.run_until(self.loop, lambda: client.nbytes) # received self.assertEqual(8, client.nbytes) # extra info is available self.assertIsNotNone(transport.get_extra_info('sockname')) # close connection transport.close() self.loop.run_until_complete(client.done) self.assertEqual('CLOSED', client.state) server.transport.close() self.loop.run_until_complete(server.done)
def _test_create_datagram_endpoint_addrs(self, family, lc_addr): class TestMyDatagramProto(MyDatagramProto): def __init__(inner_self): super().__init__(loop=self.loop) def datagram_received(self, data, addr): super().datagram_received(data, addr) self.transport.sendto(b'resp:' + data, addr) coro = self.loop.create_datagram_endpoint(TestMyDatagramProto, local_addr=lc_addr, family=family) s_transport, server = self.loop.run_until_complete(coro) host, port, *_ = s_transport.get_extra_info('sockname') self.assertIsInstance(server, TestMyDatagramProto) self.assertEqual('INITIALIZED', server.state) self.assertIs(server.transport, s_transport) extra = {} if hasattr(socket, 'SO_REUSEPORT') and \ sys.version_info[:3] >= (3, 5, 1): extra['reuse_port'] = True coro = self.loop.create_datagram_endpoint( lambda: MyDatagramProto(loop=self.loop), family=family, remote_addr=(host, port), **extra) transport, client = self.loop.run_until_complete(coro) self.assertIsInstance(client, MyDatagramProto) self.assertEqual('INITIALIZED', client.state) self.assertIs(client.transport, transport) transport.sendto(b'xxx') tb.run_until(self.loop, lambda: server.nbytes) self.assertEqual(3, server.nbytes) tb.run_until(self.loop, lambda: client.nbytes) # received self.assertEqual(8, client.nbytes) # extra info is available self.assertIsNotNone(transport.get_extra_info('sockname')) # close connection transport.close() self.loop.run_until_complete(client.done) self.assertEqual('CLOSED', client.state) server.transport.close() self.loop.run_until_complete(server.done)
def test_write_pty(self): master, slave = os.openpty() os.set_blocking(master, False) slave_write_obj = io.open(slave, 'wb', 0) proto = MyWritePipeProto(loop=self.loop) connect = self.loop.connect_write_pipe(lambda: proto, slave_write_obj) transport, p = self.loop.run_until_complete(connect) self.assertIs(p, proto) self.assertIs(transport, proto.transport) self.assertEqual('CONNECTED', proto.state) transport.write(b'1') data = bytearray() def reader(data): try: chunk = os.read(master, 1024) except BlockingIOError: return len(data) data += chunk return len(data) tb.run_until(self.loop, lambda: reader(data) >= 1, timeout=10) self.assertEqual(b'1', data) transport.write(b'2345') tb.run_until(self.loop, lambda: reader(data) >= 5, timeout=10) self.assertEqual(b'12345', data) self.assertEqual('CONNECTED', proto.state) os.close(master) # extra info is available self.assertIsNotNone(proto.transport.get_extra_info('pipe')) # close connection proto.transport.close() self.loop.run_until_complete(proto.done) self.assertEqual('CLOSED', proto.state)
def test_read_pty_output(self): proto = MyReadPipeProto(loop=self.loop) master, slave = os.openpty() master_read_obj = io.open(master, 'rb', 0) @asyncio.coroutine def connect(): t, p = yield from self.loop.connect_read_pipe( lambda: proto, master_read_obj) self.assertIs(p, proto) self.assertIs(t, proto.transport) self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) self.assertEqual(0, proto.nbytes) self.loop.run_until_complete(connect()) os.write(slave, b'1') tb.run_until(self.loop, lambda: proto.nbytes) self.assertEqual(1, proto.nbytes) os.write(slave, b'2345') tb.run_until(self.loop, lambda: proto.nbytes >= 5) self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) self.assertEqual(5, proto.nbytes) # On Linux, transport raises EIO when slave is closed -- # ignore it. self.loop.set_exception_handler(lambda loop, ctx: None) os.close(slave) proto.transport.close() self.loop.run_until_complete(proto.done) self.assertEqual(['INITIAL', 'CONNECTED', 'EOF', 'CLOSED'], proto.state) # extra info is available self.assertIsNotNone(proto.transport.get_extra_info('pipe'))
def test_read_pty_output(self): proto = MyReadPipeProto(loop=self.loop) master, slave = os.openpty() master_read_obj = io.open(master, 'rb', 0) @asyncio.coroutine def connect(): t, p = yield from self.loop.connect_read_pipe(lambda: proto, master_read_obj) self.assertIs(p, proto) self.assertIs(t, proto.transport) self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) self.assertEqual(0, proto.nbytes) self.loop.run_until_complete(connect()) os.write(slave, b'1') tb.run_until(self.loop, lambda: proto.nbytes) self.assertEqual(1, proto.nbytes) os.write(slave, b'2345') tb.run_until(self.loop, lambda: proto.nbytes >= 5) self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) self.assertEqual(5, proto.nbytes) # On Linux, transport raises EIO when slave is closed -- # ignore it. self.loop.set_exception_handler(lambda loop, ctx: None) os.close(slave) proto.transport.close() self.loop.run_until_complete(proto.done) self.assertEqual( ['INITIAL', 'CONNECTED', 'EOF', 'CLOSED'], proto.state) # extra info is available self.assertIsNotNone(proto.transport.get_extra_info('pipe'))
def _test_create_datagram_endpoint_addrs(self, family, lc_addr): class TestMyDatagramProto(MyDatagramProto): def __init__(inner_self): super().__init__(loop=self.loop) def datagram_received(self, data, addr): super().datagram_received(data, addr) self.transport.sendto(b'resp:' + data, addr) coro = self.loop.create_datagram_endpoint(TestMyDatagramProto, local_addr=lc_addr, family=family) s_transport, server = self.loop.run_until_complete(coro) remote_addr = s_transport.get_extra_info('sockname') host, port, *_ = remote_addr self.assertIsInstance(server, TestMyDatagramProto) self.assertEqual('INITIALIZED', server.state) self.assertIs(server.transport, s_transport) extra = {} if hasattr(socket, 'SO_REUSEPORT') and \ sys.version_info[:3] >= (3, 5, 1): extra['reuse_port'] = True coro = self.loop.create_datagram_endpoint( lambda: MyDatagramProto(loop=self.loop), family=family, remote_addr=(host, port), **extra) transport, client = self.loop.run_until_complete(coro) self.assertIsInstance(client, MyDatagramProto) self.assertEqual('INITIALIZED', client.state) self.assertIs(client.transport, transport) transport.sendto(b'xxx') tb.run_until(self.loop, lambda: server.nbytes) self.assertEqual(3, server.nbytes) tb.run_until(self.loop, lambda: client.nbytes) # received self.assertEqual(8, client.nbytes) # https://github.com/MagicStack/uvloop/issues/319 # uvloop should behave the same as asyncio when given remote_addr transport.sendto(b'xxx', remote_addr) tb.run_until(self.loop, lambda: server.nbytes > 3 or client.done.done()) self.assertEqual(6, server.nbytes) tb.run_until(self.loop, lambda: client.nbytes > 8) # received self.assertEqual(16, client.nbytes) # reject sendto with a different port with self.assertRaisesRegex(ValueError, "Invalid address.*" + repr(remote_addr)): bad_addr = list(remote_addr) bad_addr[1] += 1 bad_addr = tuple(bad_addr) transport.sendto(b"xxx", bad_addr) # reject sento with unresolved hostname if remote_addr[0] != lc_addr[0]: with self.assertRaisesRegex( ValueError, "Invalid address.*" + repr(remote_addr)): bad_addr = list(remote_addr) bad_addr[0] = lc_addr[0] bad_addr = tuple(bad_addr) transport.sendto(b"xxx", bad_addr) # extra info is available self.assertIsNotNone(transport.get_extra_info('sockname')) # close connection transport.close() self.loop.run_until_complete(client.done) self.assertEqual('CLOSED', client.state) server.transport.close() self.loop.run_until_complete(server.done)