From 5973379bff93096f54d84e79209bc131ed59f38b Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 4 Jun 2024 15:57:01 +0000 Subject: [PATCH 1/4] gh-120048: Make `test_imaplib` faster The `test_imaplib` was taking 40+ minutes in the refleak build bots because we were using LOOPBACK_TIMEOUT for tests cases that expect to timeout. LOOPBACK_TIMEOUT scales with the global timeout. We should use a fixed, very small timeout for cases that we expect to timeout. --- Lib/test/test_imaplib.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 79bf7dbdbb81a07..0a295ab5d54824f 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -27,6 +27,8 @@ CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "certdata", "keycert3.pem") CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "certdata", "pycacert.pem") +# Timeout used for test cases that we expect to timeout. +FAST_TIMEOUT = 0.5 class TestImaplib(unittest.TestCase): @@ -207,6 +209,13 @@ def cmd_UNSELECT(self, tag, args): else: self._send_tagged(tag, 'BAD', 'No mailbox selected') +@contextmanager +def expect_timeout(): + # gh-120048: We want a short timeout that does not scale with the global + # timeout for tests cases that we expect to timeout. + with support.swap_attr(SimpleIMAPHandler, 'timeout', FAST_TIMEOUT): + yield + class NewIMAPTestsMixin(): client = None @@ -458,15 +467,15 @@ def test_simple_with_statement(self): with self.imap_class(*server.server_address): pass - @requires_resource('walltime') + @expect_timeout() def test_imaplib_timeout_test(self): _, server = self._setup(SimpleIMAPHandler) addr = server.server_address[1] client = self.imap_class("localhost", addr, timeout=None) self.assertEqual(client.sock.timeout, None) client.shutdown() - client = self.imap_class("localhost", addr, timeout=support.LOOPBACK_TIMEOUT) - self.assertEqual(client.sock.timeout, support.LOOPBACK_TIMEOUT) + client = self.imap_class("localhost", addr, timeout=FAST_TIMEOUT) + self.assertEqual(client.sock.timeout, FAST_TIMEOUT) client.shutdown() with self.assertRaises(ValueError): client = self.imap_class("localhost", addr, timeout=0) @@ -552,7 +561,7 @@ class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase): imap_class = IMAP4_SSL server_class = SecureTCPServer - @requires_resource('walltime') + @expect_timeout() def test_ssl_raises(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) self.assertEqual(ssl_context.verify_mode, ssl.CERT_REQUIRED) @@ -571,7 +580,7 @@ def test_ssl_raises(self): ssl_context=ssl_context) client.shutdown() - @requires_resource('walltime') + @expect_timeout() def test_ssl_verified(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ssl_context.load_verify_locations(CAFILE) From d980c561608427ae88b89039af42240ee5d0690a Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 4 Jun 2024 18:05:26 +0000 Subject: [PATCH 2/4] Use `connect=False` for tests that create subsequent connections --- Lib/test/test_imaplib.py | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 0a295ab5d54824f..4ef08c6b54e2a5f 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -27,8 +27,6 @@ CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "certdata", "keycert3.pem") CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "certdata", "pycacert.pem") -# Timeout used for test cases that we expect to timeout. -FAST_TIMEOUT = 0.5 class TestImaplib(unittest.TestCase): @@ -209,13 +207,6 @@ def cmd_UNSELECT(self, tag, args): else: self._send_tagged(tag, 'BAD', 'No mailbox selected') -@contextmanager -def expect_timeout(): - # gh-120048: We want a short timeout that does not scale with the global - # timeout for tests cases that we expect to timeout. - with support.swap_attr(SimpleIMAPHandler, 'timeout', FAST_TIMEOUT): - yield - class NewIMAPTestsMixin(): client = None @@ -467,18 +458,15 @@ def test_simple_with_statement(self): with self.imap_class(*server.server_address): pass - @expect_timeout() def test_imaplib_timeout_test(self): - _, server = self._setup(SimpleIMAPHandler) - addr = server.server_address[1] - client = self.imap_class("localhost", addr, timeout=None) - self.assertEqual(client.sock.timeout, None) - client.shutdown() - client = self.imap_class("localhost", addr, timeout=FAST_TIMEOUT) - self.assertEqual(client.sock.timeout, FAST_TIMEOUT) - client.shutdown() + _, server = self._setup(SimpleIMAPHandler, connect=False) + with self.imap_class(*server.server_address, timeout=None) as client: + self.assertEqual(client.sock.timeout, None) + with self.imap_class(*server.server_address,timeout=support.LOOPBACK_TIMEOUT) as client: + self.assertEqual(client.sock.timeout, support.LOOPBACK_TIMEOUT) with self.assertRaises(ValueError): - client = self.imap_class("localhost", addr, timeout=0) + with self.imap_class(*server.server_address, timeout=0): + pass def test_imaplib_timeout_functionality_test(self): class TimeoutHandler(SimpleIMAPHandler): @@ -561,7 +549,6 @@ class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase): imap_class = IMAP4_SSL server_class = SecureTCPServer - @expect_timeout() def test_ssl_raises(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) self.assertEqual(ssl_context.verify_mode, ssl.CERT_REQUIRED) @@ -575,17 +562,16 @@ def test_ssl_raises(self): CERTIFICATE_VERIFY_FAILED # AWS-LC )""", re.X) with self.assertRaisesRegex(ssl.CertificateError, regex): - _, server = self._setup(SimpleIMAPHandler) + _, server = self._setup(SimpleIMAPHandler, connect=False) client = self.imap_class(*server.server_address, ssl_context=ssl_context) client.shutdown() - @expect_timeout() def test_ssl_verified(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ssl_context.load_verify_locations(CAFILE) - _, server = self._setup(SimpleIMAPHandler) + _, server = self._setup(SimpleIMAPHandler, connect=False) client = self.imap_class("localhost", server.server_address[1], ssl_context=ssl_context) client.shutdown() From dbb8ea4e514792a6a52846005f3b7c8980d87ca3 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 4 Jun 2024 18:08:18 +0000 Subject: [PATCH 3/4] Format --- Lib/test/test_imaplib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 4ef08c6b54e2a5f..2102233718465bb 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -462,7 +462,7 @@ def test_imaplib_timeout_test(self): _, server = self._setup(SimpleIMAPHandler, connect=False) with self.imap_class(*server.server_address, timeout=None) as client: self.assertEqual(client.sock.timeout, None) - with self.imap_class(*server.server_address,timeout=support.LOOPBACK_TIMEOUT) as client: + with self.imap_class(*server.server_address, timeout=support.LOOPBACK_TIMEOUT) as client: self.assertEqual(client.sock.timeout, support.LOOPBACK_TIMEOUT) with self.assertRaises(ValueError): with self.imap_class(*server.server_address, timeout=0): From fcce846e6c0d8274275f74ac17327137891f016f Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 4 Jun 2024 14:22:40 -0400 Subject: [PATCH 4/4] Update Lib/test/test_imaplib.py Co-authored-by: Serhiy Storchaka --- Lib/test/test_imaplib.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 2102233718465bb..b5384b594637424 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -465,8 +465,7 @@ def test_imaplib_timeout_test(self): with self.imap_class(*server.server_address, timeout=support.LOOPBACK_TIMEOUT) as client: self.assertEqual(client.sock.timeout, support.LOOPBACK_TIMEOUT) with self.assertRaises(ValueError): - with self.imap_class(*server.server_address, timeout=0): - pass + self.imap_class(*server.server_address, timeout=0) def test_imaplib_timeout_functionality_test(self): class TimeoutHandler(SimpleIMAPHandler):