From 52f35d80953a0b0321dfa63216d5471f55ad1a32 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 7 Jan 2026 10:35:58 +0200 Subject: [PATCH 1/2] gh-143443: Try to fix test_ssl_in_multiple_threads Monkey-patch not thread-safe subTest. Ensure that waiting for all threads does not hang indefinitely. --- Lib/test/test_ssl.py | 67 ++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index ebdf5455163c65..e0a67470e4ca1c 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -13,6 +13,7 @@ from test.support import warnings_helper from test.support import asyncore import array +import contextlib import re import socket import select @@ -2998,44 +2999,38 @@ def test_echo(self): @unittest.skipUnless(support.Py_GIL_DISABLED, "test is only useful if the GIL is disabled") def test_ssl_in_multiple_threads(self): # See GH-124984: OpenSSL is not thread safe. + self.enterContext( + support.swap_item(globals(), 'USE_SAME_TEST_CONTEXT', True)) + self.enterContext( + support.swap_attr(self, 'subTest', + lambda *args, **kwargs: contextlib.nullcontext())) + warnings_filters = sys.flags.context_aware_warnings + funcs = ( + self.test_echo, + self.test_alpn_protocols, + self.test_getpeercert, + self.test_crl_check, + functools.partial( + self.test_check_hostname_idn, + warnings_filters=warnings_filters, + ), + self.test_wrong_cert_tls12, + self.test_wrong_cert_tls13, + ) + # Be careful with the number of threads here. + # Too many can result in failing tests. threads = [] + for num in range(5): + for func in funcs: + threads.append(Thread(target=func)) - warnings_filters = sys.flags.context_aware_warnings - global USE_SAME_TEST_CONTEXT - USE_SAME_TEST_CONTEXT = True - try: - for func in ( - self.test_echo, - self.test_alpn_protocols, - self.test_getpeercert, - self.test_crl_check, - functools.partial( - self.test_check_hostname_idn, - warnings_filters=warnings_filters, - ), - self.test_wrong_cert_tls12, - self.test_wrong_cert_tls13, - ): - # Be careful with the number of threads here. - # Too many can result in failing tests. - for num in range(5): - with self.subTest(func=func, num=num): - threads.append(Thread(target=func)) - - with threading_helper.catch_threading_exception() as cm: - for thread in threads: - with self.subTest(thread=thread): - thread.start() - - for thread in threads: - with self.subTest(thread=thread): - thread.join() - if cm.exc_value is not None: - # Some threads can skip their test - if not isinstance(cm.exc_value, unittest.SkipTest): - raise cm.exc_value - finally: - USE_SAME_TEST_CONTEXT = False + with threading_helper.catch_threading_exception() as cm: + with threading_helper.start_threads(threads): + pass + if cm.exc_value is not None: + # Some threads can skip their test + if not isinstance(cm.exc_value, unittest.SkipTest): + raise cm.exc_value def test_getpeercert(self): if support.verbose: From d3e5689576633c2f6aad1bf5464a1e0a3fd1009c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 7 Jan 2026 11:22:43 +0200 Subject: [PATCH 2/2] Use the bigmemtest decorator. --- Lib/test/test_ssl.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index e0a67470e4ca1c..4fbb20ad8070b6 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2997,7 +2997,8 @@ def test_echo(self): str(e.exception)) @unittest.skipUnless(support.Py_GIL_DISABLED, "test is only useful if the GIL is disabled") - def test_ssl_in_multiple_threads(self): + @support.bigmemtest(size=12 * 2**30, memuse=1, dry_run=False) + def test_ssl_in_multiple_threads(self, size): # See GH-124984: OpenSSL is not thread safe. self.enterContext( support.swap_item(globals(), 'USE_SAME_TEST_CONTEXT', True))