"""Test the test support.""" from __future__ import absolute_import import filecmp import re import sys from contextlib import contextmanager from os.path import isdir, join import pytest from tests.lib import SRC_DIR @contextmanager def assert_error_startswith(exc_type, expected_start): """ Assert that an exception is raised starting with a certain message. """ with pytest.raises(exc_type) as err: yield assert str(err.value).startswith(expected_start), ( 'full message: {}'.format(err.value) ) def test_tmp_dir_exists_in_env(script): """ Test that $TMPDIR == env.temp_path and path exists and env.assert_no_temp() passes (in fast env) """ # need these tests to ensure the assert_no_temp feature of scripttest is # working script.assert_no_temp() # this fails if env.tmp_path doesn't exist assert script.environ['TMPDIR'] == script.temp_path assert isdir(script.temp_path) def test_correct_pip_version(script): """ Check we are running proper version of pip in run_pip. """ # output is like: # pip PIPVERSION from PIPDIRECTORY (python PYVERSION) result = script.pip('--version') # compare the directory tree of the invoked pip with that of this source # distribution pip_folder_outputed = re.match( r'pip \d+(\.[\d]+)+(\.?(b|rc|dev|pre|post)\d+)? from (.*) ' r'\(python \d(.[\d])+\)$', result.stdout ).group(4) pip_folder = join(SRC_DIR, 'src', 'pip') diffs = filecmp.dircmp(pip_folder, pip_folder_outputed) # If any non-matching .py files exist, we have a problem: run_pip # is picking up some other version! N.B. if this project acquires # primary resources other than .py files, this code will need # maintenance mismatch_py = [ x for x in diffs.left_only + diffs.right_only + diffs.diff_files if x.endswith('.py') ] assert not mismatch_py, ( 'mismatched source files in {pip_folder!r} ' 'and {pip_folder_outputed!r}: {mismatch_py!r}'.format(**locals()) ) def test_as_import(script): """ test that pip.__init__.py does not shadow the command submodule with a dictionary """ import pip._internal.commands.install as inst assert inst is not None class TestPipTestEnvironment: def run_stderr_with_prefix(self, script, prefix, **kwargs): """ Call run() that prints stderr with the given prefix. """ text = '{}: hello, world\\n'.format(prefix) command = 'import sys; sys.stderr.write("{}")'.format(text) args = [sys.executable, '-c', command] script.run(*args, **kwargs) def run_with_log_command(self, script, sub_string, **kwargs): """ Call run() on a command that logs a "%"-style format string using the given substring as the string's replacement field. """ command = ( "import logging; logging.basicConfig(level='INFO'); " "logging.getLogger().info('sub: {}', 'foo')" ).format(sub_string) args = [sys.executable, '-c', command] script.run(*args, **kwargs) @pytest.mark.parametrize('prefix', ( 'DEBUG', 'INFO', 'FOO', )) def test_run__allowed_stderr(self, script, prefix): """ Test calling run() with allowed stderr. """ # Check that no error happens. self.run_stderr_with_prefix(script, prefix) def test_run__allow_stderr_warning(self, script): """ Test passing allow_stderr_warning=True. """ # Check that no error happens. self.run_stderr_with_prefix( script, 'WARNING', allow_stderr_warning=True, ) # Check that an error still happens with ERROR. expected_start = 'stderr has an unexpected error' with assert_error_startswith(RuntimeError, expected_start): self.run_stderr_with_prefix( script, 'ERROR', allow_stderr_warning=True, ) @pytest.mark.parametrize('prefix', ( 'DEPRECATION', 'WARNING', 'ERROR', )) def test_run__allow_stderr_error(self, script, prefix): """ Test passing allow_stderr_error=True. """ # Check that no error happens. self.run_stderr_with_prefix(script, prefix, allow_stderr_error=True) @pytest.mark.parametrize('prefix, expected_start', ( ('DEPRECATION', 'stderr has an unexpected warning'), ('WARNING', 'stderr has an unexpected warning'), ('ERROR', 'stderr has an unexpected error'), )) def test_run__unexpected_stderr(self, script, prefix, expected_start): """ Test calling run() with unexpected stderr output. """ with assert_error_startswith(RuntimeError, expected_start): self.run_stderr_with_prefix(script, prefix) def test_run__logging_error(self, script): """ Test calling run() with an unexpected logging error. """ # Pass a good substitution string. self.run_with_log_command(script, sub_string='%r') expected_start = 'stderr has a logging error, which is never allowed' with assert_error_startswith(RuntimeError, expected_start): # Pass a bad substitution string. Also, pass # allow_stderr_error=True to check that the RuntimeError occurs # even under the stricter test condition of when we are allowing # other types of errors. self.run_with_log_command( script, sub_string='{!r}', allow_stderr_error=True, ) def test_run__allow_stderr_error_false_error_with_expect_error( self, script, ): """ Test passing allow_stderr_error=False with expect_error=True. """ expected_start = ( 'cannot pass allow_stderr_error=False with expect_error=True' ) with assert_error_startswith(RuntimeError, expected_start): script.run('python', allow_stderr_error=False, expect_error=True) def test_run__allow_stderr_warning_false_error_with_expect_stderr( self, script, ): """ Test passing allow_stderr_warning=False with expect_stderr=True. """ expected_start = ( 'cannot pass allow_stderr_warning=False with expect_stderr=True' ) with assert_error_startswith(RuntimeError, expected_start): script.run( 'python', allow_stderr_warning=False, expect_stderr=True, ) @pytest.mark.parametrize('arg_name', ( 'expect_error', 'allow_stderr_error', )) def test_run__allow_stderr_warning_false_error(self, script, arg_name): """ Test passing allow_stderr_warning=False when it is not allowed. """ kwargs = {'allow_stderr_warning': False, arg_name: True} expected_start = ( 'cannot pass allow_stderr_warning=False with ' 'allow_stderr_error=True' ) with assert_error_startswith(RuntimeError, expected_start): script.run('python', **kwargs) def test_run__expect_error_fails_when_zero_returncode(self, script): expected_start = 'Script passed unexpectedly' with assert_error_startswith(AssertionError, expected_start): script.run( 'python', expect_error=True ) def test_run__no_expect_error_fails_when_nonzero_returncode(self, script): expected_start = 'Script returned code: 1' with assert_error_startswith(AssertionError, expected_start): script.run( 'python', '-c', 'import sys; sys.exit(1)' )