From ed70e48f1a0a72ffacf8db2aab2701778e8fbbf5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 22 Oct 2026 01:12:28 -0700 Subject: [PATCH] gh-160206: Close connection explicitly in test_ssl test_https_client_non_tls_response_ignored() now uses a context manager for the server and always closes the connection to avoid ResourceWarning. Also add a timeout to SingleConnectionTestServerThread.__exit__() to not hang forever if something goes wrong. --- Lib/test/test_ssl.py | 48 +++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index d4213482cd1215..27d5e56368bfbc 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -5927,7 +5927,11 @@ def __exit__(self, *args): self.listener.close() except OSError: pass - self.join() + timeout = support.SHORT_TIMEOUT + self.join(timeout=timeout) + if self.is_alive(): + raise AssertionError("failed to join the server thread " + f"in {timeout} seconds") self.wrap_error = None # avoid dangling references def start(self): @@ -6133,28 +6137,30 @@ def call_after_accept(conn_to_client): call_after_accept=call_after_accept, name="non_tls_http_RST_responder", timeout=timeout) - self.enterContext(server) # starts it & unittest.TestCase stops it. - # Redundant; call_after_accept sets SO_LINGER on the accepted conn. - set_socket_so_linger_on_with_zero_timeout(server.listener) - - connection = SynchronizedHTTPSConnection( - server.listener.getsockname()[0], - port=server.port, - context=ssl.create_default_context(), - timeout=timeout, - ) - # There are lots of reasons this raises as desired, long before this - # test was added. Sending the request requires a successful TLS wrapped - # socket; that fails if the connection is broken. It may seem pointless - # to test this. It serves as an illustration of something that we never - # want to happen... properly not happening. - with warnings_helper.check_no_resource_warning(self), \ - self.assertRaises(OSError): - connection.request("HEAD", "/test", headers={"Host": "localhost"}) - response = connection.getresponse() + with server: + # Redundant; call_after_accept sets SO_LINGER on the accepted conn. + set_socket_so_linger_on_with_zero_timeout(server.listener) + + connection = SynchronizedHTTPSConnection( + server.listener.getsockname()[0], + port=server.port, + context=ssl.create_default_context(), + timeout=timeout, + ) - server.join() + # There are lots of reasons this raises as desired, long before this + # test was added. Sending the request requires a successful TLS wrapped + # socket; that fails if the connection is broken. It may seem pointless + # to test this. It serves as an illustration of something that we never + # want to happen... properly not happening. + with warnings_helper.check_no_resource_warning(self), \ + self.assertRaises(OSError): + try: + connection.request("HEAD", "/test", headers={"Host": "localhost"}) + response = connection.getresponse() + finally: + connection.close() class TestEnumerations(unittest.TestCase):