summaryrefslogtreecommitdiff
path: root/Lib/test/test_asynchat.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_asynchat.py')
-rw-r--r--Lib/test/test_asynchat.py105
1 files changed, 81 insertions, 24 deletions
diff --git a/Lib/test/test_asynchat.py b/Lib/test/test_asynchat.py
index c79fe6f613..2dc9d0c17a 100644
--- a/Lib/test/test_asynchat.py
+++ b/Lib/test/test_asynchat.py
@@ -5,9 +5,14 @@ from test import support
# If this fails, the test will be skipped.
thread = support.import_module('_thread')
-import asyncore, asynchat, socket, time
-import unittest
+import asynchat
+import asyncore
+import errno
+import socket
import sys
+import time
+import unittest
+import unittest.mock
try:
import threading
except ImportError:
@@ -15,6 +20,7 @@ except ImportError:
HOST = support.HOST
SERVER_QUIT = b'QUIT\n'
+TIMEOUT = 3.0
if threading:
class echo_server(threading.Thread):
@@ -27,8 +33,8 @@ if threading:
self.event = event
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.port = support.bind_port(self.sock)
- # This will be set if the client wants us to wait before echoing data
- # back.
+ # This will be set if the client wants us to wait before echoing
+ # data back.
self.start_resend_event = None
def run(self):
@@ -51,8 +57,8 @@ if threading:
# 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
+ # 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)
@@ -95,7 +101,7 @@ if threading:
s.start()
event.wait()
event.clear()
- time.sleep(0.01) # Give server time to start accepting.
+ time.sleep(0.01) # Give server time to start accepting.
return s, event
@@ -103,10 +109,10 @@ if threading:
class TestAsynchat(unittest.TestCase):
usepoll = False
- def setUp (self):
+ def setUp(self):
self._threads = support.threading_setup()
- def tearDown (self):
+ def tearDown(self):
support.threading_cleanup(*self._threads)
def line_terminator_check(self, term, server_chunk):
@@ -116,14 +122,16 @@ class TestAsynchat(unittest.TestCase):
s.start()
event.wait()
event.clear()
- time.sleep(0.01) # Give server time to start accepting.
+ 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()
+ s.join(timeout=TIMEOUT)
+ if s.is_alive():
+ self.fail("join() timed out")
self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"])
@@ -133,17 +141,17 @@ class TestAsynchat(unittest.TestCase):
def test_line_terminator1(self):
# test one-character terminator
- for l in (1,2,3):
+ 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):
+ 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):
+ for l in (1, 2, 3):
self.line_terminator_check(b'qqq', l)
def numeric_terminator_check(self, termlen):
@@ -154,7 +162,9 @@ class TestAsynchat(unittest.TestCase):
c.push(data)
c.push(SERVER_QUIT)
asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
- s.join()
+ s.join(timeout=TIMEOUT)
+ if s.is_alive():
+ self.fail("join() timed out")
self.assertEqual(c.contents, [data[:termlen]])
@@ -174,7 +184,9 @@ class TestAsynchat(unittest.TestCase):
c.push(data)
c.push(SERVER_QUIT)
asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
- s.join()
+ s.join(timeout=TIMEOUT)
+ if s.is_alive():
+ self.fail("join() timed out")
self.assertEqual(c.contents, [])
self.assertEqual(c.buffer, data)
@@ -186,7 +198,9 @@ class TestAsynchat(unittest.TestCase):
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()
+ s.join(timeout=TIMEOUT)
+ if s.is_alive():
+ self.fail("join() timed out")
self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"])
@@ -196,7 +210,9 @@ class TestAsynchat(unittest.TestCase):
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()
+ s.join(timeout=TIMEOUT)
+ if s.is_alive():
+ self.fail("join() timed out")
self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"])
@@ -207,7 +223,9 @@ class TestAsynchat(unittest.TestCase):
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()
+ s.join(timeout=TIMEOUT)
+ if s.is_alive():
+ self.fail("join() timed out")
self.assertEqual(c.contents,
[b"hello world", b"", b"I'm not dead yet!"])
@@ -226,7 +244,9 @@ class TestAsynchat(unittest.TestCase):
# where the server echoes all of its data before we can check that it
# got any down below.
s.start_resend_event.set()
- s.join()
+ s.join(timeout=TIMEOUT)
+ if s.is_alive():
+ self.fail("join() timed out")
self.assertEqual(c.contents, [])
# the server might have been able to send a byte or two back, but this
@@ -234,15 +254,48 @@ class TestAsynchat(unittest.TestCase):
# (which could still result in the client not having received anything)
self.assertGreater(len(s.buffer), 0)
+ def test_push(self):
+ # Issue #12523: push() should raise a TypeError if it doesn't get
+ # a bytes string
+ s, event = start_echo_server()
+ c = echo_client(b'\n', s.port)
+ data = b'bytes\n'
+ c.push(data)
+ c.push(bytearray(data))
+ c.push(memoryview(data))
+ self.assertRaises(TypeError, c.push, 10)
+ self.assertRaises(TypeError, c.push, 'unicode')
+ c.push(SERVER_QUIT)
+ asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
+ s.join(timeout=TIMEOUT)
+ self.assertEqual(c.contents, [b'bytes', b'bytes', b'bytes'])
+
class TestAsynchat_WithPoll(TestAsynchat):
usepoll = True
+
+class TestAsynchatMocked(unittest.TestCase):
+ def test_blockingioerror(self):
+ # Issue #16133: handle_read() must ignore BlockingIOError
+ sock = unittest.mock.Mock()
+ sock.recv.side_effect = BlockingIOError(errno.EAGAIN)
+
+ dispatcher = asynchat.async_chat()
+ dispatcher.set_socket(sock)
+ self.addCleanup(dispatcher.del_channel)
+
+ with unittest.mock.patch.object(dispatcher, 'handle_error') as error:
+ dispatcher.handle_read()
+ self.assertFalse(error.called)
+
+
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()
@@ -268,9 +321,13 @@ class TestFifo(unittest.TestCase):
self.assertEqual(f.pop(), (0, None))
-def test_main(verbose=None):
- support.run_unittest(TestAsynchat, TestAsynchat_WithPoll,
- TestHelperFunctions, TestFifo)
+class TestNotConnected(unittest.TestCase):
+ def test_disallow_negative_terminator(self):
+ # Issue #11259
+ client = asynchat.async_chat()
+ self.assertRaises(ValueError, client.set_terminator, -1)
+
+
if __name__ == "__main__":
- test_main(verbose=True)
+ unittest.main()