4
4
import unittest
5
5
import unittest .mock
6
6
from ast import literal_eval
7
+ from threading import Thread
7
8
from test import support
8
9
from test .support import import_helper
9
10
from test .support import os_helper
@@ -277,11 +278,19 @@ def test_wrap_socket(sock, *,
277
278
return context .wrap_socket (sock , ** kwargs )
278
279
279
280
281
+ USE_SAME_TEST_CONTEXT = False
282
+ _TEST_CONTEXT = None
283
+
280
284
def testing_context (server_cert = SIGNED_CERTFILE , * , server_chain = True ):
281
285
"""Create context
282
286
283
287
client_context, server_context, hostname = testing_context()
284
288
"""
289
+ global _TEST_CONTEXT
290
+ if USE_SAME_TEST_CONTEXT :
291
+ if _TEST_CONTEXT is not None :
292
+ return _TEST_CONTEXT
293
+
285
294
if server_cert == SIGNED_CERTFILE :
286
295
hostname = SIGNED_CERTFILE_HOSTNAME
287
296
elif server_cert == SIGNED_CERTFILE2 :
@@ -299,6 +308,10 @@ def testing_context(server_cert=SIGNED_CERTFILE, *, server_chain=True):
299
308
if server_chain :
300
309
server_context .load_verify_locations (SIGNING_CA )
301
310
311
+ if USE_SAME_TEST_CONTEXT :
312
+ if _TEST_CONTEXT is not None :
313
+ _TEST_CONTEXT = client_context , server_context , hostname
314
+
302
315
return client_context , server_context , hostname
303
316
304
317
@@ -2801,6 +2814,44 @@ def test_echo(self):
2801
2814
'Cannot create a client socket with a PROTOCOL_TLS_SERVER context' ,
2802
2815
str (e .exception ))
2803
2816
2817
+ @unittest .skipUnless (support .Py_GIL_DISABLED , "test is only useful if the GIL is disabled" )
2818
+ def test_ssl_in_multiple_threads (self ):
2819
+ # See GH-124984: OpenSSL is not thread safe.
2820
+ threads = []
2821
+
2822
+ global USE_SAME_TEST_CONTEXT
2823
+ USE_SAME_TEST_CONTEXT = True
2824
+ try :
2825
+ for func in (
2826
+ self .test_echo ,
2827
+ self .test_alpn_protocols ,
2828
+ self .test_getpeercert ,
2829
+ self .test_crl_check ,
2830
+ self .test_check_hostname_idn ,
2831
+ self .test_wrong_cert_tls12 ,
2832
+ self .test_wrong_cert_tls13 ,
2833
+ ):
2834
+ # Be careful with the number of threads here.
2835
+ # Too many can result in failing tests.
2836
+ for num in range (5 ):
2837
+ with self .subTest (func = func , num = num ):
2838
+ threads .append (Thread (target = func ))
2839
+
2840
+ with threading_helper .catch_threading_exception () as cm :
2841
+ for thread in threads :
2842
+ with self .subTest (thread = thread ):
2843
+ thread .start ()
2844
+
2845
+ for thread in threads :
2846
+ with self .subTest (thread = thread ):
2847
+ thread .join ()
2848
+ if cm .exc_value is not None :
2849
+ # Some threads can skip their test
2850
+ if not isinstance (cm .exc_value , unittest .SkipTest ):
2851
+ raise cm .exc_value
2852
+ finally :
2853
+ USE_SAME_TEST_CONTEXT = False
2854
+
2804
2855
def test_getpeercert (self ):
2805
2856
if support .verbose :
2806
2857
sys .stdout .write ("\n " )
0 commit comments