def test_telnet_client_tty_cmdline(bind_host, unused_tcp_port, event_loop): """Test executing telnetlib3/client.py as client using a tty (pexpect)""" # this code may be reduced when pexpect asyncio is bugfixed .. # we especially need pexpect to pass sys.stdin.isatty() test. prog, args = 'telnetlib3-client', [ bind_host, str(unused_tcp_port), '--loglevel=warn', '--connect-minwait=0.05', '--connect-maxwait=0.05' ] class HelloServer(asyncio.Protocol): def connection_made(self, transport): super().connection_made(transport) transport.write(b'hello, space cadet.\r\n') event_loop.call_soon(transport.close) # start vanilla tcp server yield from event_loop.create_server(HelloServer, bind_host, unused_tcp_port) proc = pexpect.spawn(prog, args) yield from proc.expect(pexpect.EOF, async=True, timeout=5) # our 'space cadet' has \r\n hardcoded, so \r\r\n happens, ignore it assert proc.before == (b"Escape character is '^]'.\r\n" b"hello, space cadet.\r\r\n" b"\x1b[m\r\n" b"Connection closed by foreign host.\r\n")
def test_telnet_client_negotiation_fail(event_loop, bind_host, unused_tcp_port): """Test telnetlib3.TelnetCLient() negotiation failure with server.""" class ClientNegotiationFail(telnetlib3.TelnetClient): def connection_made(self, transport): from telnetlib3.telopt import WILL, TTYPE super().connection_made(transport) # this creates a pending negotiation demand from the client-side. self.writer.iac(WILL, TTYPE) # a server that never responds with nothing. yield from event_loop.create_server(asyncio.Protocol, bind_host, unused_tcp_port) given_minwait = 0.05 given_maxwait = 0.100 stime = time.time() reader, writer = yield from asyncio.wait_for( telnetlib3.open_connection(client_factory=ClientNegotiationFail, host=bind_host, port=unused_tcp_port, connect_minwait=given_minwait, connect_maxwait=given_maxwait), 5) elapsed_ms = int((time.time() - stime) * 1e3) expected_ms = int(given_maxwait * 1e3) assert expected_ms <= elapsed_ms <= expected_ms + 50
def test_telnet_client_idle_duration_minwait(event_loop, bind_host, unused_tcp_port): """Exercise TelnetClient.idle property and minimum connection time.""" from telnetlib3.telopt import IAC, WONT, TTYPE # a server that doesn't care yield from event_loop.create_server(asyncio.Protocol, bind_host, unused_tcp_port) given_minwait = 0.100 stime = time.time() reader, writer = yield from telnetlib3.open_connection( host=bind_host, port=unused_tcp_port, loop=event_loop, connect_minwait=given_minwait, connect_maxwait=given_minwait) elapsed_ms = int((time.time() - stime) * 1e3) expected_ms = int(given_minwait * 1e3) assert expected_ms <= elapsed_ms <= expected_ms + 50 # verify assert 0 <= writer.protocol.idle <= 0.5 assert 0 <= writer.protocol.duration <= 0.5
def test_curltelnet(server_factory, event_loop, bind_host, unused_tcp_port, log): """Simple curl(1) as Telnet client (simple capabilities).""" event_loop.set_debug(True) waiter_connected = asyncio.Future() server = yield from event_loop.create_server( protocol_factory=lambda: server_factory( waiter_connected=waiter_connected, log=log), host=bind_host, port=unused_tcp_port) log.info('Listening on {0}'.format(server.sockets[0].getsockname())) curl = yield from asyncio.create_subprocess_exec('curl', '--verbose', '--progress-bar', 'telnet://{0}:{1}'.format( bind_host, unused_tcp_port), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) wait_for = [waiter_connected, curl.communicate(input=b'quit\r')] done, pending = yield from asyncio.wait(wait_for, loop=event_loop, timeout=1) assert not pending, wait_for server.close() yield from server.wait_closed()
def test_curltelnet(server_factory, event_loop, bind_host, unused_tcp_port, log): """Simple curl(1) as Telnet client (simple capabilities).""" event_loop.set_debug(True) waiter_connected = asyncio.Future() server = yield from event_loop.create_server( protocol_factory=lambda: server_factory( waiter_connected=waiter_connected, log=log), host=bind_host, port=unused_tcp_port) log.info('Listening on {0}'.format(server.sockets[0].getsockname())) curl = yield from asyncio.create_subprocess_exec( 'curl', '--verbose', '--progress-bar', 'telnet://{0}:{1}'.format(bind_host, unused_tcp_port), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) wait_for = [waiter_connected, curl.communicate(input=b'quit\r')] done, pending = yield from asyncio.wait(wait_for, loop=event_loop, timeout=1) assert not pending, wait_for server.close() yield from server.wait_closed()
def test_netcat_z(event_loop, bind_host, unused_tcp_port, log): """Simple nc(1) -z as client (rapidly disconnecting client).""" server = yield from event_loop.create_server( protocol_factory=lambda: server_factory(log=log), host=bind_host, port=unused_tcp_port) log.info('Listening on {0}'.format(server.sockets[0].getsockname())) netcat = yield from asyncio.create_subprocess_exec( get_netcat(), '-z', bind_host, '{0}'.format(unused_tcp_port), stdout=subprocess.PIPE, stderr=subprocess.PIPE) wait_for = [netcat.wait()] done, pending = yield from asyncio.wait(wait_for, loop=event_loop, timeout=1) assert not pending, (done, pending, wait_for) server.close() yield from server.wait_closed()
def test_telnet_client_open_close_by_write(event_loop, bind_host, unused_tcp_port): """Exercise BaseClient.connection_lost() on writer closed.""" yield from event_loop.create_server(asyncio.Protocol, bind_host, unused_tcp_port) reader, writer = yield from telnetlib3.open_connection( host=bind_host, port=unused_tcp_port, connect_minwait=0.05) writer.close() assert (yield from reader.read()) == ''
def test_telnet_client_open_close_by_error(event_loop, bind_host, unused_tcp_port): """Exercise BaseClient.connection_lost() on error.""" yield from event_loop.create_server(asyncio.Protocol, bind_host, unused_tcp_port) class GivenException(Exception): pass reader, writer = yield from telnetlib3.open_connection( host=bind_host, port=unused_tcp_port, connect_minwait=0.05) writer.protocol.connection_lost(GivenException("candy corn 4 everyone")) with pytest.raises(GivenException): yield from reader.read()
def test_telnet_client_open_closed_by_peer(event_loop, bind_host, unused_tcp_port): """Exercise BaseClient.connection_lost().""" class DisconnecterProtocol(asyncio.Protocol): def connection_made(self, transport): # disconnect on connect transport.close() yield from event_loop.create_server(DisconnecterProtocol, bind_host, unused_tcp_port) reader, writer = yield from telnetlib3.open_connection( host=bind_host, port=unused_tcp_port, connect_minwait=0.05) # read until EOF, no data received. data_received = yield from reader.read() assert data_received == ''
def test_telnet_client_shell_as_coroutine(event_loop, bind_host, unused_tcp_port): """Test callback shell(reader, writer) as coroutine of create_server().""" _waiter = asyncio.Future() @asyncio.coroutine def shell(reader, writer): _waiter.set_result(True) # a server that doesn't care yield from event_loop.create_server(asyncio.Protocol, bind_host, unused_tcp_port) reader, writer = yield from telnetlib3.open_connection( host=bind_host, port=unused_tcp_port, loop=event_loop, shell=shell, connect_minwait=0.05) yield from asyncio.wait_for(_waiter, 0.5)
def test_netcat_z(event_loop, bind_host, unused_tcp_port, log): """Simple nc(1) -z as client (rapidly disconnecting client).""" server = yield from event_loop.create_server( protocol_factory=lambda: server_factory(log=log), host=bind_host, port=unused_tcp_port) log.info('Listening on {0}'.format(server.sockets[0].getsockname())) netcat = yield from asyncio.create_subprocess_exec( get_netcat(), '-z', bind_host, '{0}'.format(unused_tcp_port), stdout=subprocess.PIPE, stderr=subprocess.PIPE ) wait_for = [netcat.wait()] done, pending = yield from asyncio.wait(wait_for, loop=event_loop, timeout=1) assert not pending, (done, pending, wait_for) server.close() yield from server.wait_closed()
def test_telnet_client_encoding_default(event_loop, bind_host, unused_tcp_port): """Default encoding US-ASCII unless it can be negotiated/confirmed!""" from telnetlib3.telopt import IAC, WONT, TTYPE # given _waiter = asyncio.Future() yield from event_loop.create_server(asyncio.Protocol, bind_host, unused_tcp_port) reader, writer = yield from telnetlib3.open_connection( host=bind_host, port=unused_tcp_port, loop=event_loop, connect_minwait=0.05) # after MIN_CONNECT elapsed, client is in US-ASCII state. assert writer.protocol.encoding(incoming=True) == 'US-ASCII' assert writer.protocol.encoding(outgoing=True) == 'US-ASCII' assert writer.protocol.encoding(incoming=True, outgoing=True) == 'US-ASCII' with pytest.raises(TypeError): # at least one direction should be specified writer.protocol.encoding()
def test_telnet_client_cmdline(bind_host, unused_tcp_port, event_loop): """Test executing telnetlib3/client.py as client""" # this code may be reduced when pexpect asyncio is bugfixed .. # we especially need pexpect to pass sys.stdin.isatty() test. prog = pexpect.which('telnetlib3-client') args = [ prog, bind_host, str(unused_tcp_port), '--loglevel=info', '--connect-minwait=0.05', '--connect-maxwait=0.05' ] class HelloServer(asyncio.Protocol): def connection_made(self, transport): super().connection_made(transport) transport.write(b'hello, space cadet.\r\n') # hangup event_loop.call_soon(transport.close) # start vanilla tcp server yield from event_loop.create_server(HelloServer, bind_host, unused_tcp_port) proc = yield from asyncio.create_subprocess_exec( *args, loop=event_loop, stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE) line = yield from asyncio.wait_for(proc.stdout.readline(), 1.5) assert line.strip() == b"Escape character is '^]'." line = yield from asyncio.wait_for(proc.stdout.readline(), 1.5) assert line.strip() == b'hello, space cadet.' # message received, expect the client to gracefully quit. out, err = yield from asyncio.wait_for(proc.communicate(), 1) assert out == b'\x1b[m\nConnection closed by foreign host.\n'