bpo-34246: Make sure test_smtplib always cleans resources when finish… · python/cpython@5b7a2cb
@@ -20,6 +20,7 @@
2020import unittest
2121from test import support, mock_socket
2222from test.support import HOST, HOSTv4, HOSTv6
23+from test.support import threading_setup, threading_cleanup, join_thread
2324from unittest.mock import Mock
24252526@@ -193,6 +194,7 @@ class DebuggingServerTests(unittest.TestCase):
193194maxDiff = None
194195195196def setUp(self):
197+self.thread_key = threading_setup()
196198self.real_getfqdn = socket.getfqdn
197199socket.getfqdn = mock_socket.getfqdn
198200# temporarily replace sys.stdout to capture DebuggingServer output
@@ -224,12 +226,15 @@ def tearDown(self):
224226self.client_evt.set()
225227# wait for the server thread to terminate
226228self.serv_evt.wait()
227-self.thread.join()
229+join_thread(self.thread)
228230# restore sys.stdout
229231sys.stdout = self.old_stdout
230232# restore DEBUGSTREAM
231233smtpd.DEBUGSTREAM.close()
232234smtpd.DEBUGSTREAM = self.old_DEBUGSTREAM
235+del self.thread
236+self.doCleanups()
237+threading_cleanup(*self.thread_key)
233238234239def get_output_without_xpeer(self):
235240test_output = self.output.getvalue()
@@ -247,6 +252,7 @@ def testSourceAddress(self):
247252try:
248253smtp = smtplib.SMTP(self.host, self.port, local_hostname='localhost',
249254timeout=3, source_address=(self.host, src_port))
255+self.addCleanup(smtp.close)
250256self.assertEqual(smtp.source_address, (self.host, src_port))
251257self.assertEqual(smtp.local_hostname, 'localhost')
252258smtp.quit()
@@ -257,33 +263,38 @@ def testSourceAddress(self):
257263258264def testNOOP(self):
259265smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
266+self.addCleanup(smtp.close)
260267expected = (250, b'OK')
261268self.assertEqual(smtp.noop(), expected)
262269smtp.quit()
263270264271def testRSET(self):
265272smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
273+self.addCleanup(smtp.close)
266274expected = (250, b'OK')
267275self.assertEqual(smtp.rset(), expected)
268276smtp.quit()
269277270278def testELHO(self):
271279# EHLO isn't implemented in DebuggingServer
272280smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
281+self.addCleanup(smtp.close)
273282expected = (250, b'\nSIZE 33554432\nHELP')
274283self.assertEqual(smtp.ehlo(), expected)
275284smtp.quit()
276285277286def testEXPNNotImplemented(self):
278287# EXPN isn't implemented in DebuggingServer
279288smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
289+self.addCleanup(smtp.close)
280290expected = (502, b'EXPN not implemented')
281291smtp.putcmd('EXPN')
282292self.assertEqual(smtp.getreply(), expected)
283293smtp.quit()
284294285295def testVRFY(self):
286296smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
297+self.addCleanup(smtp.close)
287298expected = (252, b'Cannot VRFY user, but will accept message ' + \
288299b'and attempt delivery')
289300self.assertEqual(smtp.vrfy('nobody@nowhere.com'), expected)
@@ -294,13 +305,15 @@ def testSecondHELO(self):
294305# check that a second HELO returns a message that it's a duplicate
295306# (this behavior is specific to smtpd.SMTPChannel)
296307smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
308+self.addCleanup(smtp.close)
297309smtp.helo()
298310expected = (503, b'Duplicate HELO/EHLO')
299311self.assertEqual(smtp.helo(), expected)
300312smtp.quit()
301313302314def testHELP(self):
303315smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
316+self.addCleanup(smtp.close)
304317self.assertEqual(smtp.help(), b'Supported commands: EHLO HELO MAIL ' + \
305318b'RCPT DATA RSET NOOP QUIT VRFY')
306319smtp.quit()
@@ -309,6 +322,7 @@ def testSend(self):
309322# connect and send mail
310323m = 'A test message'
311324smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
325+self.addCleanup(smtp.close)
312326smtp.sendmail('John', 'Sally', m)
313327# XXX(nnorwitz): this test is flaky and dies with a bad file descriptor
314328# in asyncore. This sleep might help, but should really be fixed
@@ -325,6 +339,7 @@ def testSend(self):
325339def testSendBinary(self):
326340m = b'A test message'
327341smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
342+self.addCleanup(smtp.close)
328343smtp.sendmail('John', 'Sally', m)
329344# XXX (see comment in testSend)
330345time.sleep(0.01)
@@ -340,6 +355,7 @@ def testSendNeedingDotQuote(self):
340355# Issue 12283
341356m = '.A test\n.mes.sage.'
342357smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
358+self.addCleanup(smtp.close)
343359smtp.sendmail('John', 'Sally', m)
344360# XXX (see comment in testSend)
345361time.sleep(0.01)
@@ -354,6 +370,7 @@ def testSendNeedingDotQuote(self):
354370def testSendNullSender(self):
355371m = 'A test message'
356372smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
373+self.addCleanup(smtp.close)
357374smtp.sendmail('<>', 'Sally', m)
358375# XXX (see comment in testSend)
359376time.sleep(0.01)
@@ -371,6 +388,7 @@ def testSendNullSender(self):
371388def testSendMessage(self):
372389m = email.mime.text.MIMEText('A test message')
373390smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
391+self.addCleanup(smtp.close)
374392smtp.send_message(m, from_addr='John', to_addrs='Sally')
375393# XXX (see comment in testSend)
376394time.sleep(0.01)
@@ -395,6 +413,7 @@ def testSendMessageWithAddresses(self):
395413m['CC'] = 'Sally, Fred'
396414m['Bcc'] = 'John Root <root@localhost>, "Dinsdale" <warped@silly.walks.com>'
397415smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
416+self.addCleanup(smtp.close)
398417smtp.send_message(m)
399418# XXX (see comment in testSend)
400419time.sleep(0.01)
@@ -428,6 +447,7 @@ def testSendMessageWithSomeAddresses(self):
428447m['From'] = 'foo@bar.com'
429448m['To'] = 'John, Dinsdale'
430449smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
450+self.addCleanup(smtp.close)
431451smtp.send_message(m)
432452# XXX (see comment in testSend)
433453time.sleep(0.01)
@@ -455,6 +475,7 @@ def testSendMessageWithSpecifiedAddresses(self):
455475m['From'] = 'foo@bar.com'
456476m['To'] = 'John, Dinsdale'
457477smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
478+self.addCleanup(smtp.close)
458479smtp.send_message(m, from_addr='joe@example.com', to_addrs='foo@example.net')
459480# XXX (see comment in testSend)
460481time.sleep(0.01)
@@ -485,6 +506,7 @@ def testSendMessageWithMultipleFrom(self):
485506m['Sender'] = 'the_rescuers@Rescue-Aid-Society.com'
486507m['To'] = 'John, Dinsdale'
487508smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
509+self.addCleanup(smtp.close)
488510smtp.send_message(m)
489511# XXX (see comment in testSend)
490512time.sleep(0.01)
@@ -517,6 +539,7 @@ def testSendMessageResent(self):
517539m['Resent-To'] = 'Martha <my_mom@great.cooker.com>, Jeff'
518540m['Resent-Bcc'] = 'doe@losthope.net'
519541smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
542+self.addCleanup(smtp.close)
520543smtp.send_message(m)
521544# XXX (see comment in testSend)
522545time.sleep(0.01)
@@ -555,6 +578,7 @@ def testSendMessageMultipleResentRaises(self):
555578m['Resent-To'] = 'holy@grail.net'
556579m['Resent-From'] = 'Martha <my_mom@great.cooker.com>, Jeff'
557580smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
581+self.addCleanup(smtp.close)
558582with self.assertRaises(ValueError):
559583smtp.send_message(m)
560584smtp.close()
@@ -630,6 +654,7 @@ class TooLongLineTests(unittest.TestCase):
630654respdata = b'250 OK' + (b'.' * smtplib._MAXLINE * 2) + b'\n'
631655632656def setUp(self):
657+self.thread_key = threading_setup()
633658self.old_stdout = sys.stdout
634659self.output = io.StringIO()
635660sys.stdout = self.output
@@ -639,15 +664,18 @@ def setUp(self):
639664self.sock.settimeout(15)
640665self.port = support.bind_port(self.sock)
641666servargs = (self.evt, self.respdata, self.sock)
642-thread = threading.Thread(target=server, args=servargs)
643-thread.start()
644-self.addCleanup(thread.join)
667+self.thread = threading.Thread(target=server, args=servargs)
668+self.thread.start()
645669self.evt.wait()
646670self.evt.clear()
647671648672def tearDown(self):
649673self.evt.wait()
650674sys.stdout = self.old_stdout
675+join_thread(self.thread)
676+del self.thread
677+self.doCleanups()
678+threading_cleanup(*self.thread_key)
651679652680def testLineTooLong(self):
653681self.assertRaises(smtplib.SMTPResponseException, smtplib.SMTP,
@@ -877,6 +905,7 @@ def handle_error(self):
877905class SMTPSimTests(unittest.TestCase):
878906879907def setUp(self):
908+self.thread_key = threading_setup()
880909self.real_getfqdn = socket.getfqdn
881910socket.getfqdn = mock_socket.getfqdn
882911self.serv_evt = threading.Event()
@@ -899,7 +928,10 @@ def tearDown(self):
899928self.client_evt.set()
900929# wait for the server thread to terminate
901930self.serv_evt.wait()
902-self.thread.join()
931+join_thread(self.thread)
932+del self.thread
933+self.doCleanups()
934+threading_cleanup(*self.thread_key)
903935904936def testBasic(self):
905937# smoke test
@@ -1162,6 +1194,7 @@ class SMTPUTF8SimTests(unittest.TestCase):
11621194maxDiff = None
1163119511641196def setUp(self):
1197+self.thread_key = threading_setup()
11651198self.real_getfqdn = socket.getfqdn
11661199socket.getfqdn = mock_socket.getfqdn
11671200self.serv_evt = threading.Event()
@@ -1186,7 +1219,10 @@ def tearDown(self):
11861219self.client_evt.set()
11871220# wait for the server thread to terminate
11881221self.serv_evt.wait()
1189-self.thread.join()
1222+join_thread(self.thread)
1223+del self.thread
1224+self.doCleanups()
1225+threading_cleanup(*self.thread_key)
1190122611911227def test_test_server_supports_extensions(self):
11921228smtp = smtplib.SMTP(
@@ -1283,6 +1319,7 @@ class SimSMTPAUTHInitialResponseServer(SimSMTPServer):
1283131912841320class SMTPAUTHInitialResponseSimTests(unittest.TestCase):
12851321def setUp(self):
1322+self.thread_key = threading_setup()
12861323self.real_getfqdn = socket.getfqdn
12871324socket.getfqdn = mock_socket.getfqdn
12881325self.serv_evt = threading.Event()
@@ -1306,7 +1343,10 @@ def tearDown(self):
13061343self.client_evt.set()
13071344# wait for the server thread to terminate
13081345self.serv_evt.wait()
1309-self.thread.join()
1346+join_thread(self.thread)
1347+del self.thread
1348+self.doCleanups()
1349+threading_cleanup(*self.thread_key)
1310135013111351def testAUTH_PLAIN_initial_response_login(self):
13121352self.serv.add_feature('AUTH PLAIN')