blob: 5a179f0cd18ae1c15bb207f50e3808a0a51a0b29 [file] [log] [blame]
Facundo Batistab6a5c9d2007-03-29 18:22:35 +00001import socket
Facundo Batistab6a5c9d2007-03-29 18:22:35 +00002import telnetlib
3import time
Jack Diederich183028e2009-04-06 02:08:44 +00004import Queue
Facundo Batistab6a5c9d2007-03-29 18:22:35 +00005
6from unittest import TestCase
7from test import test_support
Victor Stinner6a102812010-04-27 23:55:59 +00008threading = test_support.import_module('threading')
Facundo Batistab6a5c9d2007-03-29 18:22:35 +00009
Trent Nelsone41b0062008-04-08 23:47:30 +000010HOST = test_support.HOST
Jack Diederich183028e2009-04-06 02:08:44 +000011EOF_sigil = object()
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000012
Jack Diederich183028e2009-04-06 02:08:44 +000013def server(evt, serv, dataq=None):
14 """ Open a tcp server in three steps
15 1) set evt to true to let the parent know we are ready
Jack Diederich3b2312e2009-04-07 20:22:59 +000016 2) [optional] if is not False, write the list of data from dataq.get()
17 to the socket.
Jack Diederich183028e2009-04-06 02:08:44 +000018 """
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000019 serv.listen(5)
Neal Norwitz37184292008-01-26 21:21:59 +000020 evt.set()
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000021 try:
22 conn, addr = serv.accept()
Jack Diederich183028e2009-04-06 02:08:44 +000023 if dataq:
24 data = ''
Jack Diederich7f9bb912009-04-07 23:56:57 +000025 new_data = dataq.get(True, 0.5)
26 dataq.task_done()
27 for item in new_data:
28 if item == EOF_sigil:
Jack Diederich3b2312e2009-04-07 20:22:59 +000029 break
Jack Diederich7f9bb912009-04-07 23:56:57 +000030 if type(item) in [int, float]:
31 time.sleep(item)
Jack Diederich3b2312e2009-04-07 20:22:59 +000032 else:
Jack Diederich7f9bb912009-04-07 23:56:57 +000033 data += item
Jack Diederich183028e2009-04-06 02:08:44 +000034 written = conn.send(data)
35 data = data[written:]
Jesus Ceacb65f322011-11-08 16:06:44 +010036 conn.close()
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000037 except socket.timeout:
38 pass
39 finally:
40 serv.close()
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000041
42class GeneralTests(TestCase):
Neal Norwitz0d4c06e2007-04-25 06:30:05 +000043
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000044 def setUp(self):
45 self.evt = threading.Event()
Trent Nelsone41b0062008-04-08 23:47:30 +000046 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Jesus Ceacb65f322011-11-08 16:06:44 +010047 self.sock.settimeout(60) # Safety net. Look issue 11812
Trent Nelsone41b0062008-04-08 23:47:30 +000048 self.port = test_support.bind_port(self.sock)
Jack Diederich183028e2009-04-06 02:08:44 +000049 self.thread = threading.Thread(target=server, args=(self.evt,self.sock))
Jesus Ceacb65f322011-11-08 16:06:44 +010050 self.thread.setDaemon(True)
Jack Diederich183028e2009-04-06 02:08:44 +000051 self.thread.start()
Neal Norwitz37184292008-01-26 21:21:59 +000052 self.evt.wait()
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000053
54 def tearDown(self):
Jack Diederich183028e2009-04-06 02:08:44 +000055 self.thread.join()
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000056
57 def testBasic(self):
58 # connects
Trent Nelsone41b0062008-04-08 23:47:30 +000059 telnet = telnetlib.Telnet(HOST, self.port)
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000060 telnet.sock.close()
Neal Norwitz0d4c06e2007-04-25 06:30:05 +000061
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000062 def testTimeoutDefault(self):
Facundo Batista4f1b1ed2008-05-29 16:39:26 +000063 self.assertTrue(socket.getdefaulttimeout() is None)
64 socket.setdefaulttimeout(30)
65 try:
Jesus Ceacb65f322011-11-08 16:06:44 +010066 telnet = telnetlib.Telnet(HOST, self.port)
Facundo Batista4f1b1ed2008-05-29 16:39:26 +000067 finally:
68 socket.setdefaulttimeout(None)
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000069 self.assertEqual(telnet.sock.gettimeout(), 30)
70 telnet.sock.close()
71
72 def testTimeoutNone(self):
73 # None, having other default
Facundo Batista4f1b1ed2008-05-29 16:39:26 +000074 self.assertTrue(socket.getdefaulttimeout() is None)
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000075 socket.setdefaulttimeout(30)
76 try:
Trent Nelsone41b0062008-04-08 23:47:30 +000077 telnet = telnetlib.Telnet(HOST, self.port, timeout=None)
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000078 finally:
Facundo Batista4f1b1ed2008-05-29 16:39:26 +000079 socket.setdefaulttimeout(None)
80 self.assertTrue(telnet.sock.gettimeout() is None)
81 telnet.sock.close()
82
83 def testTimeoutValue(self):
Jesus Ceacb65f322011-11-08 16:06:44 +010084 telnet = telnetlib.Telnet(HOST, self.port, timeout=30)
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000085 self.assertEqual(telnet.sock.gettimeout(), 30)
86 telnet.sock.close()
87
Facundo Batista4f1b1ed2008-05-29 16:39:26 +000088 def testTimeoutOpen(self):
89 telnet = telnetlib.Telnet()
Jesus Ceacb65f322011-11-08 16:06:44 +010090 telnet.open(HOST, self.port, timeout=30)
Facundo Batista4f1b1ed2008-05-29 16:39:26 +000091 self.assertEqual(telnet.sock.gettimeout(), 30)
92 telnet.sock.close()
Facundo Batistab6a5c9d2007-03-29 18:22:35 +000093
Jack Diederich183028e2009-04-06 02:08:44 +000094def _read_setUp(self):
Jack Diederich183028e2009-04-06 02:08:44 +000095 self.evt = threading.Event()
96 self.dataq = Queue.Queue()
97 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Charles-François Natali3b818072011-12-19 16:11:04 +010098 self.sock.settimeout(10)
Jack Diederich183028e2009-04-06 02:08:44 +000099 self.port = test_support.bind_port(self.sock)
100 self.thread = threading.Thread(target=server, args=(self.evt,self.sock, self.dataq))
101 self.thread.start()
102 self.evt.wait()
Jack Diederich183028e2009-04-06 02:08:44 +0000103
104def _read_tearDown(self):
Jack Diederich183028e2009-04-06 02:08:44 +0000105 self.thread.join()
106
Jack Diederich183028e2009-04-06 02:08:44 +0000107class ReadTests(TestCase):
108 setUp = _read_setUp
109 tearDown = _read_tearDown
110
Jack Diederich7f9bb912009-04-07 23:56:57 +0000111 # use a similar approach to testing timeouts as test_timeout.py
112 # these will never pass 100% but make the fuzz big enough that it is rare
113 block_long = 0.6
114 block_short = 0.3
Jack Diederich183028e2009-04-06 02:08:44 +0000115 def test_read_until_A(self):
116 """
117 read_until(expected, [timeout])
118 Read until the expected string has been seen, or a timeout is
119 hit (default is no timeout); may block.
120 """
121 want = ['x' * 10, 'match', 'y' * 10, EOF_sigil]
Jack Diederich3b2312e2009-04-07 20:22:59 +0000122 self.dataq.put(want)
Jack Diederich183028e2009-04-06 02:08:44 +0000123 telnet = telnetlib.Telnet(HOST, self.port)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000124 self.dataq.join()
Jack Diederich183028e2009-04-06 02:08:44 +0000125 data = telnet.read_until('match')
126 self.assertEqual(data, ''.join(want[:-2]))
127
128 def test_read_until_B(self):
129 # test the timeout - it does NOT raise socket.timeout
Jack Diederich7f9bb912009-04-07 23:56:57 +0000130 want = ['hello', self.block_long, 'not seen', EOF_sigil]
Jack Diederich3b2312e2009-04-07 20:22:59 +0000131 self.dataq.put(want)
Jack Diederich183028e2009-04-06 02:08:44 +0000132 telnet = telnetlib.Telnet(HOST, self.port)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000133 self.dataq.join()
Jack Diederich7f9bb912009-04-07 23:56:57 +0000134 data = telnet.read_until('not seen', self.block_short)
Jack Diederich183028e2009-04-06 02:08:44 +0000135 self.assertEqual(data, want[0])
Jack Diederich7f9bb912009-04-07 23:56:57 +0000136 self.assertEqual(telnet.read_all(), 'not seen')
Jack Diederich183028e2009-04-06 02:08:44 +0000137
138 def test_read_all_A(self):
139 """
140 read_all()
141 Read all data until EOF; may block.
142 """
143 want = ['x' * 500, 'y' * 500, 'z' * 500, EOF_sigil]
Jack Diederich3b2312e2009-04-07 20:22:59 +0000144 self.dataq.put(want)
Jack Diederich183028e2009-04-06 02:08:44 +0000145 telnet = telnetlib.Telnet(HOST, self.port)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000146 self.dataq.join()
Jack Diederich183028e2009-04-06 02:08:44 +0000147 data = telnet.read_all()
148 self.assertEqual(data, ''.join(want[:-1]))
149 return
150
Jack Diederich3b2312e2009-04-07 20:22:59 +0000151 def _test_blocking(self, func):
Jack Diederich7f9bb912009-04-07 23:56:57 +0000152 self.dataq.put([self.block_long, EOF_sigil])
Jack Diederich3b2312e2009-04-07 20:22:59 +0000153 self.dataq.join()
154 start = time.time()
155 data = func()
Jack Diederich7f9bb912009-04-07 23:56:57 +0000156 self.assertTrue(self.block_short <= time.time() - start)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000157
Jack Diederich183028e2009-04-06 02:08:44 +0000158 def test_read_all_B(self):
159 self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all)
160
Jack Diederich3b2312e2009-04-07 20:22:59 +0000161 def test_read_all_C(self):
162 self.dataq.put([EOF_sigil])
163 telnet = telnetlib.Telnet(HOST, self.port)
164 self.dataq.join()
165 telnet.read_all()
166 telnet.read_all() # shouldn't raise
167
Jack Diederich183028e2009-04-06 02:08:44 +0000168 def test_read_some_A(self):
169 """
170 read_some()
171 Read at least one byte or EOF; may block.
172 """
173 # test 'at least one byte'
174 want = ['x' * 500, EOF_sigil]
Jack Diederich3b2312e2009-04-07 20:22:59 +0000175 self.dataq.put(want)
Jack Diederich183028e2009-04-06 02:08:44 +0000176 telnet = telnetlib.Telnet(HOST, self.port)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000177 self.dataq.join()
Jack Diederich183028e2009-04-06 02:08:44 +0000178 data = telnet.read_all()
179 self.assertTrue(len(data) >= 1)
180
181 def test_read_some_B(self):
182 # test EOF
Jack Diederich3b2312e2009-04-07 20:22:59 +0000183 self.dataq.put([EOF_sigil])
Jack Diederich183028e2009-04-06 02:08:44 +0000184 telnet = telnetlib.Telnet(HOST, self.port)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000185 self.dataq.join()
Jack Diederich183028e2009-04-06 02:08:44 +0000186 self.assertEqual('', telnet.read_some())
187
Jack Diederich3b2312e2009-04-07 20:22:59 +0000188 def test_read_some_C(self):
Jack Diederich183028e2009-04-06 02:08:44 +0000189 self._test_blocking(telnetlib.Telnet(HOST, self.port).read_some)
190
191 def _test_read_any_eager_A(self, func_name):
192 """
193 read_very_eager()
194 Read all data available already queued or on the socket,
195 without blocking.
196 """
Jack Diederich7f9bb912009-04-07 23:56:57 +0000197 want = [self.block_long, 'x' * 100, 'y' * 100, EOF_sigil]
198 expects = want[1] + want[2]
Jack Diederich3b2312e2009-04-07 20:22:59 +0000199 self.dataq.put(want)
Jack Diederich183028e2009-04-06 02:08:44 +0000200 telnet = telnetlib.Telnet(HOST, self.port)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000201 self.dataq.join()
Jack Diederich183028e2009-04-06 02:08:44 +0000202 func = getattr(telnet, func_name)
Jack Diederich183028e2009-04-06 02:08:44 +0000203 data = ''
204 while True:
205 try:
206 data += func()
207 self.assertTrue(expects.startswith(data))
Jack Diederich183028e2009-04-06 02:08:44 +0000208 except EOFError:
209 break
210 self.assertEqual(expects, data)
211
212 def _test_read_any_eager_B(self, func_name):
213 # test EOF
Jack Diederich3b2312e2009-04-07 20:22:59 +0000214 self.dataq.put([EOF_sigil])
Jack Diederich183028e2009-04-06 02:08:44 +0000215 telnet = telnetlib.Telnet(HOST, self.port)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000216 self.dataq.join()
Jack Diederich7f9bb912009-04-07 23:56:57 +0000217 time.sleep(self.block_short)
Jack Diederich183028e2009-04-06 02:08:44 +0000218 func = getattr(telnet, func_name)
219 self.assertRaises(EOFError, func)
220
221 # read_eager and read_very_eager make the same gaurantees
222 # (they behave differently but we only test the gaurantees)
223 def test_read_very_eager_A(self):
224 self._test_read_any_eager_A('read_very_eager')
225 def test_read_very_eager_B(self):
226 self._test_read_any_eager_B('read_very_eager')
227 def test_read_eager_A(self):
228 self._test_read_any_eager_A('read_eager')
229 def test_read_eager_B(self):
230 self._test_read_any_eager_B('read_eager')
231 # NB -- we need to test the IAC block which is mentioned in the docstring
232 # but not in the module docs
233
Jack Diederich183028e2009-04-06 02:08:44 +0000234 def _test_read_any_lazy_B(self, func_name):
Jack Diederich3b2312e2009-04-07 20:22:59 +0000235 self.dataq.put([EOF_sigil])
Jack Diederich183028e2009-04-06 02:08:44 +0000236 telnet = telnetlib.Telnet(HOST, self.port)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000237 self.dataq.join()
Jack Diederich183028e2009-04-06 02:08:44 +0000238 func = getattr(telnet, func_name)
Jack Diederich183028e2009-04-06 02:08:44 +0000239 telnet.fill_rawq()
240 self.assertRaises(EOFError, func)
241
Jack Diederich7f9bb912009-04-07 23:56:57 +0000242 def test_read_lazy_A(self):
243 want = ['x' * 100, EOF_sigil]
244 self.dataq.put(want)
245 telnet = telnetlib.Telnet(HOST, self.port)
246 self.dataq.join()
247 time.sleep(self.block_short)
248 self.assertEqual('', telnet.read_lazy())
249 data = ''
250 while True:
251 try:
252 read_data = telnet.read_lazy()
253 data += read_data
254 if not read_data:
255 telnet.fill_rawq()
256 except EOFError:
257 break
258 self.assertTrue(want[0].startswith(data))
259 self.assertEqual(data, want[0])
260
Jack Diederich183028e2009-04-06 02:08:44 +0000261 def test_read_lazy_B(self):
262 self._test_read_any_lazy_B('read_lazy')
263
Jack Diederich7f9bb912009-04-07 23:56:57 +0000264 def test_read_very_lazy_A(self):
265 want = ['x' * 100, EOF_sigil]
266 self.dataq.put(want)
267 telnet = telnetlib.Telnet(HOST, self.port)
268 self.dataq.join()
269 time.sleep(self.block_short)
270 self.assertEqual('', telnet.read_very_lazy())
271 data = ''
272 while True:
273 try:
274 read_data = telnet.read_very_lazy()
275 except EOFError:
276 break
277 data += read_data
278 if not read_data:
279 telnet.fill_rawq()
280 self.assertEqual('', telnet.cookedq)
281 telnet.process_rawq()
282 self.assertTrue(want[0].startswith(data))
283 self.assertEqual(data, want[0])
284
285 def test_read_very_lazy_B(self):
286 self._test_read_any_lazy_B('read_very_lazy')
287
Jack Diederich183028e2009-04-06 02:08:44 +0000288class nego_collector(object):
289 def __init__(self, sb_getter=None):
290 self.seen = ''
291 self.sb_getter = sb_getter
292 self.sb_seen = ''
293
294 def do_nego(self, sock, cmd, opt):
295 self.seen += cmd + opt
296 if cmd == tl.SE and self.sb_getter:
297 sb_data = self.sb_getter()
298 self.sb_seen += sb_data
299
300tl = telnetlib
301class OptionTests(TestCase):
302 setUp = _read_setUp
303 tearDown = _read_tearDown
304 # RFC 854 commands
305 cmds = [tl.AO, tl.AYT, tl.BRK, tl.EC, tl.EL, tl.GA, tl.IP, tl.NOP]
306
307 def _test_command(self, data):
308 """ helper for testing IAC + cmd """
309 self.setUp()
Jack Diederich3b2312e2009-04-07 20:22:59 +0000310 self.dataq.put(data)
Jack Diederich183028e2009-04-06 02:08:44 +0000311 telnet = telnetlib.Telnet(HOST, self.port)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000312 self.dataq.join()
Jack Diederich183028e2009-04-06 02:08:44 +0000313 nego = nego_collector()
314 telnet.set_option_negotiation_callback(nego.do_nego)
Jack Diederich183028e2009-04-06 02:08:44 +0000315 txt = telnet.read_all()
316 cmd = nego.seen
317 self.assertTrue(len(cmd) > 0) # we expect at least one command
Ezio Melottiaa980582010-01-23 23:04:36 +0000318 self.assertIn(cmd[0], self.cmds)
Jack Diederich183028e2009-04-06 02:08:44 +0000319 self.assertEqual(cmd[1], tl.NOOPT)
320 self.assertEqual(len(''.join(data[:-1])), len(txt + cmd))
Jack Diederich7f9bb912009-04-07 23:56:57 +0000321 nego.sb_getter = None # break the nego => telnet cycle
Jack Diederich183028e2009-04-06 02:08:44 +0000322 self.tearDown()
323
324 def test_IAC_commands(self):
325 # reset our setup
Jack Diederich3b2312e2009-04-07 20:22:59 +0000326 self.dataq.put([EOF_sigil])
Jack Diederich183028e2009-04-06 02:08:44 +0000327 telnet = telnetlib.Telnet(HOST, self.port)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000328 self.dataq.join()
Jack Diederich183028e2009-04-06 02:08:44 +0000329 self.tearDown()
330
331 for cmd in self.cmds:
332 self._test_command(['x' * 100, tl.IAC + cmd, 'y'*100, EOF_sigil])
333 self._test_command(['x' * 10, tl.IAC + cmd, 'y'*10, EOF_sigil])
334 self._test_command([tl.IAC + cmd, EOF_sigil])
335 # all at once
336 self._test_command([tl.IAC + cmd for (cmd) in self.cmds] + [EOF_sigil])
Jack Diederich3b2312e2009-04-07 20:22:59 +0000337 self.assertEqual('', telnet.read_sb_data())
Jack Diederich183028e2009-04-06 02:08:44 +0000338
339 def test_SB_commands(self):
340 # RFC 855, subnegotiations portion
341 send = [tl.IAC + tl.SB + tl.IAC + tl.SE,
342 tl.IAC + tl.SB + tl.IAC + tl.IAC + tl.IAC + tl.SE,
343 tl.IAC + tl.SB + tl.IAC + tl.IAC + 'aa' + tl.IAC + tl.SE,
344 tl.IAC + tl.SB + 'bb' + tl.IAC + tl.IAC + tl.IAC + tl.SE,
345 tl.IAC + tl.SB + 'cc' + tl.IAC + tl.IAC + 'dd' + tl.IAC + tl.SE,
346 EOF_sigil,
347 ]
Jack Diederich3b2312e2009-04-07 20:22:59 +0000348 self.dataq.put(send)
Jack Diederich183028e2009-04-06 02:08:44 +0000349 telnet = telnetlib.Telnet(HOST, self.port)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000350 self.dataq.join()
Jack Diederich183028e2009-04-06 02:08:44 +0000351 nego = nego_collector(telnet.read_sb_data)
352 telnet.set_option_negotiation_callback(nego.do_nego)
Jack Diederich183028e2009-04-06 02:08:44 +0000353 txt = telnet.read_all()
354 self.assertEqual(txt, '')
355 want_sb_data = tl.IAC + tl.IAC + 'aabb' + tl.IAC + 'cc' + tl.IAC + 'dd'
356 self.assertEqual(nego.sb_seen, want_sb_data)
Jack Diederich3b2312e2009-04-07 20:22:59 +0000357 self.assertEqual('', telnet.read_sb_data())
Jack Diederich7f9bb912009-04-07 23:56:57 +0000358 nego.sb_getter = None # break the nego => telnet cycle
Facundo Batistab6a5c9d2007-03-29 18:22:35 +0000359
360def test_main(verbose=None):
Jack Diederich183028e2009-04-06 02:08:44 +0000361 test_support.run_unittest(GeneralTests, ReadTests, OptionTests)
Facundo Batistab6a5c9d2007-03-29 18:22:35 +0000362
363if __name__ == '__main__':
364 test_main()