Skip to content

Commit

Permalink
bpo-40280: Skip subprocess-based tests on wasm32-emscripten (GH-30615)
Browse files Browse the repository at this point in the history
  • Loading branch information
tiran committed Jan 25, 2022
1 parent e1abffc commit 8464fbc
Show file tree
Hide file tree
Showing 42 changed files with 139 additions and 23 deletions.
5 changes: 4 additions & 1 deletion Lib/distutils/tests/test_build_clib.py
Expand Up @@ -4,7 +4,9 @@
import sys
import sysconfig

from test.support import run_unittest, missing_compiler_executable
from test.support import (
run_unittest, missing_compiler_executable, requires_subprocess
)

from distutils.command.build_clib import build_clib
from distutils.errors import DistutilsSetupError
Expand Down Expand Up @@ -112,6 +114,7 @@ def test_finalize_options(self):
self.assertRaises(DistutilsSetupError, cmd.finalize_options)

@unittest.skipIf(sys.platform == 'win32', "can't test on Windows")
@requires_subprocess()
def test_run(self):
pkg_dir, dist = self.create_dist()
cmd = build_clib(dist)
Expand Down
2 changes: 2 additions & 0 deletions Lib/distutils/tests/test_build_ext.py
Expand Up @@ -56,6 +56,7 @@ def tearDown(self):
def build_ext(self, *args, **kwargs):
return build_ext(*args, **kwargs)

@support.requires_subprocess()
def test_build_ext(self):
cmd = support.missing_compiler_executable()
if cmd is not None:
Expand Down Expand Up @@ -332,6 +333,7 @@ def test_compiler_option(self):
cmd.run()
self.assertEqual(cmd.compiler, 'unix')

@support.requires_subprocess()
def test_get_outputs(self):
cmd = support.missing_compiler_executable()
if cmd is not None:
Expand Down
4 changes: 3 additions & 1 deletion Lib/distutils/tests/test_build_py.py
Expand Up @@ -9,7 +9,7 @@
from distutils.errors import DistutilsFileError

from distutils.tests import support
from test.support import run_unittest
from test.support import run_unittest, requires_subprocess


class BuildPyTestCase(support.TempdirManager,
Expand Down Expand Up @@ -89,6 +89,7 @@ def test_empty_package_dir(self):
self.fail("failed package_data test when package_dir is ''")

@unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled')
@requires_subprocess()
def test_byte_compile(self):
project_dir, dist = self.create_dist(py_modules=['boiledeggs'])
os.chdir(project_dir)
Expand All @@ -106,6 +107,7 @@ def test_byte_compile(self):
['boiledeggs.%s.pyc' % sys.implementation.cache_tag])

@unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled')
@requires_subprocess()
def test_byte_compile_optimized(self):
project_dir, dist = self.create_dist(py_modules=['boiledeggs'])
os.chdir(project_dir)
Expand Down
5 changes: 4 additions & 1 deletion Lib/distutils/tests/test_config_cmd.py
Expand Up @@ -3,7 +3,9 @@
import os
import sys
import sysconfig
from test.support import run_unittest, missing_compiler_executable
from test.support import (
run_unittest, missing_compiler_executable, requires_subprocess
)

from distutils.command.config import dump_file, config
from distutils.tests import support
Expand Down Expand Up @@ -42,6 +44,7 @@ def test_dump_file(self):
self.assertEqual(len(self._logs), numlines+1)

@unittest.skipIf(sys.platform == 'win32', "can't test on Windows")
@requires_subprocess()
def test_search_cpp(self):
cmd = missing_compiler_executable(['preprocessor'])
if cmd is not None:
Expand Down
3 changes: 2 additions & 1 deletion Lib/distutils/tests/test_install.py
Expand Up @@ -5,7 +5,7 @@
import unittest
import site

from test.support import captured_stdout, run_unittest
from test.support import captured_stdout, run_unittest, requires_subprocess

from distutils import sysconfig
from distutils.command.install import install, HAS_USER_SITE
Expand Down Expand Up @@ -208,6 +208,7 @@ def test_record(self):
'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]]
self.assertEqual(found, expected)

@requires_subprocess()
def test_record_extensions(self):
cmd = test_support.missing_compiler_executable()
if cmd is not None:
Expand Down
4 changes: 3 additions & 1 deletion Lib/distutils/tests/test_install_lib.py
Expand Up @@ -8,7 +8,7 @@
from distutils.extension import Extension
from distutils.tests import support
from distutils.errors import DistutilsOptionError
from test.support import run_unittest
from test.support import run_unittest, requires_subprocess


class InstallLibTestCase(support.TempdirManager,
Expand All @@ -35,6 +35,7 @@ def test_finalize_options(self):
self.assertEqual(cmd.optimize, 2)

@unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled')
@requires_subprocess()
def test_byte_compile(self):
project_dir, dist = self.create_dist()
os.chdir(project_dir)
Expand Down Expand Up @@ -90,6 +91,7 @@ def test_get_inputs(self):
inputs = cmd.get_inputs()
self.assertEqual(len(inputs), 2, inputs)

@requires_subprocess()
def test_dont_write_bytecode(self):
# makes sure byte_compile is not used
dist = self.create_dist()[1]
Expand Down
4 changes: 3 additions & 1 deletion Lib/distutils/tests/test_spawn.py
Expand Up @@ -3,14 +3,16 @@
import stat
import sys
import unittest.mock
from test.support import run_unittest, unix_shell
from test.support import run_unittest, unix_shell, requires_subprocess
from test.support import os_helper

from distutils.spawn import find_executable
from distutils.spawn import spawn
from distutils.errors import DistutilsExecError
from distutils.tests import support


@requires_subprocess()
class SpawnTestCase(support.TempdirManager,
support.LoggingSilencer,
unittest.TestCase):
Expand Down
3 changes: 2 additions & 1 deletion Lib/distutils/tests/test_sysconfig.py
Expand Up @@ -10,7 +10,7 @@
from distutils import sysconfig
from distutils.ccompiler import get_default_compiler
from distutils.tests import support
from test.support import run_unittest, swap_item
from test.support import run_unittest, swap_item, requires_subprocess
from test.support.os_helper import TESTFN
from test.support.warnings_helper import check_warnings

Expand Down Expand Up @@ -247,6 +247,7 @@ def test_SO_in_vars(self):
self.assertIsNotNone(vars['SO'])
self.assertEqual(vars['SO'], vars['EXT_SUFFIX'])

@requires_subprocess()
def test_customize_compiler_before_get_config_vars(self):
# Issue #21923: test that a Distribution compiler
# instance can be called without an explicit call to
Expand Down
3 changes: 3 additions & 0 deletions Lib/lib2to3/tests/test_parser.py
Expand Up @@ -61,6 +61,9 @@ def test_load_grammar_from_pickle(self):
shutil.rmtree(tmpdir)

@unittest.skipIf(sys.executable is None, 'sys.executable required')
@unittest.skipIf(
sys.platform == 'emscripten', 'requires working subprocess'
)
def test_load_grammar_from_subprocess(self):
tmpdir = tempfile.mkdtemp()
tmpsubdir = os.path.join(tmpdir, 'subdir')
Expand Down
17 changes: 13 additions & 4 deletions Lib/test/support/__init__.py
Expand Up @@ -40,11 +40,12 @@
"bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute",
"requires_IEEE_754", "requires_zlib",
"has_fork_support", "requires_fork",
"has_subprocess_support", "requires_subprocess",
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
"check__all__", "skip_if_buggy_ucrt_strfptime",
"check_disallow_instantiation",
# sys
"is_jython", "is_android", "is_emscripten",
"is_jython", "is_android", "is_emscripten", "is_wasi",
"check_impl_detail", "unix_shell", "setswitchinterval",
# network
"open_urlresource",
Expand Down Expand Up @@ -467,15 +468,23 @@ def requires_debug_ranges(reason='requires co_positions / debug_ranges'):
else:
unix_shell = None

# wasm32-emscripten is POSIX-like but does not provide a
# working fork() or subprocess API.
# wasm32-emscripten and -wasi are POSIX-like but do not
# have subprocess or fork support.
is_emscripten = sys.platform == "emscripten"
is_wasi = sys.platform == "wasi"

has_fork_support = hasattr(os, "fork") and not is_emscripten
has_fork_support = hasattr(os, "fork") and not is_emscripten and not is_wasi

def requires_fork():
return unittest.skipUnless(has_fork_support, "requires working os.fork()")

has_subprocess_support = not is_emscripten and not is_wasi

def requires_subprocess():
"""Used for subprocess, os.spawn calls"""
return unittest.skipUnless(has_subprocess_support, "requires subprocess support")


# Define the URL of a dedicated HTTP server for the network tests.
# The URL must use clear-text HTTP: no redirection to encrypted HTTPS.
TEST_HTTP_URL = "http://www.pythontest.net"
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/support/script_helper.py
Expand Up @@ -42,6 +42,10 @@ def interpreter_requires_environment():
if 'PYTHONHOME' in os.environ:
__cached_interp_requires_environment = True
return True
# cannot run subprocess, assume we don't need it
if not support.has_subprocess_support:
__cached_interp_requires_environment = False
return False

# Try running an interpreter with -E to see if it works or not.
try:
Expand Down Expand Up @@ -87,6 +91,7 @@ def fail(self, cmd_line):


# Executing the interpreter in a subprocess
@support.requires_subprocess()
def run_python_until_end(*args, **env_vars):
env_required = interpreter_requires_environment()
cwd = env_vars.pop('__cwd', None)
Expand Down Expand Up @@ -139,6 +144,7 @@ def run_python_until_end(*args, **env_vars):
return _PythonRunResult(rc, out, err), cmd_line


@support.requires_subprocess()
def _assert_python(expected_success, /, *args, **env_vars):
res, cmd_line = run_python_until_end(*args, **env_vars)
if (res.rc and expected_success) or (not res.rc and not expected_success):
Expand Down Expand Up @@ -171,6 +177,7 @@ def assert_python_failure(*args, **env_vars):
return _assert_python(False, *args, **env_vars)


@support.requires_subprocess()
def spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw):
"""Run a Python subprocess with the given arguments.
Expand Down Expand Up @@ -273,6 +280,7 @@ def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,
return zip_name, os.path.join(zip_name, script_name_in_zip)


@support.requires_subprocess()
def run_test_script(script):
# use -u to try to get the full output if the test hangs or crash
if support.verbose:
Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_audit.py
Expand Up @@ -16,6 +16,8 @@


class AuditTest(unittest.TestCase):

@support.requires_subprocess()
def do_test(self, *args):
with subprocess.Popen(
[sys.executable, "-Xutf8", AUDIT_TESTS_PY, *args],
Expand All @@ -29,6 +31,7 @@ def do_test(self, *args):
if p.returncode:
self.fail("".join(p.stderr))

@support.requires_subprocess()
def run_python(self, *args):
events = []
with subprocess.Popen(
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_capi.py
Expand Up @@ -66,6 +66,7 @@ def test_instancemethod(self):
self.assertEqual(testfunction.attribute, "test")
self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test")

@support.requires_subprocess()
def test_no_FatalError_infinite_loop(self):
with support.SuppressCrashReport():
p = subprocess.Popen([sys.executable, "-c",
Expand Down
2 changes: 2 additions & 0 deletions Lib/test/test_cmd_line.py
Expand Up @@ -15,6 +15,8 @@
interpreter_requires_environment
)

if not support.has_subprocess_support:
raise unittest.SkipTest("test module requires subprocess")

# Debug build?
Py_DEBUG = hasattr(sys, "gettotalrefcount")
Expand Down
2 changes: 2 additions & 0 deletions Lib/test/test_embed.py
Expand Up @@ -17,6 +17,8 @@
import tempfile
import textwrap

if not support.has_subprocess_support:
raise unittest.SkipTest("test module requires subprocess")

MS_WINDOWS = (os.name == 'nt')
MACOS = (sys.platform == 'darwin')
Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_faulthandler.py
Expand Up @@ -412,6 +412,7 @@ def test_is_enabled(self):
finally:
sys.stderr = orig_stderr

@support.requires_subprocess()
def test_disabled_by_default(self):
# By default, the module should be disabled
code = "import faulthandler; print(faulthandler.is_enabled())"
Expand All @@ -420,6 +421,7 @@ def test_disabled_by_default(self):
output = subprocess.check_output(args)
self.assertEqual(output.rstrip(), b"False")

@support.requires_subprocess()
def test_sys_xoptions(self):
# Test python -X faulthandler
code = "import faulthandler; print(faulthandler.is_enabled())"
Expand All @@ -432,6 +434,7 @@ def test_sys_xoptions(self):
output = subprocess.check_output(args, env=env)
self.assertEqual(output.rstrip(), b"True")

@support.requires_subprocess()
def test_env_var(self):
# empty env var
code = "import faulthandler; print(faulthandler.is_enabled())"
Expand Down
5 changes: 4 additions & 1 deletion Lib/test/test_file_eintr.py
Expand Up @@ -15,12 +15,15 @@
import sys
import time
import unittest
from test import support

if not support.has_subprocess_support:
raise unittest.SkipTest("test module requires subprocess")

# Test import all of the things we're about to try testing up front.
import _io
import _pyio


@unittest.skipUnless(os.name == 'posix', 'tests requires a posix system.')
class TestFileIOSignalInterrupt:
def setUp(self):
Expand Down
3 changes: 2 additions & 1 deletion Lib/test/test_gc.py
@@ -1,7 +1,7 @@
import unittest
import unittest.mock
from test.support import (verbose, refcount_test,
cpython_only)
cpython_only, requires_subprocess)
from test.support.import_helper import import_module
from test.support.os_helper import temp_dir, TESTFN, unlink
from test.support.script_helper import assert_python_ok, make_script
Expand Down Expand Up @@ -661,6 +661,7 @@ def do_work():
gc.collect() # this blows up (bad C pointer) when it fails

@cpython_only
@requires_subprocess()
def test_garbage_at_shutdown(self):
import subprocess
code = """if 1:
Expand Down
4 changes: 3 additions & 1 deletion Lib/test/test_gzip.py
Expand Up @@ -12,7 +12,7 @@
from subprocess import PIPE, Popen
from test.support import import_helper
from test.support import os_helper
from test.support import _4G, bigmemtest
from test.support import _4G, bigmemtest, requires_subprocess
from test.support.script_helper import assert_python_ok, assert_python_failure

gzip = import_helper.import_module('gzip')
Expand Down Expand Up @@ -760,6 +760,7 @@ def wrapper(*args, **kwargs):
class TestCommandLine(unittest.TestCase):
data = b'This is a simple test with gzip'

@requires_subprocess()
def test_decompress_stdin_stdout(self):
with io.BytesIO() as bytes_io:
with gzip.GzipFile(fileobj=bytes_io, mode='wb') as gzip_file:
Expand Down Expand Up @@ -795,6 +796,7 @@ def test_decompress_infile_outfile_error(self):
self.assertEqual(rc, 1)
self.assertEqual(out, b'')

@requires_subprocess()
@create_and_remove_directory(TEMPDIR)
def test_compress_stdin_outfile(self):
args = sys.executable, '-m', 'gzip'
Expand Down

0 comments on commit 8464fbc

Please sign in to comment.