Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 1 | import socket |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 2 | import telnetlib |
| 3 | import time |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 4 | import Queue |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 5 | |
Gregory P. Smith | e4220a5 | 2012-07-16 13:36:01 -0700 | [diff] [blame] | 6 | import unittest |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 7 | from unittest import TestCase |
| 8 | from test import test_support |
Victor Stinner | 6a10281 | 2010-04-27 23:55:59 +0000 | [diff] [blame] | 9 | threading = test_support.import_module('threading') |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 10 | |
Trent Nelson | e41b006 | 2008-04-08 23:47:30 +0000 | [diff] [blame] | 11 | HOST = test_support.HOST |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 12 | EOF_sigil = object() |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 13 | |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 14 | def server(evt, serv, dataq=None): |
| 15 | """ Open a tcp server in three steps |
| 16 | 1) set evt to true to let the parent know we are ready |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 17 | 2) [optional] if is not False, write the list of data from dataq.get() |
| 18 | to the socket. |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 19 | """ |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 20 | serv.listen(5) |
Neal Norwitz | 3718429 | 2008-01-26 21:21:59 +0000 | [diff] [blame] | 21 | evt.set() |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 22 | try: |
| 23 | conn, addr = serv.accept() |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 24 | if dataq: |
| 25 | data = '' |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 26 | new_data = dataq.get(True, 0.5) |
| 27 | dataq.task_done() |
| 28 | for item in new_data: |
| 29 | if item == EOF_sigil: |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 30 | break |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 31 | if type(item) in [int, float]: |
| 32 | time.sleep(item) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 33 | else: |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 34 | data += item |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 35 | written = conn.send(data) |
| 36 | data = data[written:] |
Jesus Cea | cb65f32 | 2011-11-08 16:06:44 +0100 | [diff] [blame] | 37 | conn.close() |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 38 | except socket.timeout: |
| 39 | pass |
| 40 | finally: |
| 41 | serv.close() |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 42 | |
| 43 | class GeneralTests(TestCase): |
Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 44 | |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 45 | def setUp(self): |
| 46 | self.evt = threading.Event() |
Trent Nelson | e41b006 | 2008-04-08 23:47:30 +0000 | [diff] [blame] | 47 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
Jesus Cea | cb65f32 | 2011-11-08 16:06:44 +0100 | [diff] [blame] | 48 | self.sock.settimeout(60) # Safety net. Look issue 11812 |
Trent Nelson | e41b006 | 2008-04-08 23:47:30 +0000 | [diff] [blame] | 49 | self.port = test_support.bind_port(self.sock) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 50 | self.thread = threading.Thread(target=server, args=(self.evt,self.sock)) |
Jesus Cea | cb65f32 | 2011-11-08 16:06:44 +0100 | [diff] [blame] | 51 | self.thread.setDaemon(True) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 52 | self.thread.start() |
Neal Norwitz | 3718429 | 2008-01-26 21:21:59 +0000 | [diff] [blame] | 53 | self.evt.wait() |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 54 | |
| 55 | def tearDown(self): |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 56 | self.thread.join() |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 57 | |
| 58 | def testBasic(self): |
| 59 | # connects |
Trent Nelson | e41b006 | 2008-04-08 23:47:30 +0000 | [diff] [blame] | 60 | telnet = telnetlib.Telnet(HOST, self.port) |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 61 | telnet.sock.close() |
Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 62 | |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 63 | def testTimeoutDefault(self): |
Facundo Batista | 4f1b1ed | 2008-05-29 16:39:26 +0000 | [diff] [blame] | 64 | self.assertTrue(socket.getdefaulttimeout() is None) |
| 65 | socket.setdefaulttimeout(30) |
| 66 | try: |
Jesus Cea | cb65f32 | 2011-11-08 16:06:44 +0100 | [diff] [blame] | 67 | telnet = telnetlib.Telnet(HOST, self.port) |
Facundo Batista | 4f1b1ed | 2008-05-29 16:39:26 +0000 | [diff] [blame] | 68 | finally: |
| 69 | socket.setdefaulttimeout(None) |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 70 | self.assertEqual(telnet.sock.gettimeout(), 30) |
| 71 | telnet.sock.close() |
| 72 | |
| 73 | def testTimeoutNone(self): |
| 74 | # None, having other default |
Facundo Batista | 4f1b1ed | 2008-05-29 16:39:26 +0000 | [diff] [blame] | 75 | self.assertTrue(socket.getdefaulttimeout() is None) |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 76 | socket.setdefaulttimeout(30) |
| 77 | try: |
Trent Nelson | e41b006 | 2008-04-08 23:47:30 +0000 | [diff] [blame] | 78 | telnet = telnetlib.Telnet(HOST, self.port, timeout=None) |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 79 | finally: |
Facundo Batista | 4f1b1ed | 2008-05-29 16:39:26 +0000 | [diff] [blame] | 80 | socket.setdefaulttimeout(None) |
| 81 | self.assertTrue(telnet.sock.gettimeout() is None) |
| 82 | telnet.sock.close() |
| 83 | |
| 84 | def testTimeoutValue(self): |
Jesus Cea | cb65f32 | 2011-11-08 16:06:44 +0100 | [diff] [blame] | 85 | telnet = telnetlib.Telnet(HOST, self.port, timeout=30) |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 86 | self.assertEqual(telnet.sock.gettimeout(), 30) |
| 87 | telnet.sock.close() |
| 88 | |
Facundo Batista | 4f1b1ed | 2008-05-29 16:39:26 +0000 | [diff] [blame] | 89 | def testTimeoutOpen(self): |
| 90 | telnet = telnetlib.Telnet() |
Jesus Cea | cb65f32 | 2011-11-08 16:06:44 +0100 | [diff] [blame] | 91 | telnet.open(HOST, self.port, timeout=30) |
Facundo Batista | 4f1b1ed | 2008-05-29 16:39:26 +0000 | [diff] [blame] | 92 | self.assertEqual(telnet.sock.gettimeout(), 30) |
| 93 | telnet.sock.close() |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 94 | |
Ezio Melotti | 290c6b3 | 2013-08-25 23:56:43 +0300 | [diff] [blame] | 95 | def testGetters(self): |
| 96 | # Test telnet getter methods |
| 97 | telnet = telnetlib.Telnet(HOST, self.port, timeout=30) |
| 98 | t_sock = telnet.sock |
| 99 | self.assertEqual(telnet.get_socket(), t_sock) |
| 100 | self.assertEqual(telnet.fileno(), t_sock.fileno()) |
| 101 | telnet.sock.close() |
| 102 | |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 103 | def _read_setUp(self): |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 104 | self.evt = threading.Event() |
| 105 | self.dataq = Queue.Queue() |
| 106 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
Charles-François Natali | 3b81807 | 2011-12-19 16:11:04 +0100 | [diff] [blame] | 107 | self.sock.settimeout(10) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 108 | self.port = test_support.bind_port(self.sock) |
| 109 | self.thread = threading.Thread(target=server, args=(self.evt,self.sock, self.dataq)) |
| 110 | self.thread.start() |
| 111 | self.evt.wait() |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 112 | |
| 113 | def _read_tearDown(self): |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 114 | self.thread.join() |
| 115 | |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 116 | class ReadTests(TestCase): |
| 117 | setUp = _read_setUp |
| 118 | tearDown = _read_tearDown |
| 119 | |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 120 | # use a similar approach to testing timeouts as test_timeout.py |
| 121 | # these will never pass 100% but make the fuzz big enough that it is rare |
| 122 | block_long = 0.6 |
| 123 | block_short = 0.3 |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 124 | def test_read_until_A(self): |
| 125 | """ |
| 126 | read_until(expected, [timeout]) |
| 127 | Read until the expected string has been seen, or a timeout is |
| 128 | hit (default is no timeout); may block. |
| 129 | """ |
| 130 | want = ['x' * 10, 'match', 'y' * 10, EOF_sigil] |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 131 | self.dataq.put(want) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 132 | telnet = telnetlib.Telnet(HOST, self.port) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 133 | self.dataq.join() |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 134 | data = telnet.read_until('match') |
| 135 | self.assertEqual(data, ''.join(want[:-2])) |
| 136 | |
| 137 | def test_read_until_B(self): |
| 138 | # test the timeout - it does NOT raise socket.timeout |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 139 | want = ['hello', self.block_long, 'not seen', EOF_sigil] |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 140 | self.dataq.put(want) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 141 | telnet = telnetlib.Telnet(HOST, self.port) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 142 | self.dataq.join() |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 143 | data = telnet.read_until('not seen', self.block_short) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 144 | self.assertEqual(data, want[0]) |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 145 | self.assertEqual(telnet.read_all(), 'not seen') |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 146 | |
Gregory P. Smith | e0c2220 | 2012-07-15 22:16:06 -0700 | [diff] [blame] | 147 | def test_read_until_with_poll(self): |
| 148 | """Use select.poll() to implement telnet.read_until().""" |
| 149 | want = ['x' * 10, 'match', 'y' * 10, EOF_sigil] |
| 150 | self.dataq.put(want) |
| 151 | telnet = telnetlib.Telnet(HOST, self.port) |
| 152 | if not telnet._has_poll: |
| 153 | raise unittest.SkipTest('select.poll() is required') |
| 154 | telnet._has_poll = True |
| 155 | self.dataq.join() |
| 156 | data = telnet.read_until('match') |
| 157 | self.assertEqual(data, ''.join(want[:-2])) |
| 158 | |
| 159 | def test_read_until_with_select(self): |
| 160 | """Use select.select() to implement telnet.read_until().""" |
| 161 | want = ['x' * 10, 'match', 'y' * 10, EOF_sigil] |
| 162 | self.dataq.put(want) |
| 163 | telnet = telnetlib.Telnet(HOST, self.port) |
| 164 | telnet._has_poll = False |
| 165 | self.dataq.join() |
| 166 | data = telnet.read_until('match') |
| 167 | self.assertEqual(data, ''.join(want[:-2])) |
| 168 | |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 169 | def test_read_all_A(self): |
| 170 | """ |
| 171 | read_all() |
| 172 | Read all data until EOF; may block. |
| 173 | """ |
| 174 | want = ['x' * 500, 'y' * 500, 'z' * 500, EOF_sigil] |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 175 | self.dataq.put(want) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 176 | telnet = telnetlib.Telnet(HOST, self.port) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 177 | self.dataq.join() |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 178 | data = telnet.read_all() |
| 179 | self.assertEqual(data, ''.join(want[:-1])) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 180 | |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 181 | def _test_blocking(self, func): |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 182 | self.dataq.put([self.block_long, EOF_sigil]) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 183 | self.dataq.join() |
| 184 | start = time.time() |
| 185 | data = func() |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 186 | self.assertTrue(self.block_short <= time.time() - start) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 187 | |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 188 | def test_read_all_B(self): |
| 189 | self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all) |
| 190 | |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 191 | def test_read_all_C(self): |
| 192 | self.dataq.put([EOF_sigil]) |
| 193 | telnet = telnetlib.Telnet(HOST, self.port) |
| 194 | self.dataq.join() |
| 195 | telnet.read_all() |
| 196 | telnet.read_all() # shouldn't raise |
| 197 | |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 198 | def test_read_some_A(self): |
| 199 | """ |
| 200 | read_some() |
| 201 | Read at least one byte or EOF; may block. |
| 202 | """ |
| 203 | # test 'at least one byte' |
| 204 | want = ['x' * 500, EOF_sigil] |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 205 | self.dataq.put(want) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 206 | telnet = telnetlib.Telnet(HOST, self.port) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 207 | self.dataq.join() |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 208 | data = telnet.read_all() |
| 209 | self.assertTrue(len(data) >= 1) |
| 210 | |
| 211 | def test_read_some_B(self): |
| 212 | # test EOF |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 213 | self.dataq.put([EOF_sigil]) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 214 | telnet = telnetlib.Telnet(HOST, self.port) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 215 | self.dataq.join() |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 216 | self.assertEqual('', telnet.read_some()) |
| 217 | |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 218 | def test_read_some_C(self): |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 219 | self._test_blocking(telnetlib.Telnet(HOST, self.port).read_some) |
| 220 | |
| 221 | def _test_read_any_eager_A(self, func_name): |
| 222 | """ |
| 223 | read_very_eager() |
| 224 | Read all data available already queued or on the socket, |
| 225 | without blocking. |
| 226 | """ |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 227 | want = [self.block_long, 'x' * 100, 'y' * 100, EOF_sigil] |
| 228 | expects = want[1] + want[2] |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 229 | self.dataq.put(want) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 230 | telnet = telnetlib.Telnet(HOST, self.port) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 231 | self.dataq.join() |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 232 | func = getattr(telnet, func_name) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 233 | data = '' |
| 234 | while True: |
| 235 | try: |
| 236 | data += func() |
| 237 | self.assertTrue(expects.startswith(data)) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 238 | except EOFError: |
| 239 | break |
| 240 | self.assertEqual(expects, data) |
| 241 | |
| 242 | def _test_read_any_eager_B(self, func_name): |
| 243 | # test EOF |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 244 | self.dataq.put([EOF_sigil]) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 245 | telnet = telnetlib.Telnet(HOST, self.port) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 246 | self.dataq.join() |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 247 | time.sleep(self.block_short) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 248 | func = getattr(telnet, func_name) |
| 249 | self.assertRaises(EOFError, func) |
| 250 | |
| 251 | # read_eager and read_very_eager make the same gaurantees |
| 252 | # (they behave differently but we only test the gaurantees) |
| 253 | def test_read_very_eager_A(self): |
| 254 | self._test_read_any_eager_A('read_very_eager') |
| 255 | def test_read_very_eager_B(self): |
| 256 | self._test_read_any_eager_B('read_very_eager') |
| 257 | def test_read_eager_A(self): |
| 258 | self._test_read_any_eager_A('read_eager') |
| 259 | def test_read_eager_B(self): |
| 260 | self._test_read_any_eager_B('read_eager') |
| 261 | # NB -- we need to test the IAC block which is mentioned in the docstring |
| 262 | # but not in the module docs |
| 263 | |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 264 | def _test_read_any_lazy_B(self, func_name): |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 265 | self.dataq.put([EOF_sigil]) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 266 | telnet = telnetlib.Telnet(HOST, self.port) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 267 | self.dataq.join() |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 268 | func = getattr(telnet, func_name) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 269 | telnet.fill_rawq() |
| 270 | self.assertRaises(EOFError, func) |
| 271 | |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 272 | def test_read_lazy_A(self): |
| 273 | want = ['x' * 100, EOF_sigil] |
| 274 | self.dataq.put(want) |
| 275 | telnet = telnetlib.Telnet(HOST, self.port) |
| 276 | self.dataq.join() |
| 277 | time.sleep(self.block_short) |
| 278 | self.assertEqual('', telnet.read_lazy()) |
| 279 | data = '' |
| 280 | while True: |
| 281 | try: |
| 282 | read_data = telnet.read_lazy() |
| 283 | data += read_data |
| 284 | if not read_data: |
| 285 | telnet.fill_rawq() |
| 286 | except EOFError: |
| 287 | break |
| 288 | self.assertTrue(want[0].startswith(data)) |
| 289 | self.assertEqual(data, want[0]) |
| 290 | |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 291 | def test_read_lazy_B(self): |
| 292 | self._test_read_any_lazy_B('read_lazy') |
| 293 | |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 294 | def test_read_very_lazy_A(self): |
| 295 | want = ['x' * 100, EOF_sigil] |
| 296 | self.dataq.put(want) |
| 297 | telnet = telnetlib.Telnet(HOST, self.port) |
| 298 | self.dataq.join() |
| 299 | time.sleep(self.block_short) |
| 300 | self.assertEqual('', telnet.read_very_lazy()) |
| 301 | data = '' |
| 302 | while True: |
| 303 | try: |
| 304 | read_data = telnet.read_very_lazy() |
| 305 | except EOFError: |
| 306 | break |
| 307 | data += read_data |
| 308 | if not read_data: |
| 309 | telnet.fill_rawq() |
| 310 | self.assertEqual('', telnet.cookedq) |
| 311 | telnet.process_rawq() |
| 312 | self.assertTrue(want[0].startswith(data)) |
| 313 | self.assertEqual(data, want[0]) |
| 314 | |
| 315 | def test_read_very_lazy_B(self): |
| 316 | self._test_read_any_lazy_B('read_very_lazy') |
| 317 | |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 318 | class nego_collector(object): |
| 319 | def __init__(self, sb_getter=None): |
| 320 | self.seen = '' |
| 321 | self.sb_getter = sb_getter |
| 322 | self.sb_seen = '' |
| 323 | |
| 324 | def do_nego(self, sock, cmd, opt): |
| 325 | self.seen += cmd + opt |
| 326 | if cmd == tl.SE and self.sb_getter: |
| 327 | sb_data = self.sb_getter() |
| 328 | self.sb_seen += sb_data |
| 329 | |
| 330 | tl = telnetlib |
| 331 | class OptionTests(TestCase): |
| 332 | setUp = _read_setUp |
| 333 | tearDown = _read_tearDown |
| 334 | # RFC 854 commands |
| 335 | cmds = [tl.AO, tl.AYT, tl.BRK, tl.EC, tl.EL, tl.GA, tl.IP, tl.NOP] |
| 336 | |
| 337 | def _test_command(self, data): |
| 338 | """ helper for testing IAC + cmd """ |
| 339 | self.setUp() |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 340 | self.dataq.put(data) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 341 | telnet = telnetlib.Telnet(HOST, self.port) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 342 | self.dataq.join() |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 343 | nego = nego_collector() |
| 344 | telnet.set_option_negotiation_callback(nego.do_nego) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 345 | txt = telnet.read_all() |
| 346 | cmd = nego.seen |
| 347 | self.assertTrue(len(cmd) > 0) # we expect at least one command |
Ezio Melotti | aa98058 | 2010-01-23 23:04:36 +0000 | [diff] [blame] | 348 | self.assertIn(cmd[0], self.cmds) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 349 | self.assertEqual(cmd[1], tl.NOOPT) |
| 350 | self.assertEqual(len(''.join(data[:-1])), len(txt + cmd)) |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 351 | nego.sb_getter = None # break the nego => telnet cycle |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 352 | self.tearDown() |
| 353 | |
| 354 | def test_IAC_commands(self): |
| 355 | # reset our setup |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 356 | self.dataq.put([EOF_sigil]) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 357 | telnet = telnetlib.Telnet(HOST, self.port) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 358 | self.dataq.join() |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 359 | self.tearDown() |
| 360 | |
| 361 | for cmd in self.cmds: |
| 362 | self._test_command(['x' * 100, tl.IAC + cmd, 'y'*100, EOF_sigil]) |
| 363 | self._test_command(['x' * 10, tl.IAC + cmd, 'y'*10, EOF_sigil]) |
| 364 | self._test_command([tl.IAC + cmd, EOF_sigil]) |
| 365 | # all at once |
| 366 | self._test_command([tl.IAC + cmd for (cmd) in self.cmds] + [EOF_sigil]) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 367 | self.assertEqual('', telnet.read_sb_data()) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 368 | |
| 369 | def test_SB_commands(self): |
| 370 | # RFC 855, subnegotiations portion |
| 371 | send = [tl.IAC + tl.SB + tl.IAC + tl.SE, |
| 372 | tl.IAC + tl.SB + tl.IAC + tl.IAC + tl.IAC + tl.SE, |
| 373 | tl.IAC + tl.SB + tl.IAC + tl.IAC + 'aa' + tl.IAC + tl.SE, |
| 374 | tl.IAC + tl.SB + 'bb' + tl.IAC + tl.IAC + tl.IAC + tl.SE, |
| 375 | tl.IAC + tl.SB + 'cc' + tl.IAC + tl.IAC + 'dd' + tl.IAC + tl.SE, |
| 376 | EOF_sigil, |
| 377 | ] |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 378 | self.dataq.put(send) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 379 | telnet = telnetlib.Telnet(HOST, self.port) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 380 | self.dataq.join() |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 381 | nego = nego_collector(telnet.read_sb_data) |
| 382 | telnet.set_option_negotiation_callback(nego.do_nego) |
Jack Diederich | 183028e | 2009-04-06 02:08:44 +0000 | [diff] [blame] | 383 | txt = telnet.read_all() |
| 384 | self.assertEqual(txt, '') |
| 385 | want_sb_data = tl.IAC + tl.IAC + 'aabb' + tl.IAC + 'cc' + tl.IAC + 'dd' |
| 386 | self.assertEqual(nego.sb_seen, want_sb_data) |
Jack Diederich | 3b2312e | 2009-04-07 20:22:59 +0000 | [diff] [blame] | 387 | self.assertEqual('', telnet.read_sb_data()) |
Jack Diederich | 7f9bb91 | 2009-04-07 23:56:57 +0000 | [diff] [blame] | 388 | nego.sb_getter = None # break the nego => telnet cycle |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 389 | |
Gregory P. Smith | e0c2220 | 2012-07-15 22:16:06 -0700 | [diff] [blame] | 390 | |
| 391 | class ExpectTests(TestCase): |
| 392 | def setUp(self): |
| 393 | self.evt = threading.Event() |
| 394 | self.dataq = Queue.Queue() |
| 395 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
| 396 | self.sock.settimeout(10) |
| 397 | self.port = test_support.bind_port(self.sock) |
| 398 | self.thread = threading.Thread(target=server, args=(self.evt,self.sock, |
| 399 | self.dataq)) |
| 400 | self.thread.start() |
| 401 | self.evt.wait() |
| 402 | |
| 403 | def tearDown(self): |
| 404 | self.thread.join() |
| 405 | |
| 406 | # use a similar approach to testing timeouts as test_timeout.py |
| 407 | # these will never pass 100% but make the fuzz big enough that it is rare |
| 408 | block_long = 0.6 |
| 409 | block_short = 0.3 |
| 410 | def test_expect_A(self): |
| 411 | """ |
| 412 | expect(expected, [timeout]) |
| 413 | Read until the expected string has been seen, or a timeout is |
| 414 | hit (default is no timeout); may block. |
| 415 | """ |
| 416 | want = ['x' * 10, 'match', 'y' * 10, EOF_sigil] |
| 417 | self.dataq.put(want) |
| 418 | telnet = telnetlib.Telnet(HOST, self.port) |
| 419 | self.dataq.join() |
| 420 | (_,_,data) = telnet.expect(['match']) |
| 421 | self.assertEqual(data, ''.join(want[:-2])) |
| 422 | |
| 423 | def test_expect_B(self): |
| 424 | # test the timeout - it does NOT raise socket.timeout |
| 425 | want = ['hello', self.block_long, 'not seen', EOF_sigil] |
| 426 | self.dataq.put(want) |
| 427 | telnet = telnetlib.Telnet(HOST, self.port) |
| 428 | self.dataq.join() |
| 429 | (_,_,data) = telnet.expect(['not seen'], self.block_short) |
| 430 | self.assertEqual(data, want[0]) |
| 431 | self.assertEqual(telnet.read_all(), 'not seen') |
| 432 | |
| 433 | def test_expect_with_poll(self): |
| 434 | """Use select.poll() to implement telnet.expect().""" |
| 435 | want = ['x' * 10, 'match', 'y' * 10, EOF_sigil] |
| 436 | self.dataq.put(want) |
| 437 | telnet = telnetlib.Telnet(HOST, self.port) |
| 438 | if not telnet._has_poll: |
| 439 | raise unittest.SkipTest('select.poll() is required') |
| 440 | telnet._has_poll = True |
| 441 | self.dataq.join() |
| 442 | (_,_,data) = telnet.expect(['match']) |
| 443 | self.assertEqual(data, ''.join(want[:-2])) |
| 444 | |
| 445 | def test_expect_with_select(self): |
| 446 | """Use select.select() to implement telnet.expect().""" |
| 447 | want = ['x' * 10, 'match', 'y' * 10, EOF_sigil] |
| 448 | self.dataq.put(want) |
| 449 | telnet = telnetlib.Telnet(HOST, self.port) |
| 450 | telnet._has_poll = False |
| 451 | self.dataq.join() |
| 452 | (_,_,data) = telnet.expect(['match']) |
| 453 | self.assertEqual(data, ''.join(want[:-2])) |
| 454 | |
| 455 | |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 456 | def test_main(verbose=None): |
Gregory P. Smith | e0c2220 | 2012-07-15 22:16:06 -0700 | [diff] [blame] | 457 | test_support.run_unittest(GeneralTests, ReadTests, OptionTests, |
| 458 | ExpectTests) |
Facundo Batista | b6a5c9d | 2007-03-29 18:22:35 +0000 | [diff] [blame] | 459 | |
| 460 | if __name__ == '__main__': |
| 461 | test_main() |