pip/tests/lib/test_lib.py

228 lines
7.6 KiB
Python

"""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)'
)