Convert ansible-test compile into a sanity test.
This commit is contained in:
parent
0ce8d389a4
commit
7abdab6c9e
13 changed files with 166 additions and 198 deletions
4
docs/docsite/rst/dev_guide/testing/sanity/compile.rst
Normal file
4
docs/docsite/rst/dev_guide/testing/sanity/compile.rst
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
Sanity Tests » compile
|
||||||
|
======================
|
||||||
|
|
||||||
|
See :doc:`../../testing_compile` for more information.
|
|
@ -15,34 +15,36 @@ Compile tests check source files for valid syntax on all supported python versio
|
||||||
- 3.5
|
- 3.5
|
||||||
- 3.6
|
- 3.6
|
||||||
|
|
||||||
|
NOTE: In Ansible 2.4 and earlier the compile test was provided by a dedicated sub-command ``ansible-test compile`` instead of a sanity test using ``ansible-test sanity --test compile``.
|
||||||
|
|
||||||
Running compile tests locally
|
Running compile tests locally
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
Unit tests can be run across the whole code base by doing:
|
Compile tests can be run across the whole code base by doing:
|
||||||
|
|
||||||
.. code:: shell
|
.. code:: shell
|
||||||
|
|
||||||
cd /path/to/ansible/source
|
cd /path/to/ansible/source
|
||||||
source hacking/env-setup
|
source hacking/env-setup
|
||||||
ansible-test compile
|
ansible-test sanity --test compile
|
||||||
|
|
||||||
Against a single file by doing:
|
Against a single file by doing:
|
||||||
|
|
||||||
.. code:: shell
|
.. code:: shell
|
||||||
|
|
||||||
ansible-test compile lineinfile
|
ansible-test sanity --test compile lineinfile
|
||||||
|
|
||||||
Or against a specific Python version by doing:
|
Or against a specific Python version by doing:
|
||||||
|
|
||||||
.. code:: shell
|
.. code:: shell
|
||||||
|
|
||||||
ansible-test compile --python 2.7 lineinfile
|
ansible-test sanity --test compile --python 2.7 lineinfile
|
||||||
|
|
||||||
For advanced usage see the help:
|
For advanced usage see the help:
|
||||||
|
|
||||||
.. code:: shell
|
.. code:: shell
|
||||||
|
|
||||||
ansible-test units --help
|
ansible-test sanity --help
|
||||||
|
|
||||||
|
|
||||||
Installing dependencies
|
Installing dependencies
|
||||||
|
@ -54,7 +56,7 @@ The dependencies can be installed using the ``--requirements`` argument. For exa
|
||||||
|
|
||||||
.. code:: shell
|
.. code:: shell
|
||||||
|
|
||||||
ansible-test units --requirements lineinfile
|
ansible-test sanity --test compile --requirements lineinfile
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,4 +66,4 @@ The full list of requirements can be found at `test/runner/requirements <https:/
|
||||||
Extending compile tests
|
Extending compile tests
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
If you believe changes are needed to the Compile tests please add a comment on the `Testing Working Group Agenda <https://github.com/ansible/community/blob/master/meetings/README.md>`_ so it can be discussed.
|
If you believe changes are needed to the compile tests please add a comment on the `Testing Working Group Agenda <https://github.com/ansible/community/blob/master/meetings/README.md>`_ so it can be discussed.
|
||||||
|
|
|
@ -8,7 +8,8 @@ matrix:
|
||||||
exclude:
|
exclude:
|
||||||
- env: T=none
|
- env: T=none
|
||||||
include:
|
include:
|
||||||
- env: T=other
|
- env: T=sanity/1
|
||||||
|
- env: T=sanity/2
|
||||||
|
|
||||||
- env: T=units/2.6
|
- env: T=units/2.6
|
||||||
- env: T=units/2.7
|
- env: T=units/2.7
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
.PHONY: all compile sanity units
|
.PHONY: all sanity units
|
||||||
|
|
||||||
all: compile sanity units
|
all: sanity units
|
||||||
|
|
||||||
compile:
|
|
||||||
./ansible-test compile test/runner/ ${TEST_FLAGS}
|
|
||||||
|
|
||||||
sanity:
|
sanity:
|
||||||
./ansible-test sanity test/runner/ ${TEST_FLAGS}
|
./ansible-test sanity test/runner/ ${TEST_FLAGS}
|
||||||
|
|
|
@ -44,7 +44,6 @@ def categorize_changes(args, paths, verbose_command=None):
|
||||||
|
|
||||||
commands = {
|
commands = {
|
||||||
'sanity': set(),
|
'sanity': set(),
|
||||||
'compile': set(),
|
|
||||||
'units': set(),
|
'units': set(),
|
||||||
'integration': set(),
|
'integration': set(),
|
||||||
'windows-integration': set(),
|
'windows-integration': set(),
|
||||||
|
@ -128,7 +127,6 @@ class PathMapper(object):
|
||||||
self.sanity_targets = list(walk_sanity_targets())
|
self.sanity_targets = list(walk_sanity_targets())
|
||||||
self.powershell_targets = [t for t in self.sanity_targets if os.path.splitext(t.path)[1] == '.ps1']
|
self.powershell_targets = [t for t in self.sanity_targets if os.path.splitext(t.path)[1] == '.ps1']
|
||||||
|
|
||||||
self.compile_paths = set(t.path for t in self.compile_targets)
|
|
||||||
self.units_modules = set(t.module for t in self.units_targets if t.module)
|
self.units_modules = set(t.module for t in self.units_targets if t.module)
|
||||||
self.units_paths = set(a for t in self.units_targets for a in t.aliases)
|
self.units_paths = set(a for t in self.units_targets for a in t.aliases)
|
||||||
self.sanity_paths = set(t.path for t in self.sanity_targets)
|
self.sanity_paths = set(t.path for t in self.sanity_targets)
|
||||||
|
@ -228,10 +226,6 @@ class PathMapper(object):
|
||||||
if result is None:
|
if result is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# compile path if eligible
|
|
||||||
if path in self.compile_paths:
|
|
||||||
result['compile'] = path
|
|
||||||
|
|
||||||
# run sanity on path unless result specified otherwise
|
# run sanity on path unless result specified otherwise
|
||||||
if path in self.sanity_paths and 'sanity' not in result:
|
if path in self.sanity_paths and 'sanity' not in result:
|
||||||
result['sanity'] = path
|
result['sanity'] = path
|
||||||
|
@ -393,11 +387,6 @@ class PathMapper(object):
|
||||||
if path.startswith('test/cache/'):
|
if path.startswith('test/cache/'):
|
||||||
return minimal
|
return minimal
|
||||||
|
|
||||||
if path.startswith('test/compile/'):
|
|
||||||
return {
|
|
||||||
'compile': 'all',
|
|
||||||
}
|
|
||||||
|
|
||||||
if path.startswith('test/results/'):
|
if path.startswith('test/results/'):
|
||||||
return minimal
|
return minimal
|
||||||
|
|
||||||
|
@ -544,7 +533,32 @@ class PathMapper(object):
|
||||||
|
|
||||||
return all_tests(self.args) # test infrastructure, run all tests
|
return all_tests(self.args) # test infrastructure, run all tests
|
||||||
|
|
||||||
|
if path.startswith('test/utils/shippable/tools/'):
|
||||||
|
return minimal # not used by tests
|
||||||
|
|
||||||
if path.startswith('test/utils/shippable/'):
|
if path.startswith('test/utils/shippable/'):
|
||||||
|
if dirname == 'test/utils/shippable':
|
||||||
|
test_map = {
|
||||||
|
'cloud.sh': 'integration:cloud/',
|
||||||
|
'freebsd.sh': 'integration:all',
|
||||||
|
'linux.sh': 'integration:all',
|
||||||
|
'network.sh': 'network-integration:all',
|
||||||
|
'osx.sh': 'integration:all',
|
||||||
|
'rhel.sh': 'integration:all',
|
||||||
|
'sanity.sh': 'sanity:all',
|
||||||
|
'units.sh': 'units:all',
|
||||||
|
'windows.sh': 'windows-integration:all',
|
||||||
|
}
|
||||||
|
|
||||||
|
test_match = test_map.get(filename)
|
||||||
|
|
||||||
|
if test_match:
|
||||||
|
test_command, test_target = test_match.split(':')
|
||||||
|
|
||||||
|
return {
|
||||||
|
test_command: test_target,
|
||||||
|
}
|
||||||
|
|
||||||
return all_tests(self.args) # test infrastructure, run all tests
|
return all_tests(self.args) # test infrastructure, run all tests
|
||||||
|
|
||||||
if path.startswith('test/utils/'):
|
if path.startswith('test/utils/'):
|
||||||
|
@ -602,7 +616,6 @@ def all_tests(args, force=False):
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'sanity': 'all',
|
'sanity': 'all',
|
||||||
'compile': 'all',
|
|
||||||
'units': 'all',
|
'units': 'all',
|
||||||
'integration': integration_all_target,
|
'integration': integration_all_target,
|
||||||
'windows-integration': integration_all_target,
|
'windows-integration': integration_all_target,
|
||||||
|
|
|
@ -206,15 +206,6 @@ class UnitsConfig(TestConfig):
|
||||||
self.collect_only = args.collect_only # type: bool
|
self.collect_only = args.collect_only # type: bool
|
||||||
|
|
||||||
|
|
||||||
class CompileConfig(TestConfig):
|
|
||||||
"""Configuration for the compile command."""
|
|
||||||
def __init__(self, args):
|
|
||||||
"""
|
|
||||||
:type args: any
|
|
||||||
"""
|
|
||||||
super(CompileConfig, self).__init__(args, 'compile')
|
|
||||||
|
|
||||||
|
|
||||||
class CoverageConfig(EnvironmentConfig):
|
class CoverageConfig(EnvironmentConfig):
|
||||||
"""Configuration for the coverage command."""
|
"""Configuration for the coverage command."""
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
|
|
|
@ -63,7 +63,6 @@ from lib.target import (
|
||||||
walk_network_integration_targets,
|
walk_network_integration_targets,
|
||||||
walk_windows_integration_targets,
|
walk_windows_integration_targets,
|
||||||
walk_units_targets,
|
walk_units_targets,
|
||||||
walk_compile_targets,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from lib.changes import (
|
from lib.changes import (
|
||||||
|
@ -82,7 +81,6 @@ from lib.classification import (
|
||||||
from lib.config import (
|
from lib.config import (
|
||||||
TestConfig,
|
TestConfig,
|
||||||
EnvironmentConfig,
|
EnvironmentConfig,
|
||||||
CompileConfig,
|
|
||||||
IntegrationConfig,
|
IntegrationConfig,
|
||||||
NetworkIntegrationConfig,
|
NetworkIntegrationConfig,
|
||||||
PosixIntegrationConfig,
|
PosixIntegrationConfig,
|
||||||
|
@ -91,13 +89,6 @@ from lib.config import (
|
||||||
WindowsIntegrationConfig,
|
WindowsIntegrationConfig,
|
||||||
)
|
)
|
||||||
|
|
||||||
from lib.test import (
|
|
||||||
TestMessage,
|
|
||||||
TestSuccess,
|
|
||||||
TestFailure,
|
|
||||||
TestSkipped,
|
|
||||||
)
|
|
||||||
|
|
||||||
SUPPORTED_PYTHON_VERSIONS = (
|
SUPPORTED_PYTHON_VERSIONS = (
|
||||||
'2.6',
|
'2.6',
|
||||||
'2.7',
|
'2.7',
|
||||||
|
@ -106,8 +97,6 @@ SUPPORTED_PYTHON_VERSIONS = (
|
||||||
'3.7',
|
'3.7',
|
||||||
)
|
)
|
||||||
|
|
||||||
COMPILE_PYTHON_VERSIONS = SUPPORTED_PYTHON_VERSIONS
|
|
||||||
|
|
||||||
|
|
||||||
def check_startup():
|
def check_startup():
|
||||||
"""Checks to perform at startup before running commands."""
|
"""Checks to perform at startup before running commands."""
|
||||||
|
@ -1024,114 +1013,6 @@ def command_units(args):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def command_compile(args):
|
|
||||||
"""
|
|
||||||
:type args: CompileConfig
|
|
||||||
"""
|
|
||||||
changes = get_changes_filter(args)
|
|
||||||
require = (args.require or []) + changes
|
|
||||||
include, exclude = walk_external_targets(walk_compile_targets(), args.include, args.exclude, require)
|
|
||||||
|
|
||||||
if not include:
|
|
||||||
raise AllTargetsSkipped()
|
|
||||||
|
|
||||||
if args.delegate:
|
|
||||||
raise Delegate(require=changes)
|
|
||||||
|
|
||||||
install_command_requirements(args)
|
|
||||||
|
|
||||||
total = 0
|
|
||||||
failed = []
|
|
||||||
|
|
||||||
for version in COMPILE_PYTHON_VERSIONS:
|
|
||||||
# run all versions unless version given, in which case run only that version
|
|
||||||
if args.python and version != args.python_version:
|
|
||||||
continue
|
|
||||||
|
|
||||||
display.info('Compile with Python %s' % version)
|
|
||||||
|
|
||||||
result = compile_version(args, version, include, exclude)
|
|
||||||
result.write(args)
|
|
||||||
|
|
||||||
total += 1
|
|
||||||
|
|
||||||
if isinstance(result, TestFailure):
|
|
||||||
failed.append('compile --python %s' % version)
|
|
||||||
|
|
||||||
if failed:
|
|
||||||
message = 'The %d compile test(s) listed below (out of %d) failed. See error output above for details.\n%s' % (
|
|
||||||
len(failed), total, '\n'.join(failed))
|
|
||||||
|
|
||||||
if args.failure_ok:
|
|
||||||
display.error(message)
|
|
||||||
else:
|
|
||||||
raise ApplicationError(message)
|
|
||||||
|
|
||||||
|
|
||||||
def compile_version(args, python_version, include, exclude):
|
|
||||||
"""
|
|
||||||
:type args: CompileConfig
|
|
||||||
:type python_version: str
|
|
||||||
:type include: tuple[CompletionTarget]
|
|
||||||
:type exclude: tuple[CompletionTarget]
|
|
||||||
:rtype: TestResult
|
|
||||||
"""
|
|
||||||
command = 'compile'
|
|
||||||
test = ''
|
|
||||||
|
|
||||||
# optional list of regex patterns to exclude from tests
|
|
||||||
skip_file = 'test/compile/python%s-skip.txt' % python_version
|
|
||||||
|
|
||||||
if os.path.exists(skip_file):
|
|
||||||
with open(skip_file, 'r') as skip_fd:
|
|
||||||
skip_paths = skip_fd.read().splitlines()
|
|
||||||
else:
|
|
||||||
skip_paths = []
|
|
||||||
|
|
||||||
# augment file exclusions
|
|
||||||
skip_paths += [e.path for e in exclude]
|
|
||||||
|
|
||||||
skip_paths = sorted(skip_paths)
|
|
||||||
|
|
||||||
python = 'python%s' % python_version
|
|
||||||
cmd = [python, 'test/compile/compile.py']
|
|
||||||
|
|
||||||
if skip_paths:
|
|
||||||
cmd += ['-x', '|'.join(skip_paths)]
|
|
||||||
|
|
||||||
cmd += [target.path if target.path == '.' else './%s' % target.path for target in include]
|
|
||||||
|
|
||||||
try:
|
|
||||||
stdout, stderr = run_command(args, cmd, capture=True)
|
|
||||||
status = 0
|
|
||||||
except SubprocessError as ex:
|
|
||||||
stdout = ex.stdout
|
|
||||||
stderr = ex.stderr
|
|
||||||
status = ex.status
|
|
||||||
|
|
||||||
if stderr:
|
|
||||||
raise SubprocessError(cmd=cmd, status=status, stderr=stderr, stdout=stdout)
|
|
||||||
|
|
||||||
if args.explain:
|
|
||||||
return TestSkipped(command, test, python_version=python_version)
|
|
||||||
|
|
||||||
pattern = r'^(?P<path>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+): (?P<message>.*)$'
|
|
||||||
|
|
||||||
results = [re.search(pattern, line).groupdict() for line in stdout.splitlines()]
|
|
||||||
|
|
||||||
results = [TestMessage(
|
|
||||||
message=r['message'],
|
|
||||||
path=r['path'].replace('./', ''),
|
|
||||||
line=int(r['line']),
|
|
||||||
column=int(r['column']),
|
|
||||||
) for r in results]
|
|
||||||
|
|
||||||
if results:
|
|
||||||
return TestFailure(command, test, messages=results, python_version=python_version)
|
|
||||||
|
|
||||||
return TestSuccess(command, test, python_version=python_version)
|
|
||||||
|
|
||||||
|
|
||||||
def get_changes_filter(args):
|
def get_changes_filter(args):
|
||||||
"""
|
"""
|
||||||
:type args: TestConfig
|
:type args: TestConfig
|
||||||
|
|
98
test/runner/lib/sanity/compile.py
Normal file
98
test/runner/lib/sanity/compile.py
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
"""Sanity test for proper python syntax."""
|
||||||
|
from __future__ import absolute_import, print_function
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
from lib.sanity import (
|
||||||
|
SanityMultipleVersion,
|
||||||
|
SanityMessage,
|
||||||
|
SanityFailure,
|
||||||
|
SanitySuccess,
|
||||||
|
SanitySkipped,
|
||||||
|
)
|
||||||
|
|
||||||
|
from lib.util import (
|
||||||
|
SubprocessError,
|
||||||
|
run_command,
|
||||||
|
)
|
||||||
|
|
||||||
|
from lib.config import (
|
||||||
|
SanityConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
from lib.test import (
|
||||||
|
calculate_best_confidence,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CompileTest(SanityMultipleVersion):
|
||||||
|
"""Sanity test for proper python syntax."""
|
||||||
|
def test(self, args, targets, python_version):
|
||||||
|
"""
|
||||||
|
:type args: SanityConfig
|
||||||
|
:type targets: SanityTargets
|
||||||
|
:type python_version: str
|
||||||
|
:rtype: SanityResult
|
||||||
|
"""
|
||||||
|
# optional list of regex patterns to exclude from tests
|
||||||
|
skip_file = 'test/sanity/compile/python%s-skip.txt' % python_version
|
||||||
|
|
||||||
|
if os.path.exists(skip_file):
|
||||||
|
with open(skip_file, 'r') as skip_fd:
|
||||||
|
skip_paths = skip_fd.read().splitlines()
|
||||||
|
else:
|
||||||
|
skip_paths = []
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
if not paths:
|
||||||
|
return SanitySkipped(self.name, python_version=python_version)
|
||||||
|
|
||||||
|
cmd = ['python%s' % python_version, 'test/sanity/compile/compile.py'] + paths
|
||||||
|
|
||||||
|
try:
|
||||||
|
stdout, stderr = run_command(args, cmd, capture=True)
|
||||||
|
status = 0
|
||||||
|
except SubprocessError as ex:
|
||||||
|
stdout = ex.stdout
|
||||||
|
stderr = ex.stderr
|
||||||
|
status = ex.status
|
||||||
|
|
||||||
|
if stderr:
|
||||||
|
raise SubprocessError(cmd=cmd, status=status, stderr=stderr, stdout=stdout)
|
||||||
|
|
||||||
|
if args.explain:
|
||||||
|
return SanitySuccess(self.name, python_version=python_version)
|
||||||
|
|
||||||
|
pattern = r'^(?P<path>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+): (?P<message>.*)$'
|
||||||
|
|
||||||
|
results = [re.search(pattern, line).groupdict() for line in stdout.splitlines()]
|
||||||
|
|
||||||
|
results = [SanityMessage(
|
||||||
|
message=r['message'],
|
||||||
|
path=r['path'].replace('./', ''),
|
||||||
|
line=int(r['line']),
|
||||||
|
column=int(r['column']),
|
||||||
|
) for r in results]
|
||||||
|
|
||||||
|
line = 0
|
||||||
|
|
||||||
|
for path in skip_paths:
|
||||||
|
line += 1
|
||||||
|
|
||||||
|
if not os.path.exists(path):
|
||||||
|
# Keep files out of the list which no longer exist in the repo.
|
||||||
|
results.append(SanityMessage(
|
||||||
|
code='A101',
|
||||||
|
message='Remove "%s" since it does not exist' % path,
|
||||||
|
path=skip_file,
|
||||||
|
line=line,
|
||||||
|
column=1,
|
||||||
|
confidence=calculate_best_confidence(((skip_file, line), (path, 0)), args.metadata) if args.metadata.changes else None,
|
||||||
|
))
|
||||||
|
|
||||||
|
if results:
|
||||||
|
return SanityFailure(self.name, messages=results, python_version=python_version)
|
||||||
|
|
||||||
|
return SanitySuccess(self.name, python_version=python_version)
|
|
@ -25,10 +25,8 @@ from lib.executor import (
|
||||||
command_network_integration,
|
command_network_integration,
|
||||||
command_windows_integration,
|
command_windows_integration,
|
||||||
command_units,
|
command_units,
|
||||||
command_compile,
|
|
||||||
command_shell,
|
command_shell,
|
||||||
SUPPORTED_PYTHON_VERSIONS,
|
SUPPORTED_PYTHON_VERSIONS,
|
||||||
COMPILE_PYTHON_VERSIONS,
|
|
||||||
ApplicationWarning,
|
ApplicationWarning,
|
||||||
Delegate,
|
Delegate,
|
||||||
generate_pip_install,
|
generate_pip_install,
|
||||||
|
@ -42,7 +40,6 @@ from lib.config import (
|
||||||
NetworkIntegrationConfig,
|
NetworkIntegrationConfig,
|
||||||
SanityConfig,
|
SanityConfig,
|
||||||
UnitsConfig,
|
UnitsConfig,
|
||||||
CompileConfig,
|
|
||||||
ShellConfig,
|
ShellConfig,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -58,7 +55,6 @@ from lib.target import (
|
||||||
walk_network_integration_targets,
|
walk_network_integration_targets,
|
||||||
walk_windows_integration_targets,
|
walk_windows_integration_targets,
|
||||||
walk_units_targets,
|
walk_units_targets,
|
||||||
walk_compile_targets,
|
|
||||||
walk_sanity_targets,
|
walk_sanity_targets,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -302,22 +298,6 @@ def parse_args():
|
||||||
|
|
||||||
add_extra_docker_options(units, integration=False)
|
add_extra_docker_options(units, integration=False)
|
||||||
|
|
||||||
compiler = subparsers.add_parser('compile',
|
|
||||||
parents=[test],
|
|
||||||
help='compile tests')
|
|
||||||
|
|
||||||
compiler.set_defaults(func=command_compile,
|
|
||||||
targets=walk_compile_targets,
|
|
||||||
config=CompileConfig)
|
|
||||||
|
|
||||||
compiler.add_argument('--python',
|
|
||||||
metavar='VERSION',
|
|
||||||
choices=COMPILE_PYTHON_VERSIONS + ('default',),
|
|
||||||
help='python version: %s' % ', '.join(COMPILE_PYTHON_VERSIONS))
|
|
||||||
|
|
||||||
add_lint(compiler)
|
|
||||||
add_extra_docker_options(compiler, integration=False)
|
|
||||||
|
|
||||||
sanity = subparsers.add_parser('sanity',
|
sanity = subparsers.add_parser('sanity',
|
||||||
parents=[test],
|
parents=[test],
|
||||||
help='sanity tests')
|
help='sanity tests')
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash -eux
|
|
||||||
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
shippable.py
|
|
||||||
|
|
||||||
echo '{"verified": false, "results": []}' > test/results/bot/ansible-test-failure.json
|
|
||||||
|
|
||||||
if [ "${BASE_BRANCH:-}" ]; then
|
|
||||||
base_branch="origin/${BASE_BRANCH}"
|
|
||||||
else
|
|
||||||
base_branch=""
|
|
||||||
fi
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
ansible-test compile --failure-ok --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} --docker default
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
ansible-test sanity --failure-ok --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} --docker default --docker-keep-git --base-branch "${base_branch}"
|
|
||||||
|
|
||||||
rm test/results/bot/ansible-test-failure.json
|
|
||||||
|
|
||||||
if find test/results/bot/ -mindepth 1 -name '.*' -prune -o -print -quit | grep -q .; then
|
|
||||||
echo "One or more of the above tests reported at least one failure."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
26
test/utils/shippable/sanity.sh
Executable file
26
test/utils/shippable/sanity.sh
Executable file
|
@ -0,0 +1,26 @@
|
||||||
|
#!/bin/bash -eux
|
||||||
|
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
declare -a args
|
||||||
|
IFS='/:' read -ra args <<< "$1"
|
||||||
|
|
||||||
|
group="${args[1]}"
|
||||||
|
|
||||||
|
shippable.py
|
||||||
|
|
||||||
|
if [ "${BASE_BRANCH:-}" ]; then
|
||||||
|
base_branch="origin/${BASE_BRANCH}"
|
||||||
|
else
|
||||||
|
base_branch=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${group}" in
|
||||||
|
1) options=(--skip-test pylint) ;;
|
||||||
|
2) options=(--test pylint) ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
ansible-test sanity --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \
|
||||||
|
--docker --docker-keep-git --base-branch "${base_branch}" \
|
||||||
|
"${options[@]}"
|
1
tox.ini
1
tox.ini
|
@ -12,7 +12,6 @@ commands =
|
||||||
# ansible-test directly and use the --tox and --python options.
|
# ansible-test directly and use the --tox and --python options.
|
||||||
# The commands below are provided as a convenience for those who
|
# The commands below are provided as a convenience for those who
|
||||||
# prefer to run tox directly instead of through ansible-test.
|
# prefer to run tox directly instead of through ansible-test.
|
||||||
{toxinidir}/test/runner/ansible-test compile --python default -v
|
|
||||||
{toxinidir}/test/runner/ansible-test sanity --python default -v
|
{toxinidir}/test/runner/ansible-test sanity --python default -v
|
||||||
{toxinidir}/test/runner/ansible-test units --python default -v
|
{toxinidir}/test/runner/ansible-test units --python default -v
|
||||||
passenv =
|
passenv =
|
||||||
|
|
Loading…
Reference in a new issue