Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 25 additions & 27 deletions Lib/test/test_ftplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,13 +272,15 @@ def start(self):
self.__flag.wait()

def run(self):
self.active = True
self.__flag.set()
while self.active and asyncore.socket_map:
self.active_lock.acquire()
asyncore.loop(timeout=0.1, count=1)
self.active_lock.release()
asyncore.close_all(ignore_all=True)
try:
self.active = True
self.__flag.set()
while self.active and asyncore.socket_map:
self.active_lock.acquire()
asyncore.loop(timeout=0.1, count=1)
self.active_lock.release()
finally:
self.close()

def stop(self):
assert self.active
Expand Down Expand Up @@ -464,20 +466,27 @@ class DummyTLS_FTPServer(DummyFTPServer):
handler = DummyTLS_FTPHandler


def setup_server(self, server):
self.server = server
self.server.start()

@self.addCleanup
def close_server():
self.server.stop()
# Explicitly clear the attribute to prevent dangling thread
self.server = None
asyncore.close_all(ignore_all=True)


class TestFTPClass(TestCase):

def setUp(self):
self.server = DummyFTPServer((HOST, 0))
self.server.start()
setup_server(self, DummyFTPServer((HOST, 0)))
self.client = ftplib.FTP(timeout=TIMEOUT)
self.client.connect(self.server.host, self.server.port)

def tearDown(self):
self.client.close()
self.server.stop()
# Explicitly clear the attribute to prevent dangling thread
self.server = None
asyncore.close_all(ignore_all=True)

def check_data(self, received, expected):
self.assertEqual(len(received), len(expected))
Expand Down Expand Up @@ -799,17 +808,12 @@ def test_storlines_too_long(self):
class TestIPv6Environment(TestCase):

def setUp(self):
self.server = DummyFTPServer((HOSTv6, 0), af=socket.AF_INET6)
self.server.start()
setup_server(self, DummyFTPServer((HOSTv6, 0), af=socket.AF_INET6))
self.client = ftplib.FTP(timeout=TIMEOUT)
self.client.connect(self.server.host, self.server.port)

def tearDown(self):
self.client.close()
self.server.stop()
# Explicitly clear the attribute to prevent dangling thread
self.server = None
asyncore.close_all(ignore_all=True)

def test_af(self):
self.assertEqual(self.client.af, socket.AF_INET6)
Expand Down Expand Up @@ -846,8 +850,7 @@ class TestTLS_FTPClassMixin(TestFTPClass):
"""

def setUp(self):
self.server = DummyTLS_FTPServer((HOST, 0))
self.server.start()
setup_server(self, DummyTLS_FTPServer((HOST, 0)))
self.client = ftplib.FTP_TLS(timeout=TIMEOUT)
self.client.connect(self.server.host, self.server.port)
# enable TLS
Expand All @@ -860,17 +863,12 @@ class TestTLS_FTPClass(TestCase):
"""Specific TLS_FTP class tests."""

def setUp(self):
self.server = DummyTLS_FTPServer((HOST, 0))
self.server.start()
setup_server(self, DummyTLS_FTPServer((HOST, 0)))
self.client = ftplib.FTP_TLS(timeout=TIMEOUT)
self.client.connect(self.server.host, self.server.port)

def tearDown(self):
self.client.close()
self.server.stop()
# Explicitly clear the attribute to prevent dangling thread
self.server = None
asyncore.close_all(ignore_all=True)

def test_control_connection(self):
self.assertNotIsInstance(self.client.sock, ssl.SSLSocket)
Expand Down
34 changes: 22 additions & 12 deletions Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -2586,13 +2586,15 @@ def wait(self):
# --- internals

def run(self):
self._active = True
self.__flag.set()
while self._active and asyncore.socket_map:
self._active_lock.acquire()
asyncore.loop(timeout=0.001, count=1)
self._active_lock.release()
asyncore.close_all()
try:
self._active = True
self.__flag.set()
while self._active and asyncore.socket_map:
self._active_lock.acquire()
asyncore.loop(timeout=0.001, count=1)
self._active_lock.release()
finally:
self.close()

def handle_accept(self):
conn, addr = self.accept()
Expand Down Expand Up @@ -2629,9 +2631,20 @@ def tearDownClass(cls):
support.threading_cleanup(*cls.key)
support.unlink(support.TESTFN)

def setUp(self):
self.server = SendfileTestServer((support.HOST, 0))
def setup_server(self, server):
self.server = server
self.server.start()

@self.addCleanup
def close_server():
if self.server.running:
self.server.stop()
# Explicitly clear the attribute to prevent dangling thread
self.server = None
asyncore.close_all(ignore_all=True)

def setUp(self):
self.setup_server(SendfileTestServer((support.HOST, 0)))
self.client = socket.socket()
self.client.connect((self.server.host, self.server.port))
self.client.settimeout(1)
Expand All @@ -2644,9 +2657,6 @@ def setUp(self):
def tearDown(self):
self.file.close()
self.client.close()
if self.server.running:
self.server.stop()
self.server = None

def sendfile_wrapper(self, sock, file, offset, nbytes, headers=[], trailers=[]):
"""A higher level wrapper representing how an application is
Expand Down
44 changes: 25 additions & 19 deletions Lib/test/test_poplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import os
import errno
import threading
import traceback

from unittest import TestCase, skipUnless
from test import support as test_support
Expand Down Expand Up @@ -220,18 +221,21 @@ def start(self):
self.__flag.wait()

def run(self):
self.active = True
self.__flag.set()
while self.active and asyncore.socket_map:
self.active_lock.acquire()
asyncore.loop(timeout=0.1, count=1)
self.active_lock.release()
asyncore.close_all(ignore_all=True)
try:
self.active = True
self.__flag.set()
while self.active and asyncore.socket_map:
self.active_lock.acquire()
asyncore.loop(timeout=0.1, count=1)
self.active_lock.release()
finally:
self.close()

def stop(self):
assert self.active
self.active = False
self.join()
asyncore.close_all(ignore_all=True)

def handle_accepted(self, conn, addr):
self.handler_instance = self.handler(conn)
Expand All @@ -251,16 +255,24 @@ class TestPOP3Class(TestCase):
def assertOK(self, resp):
self.assertTrue(resp.startswith(b"+OK"))

def setUp(self):
def setup_server(self, handler_class=None):
self.server = DummyPOP3Server((HOST, PORT))
if handler_class is not None:
self.server.handler = handler_class
self.server.start()

@self.addCleanup
def close_server():
self.server.stop()
# Explicitly clear the attribute to prevent dangling thread
self.server = None

def setUp(self):
self.setup_server()
self.client = poplib.POP3(self.server.host, self.server.port, timeout=3)

def tearDown(self):
self.client.close()
self.server.stop()
# Explicitly clear the attribute to prevent dangling thread
self.server = None

def test_getwelcome(self):
self.assertEqual(self.client.getwelcome(),
Expand Down Expand Up @@ -400,9 +412,7 @@ class TestPOP3_SSLClass(TestPOP3Class):
# repeat previous tests by using poplib.POP3_SSL

def setUp(self):
self.server = DummyPOP3Server((HOST, PORT))
self.server.handler = DummyPOP3_SSLHandler
self.server.start()
self.setup_server(DummyPOP3_SSLHandler)
self.client = poplib.POP3_SSL(self.server.host, self.server.port)

def test__all__(self):
Expand Down Expand Up @@ -444,8 +454,7 @@ class TestPOP3_TLSClass(TestPOP3Class):
# repeat previous tests by using poplib.POP3.stls()

def setUp(self):
self.server = DummyPOP3Server((HOST, PORT))
self.server.start()
self.setup_server()
self.client = poplib.POP3(self.server.host, self.server.port, timeout=3)
self.client.stls()

Expand All @@ -458,9 +467,6 @@ def tearDown(self):
# response will be treated as response to QUIT and raise
# this exception
self.client.close()
self.server.stop()
# Explicitly clear the attribute to prevent dangling thread
self.server = None

def test_stls(self):
self.assertRaises(poplib.error_proto, self.client.stls)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix test_poplib hangs when an error occured in ``setUp()`` method or
``DummyPOP3Server.run()``.