Skip to content

Commit c9fc496

Browse files
committed
test: add support for checking for TSAN
- Skip some unsupported tests in test_threading - Skip some unsupported tests in test_concurrent_futures
1 parent cff3269 commit c9fc496

File tree

3 files changed

+15
-3
lines changed

3 files changed

+15
-3
lines changed

Lib/test/support/__init__.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,9 @@ def skip_if_buildbot(reason=None):
396396
isbuildbot = False
397397
return unittest.skipIf(isbuildbot, reason)
398398

399-
def check_sanitizer(*, address=False, memory=False, ub=False):
399+
def check_sanitizer(*, address=False, memory=False, ub=False, thread=False):
400400
"""Returns True if Python is compiled with sanitizer support"""
401-
if not (address or memory or ub):
401+
if not (address or memory or ub or thread):
402402
raise ValueError('At least one of address, memory, or ub must be True')
403403

404404

@@ -416,10 +416,15 @@ def check_sanitizer(*, address=False, memory=False, ub=False):
416416
'-fsanitize=undefined' in _cflags or
417417
'--with-undefined-behavior-sanitizer' in _config_args
418418
)
419+
thread_sanitizer = (
420+
'-fsanitize=thread' in _cflags or
421+
'--with-thread-sanitizer' in _config_args
422+
)
419423
return (
420424
(memory and memory_sanitizer) or
421425
(address and address_sanitizer) or
422-
(ub and ub_sanitizer)
426+
(ub and ub_sanitizer) or
427+
(thread and thread_sanitizer)
423428
)
424429

425430

Lib/test/test_concurrent_futures.py

+4
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ def get_context(self):
161161
self.skipTest("ProcessPoolExecutor unavailable on this system")
162162
if sys.platform == "win32":
163163
self.skipTest("require unix system")
164+
if support.check_sanitizer(thread=True):
165+
self.skipTest("TSAN doesn't support threads after fork")
164166
return super().get_context()
165167

166168

@@ -187,6 +189,8 @@ def get_context(self):
187189
self.skipTest("ProcessPoolExecutor unavailable on this system")
188190
if sys.platform == "win32":
189191
self.skipTest("require unix system")
192+
if support.check_sanitizer(thread=True):
193+
self.skipTest("TSAN doesn't support threads after fork")
190194
return super().get_context()
191195

192196

Lib/test/test_threading.py

+3
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ def exit_handler():
562562
self.assertEqual(err.rstrip(), b'child process ok')
563563

564564
@support.requires_fork()
565+
@unittest.skipIf(support.check_sanitizer(thread=True), "TSAN doesn't support threads after fork")
565566
def test_dummy_thread_after_fork(self):
566567
# Issue #14308: a dummy thread in the active list doesn't mess up
567568
# the after-fork mechanism.
@@ -653,6 +654,7 @@ def test_main_thread_after_fork(self):
653654
@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
654655
@support.requires_fork()
655656
@unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
657+
@unittest.skipIf(support.check_sanitizer(thread=True), "TSAN doesn't support threads after fork")
656658
def test_main_thread_after_fork_from_nonmain_thread(self):
657659
code = """if 1:
658660
import os, threading, sys, warnings
@@ -1071,6 +1073,7 @@ def test_2_join_in_forked_process(self):
10711073

10721074
@support.requires_fork()
10731075
@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
1076+
@unittest.skipIf(support.check_sanitizer(thread=True), "TSAN doesn't support threads after fork")
10741077
def test_3_join_in_forked_from_thread(self):
10751078
# Like the test above, but fork() was called from a worker thread
10761079
# In the forked process, the main Thread object must be marked as stopped.

0 commit comments

Comments
 (0)