Skip some tests that require a subinterpreter launched with -E or -I when the
interpreter under test is being run in an environment that requires the use of environment variables such as PYTHONHOME in order to function at all. Adds a test.script_helper.interpreter_requires_environment() function to be used with @unittest.skipIf on stdlib test methods requiring this.
This commit is contained in:
commit
8f2fae1e7d
@ -15,6 +15,41 @@ import zipfile
|
|||||||
from importlib.util import source_from_cache
|
from importlib.util import source_from_cache
|
||||||
from test.support import make_legacy_pyc, strip_python_stderr, temp_dir
|
from test.support import make_legacy_pyc, strip_python_stderr, temp_dir
|
||||||
|
|
||||||
|
|
||||||
|
# Cached result of the expensive test performed in the function below.
|
||||||
|
__cached_interp_requires_environment = None
|
||||||
|
|
||||||
|
def interpreter_requires_environment():
|
||||||
|
"""
|
||||||
|
Returns True if our sys.executable interpreter requires environment
|
||||||
|
variables in order to be able to run at all.
|
||||||
|
|
||||||
|
This is designed to be used with @unittest.skipIf() to annotate tests
|
||||||
|
that need to use an assert_python*() function to launch an isolated
|
||||||
|
mode (-I) or no environment mode (-E) sub-interpreter process.
|
||||||
|
|
||||||
|
A normal build & test does not run into this situation but it can happen
|
||||||
|
when trying to run the standard library test suite from an interpreter that
|
||||||
|
doesn't have an obvious home with Python's current home finding logic.
|
||||||
|
|
||||||
|
Setting PYTHONHOME is one way to get most of the testsuite to run in that
|
||||||
|
situation. PYTHONPATH or PYTHONUSERSITE are other common envirnonment
|
||||||
|
variables that might impact whether or not the interpreter can start.
|
||||||
|
"""
|
||||||
|
global __cached_interp_requires_environment
|
||||||
|
if __cached_interp_requires_environment is None:
|
||||||
|
# Try running an interpreter with -E to see if it works or not.
|
||||||
|
try:
|
||||||
|
subprocess.check_call([sys.executable, '-E',
|
||||||
|
'-c', 'import sys; sys.exit(0)'])
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
__cached_interp_requires_environment = True
|
||||||
|
else:
|
||||||
|
__cached_interp_requires_environment = False
|
||||||
|
|
||||||
|
return __cached_interp_requires_environment
|
||||||
|
|
||||||
|
|
||||||
# Executing the interpreter in a subprocess
|
# Executing the interpreter in a subprocess
|
||||||
def _assert_python(expected_success, *args, **env_vars):
|
def _assert_python(expected_success, *args, **env_vars):
|
||||||
if '__isolated' in env_vars:
|
if '__isolated' in env_vars:
|
||||||
|
@ -8,6 +8,7 @@ import shutil
|
|||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from test import script_helper
|
||||||
from test.script_helper import (spawn_python, kill_python, assert_python_ok,
|
from test.script_helper import (spawn_python, kill_python, assert_python_ok,
|
||||||
assert_python_failure)
|
assert_python_failure)
|
||||||
|
|
||||||
@ -439,7 +440,8 @@ class CmdLineTest(unittest.TestCase):
|
|||||||
self.assertEqual(err.splitlines().count(b'Unknown option: -a'), 1)
|
self.assertEqual(err.splitlines().count(b'Unknown option: -a'), 1)
|
||||||
self.assertEqual(b'', out)
|
self.assertEqual(b'', out)
|
||||||
|
|
||||||
|
@unittest.skipIf(script_helper.interpreter_requires_environment(),
|
||||||
|
'Cannot run -I tests when PYTHON env vars are required.')
|
||||||
def test_isolatedmode(self):
|
def test_isolatedmode(self):
|
||||||
self.verify_valid_flag('-I')
|
self.verify_valid_flag('-I')
|
||||||
self.verify_valid_flag('-IEs')
|
self.verify_valid_flag('-IEs')
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
"""Unittests for test.script_helper. Who tests the test helper?"""
|
"""Unittests for test.script_helper. Who tests the test helper?"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
from test import script_helper
|
from test import script_helper
|
||||||
import unittest
|
import unittest
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
|
||||||
class TestScriptHelper(unittest.TestCase):
|
class TestScriptHelper(unittest.TestCase):
|
||||||
@ -31,5 +34,43 @@ class TestScriptHelper(unittest.TestCase):
|
|||||||
msg='unexpected command line.')
|
msg='unexpected command line.')
|
||||||
|
|
||||||
|
|
||||||
|
class TestScriptHelperEnvironment(unittest.TestCase):
|
||||||
|
"""Code coverage for interpreter_requires_environment()."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.assertTrue(
|
||||||
|
hasattr(script_helper, '__cached_interp_requires_environment'))
|
||||||
|
# Reset the private cached state.
|
||||||
|
script_helper.__dict__['__cached_interp_requires_environment'] = None
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# Reset the private cached state.
|
||||||
|
script_helper.__dict__['__cached_interp_requires_environment'] = None
|
||||||
|
|
||||||
|
@mock.patch('subprocess.check_call')
|
||||||
|
def test_interpreter_requires_environment_true(self, mock_check_call):
|
||||||
|
mock_check_call.side_effect = subprocess.CalledProcessError('', '')
|
||||||
|
self.assertTrue(script_helper.interpreter_requires_environment())
|
||||||
|
self.assertTrue(script_helper.interpreter_requires_environment())
|
||||||
|
self.assertEqual(1, mock_check_call.call_count)
|
||||||
|
|
||||||
|
@mock.patch('subprocess.check_call')
|
||||||
|
def test_interpreter_requires_environment_false(self, mock_check_call):
|
||||||
|
# The mocked subprocess.check_call fakes a no-error process.
|
||||||
|
script_helper.interpreter_requires_environment()
|
||||||
|
self.assertFalse(script_helper.interpreter_requires_environment())
|
||||||
|
self.assertEqual(1, mock_check_call.call_count)
|
||||||
|
|
||||||
|
@mock.patch('subprocess.check_call')
|
||||||
|
def test_interpreter_requires_environment_details(self, mock_check_call):
|
||||||
|
script_helper.interpreter_requires_environment()
|
||||||
|
self.assertFalse(script_helper.interpreter_requires_environment())
|
||||||
|
self.assertFalse(script_helper.interpreter_requires_environment())
|
||||||
|
self.assertEqual(1, mock_check_call.call_count)
|
||||||
|
check_call_command = mock_check_call.call_args[0][0]
|
||||||
|
self.assertEqual(sys.executable, check_call_command[0])
|
||||||
|
self.assertIn('-E', check_call_command)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -5,7 +5,7 @@ import tracemalloc
|
|||||||
import unittest
|
import unittest
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
from test.script_helper import assert_python_ok, assert_python_failure
|
from test.script_helper import assert_python_ok, assert_python_failure
|
||||||
from test import support
|
from test import script_helper, support
|
||||||
try:
|
try:
|
||||||
import threading
|
import threading
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -755,6 +755,8 @@ class TestCommandLine(unittest.TestCase):
|
|||||||
stdout = stdout.rstrip()
|
stdout = stdout.rstrip()
|
||||||
self.assertEqual(stdout, b'False')
|
self.assertEqual(stdout, b'False')
|
||||||
|
|
||||||
|
@unittest.skipIf(script_helper.interpreter_requires_environment(),
|
||||||
|
'Cannot run -E tests when PYTHON env vars are required.')
|
||||||
def test_env_var_ignored_with_E(self):
|
def test_env_var_ignored_with_E(self):
|
||||||
"""PYTHON* environment variables must be ignored when -E is present."""
|
"""PYTHON* environment variables must be ignored when -E is present."""
|
||||||
code = 'import tracemalloc; print(tracemalloc.is_tracing())'
|
code = 'import tracemalloc; print(tracemalloc.is_tracing())'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user