Fix ansible-test python and pip executable search.

pull/37449/head
Matt Clay 6 years ago
parent dd37857884
commit a8487feb70

@ -15,7 +15,6 @@ from lib.util import (
display,
ApplicationError,
is_shippable,
find_pip,
run_command,
generate_password,
SubprocessError,
@ -151,8 +150,7 @@ class TowerCloudEnvironment(CloudEnvironment):
display.info('Installing Tower CLI version: %s' % tower_cli_version)
pip = find_pip(version=self.args.python_version)
cmd = [pip, 'install', '--disable-pip-version-check', 'ansible-tower-cli==%s' % tower_cli_version]
cmd = self.args.pip_command + ['install', '--disable-pip-version-check', 'ansible-tower-cli==%s' % tower_cli_version]
run_command(self.args, cmd)

@ -9,6 +9,8 @@ from lib.util import (
CommonConfig,
is_shippable,
docker_qualify_image,
find_python,
generate_pip_command,
)
from lib.metadata import (
@ -67,6 +69,20 @@ class EnvironmentConfig(CommonConfig):
if self.delegate:
self.requirements = True
@property
def python_executable(self):
"""
:rtype: str
"""
return find_python(self.python_version)
@property
def pip_command(self):
"""
:rtype: list[str]
"""
return generate_pip_command(self.python_executable)
class TestConfig(EnvironmentConfig):
"""Configuration common to all test commands."""

@ -45,7 +45,6 @@ from lib.util import (
make_dirs,
is_shippable,
is_binary_file,
find_pip,
find_executable,
raw_command,
get_coverage_path,
@ -151,7 +150,7 @@ def install_command_requirements(args):
if args.junit:
packages.append('junit-xml')
pip = find_pip(version=args.python_version)
pip = args.pip_command
commands = [generate_pip_install(pip, args.command, packages=packages)]
@ -183,7 +182,7 @@ def install_command_requirements(args):
def run_pip_commands(args, pip, commands, detect_pip_changes=False):
"""
:type args: EnvironmentConfig
:type pip: str
:type pip: list[str]
:type commands: list[list[str]]
:type detect_pip_changes: bool
:rtype: list[list[str]]
@ -210,7 +209,7 @@ def run_pip_commands(args, pip, commands, detect_pip_changes=False):
# AttributeError: 'Requirement' object has no attribute 'project_name'
# See: https://bugs.launchpad.net/ubuntu/xenial/+source/python-pip/+bug/1626258
# Upgrading pip works around the issue.
run_command(args, [pip, 'install', '--upgrade', 'pip'])
run_command(args, pip + ['install', '--upgrade', 'pip'])
run_command(args, cmd)
after_list = pip_list(args, pip) if detect_pip_changes else None
@ -224,10 +223,10 @@ def run_pip_commands(args, pip, commands, detect_pip_changes=False):
def pip_list(args, pip):
"""
:type args: EnvironmentConfig
:type pip: str
:type pip: list[str]
:rtype: str
"""
stdout, _ = run_command(args, [pip, 'list'], capture=True)
stdout, _ = run_command(args, pip + ['list'], capture=True)
return stdout
@ -238,12 +237,12 @@ def generate_egg_info(args):
if os.path.isdir('lib/ansible.egg-info'):
return
run_command(args, ['python%s' % args.python_version, 'setup.py', 'egg_info'], capture=args.verbosity < 3)
run_command(args, [args.python_executable, 'setup.py', 'egg_info'], capture=args.verbosity < 3)
def generate_pip_install(pip, command, packages=None):
"""
:type pip: str
:type pip: list[str]
:type command: str
:type packages: list[str] | None
:rtype: list[str] | None
@ -262,7 +261,7 @@ def generate_pip_install(pip, command, packages=None):
if not options:
return None
return [pip, 'install', '--disable-pip-version-check', '-c', constraints] + options
return pip + ['install', '--disable-pip-version-check', '-c', constraints] + options
def command_shell(args):

@ -221,7 +221,11 @@ class SanityCodeSmellTest(SanityTest):
:type targets: SanityTargets
:rtype: SanityResult
"""
cmd = [self.path]
if self.path.endswith('.py'):
cmd = [args.python_executable, self.path]
else:
cmd = [self.path]
env = ansible_environment(args, color=False)
pattern = None

@ -16,6 +16,7 @@ from lib.util import (
SubprocessError,
run_command,
display,
find_python,
)
from lib.config import (
@ -50,7 +51,7 @@ class CompileTest(SanityMultipleVersion):
if not paths:
return SanitySkipped(self.name, python_version=python_version)
cmd = ['python%s' % python_version, 'test/sanity/compile/compile.py']
cmd = [find_python(python_version), 'test/sanity/compile/compile.py']
data = '\n'.join(paths)

@ -18,6 +18,7 @@ from lib.util import (
intercept_command,
remove_tree,
display,
find_python,
)
from lib.ansible_util import (
@ -66,7 +67,7 @@ class ImportTest(SanityMultipleVersion):
remove_tree(virtual_environment_path)
cmd = ['virtualenv', virtual_environment_path, '--python', 'python%s' % python_version, '--no-setuptools', '--no-wheel']
cmd = ['virtualenv', virtual_environment_path, '--python', find_python(python_version), '--no-setuptools', '--no-wheel']
if not args.coverage:
cmd.append('--no-pip')
@ -84,8 +85,8 @@ class ImportTest(SanityMultipleVersion):
# make sure coverage is available in the virtual environment if needed
if args.coverage:
run_command(args, generate_pip_install('pip', 'sanity.import', packages=['setuptools']), env=env)
run_command(args, generate_pip_install('pip', 'sanity.import', packages=['coverage']), env=env)
run_command(args, generate_pip_install(['pip'], 'sanity.import', packages=['setuptools']), env=env)
run_command(args, generate_pip_install(['pip'], 'sanity.import', packages=['coverage']), env=env)
run_command(args, ['pip', 'uninstall', '--disable-pip-version-check', '-y', 'setuptools'], env=env)
run_command(args, ['pip', 'uninstall', '--disable-pip-version-check', '-y', 'pip'], env=env)

@ -15,7 +15,6 @@ from lib.util import (
SubprocessError,
display,
run_command,
find_executable,
)
from lib.config import (
@ -56,8 +55,8 @@ class Pep8Test(SanitySingleVersion):
paths = sorted(i.path for i in targets.include if (os.path.splitext(i.path)[1] == '.py' or i.path.startswith('bin/')) and i.path not in skip_paths_set)
cmd = [
'python%s' % args.python_version,
find_executable('pycodestyle'),
args.python_executable,
'-m', 'pycodestyle',
'--max-line-length', '160',
'--config', '/dev/null',
'--ignore', ','.join(sorted(current_ignore)),

@ -252,8 +252,8 @@ class PylintTest(SanitySingleVersion):
load_plugins = set(self.plugin_names) - disable_plugins
cmd = [
'python%s' % args.python_version,
find_executable('pylint'),
args.python_executable,
'-m', 'pylint',
'--jobs', '0',
'--reports', 'n',
'--max-line-length', '160',

@ -15,6 +15,7 @@ from lib.util import (
SubprocessError,
run_command,
parse_to_dict,
display,
find_executable,
)
@ -22,6 +23,10 @@ from lib.config import (
SanityConfig,
)
UNSUPPORTED_PYTHON_VERSIONS = (
'2.6',
)
class RstcheckTest(SanitySingleVersion):
"""Sanity test using rstcheck."""
@ -31,6 +36,10 @@ class RstcheckTest(SanitySingleVersion):
:type targets: SanityTargets
:rtype: SanityResult
"""
if args.python_version in UNSUPPORTED_PYTHON_VERSIONS:
display.warning('Skipping rstcheck on unsupported Python version %s.' % args.python_version)
return SanitySkipped(self.name)
with open('test/sanity/rstcheck/ignore-substitutions.txt', 'r') as ignore_fd:
ignore_substitutions = sorted(set(ignore_fd.read().splitlines()))
@ -40,8 +49,8 @@ class RstcheckTest(SanitySingleVersion):
return SanitySkipped(self.name)
cmd = [
'python%s' % args.python_version,
find_executable('rstcheck'),
args.python_executable,
'-m', 'rstcheck',
'--report', 'warning',
'--ignore-substitutions', ','.join(ignore_substitutions),
] + paths

@ -57,7 +57,7 @@ class ValidateModulesTest(SanitySingleVersion):
return SanitySkipped(self.name)
cmd = [
'python%s' % args.python_version,
args.python_executable,
'test/sanity/validate-modules/validate-modules',
'--format', 'json',
'--arg-spec',

@ -65,7 +65,7 @@ class YamllintTest(SanitySingleVersion):
:rtype: list[SanityMessage]
"""
cmd = [
'python%s' % args.python_version,
args.python_executable,
'test/sanity/yamllint/yamllinter.py',
]

@ -63,51 +63,6 @@ def remove_file(path):
os.remove(path)
def find_pip(path=None, version=None):
"""
:type path: str | None
:type version: str | None
:rtype: str
"""
if version:
version_info = version.split('.')
python_bin = find_executable('python%s' % version, path=path)
else:
version_info = sys.version_info
python_bin = sys.executable
choices = (
'pip%s' % '.'.join(str(i) for i in version_info[:2]),
'pip%s' % version_info[0],
'pip',
)
pip = None
for choice in choices:
pip = find_executable(choice, required=False, path=path)
if pip:
break
if not pip:
raise ApplicationError('Required program not found: %s' % ', '.join(choices))
with open(pip) as pip_fd:
shebang = pip_fd.readline().strip()
if not shebang.startswith('#!') or ' ' in shebang:
raise ApplicationError('Unexpected shebang in "%s": %s' % (pip, shebang))
our_python = os.path.realpath(python_bin)
pip_python = os.path.realpath(shebang[2:])
if our_python != pip_python and not filecmp.cmp(our_python, pip_python, False):
raise ApplicationError('Current interpreter "%s" does not match "%s" interpreter "%s".' % (our_python, pip, pip_python))
return pip
def find_executable(executable, cwd=None, path=None, required=True):
"""
:type executable: str
@ -160,6 +115,30 @@ def find_executable(executable, cwd=None, path=None, required=True):
return match
def find_python(version, path=None):
"""
:type version: str
:type path: str | None
:rtype: str
"""
version_info = tuple(int(n) for n in version.split('.'))
if not path and version_info == sys.version_info[:len(version_info)]:
python_bin = sys.executable
else:
python_bin = find_executable('python%s' % version, path=path)
return python_bin
def generate_pip_command(python):
"""
:type python: str
:rtype: list[str]
"""
return [python, '-m', 'pip.__main__']
def intercept_command(args, cmd, target_name, capture=False, env=None, data=None, cwd=None, python_version=None, path=None):
"""
:type args: TestConfig
@ -180,7 +159,7 @@ def intercept_command(args, cmd, target_name, capture=False, env=None, data=None
inject_path = get_coverage_path(args)
config_path = os.path.join(inject_path, 'injector.json')
version = python_version or args.python_version
interpreter = find_executable('python%s' % version, path=path)
interpreter = find_python(version, path)
coverage_file = os.path.abspath(os.path.join(inject_path, '..', 'output', '%s=%s=%s=%s=coverage' % (
args.command, target_name, args.coverage_label or 'local-%s' % version, 'python-%s' % version)))

@ -5,7 +5,7 @@ paramiko
pycodestyle
pylint ; python_version >= '2.7' # pylint 1.5.3+ is required for non-buggy JSON output, but 1.4+ requires python 2.7+
pytest
rstcheck
rstcheck ; python_version >= '2.7' # rstcheck requires python 2.7+
sphinx
virtualenv
voluptuous

@ -12,8 +12,8 @@ from lib.util import (
ApplicationError,
display,
raw_command,
find_pip,
get_docker_completion,
generate_pip_command,
)
from lib.delegation import (
@ -112,7 +112,7 @@ def parse_args():
except ImportError:
if '--requirements' not in sys.argv:
raise
raw_command(generate_pip_install(find_pip(), 'ansible-test'))
raw_command(generate_pip_install(generate_pip_command(sys.executable), 'ansible-test'))
import argparse
try:

Loading…
Cancel
Save