mirror of
https://github.com/python/cpython.git
synced 2025-07-23 19:25:40 +00:00

svn+ssh://svn.python.org/python/branches/py3k ................ r74126 | alexandre.vassalotti | 2009-07-21 02:39:03 +0200 (Di, 21 Jul 2009) | 14 lines Merged revisions 73871 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r73871 | alexandre.vassalotti | 2009-07-06 22:17:30 -0400 (Mon, 06 Jul 2009) | 7 lines Grow the allocated buffer in PyUnicode_EncodeUTF7 to avoid buffer overrun. Without this change, test_unicode.UnicodeTest.test_codecs_utf7 crashes in debug mode. What happens is the unicode string u'\U000abcde' with a length of 1 encodes to the string '+2m/c3g-' of length 8. Since only 5 bytes is reserved in the buffer, a buffer overrun occurs. ........ ................ r74130 | alexandre.vassalotti | 2009-07-21 02:57:50 +0200 (Di, 21 Jul 2009) | 2 lines Add ignore rule for the Doc/tools/jinga2/ directory. ................ r74131 | alexandre.vassalotti | 2009-07-21 04:51:58 +0200 (Di, 21 Jul 2009) | 13 lines Merged revisions 73683,73786 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r73683 | georg.brandl | 2009-06-29 10:44:49 -0400 (Mon, 29 Jun 2009) | 1 line Fix error handling in PyCode_Optimize, by Alexander Schremmer at EuroPython sprint. ........ r73786 | benjamin.peterson | 2009-07-02 18:56:16 -0400 (Thu, 02 Jul 2009) | 1 line condense with assertRaises ........ ................ r74149 | ezio.melotti | 2009-07-21 22:37:52 +0200 (Di, 21 Jul 2009) | 9 lines Merged revisions 74148 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74148 | ezio.melotti | 2009-07-21 23:18:27 +0300 (Tue, 21 Jul 2009) | 1 line #6536 fixed typo ........ ................ r74155 | alexandre.vassalotti | 2009-07-22 04:24:49 +0200 (Mi, 22 Jul 2009) | 2 lines Issue #6242: Fix deallocator of io.StringIO and io.BytesIO. ................ r74157 | alexandre.vassalotti | 2009-07-22 05:07:33 +0200 (Mi, 22 Jul 2009) | 2 lines Issue #6241: Better type checking for the arguments of io.StringIO. ................ r74180 | ezio.melotti | 2009-07-22 23:17:14 +0200 (Mi, 22 Jul 2009) | 9 lines Merged revisions 74179 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74179 | ezio.melotti | 2009-07-23 00:08:49 +0300 (Thu, 23 Jul 2009) | 1 line #6423 has_key -> in ........ ................ r74181 | alexandre.vassalotti | 2009-07-22 23:27:53 +0200 (Mi, 22 Jul 2009) | 6 lines Clean up test_curses. By using __stdout__ directly, test_curses caused regrtest.py to duplicate the output of some test results. ................ r74182 | alexandre.vassalotti | 2009-07-22 23:29:01 +0200 (Mi, 22 Jul 2009) | 2 lines Use assertGreater instead of assertTrue(x > y). ................ r74183 | alexandre.vassalotti | 2009-07-23 01:27:17 +0200 (Do, 23 Jul 2009) | 4 lines Specialize assertTrue checks when possible. We should get slightly more helpful failure messages with this change. ................ r74398 | georg.brandl | 2009-08-13 11:16:39 +0200 (Do, 13 Aug 2009) | 1 line #6694: fix old function names. ................
258 lines
8 KiB
Python
258 lines
8 KiB
Python
# test asynchat
|
|
|
|
from test import support
|
|
|
|
# If this fails, the test will be skipped.
|
|
thread = support.import_module('_thread')
|
|
|
|
import asyncore, asynchat, socket, threading, time
|
|
import unittest
|
|
import sys
|
|
|
|
HOST = support.HOST
|
|
SERVER_QUIT = b'QUIT\n'
|
|
|
|
class echo_server(threading.Thread):
|
|
# parameter to determine the number of bytes passed back to the
|
|
# client each send
|
|
chunk_size = 1
|
|
|
|
def __init__(self, event):
|
|
threading.Thread.__init__(self)
|
|
self.event = event
|
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
self.port = support.bind_port(self.sock)
|
|
|
|
def run(self):
|
|
self.sock.listen(1)
|
|
self.event.set()
|
|
conn, client = self.sock.accept()
|
|
self.buffer = b""
|
|
# collect data until quit message is seen
|
|
while SERVER_QUIT not in self.buffer:
|
|
data = conn.recv(1)
|
|
if not data:
|
|
break
|
|
self.buffer = self.buffer + data
|
|
|
|
# remove the SERVER_QUIT message
|
|
self.buffer = self.buffer.replace(SERVER_QUIT, b'')
|
|
|
|
# re-send entire set of collected data
|
|
try:
|
|
# this may fail on some tests, such as test_close_when_done, since
|
|
# the client closes the channel when it's done sending
|
|
while self.buffer:
|
|
n = conn.send(self.buffer[:self.chunk_size])
|
|
time.sleep(0.001)
|
|
self.buffer = self.buffer[n:]
|
|
except:
|
|
pass
|
|
|
|
conn.close()
|
|
self.sock.close()
|
|
|
|
class echo_client(asynchat.async_chat):
|
|
|
|
def __init__(self, terminator, server_port):
|
|
asynchat.async_chat.__init__(self)
|
|
self.contents = []
|
|
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
self.connect((HOST, server_port))
|
|
self.set_terminator(terminator)
|
|
self.buffer = b""
|
|
|
|
def handle_connect(self):
|
|
pass
|
|
|
|
if sys.platform == 'darwin':
|
|
# select.poll returns a select.POLLHUP at the end of the tests
|
|
# on darwin, so just ignore it
|
|
def handle_expt(self):
|
|
pass
|
|
|
|
def collect_incoming_data(self, data):
|
|
self.buffer += data
|
|
|
|
def found_terminator(self):
|
|
self.contents.append(self.buffer)
|
|
self.buffer = b""
|
|
|
|
|
|
def start_echo_server():
|
|
event = threading.Event()
|
|
s = echo_server(event)
|
|
s.start()
|
|
event.wait()
|
|
event.clear()
|
|
time.sleep(0.01) # Give server time to start accepting.
|
|
return s, event
|
|
|
|
|
|
class TestAsynchat(unittest.TestCase):
|
|
usepoll = False
|
|
|
|
def setUp (self):
|
|
pass
|
|
|
|
def tearDown (self):
|
|
pass
|
|
|
|
def line_terminator_check(self, term, server_chunk):
|
|
event = threading.Event()
|
|
s = echo_server(event)
|
|
s.chunk_size = server_chunk
|
|
s.start()
|
|
event.wait()
|
|
event.clear()
|
|
time.sleep(0.01) # Give server time to start accepting.
|
|
c = echo_client(term, s.port)
|
|
c.push(b"hello ")
|
|
c.push(b"world" + term)
|
|
c.push(b"I'm not dead yet!" + term)
|
|
c.push(SERVER_QUIT)
|
|
asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
|
|
s.join()
|
|
|
|
self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"])
|
|
|
|
# the line terminator tests below check receiving variously-sized
|
|
# chunks back from the server in order to exercise all branches of
|
|
# async_chat.handle_read
|
|
|
|
def test_line_terminator1(self):
|
|
# test one-character terminator
|
|
for l in (1,2,3):
|
|
self.line_terminator_check(b'\n', l)
|
|
|
|
def test_line_terminator2(self):
|
|
# test two-character terminator
|
|
for l in (1,2,3):
|
|
self.line_terminator_check(b'\r\n', l)
|
|
|
|
def test_line_terminator3(self):
|
|
# test three-character terminator
|
|
for l in (1,2,3):
|
|
self.line_terminator_check(b'qqq', l)
|
|
|
|
def numeric_terminator_check(self, termlen):
|
|
# Try reading a fixed number of bytes
|
|
s, event = start_echo_server()
|
|
c = echo_client(termlen, s.port)
|
|
data = b"hello world, I'm not dead yet!\n"
|
|
c.push(data)
|
|
c.push(SERVER_QUIT)
|
|
asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
|
|
s.join()
|
|
|
|
self.assertEqual(c.contents, [data[:termlen]])
|
|
|
|
def test_numeric_terminator1(self):
|
|
# check that ints & longs both work (since type is
|
|
# explicitly checked in async_chat.handle_read)
|
|
self.numeric_terminator_check(1)
|
|
|
|
def test_numeric_terminator2(self):
|
|
self.numeric_terminator_check(6)
|
|
|
|
def test_none_terminator(self):
|
|
# Try reading a fixed number of bytes
|
|
s, event = start_echo_server()
|
|
c = echo_client(None, s.port)
|
|
data = b"hello world, I'm not dead yet!\n"
|
|
c.push(data)
|
|
c.push(SERVER_QUIT)
|
|
asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
|
|
s.join()
|
|
|
|
self.assertEqual(c.contents, [])
|
|
self.assertEqual(c.buffer, data)
|
|
|
|
def test_simple_producer(self):
|
|
s, event = start_echo_server()
|
|
c = echo_client(b'\n', s.port)
|
|
data = b"hello world\nI'm not dead yet!\n"
|
|
p = asynchat.simple_producer(data+SERVER_QUIT, buffer_size=8)
|
|
c.push_with_producer(p)
|
|
asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
|
|
s.join()
|
|
|
|
self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"])
|
|
|
|
def test_string_producer(self):
|
|
s, event = start_echo_server()
|
|
c = echo_client(b'\n', s.port)
|
|
data = b"hello world\nI'm not dead yet!\n"
|
|
c.push_with_producer(data+SERVER_QUIT)
|
|
asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
|
|
s.join()
|
|
|
|
self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"])
|
|
|
|
def test_empty_line(self):
|
|
# checks that empty lines are handled correctly
|
|
s, event = start_echo_server()
|
|
c = echo_client(b'\n', s.port)
|
|
c.push(b"hello world\n\nI'm not dead yet!\n")
|
|
c.push(SERVER_QUIT)
|
|
asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
|
|
s.join()
|
|
|
|
self.assertEqual(c.contents,
|
|
[b"hello world", b"", b"I'm not dead yet!"])
|
|
|
|
def test_close_when_done(self):
|
|
s, event = start_echo_server()
|
|
c = echo_client(b'\n', s.port)
|
|
c.push(b"hello world\nI'm not dead yet!\n")
|
|
c.push(SERVER_QUIT)
|
|
c.close_when_done()
|
|
asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
|
|
s.join()
|
|
|
|
self.assertEqual(c.contents, [])
|
|
# the server might have been able to send a byte or two back, but this
|
|
# at least checks that it received something and didn't just fail
|
|
# (which could still result in the client not having received anything)
|
|
self.assertGreater(len(s.buffer), 0)
|
|
|
|
|
|
class TestAsynchat_WithPoll(TestAsynchat):
|
|
usepoll = True
|
|
|
|
class TestHelperFunctions(unittest.TestCase):
|
|
def test_find_prefix_at_end(self):
|
|
self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1)
|
|
self.assertEqual(asynchat.find_prefix_at_end("qwertydkjf", "\r\n"), 0)
|
|
|
|
class TestFifo(unittest.TestCase):
|
|
def test_basic(self):
|
|
f = asynchat.fifo()
|
|
f.push(7)
|
|
f.push(b'a')
|
|
self.assertEqual(len(f), 2)
|
|
self.assertEqual(f.first(), 7)
|
|
self.assertEqual(f.pop(), (1, 7))
|
|
self.assertEqual(len(f), 1)
|
|
self.assertEqual(f.first(), b'a')
|
|
self.assertEqual(f.is_empty(), False)
|
|
self.assertEqual(f.pop(), (1, b'a'))
|
|
self.assertEqual(len(f), 0)
|
|
self.assertEqual(f.is_empty(), True)
|
|
self.assertEqual(f.pop(), (0, None))
|
|
|
|
def test_given_list(self):
|
|
f = asynchat.fifo([b'x', 17, 3])
|
|
self.assertEqual(len(f), 3)
|
|
self.assertEqual(f.pop(), (1, b'x'))
|
|
self.assertEqual(f.pop(), (1, 17))
|
|
self.assertEqual(f.pop(), (1, 3))
|
|
self.assertEqual(f.pop(), (0, None))
|
|
|
|
|
|
def test_main(verbose=None):
|
|
support.run_unittest(TestAsynchat, TestAsynchat_WithPoll,
|
|
TestHelperFunctions, TestFifo)
|
|
|
|
if __name__ == "__main__":
|
|
test_main(verbose=True)
|