Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor sanitizer skip tests into test.support #30889

Merged
merged 3 commits into from
Jan 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"requires_IEEE_754", "requires_zlib",
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
"check__all__", "skip_if_buggy_ucrt_strfptime",
"check_disallow_instantiation",
"check_disallow_instantiation", "skip_if_sanitizer",
# sys
"is_jython", "is_android", "check_impl_detail", "unix_shell",
"setswitchinterval",
Expand Down Expand Up @@ -382,6 +382,35 @@ def skip_if_buildbot(reason=None):
isbuildbot = os.environ.get('USER') == 'buildbot'
return unittest.skipIf(isbuildbot, reason)

def skip_if_sanitizer(reason=None, *, address=False, memory=False, ub=False):
"""Decorator raising SkipTest if running with a sanitizer active."""
if not (address or memory or ub):
raise ValueError('At least one of address, memory, or ub must be True')

if not reason:
reason = 'not working with sanitizers active'

_cflags = sysconfig.get_config_var('CFLAGS') or ''
_config_args = sysconfig.get_config_var('CONFIG_ARGS') or ''
memory_sanitizer = (
'-fsanitize=memory' in _cflags or
'--with-memory-sanitizer' in _config_args
)
address_sanitizer = (
'-fsanitize=address' in _cflags or
'--with-memory-sanitizer' in _config_args
)
ub_sanitizer = (
'-fsanitize=undefined' in _cflags or
'--with-undefined-behavior-sanitizer' in _config_args
)
skip = (
(memory and memory_sanitizer) or
(address and address_sanitizer) or
(ub and ub_sanitizer)
)
return unittest.skipIf(skip, reason)


def system_must_validate_cert(f):
"""Skip the test on TLS certificate validation failures."""
Expand Down
20 changes: 5 additions & 15 deletions Lib/test/test_faulthandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import signal
import subprocess
import sys
import sysconfig
from test import support
from test.support import os_helper
from test.support import script_helper, is_android
from test.support import skip_if_sanitizer
import tempfile
import unittest
from textwrap import dedent
Expand All @@ -21,16 +21,6 @@

TIMEOUT = 0.5
MS_WINDOWS = (os.name == 'nt')
_cflags = sysconfig.get_config_var('CFLAGS') or ''
_config_args = sysconfig.get_config_var('CONFIG_ARGS') or ''
UB_SANITIZER = (
'-fsanitize=undefined' in _cflags or
'--with-undefined-behavior-sanitizer' in _config_args
)
MEMORY_SANITIZER = (
'-fsanitize=memory' in _cflags or
'--with-memory-sanitizer' in _config_args
)


def expected_traceback(lineno1, lineno2, header, min_count=1):
Expand Down Expand Up @@ -311,8 +301,8 @@ def test_gil_released(self):
3,
'Segmentation fault')

@unittest.skipIf(UB_SANITIZER or MEMORY_SANITIZER,
"sanitizer builds change crashing process output.")
@skip_if_sanitizer(memory=True, ub=True, reason="sanitizer "
"builds change crashing process output.")
@skip_segfault_on_android
def test_enable_file(self):
with temporary_filename() as filename:
Expand All @@ -328,8 +318,8 @@ def test_enable_file(self):

@unittest.skipIf(sys.platform == "win32",
"subprocess doesn't support pass_fds on Windows")
@unittest.skipIf(UB_SANITIZER or MEMORY_SANITIZER,
"sanitizer builds change crashing process output.")
@skip_if_sanitizer(memory=True, ub=True, reason="sanitizer "
"builds change crashing process output.")
@skip_segfault_on_android
def test_enable_fd(self):
with tempfile.TemporaryFile('wb+') as fp:
Expand Down
25 changes: 7 additions & 18 deletions Lib/test/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import random
import signal
import sys
import sysconfig
import textwrap
import threading
import time
Expand All @@ -44,6 +43,7 @@
from test.support import os_helper
from test.support import threading_helper
from test.support import warnings_helper
from test.support import skip_if_sanitizer
from test.support.os_helper import FakePath

import codecs
Expand All @@ -66,17 +66,6 @@ def byteslike(*pos, **kw):
class EmptyStruct(ctypes.Structure):
pass

_cflags = sysconfig.get_config_var('CFLAGS') or ''
_config_args = sysconfig.get_config_var('CONFIG_ARGS') or ''
MEMORY_SANITIZER = (
'-fsanitize=memory' in _cflags or
'--with-memory-sanitizer' in _config_args
)

ADDRESS_SANITIZER = (
'-fsanitize=address' in _cflags
)

# Does io.IOBase finalizer log the exception if the close() method fails?
# The exception is ignored silently by default in release build.
IOBASE_EMITS_UNRAISABLE = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode)
Expand Down Expand Up @@ -1550,8 +1539,8 @@ def test_truncate_on_read_only(self):
class CBufferedReaderTest(BufferedReaderTest, SizeofTest):
tp = io.BufferedReader

@unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing "
"instead of returning NULL for malloc failure.")
@skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing "
"instead of returning NULL for malloc failure.")
def test_constructor(self):
BufferedReaderTest.test_constructor(self)
# The allocation can succeed on 32-bit builds, e.g. with more
Expand Down Expand Up @@ -1915,8 +1904,8 @@ def test_slow_close_from_thread(self):
class CBufferedWriterTest(BufferedWriterTest, SizeofTest):
tp = io.BufferedWriter

@unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing "
"instead of returning NULL for malloc failure.")
@skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing "
"instead of returning NULL for malloc failure.")
def test_constructor(self):
BufferedWriterTest.test_constructor(self)
# The allocation can succeed on 32-bit builds, e.g. with more
Expand Down Expand Up @@ -2414,8 +2403,8 @@ def test_interleaved_readline_write(self):
class CBufferedRandomTest(BufferedRandomTest, SizeofTest):
tp = io.BufferedRandom

@unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing "
"instead of returning NULL for malloc failure.")
@skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing "
"instead of returning NULL for malloc failure.")
def test_constructor(self):
BufferedRandomTest.test_constructor(self)
# The allocation can succeed on 32-bit builds, e.g. with more
Expand Down