More prep for ansible-test relocation. (#60114)

* Update pytest plugins.
* Fix update-bundled sanity test.
* Remove old validate-modules comment.
* Fix ansible-test plugin loading
* Update code coverage comments.
* Fix Makefile ansible-test reference.
* Remove incorrect path from lint output.
* Update ansible-test unit tests.
* Make ansible-test's own unit tests singular.
pull/60117/head
Matt Clay 5 years ago committed by GitHub
parent ac5228390c
commit fa2adf3b7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,9 +1,9 @@
.PHONY: all sanity units all: sanity unit
all: sanity units
.PHONY: sanity
sanity: sanity:
./ansible-test sanity test/runner/ ${TEST_FLAGS} ansible-test sanity test/runner/ ${FLAGS}
units: .PHONY: unit
PYTHONPATH=. pytest units ${TEST_FLAGS} unit:
PYTHONPATH=.:.. pytest unit ${FLAGS}

@ -285,7 +285,7 @@ class TestFailure(TestResult):
if self.summary: if self.summary:
command = self.format_command() command = self.format_command()
message = 'The test `%s` failed. See stderr output for details.' % command message = 'The test `%s` failed. See stderr output for details.' % command
path = 'test/runner/ansible-test' path = ''
message = TestMessage(message, path) message = TestMessage(message, path)
print(message) print(message)
else: else:

@ -812,10 +812,11 @@ def import_plugins(directory, root=None): # type: (str, t.Optional[str]) -> Non
root = os.path.dirname(__file__) root = os.path.dirname(__file__)
path = os.path.join(root, directory) path = os.path.join(root, directory)
prefix = 'lib.%s.' % directory.replace(os.sep, '.') package = __name__.rsplit('.', 1)[0]
prefix = '%s.%s.' % (package, directory.replace(os.sep, '.'))
for (_module_loader, name, _ispkg) in pkgutil.iter_modules([path], prefix=prefix): for (_module_loader, name, _ispkg) in pkgutil.iter_modules([path], prefix=prefix):
module_path = os.path.join(root, name[4:].replace('.', os.sep) + '.py') module_path = os.path.join(root, name[len(package) + 1:].replace('.', os.sep) + '.py')
load_module(module_path, name) load_module(module_path, name)
@ -824,7 +825,7 @@ def load_plugins(base_type, database): # type: (t.Type[C], t.Dict[str, t.Type[C
Load plugins of the specified type and track them in the specified database. Load plugins of the specified type and track them in the specified database.
Only plugins which have already been imported will be loaded. Only plugins which have already been imported will be loaded.
""" """
plugins = dict((sc.__module__.split('.')[2], sc) for sc in get_subclasses(base_type)) # type: t.Dict[str, t.Type[C]] plugins = dict((sc.__module__.rsplit('.', 1)[1], sc) for sc in get_subclasses(base_type)) # type: t.Dict[str, t.Type[C]]
for plugin in plugins: for plugin in plugins:
database[plugin] = plugins[plugin] database[plugin] = plugins[plugin]
@ -832,6 +833,9 @@ def load_plugins(base_type, database): # type: (t.Type[C], t.Dict[str, t.Type[C
def load_module(path, name): # type: (str, str) -> None def load_module(path, name): # type: (str, str) -> None
"""Load a Python module using the given name and path.""" """Load a Python module using the given name and path."""
if name in sys.modules:
return
if sys.version_info >= (3, 4): if sys.version_info >= (3, 4):
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
import importlib.util import importlib.util

@ -169,8 +169,8 @@ def get_coverage_environment(args, target_name, version, temp_path, module_cover
coverage_file = '' coverage_file = ''
# Enable code coverage collection on local Python programs (this does not include Ansible modules). # Enable code coverage collection on local Python programs (this does not include Ansible modules).
# Used by the injectors in test/runner/injector/ to support code coverage. # Used by the injectors to support code coverage.
# Used by unit tests in test/units/conftest.py to support code coverage. # Used by the pytest unit test plugin to support code coverage.
# The COVERAGE_FILE variable is also used directly by the 'coverage' module. # The COVERAGE_FILE variable is also used directly by the 'coverage' module.
env = dict( env = dict(
COVERAGE_CONF=config_file, COVERAGE_CONF=config_file,

@ -6,6 +6,11 @@ import os
import subprocess import subprocess
import pytest import pytest
from lib.util import (
to_text,
to_bytes,
)
from lib.diff import ( from lib.diff import (
parse_diff, parse_diff,
FileDiff, FileDiff,
@ -19,18 +24,18 @@ def get_diff(base, head=None):
:rtype: list[str] :rtype: list[str]
""" """
if not head or head == 'HEAD': if not head or head == 'HEAD':
head = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip() head = to_text(subprocess.check_output(['git', 'rev-parse', 'HEAD'])).strip()
cache = '/tmp/git-diff-cache-%s-%s.log' % (base, head) cache = '/tmp/git-diff-cache-%s-%s.log' % (base, head)
if os.path.exists(cache): if os.path.exists(cache):
with open(cache, 'r') as cache_fd: with open(cache, 'rb') as cache_fd:
lines = cache_fd.read().splitlines() lines = to_text(cache_fd.read()).splitlines()
else: else:
lines = subprocess.check_output(['git', 'diff', base, head]).splitlines() lines = to_text(subprocess.check_output(['git', 'diff', base, head]), errors='replace').splitlines()
with open(cache, 'w') as cache_fd: with open(cache, 'wb') as cache_fd:
cache_fd.write('\n'.join(lines)) cache_fd.write(to_bytes('\n'.join(lines)))
assert lines assert lines

@ -1,7 +1,8 @@
{ {
"all_targets": true, "all_targets": true,
"extensions": [ "ignore_self": true,
".py" "extensions": [
], ".py"
"output": "path-message" ],
"output": "path-message"
} }

@ -70,9 +70,6 @@ def get_files_with_bundled_metadata(paths):
with_metadata = set() with_metadata = set()
for path in paths: for path in paths:
if path == 'test/sanity/code-smell/update-bundled.py':
continue
with open(path, 'rb') as f: with open(path, 'rb') as f:
body = f.read() body = f.read()

@ -7914,8 +7914,6 @@ test/units/plugins/shell/test_cmd.py metaclass-boilerplate
test/units/plugins/shell/test_powershell.py future-import-boilerplate test/units/plugins/shell/test_powershell.py future-import-boilerplate
test/units/plugins/shell/test_powershell.py metaclass-boilerplate test/units/plugins/shell/test_powershell.py metaclass-boilerplate
test/units/plugins/test_plugins.py pylint:blacklisted-name test/units/plugins/test_plugins.py pylint:blacklisted-name
test/units/pytest/plugins/ansible_pytest_collections.py metaclass-boilerplate
test/units/pytest/plugins/ansible_pytest_coverage.py metaclass-boilerplate
test/units/template/test_templar.py pylint:blacklisted-name test/units/template/test_templar.py pylint:blacklisted-name
test/units/test_constants.py future-import-boilerplate test/units/test_constants.py future-import-boilerplate
test/units/test_context.py future-import-boilerplate test/units/test_context.py future-import-boilerplate

@ -38,8 +38,6 @@ class AnsibleTextIOWrapper(TextIOWrapper):
def find_executable(executable, cwd=None, path=None): def find_executable(executable, cwd=None, path=None):
"""Finds the full path to the executable specified""" """Finds the full path to the executable specified"""
# This is mostly a copy from test/runner/lib/util.py. Should be removed once validate-modules has been integrated
# into ansible-test
match = None match = None
real_cwd = os.getcwd() real_cwd = os.getcwd()

@ -1,6 +1,6 @@
"""Enable unit testing of Ansible collections.""" """Enable unit testing of Ansible collections."""
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os import os
import sys import sys
@ -10,6 +10,7 @@ ANSIBLE_COLLECTIONS_PATH = os.path.join(os.environ['ANSIBLE_COLLECTIONS_PATHS'],
def collection_pypkgpath(self): def collection_pypkgpath(self):
"""Configure the Python package path so that pytest can find our collections."""
for parent in self.parts(reverse=True): for parent in self.parts(reverse=True):
if str(parent) == ANSIBLE_COLLECTIONS_PATH: if str(parent) == ANSIBLE_COLLECTIONS_PATH:
return parent return parent
@ -18,13 +19,16 @@ def collection_pypkgpath(self):
def pytest_configure(): def pytest_configure():
"""Configure this pytest plugin."""
from ansible.utils.collection_loader import AnsibleCollectionLoader from ansible.utils.collection_loader import AnsibleCollectionLoader
# allow unit tests to import code from collections # allow unit tests to import code from collections
sys.meta_path.insert(0, AnsibleCollectionLoader()) sys.meta_path.insert(0, AnsibleCollectionLoader())
# noinspection PyProtectedMember
import py._path.local import py._path.local
# force collections unit tests to be loaded with the ansible_collections namespace # force collections unit tests to be loaded with the ansible_collections namespace
# original idea from https://stackoverflow.com/questions/50174130/how-do-i-pytest-a-project-using-pep-420-namespace-packages/50175552#50175552 # original idea from https://stackoverflow.com/questions/50174130/how-do-i-pytest-a-project-using-pep-420-namespace-packages/50175552#50175552
py._path.local.LocalPath.pypkgpath = collection_pypkgpath # noinspection PyProtectedMember
py._path.local.LocalPath.pypkgpath = collection_pypkgpath # pylint: disable=protected-access

@ -1,15 +1,17 @@
"""Monkey patch os._exit when running under coverage so we don't lose coverage data in forks, such as with `pytest --boxed`.""" """Monkey patch os._exit when running under coverage so we don't lose coverage data in forks, such as with `pytest --boxed`."""
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
def pytest_configure(): def pytest_configure():
"""Configure this pytest plugin."""
try: try:
import coverage import coverage
except ImportError: except ImportError:
coverage = None coverage = None
try: try:
test = coverage.Coverage coverage.Coverage
except AttributeError: except AttributeError:
coverage = None coverage = None
@ -41,7 +43,8 @@ def pytest_configure():
else: else:
cov = None cov = None
os_exit = os._exit # noinspection PyProtectedMember
os_exit = os._exit # pylint: disable=protected-access
def coverage_exit(*args, **kwargs): def coverage_exit(*args, **kwargs):
for instance in coverage_instances: for instance in coverage_instances:
@ -50,7 +53,7 @@ def pytest_configure():
os_exit(*args, **kwargs) os_exit(*args, **kwargs)
os._exit = coverage_exit os._exit = coverage_exit # pylint: disable=protected-access
if cov: if cov:
cov.start() cov.start()

Loading…
Cancel
Save