Compare commits

..

No commits in common. "main" and "5.2.1" have entirely different histories.
main ... 5.2.1

35 changed files with 765 additions and 331 deletions

View File

@ -37,116 +37,293 @@ variables:
- name: coverageBranches
value: main
- name: entryPoint
value: tests/utils/shippable/nox.sh
- name: prepareEntryPoint
value: tests/utils/shippable/nox-prepare.sh
value: tests/utils/shippable/shippable.sh
- name: fetchDepth
value: 0
resources:
containers:
- container: default
image: quay.io/ansible/azure-pipelines-test-container:8.0.0
image: quay.io/ansible/azure-pipelines-test-container:7.0.0
pool: Standard
stages:
- stage: remote_2_19
displayName: Remote 2.19
### Sanity & units
- stage: Ansible_devel
displayName: Sanity & Units devel
dependsOn: []
variables:
entryPoint: tests/utils/shippable/nox.sh
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: Ubuntu 22.04 + group 1
test: ansible-test-integration-2.19-ubuntu-22.04-azp-1
- name: Ubuntu 22.04 + group 2
test: ansible-test-integration-2.19-ubuntu-22.04-azp-2
- name: Ubuntu 22.04 + group 3
test: ansible-test-integration-2.19-ubuntu-22.04-azp-3
- name: Ubuntu 22.04 + group 4
test: ansible-test-integration-2.19-ubuntu-22.04-azp-4
- name: Ubuntu 22.04 + group 5
test: ansible-test-integration-2.19-ubuntu-22.04-azp-5
- stage: remote_2_20
displayName: Remote 2.20
- name: Sanity
test: 'devel/sanity/1'
- name: Units
test: 'devel/units/1'
- stage: Ansible_2_21
displayName: Sanity & Units 2.21
dependsOn: []
variables:
entryPoint: tests/utils/shippable/nox.sh
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: RHEL 9.7 + group 1
test: ansible-test-integration-2.20-rhel-9.7-azp-1
- name: RHEL 9.7 + group 2
test: ansible-test-integration-2.20-rhel-9.7-azp-2
- name: RHEL 9.7 + group 3
test: ansible-test-integration-2.20-rhel-9.7-azp-3
- name: RHEL 9.7 + group 4
test: ansible-test-integration-2.20-rhel-9.7-azp-4
- name: RHEL 9.7 + group 5
test: ansible-test-integration-2.20-rhel-9.7-azp-5
- stage: remote_2_21
displayName: Remote 2.21
- name: Sanity
test: '2.21/sanity/1'
- name: Units
test: '2.21/units/1'
- stage: Ansible_2_20
displayName: Sanity & Units 2.20
dependsOn: []
variables:
entryPoint: tests/utils/shippable/nox.sh
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: RHEL 10.1 + group 1
test: ansible-test-integration-2.21-rhel-10.1-azp-1
- name: RHEL 10.1 + group 2
test: ansible-test-integration-2.21-rhel-10.1-azp-2
- name: RHEL 10.1 + group 3
test: ansible-test-integration-2.21-rhel-10.1-azp-3
- name: RHEL 10.1 + group 4
test: ansible-test-integration-2.21-rhel-10.1-azp-4
- name: RHEL 10.1 + group 5
test: ansible-test-integration-2.21-rhel-10.1-azp-5
- name: Sanity
test: '2.20/sanity/1'
- name: Units
test: '2.20/units/1'
- stage: Ansible_2_19
displayName: Sanity & Units 2.19
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: Sanity
test: '2.19/sanity/1'
- name: Units
test: '2.19/units/1'
- stage: Ansible_2_18
displayName: Sanity & Units 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: Sanity
test: '2.18/sanity/1'
- name: Units
test: '2.18/units/1'
- stage: remote_devel
### Docker
- stage: Docker_devel
displayName: Docker devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux/{0}
targets:
- name: Fedora 44
test: fedora44
- name: Ubuntu 26.04
test: ubuntu2604
- name: Ubuntu 24.04
test: ubuntu2404
- name: Alpine 3.23
test: alpine323
groups:
- 4
- 5
- stage: Docker_2_21
displayName: Docker 2.21
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.21/linux/{0}
targets:
- name: Fedora 43
test: fedora43
- name: Ubuntu 22.04
test: ubuntu2204
- name: Ubuntu 24.04
test: ubuntu2404
# - name: Alpine 3.23
# test: alpine323
groups:
- 4
- 5
- stage: Docker_2_20
displayName: Docker 2.20
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.20/linux/{0}
targets:
- name: Fedora 42
test: fedora42
- name: Alpine 3.22
test: alpine322
groups:
- 4
- 5
- stage: Docker_2_19
displayName: Docker 2.19
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.19/linux/{0}
targets:
- name: Fedora 41
test: fedora41
- name: Alpine 3.21
test: alpine321
groups:
- 4
- 5
- stage: Docker_2_18
displayName: Docker 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.18/linux/{0}
targets:
- name: Fedora 40
test: fedora40
- name: Ubuntu 22.04
test: ubuntu2204
- name: Alpine 3.20
test: alpine320
groups:
- 4
- 5
### Community Docker
- stage: Docker_community_devel
displayName: Docker (community images) devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux-community/{0}
targets:
- name: Debian 11 Bullseye
test: debian-bullseye/3.9
- name: Debian 12 Bookworm
test: debian-bookworm/3.11
- name: Debian 13 Trixie
test: debian-13-trixie/3.13
- name: ArchLinux
test: archlinux/3.14
groups:
- 4
- 5
### Remote
- stage: Remote_devel
displayName: Remote devel
dependsOn: []
variables:
entryPoint: tests/utils/shippable/nox.sh
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/{0}
targets:
- name: RHEL 10.1 + group 1 + sdk-dev-latest
test: ansible-test-integration-devel-rhel-10.1-azp-1
- name: RHEL 10.1 + group 2 + sdk-dev-latest
test: ansible-test-integration-devel-rhel-10.1-azp-2
- name: RHEL 10.1 + group 3 + sdk-dev-latest
test: ansible-test-integration-devel-rhel-10.1-azp-3
- name: RHEL 10.1 + group 4 + sdk-dev-latest
test: ansible-test-integration-devel-rhel-10.1-azp-4
- name: RHEL 10.1 + group 5 + sdk-dev-latest
test: ansible-test-integration-devel-rhel-10.1-azp-5
- name: RHEL 9.7 + group 1
test: ansible-test-integration-devel-rhel-9.7-azp-1
- name: RHEL 9.7 + group 2
test: ansible-test-integration-devel-rhel-9.7-azp-2
- name: RHEL 9.7 + group 3
test: ansible-test-integration-devel-rhel-9.7-azp-3
- name: RHEL 9.7 + group 4
test: ansible-test-integration-devel-rhel-9.7-azp-4
- name: RHEL 9.7 + group 5
test: ansible-test-integration-devel-rhel-9.7-azp-5
- name: RHEL 10.1 with Docker SDK, urllib3, requests from sources
test: rhel/10.1-dev-latest
- name: RHEL 9.7
test: rhel/9.7
# For some reason, Ubuntu 24.04 is *extremely* slower than RHEL 9.6
# - name: Ubuntu 24.04
# test: ubuntu/24.04
groups:
- 1
- 2
- 3
- 4
- 5
- stage: Remote_2_21
displayName: Remote 2.21
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.21/{0}
targets:
- name: RHEL 10.1
test: rhel/10.1
# - name: RHEL 9.7
# test: rhel/9.7
groups:
- 1
- 2
- 3
- 4
- 5
- stage: Remote_2_20
displayName: Remote 2.20
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.20/{0}
targets:
- name: RHEL 9.7
test: rhel/9.7
groups:
- 1
- 2
- 3
- 4
- 5
- stage: Remote_2_19
displayName: Remote 2.19
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.19/{0}
targets:
- name: Ubuntu 22.04
test: ubuntu/22.04
groups:
- 1
- 2
- 3
- 4
- 5
- stage: Remote_2_18
displayName: Remote 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.18/{0}
targets:
- name: RHEL 9.7
test: rhel/9.7
groups:
- 1
- 2
- 3
- 4
- 5
## Finally
- stage: Summary
condition: succeededOrFailed()
dependsOn:
- remote_2_19
- remote_2_20
- remote_2_21
- remote_devel
- Ansible_devel
- Ansible_2_21
- Ansible_2_20
- Ansible_2_19
- Ansible_2_18
- Remote_devel
- Remote_2_21
- Remote_2_20
- Remote_2_19
- Remote_2_18
- Docker_devel
- Docker_2_21
- Docker_2_20
- Docker_2_19
- Docker_2_18
- Docker_community_devel
jobs:
- template: templates/coverage.yml

View File

@ -1,10 +1,10 @@
#!/usr/bin/env bash
# Aggregate code coverage results for later processing.
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# Aggregate code coverage results for later processing.
set -o pipefail -eu
agent_temp_directory="$1"
@ -13,6 +13,10 @@ PATH="${PWD}/bin:${PATH}"
mkdir "${agent_temp_directory}/coverage/"
if [[ "$(ansible --version)" =~ \ 2\.9\. ]]; then
exit
fi
options=(--venv --venv-system-site-packages --color -v)
ansible-test coverage combine --group-by command --export "${agent_temp_directory}/coverage/" "${options[@]}"

View File

@ -11,7 +11,8 @@ Keep in mind that Azure Pipelines does not enforce unique job display names (onl
It is up to pipeline authors to avoid name collisions when deviating from the recommended format.
"""
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import re
@ -23,12 +24,12 @@ def main():
"""Main program entry point."""
source_directory = sys.argv[1]
if "/ansible_collections/" in os.getcwd():
if '/ansible_collections/' in os.getcwd():
output_path = "tests/output"
else:
output_path = "test/results"
destination_directory = os.path.join(output_path, "coverage")
destination_directory = os.path.join(output_path, 'coverage')
if not os.path.exists(destination_directory):
os.makedirs(destination_directory)
@ -37,27 +38,27 @@ def main():
count = 0
for name in os.listdir(source_directory):
match = re.search("^Coverage (?P<attempt>[0-9]+) (?P<label>.+)$", name)
label = match.group("label")
attempt = int(match.group("attempt"))
match = re.search('^Coverage (?P<attempt>[0-9]+) (?P<label>.+)$', name)
label = match.group('label')
attempt = int(match.group('attempt'))
jobs[label] = max(attempt, jobs.get(label, 0))
for label, attempt in jobs.items():
name = f"Coverage {attempt} {label}"
name = 'Coverage {attempt} {label}'.format(label=label, attempt=attempt)
source = os.path.join(source_directory, name)
source_files = os.listdir(source)
for source_file in source_files:
source_path = os.path.join(source, source_file)
destination_path = os.path.join(destination_directory, source_file + "." + label)
print(f'"{source_path}" -> "{destination_path}"')
destination_path = os.path.join(destination_directory, source_file + '.' + label)
print('"%s" -> "%s"' % (source_path, destination_path))
shutil.copyfile(source_path, destination_path)
count += 1
print(f"Coverage file count: {count}")
print(f"##vso[task.setVariable variable=coverageFileCount]{count}")
print(f"##vso[task.setVariable variable=outputPath]{output_path}")
print('Coverage file count: %d' % count)
print('##vso[task.setVariable variable=coverageFileCount]%d' % count)
print('##vso[task.setVariable variable=outputPath]%s' % output_path)
if __name__ == "__main__":
if __name__ == '__main__':
main()

View File

@ -1,10 +1,10 @@
#!/usr/bin/env bash
# Check the test results and set variables for use in later steps.
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# Check the test results and set variables for use in later steps.
set -o pipefail -eu
if [[ "$PWD" =~ /ansible_collections/ ]]; then

View File

@ -15,6 +15,7 @@ import pathlib
import shutil
import subprocess
import tempfile
import typing as t
import urllib.request
@ -22,7 +23,7 @@ import urllib.request
class CoverageFile:
name: str
path: pathlib.Path
flags: list[str]
flags: t.List[str]
@dataclasses.dataclass(frozen=True)
@ -33,8 +34,8 @@ class Args:
def parse_args() -> Args:
parser = argparse.ArgumentParser()
parser.add_argument("-n", "--dry-run", action="store_true")
parser.add_argument("path", type=pathlib.Path)
parser.add_argument('-n', '--dry-run', action='store_true')
parser.add_argument('path', type=pathlib.Path)
args = parser.parse_args()
@ -45,36 +46,32 @@ def parse_args() -> Args:
return Args(**kwargs)
def process_files(directory: pathlib.Path) -> tuple[CoverageFile, ...]:
def process_files(directory: pathlib.Path) -> t.Tuple[CoverageFile, ...]:
processed = []
for file in directory.joinpath("reports").glob("coverage*.xml"):
name = file.stem.replace("coverage=", "")
for file in directory.joinpath('reports').glob('coverage*.xml'):
name = file.stem.replace('coverage=', '')
# Get flags from name
flags = name.replace("-powershell", "").split("=") # Drop '-powershell' suffix
flags = [
flag if not flag.startswith("stub") else flag.split("-")[0] for flag in flags
] # Remove "-01" from stub files
flags = name.replace('-powershell', '').split('=') # Drop '-powershell' suffix
flags = [flag if not flag.startswith('stub') else flag.split('-')[0] for flag in flags] # Remove "-01" from stub files
processed.append(CoverageFile(name, file, flags))
return tuple(processed)
def upload_files(codecov_bin: pathlib.Path, files: tuple[CoverageFile, ...], dry_run: bool = False) -> None:
def upload_files(codecov_bin: pathlib.Path, files: t.Tuple[CoverageFile, ...], dry_run: bool = False) -> None:
for file in files:
cmd = [
str(codecov_bin),
"--name",
file.name,
"--file",
str(file.path),
'--name', file.name,
'--file', str(file.path),
]
for flag in file.flags:
cmd.extend(["--flags", flag])
cmd.extend(['--flags', flag])
if dry_run:
print(f"DRY-RUN: Would run command: {cmd}")
print(f'DRY-RUN: Would run command: {cmd}')
continue
subprocess.run(cmd, check=True)
@ -82,11 +79,11 @@ def upload_files(codecov_bin: pathlib.Path, files: tuple[CoverageFile, ...], dry
def download_file(url: str, dest: pathlib.Path, flags: int, dry_run: bool = False) -> None:
if dry_run:
print(f"DRY-RUN: Would download {url} to {dest} and set mode to {flags:o}")
print(f'DRY-RUN: Would download {url} to {dest} and set mode to {flags:o}')
return
with urllib.request.urlopen(url) as resp:
with dest.open("w+b") as f:
with dest.open('w+b') as f:
# Read data in chunks rather than all at once
shutil.copyfileobj(resp, f, 64 * 1024)
@ -95,14 +92,14 @@ def download_file(url: str, dest: pathlib.Path, flags: int, dry_run: bool = Fals
def main():
args = parse_args()
url = "https://ansible-ci-files.s3.amazonaws.com/codecov/linux/codecov"
with tempfile.TemporaryDirectory(prefix="codecov-") as tmpdir:
codecov_bin = pathlib.Path(tmpdir) / "codecov"
url = 'https://ansible-ci-files.s3.amazonaws.com/codecov/linux/codecov'
with tempfile.TemporaryDirectory(prefix='codecov-') as tmpdir:
codecov_bin = pathlib.Path(tmpdir) / 'codecov'
download_file(url, codecov_bin, 0o755, args.dry_run)
files = process_files(args.path)
upload_files(codecov_bin, files, args.dry_run)
if __name__ == "__main__":
if __name__ == '__main__':
main()

View File

@ -1,14 +1,18 @@
#!/usr/bin/env bash
# Generate code coverage reports for uploading to Azure Pipelines and codecov.io.
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# Generate code coverage reports for uploading to Azure Pipelines and codecov.io.
set -o pipefail -eu
PATH="${PWD}/bin:${PATH}"
if [[ "$(ansible --version)" =~ \ 2\.9\. ]]; then
exit
fi
if ! ansible-test --help >/dev/null 2>&1; then
# Install the devel version of ansible-test for generating code coverage reports.
# This is only used by Ansible Collections, which are typically tested against multiple Ansible versions (in separate jobs).

View File

@ -1,22 +1,20 @@
#!/usr/bin/env bash
# Configure the test environment and run the tests.
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# Configure the test environment and run the tests.
set -o pipefail -eu
entry_point="$1"
test="$2"
read -r -a coverage_branches <<< "$3" # space separated list of branches to run code coverage on for scheduled builds
agent_temp_directory="$4"
export COMMIT_MESSAGE
export COMPLETE
export COVERAGE
export IS_PULL_REQUEST
export COVERAGE_DESTINATION_DIRECTORY="${agent_temp_directory}/coverage"
if [ "${SYSTEM_PULLREQUEST_TARGETBRANCH:-}" ]; then
IS_PULL_REQUEST=true

View File

@ -5,7 +5,8 @@
"""Prepends a relative timestamp to each input line from stdin and writes it to stdout."""
from __future__ import annotations
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import sys
import time
@ -15,14 +16,14 @@ def main():
"""Main program entry point."""
start = time.time()
sys.stdin.reconfigure(errors="surrogateescape")
sys.stdout.reconfigure(errors="surrogateescape")
sys.stdin.reconfigure(errors='surrogateescape')
sys.stdout.reconfigure(errors='surrogateescape')
for line in sys.stdin:
seconds = int(time.time() - start)
sys.stdout.write(f"{seconds // 60:02}:{seconds % 60:02} {line}")
seconds = time.time() - start
sys.stdout.write('%02d:%02d %s' % (seconds // 60, seconds % 60, line))
sys.stdout.flush()
if __name__ == "__main__":
if __name__ == '__main__':
main()

View File

@ -23,16 +23,14 @@ jobs:
- checkout: self
fetchDepth: $(fetchDepth)
path: $(checkoutPath)
- bash: .azure-pipelines/scripts/run-tests.sh "$(prepareEntryPoint)" "${{ job.test }}" "$(coverageBranches)" "$(Agent.TempDirectory)"
displayName: Prepare Tests
- bash: .azure-pipelines/scripts/run-tests.sh "$(entryPoint)" "${{ job.test }}" "$(coverageBranches)" "$(Agent.TempDirectory)"
- bash: .azure-pipelines/scripts/run-tests.sh "$(entryPoint)" "${{ job.test }}" "$(coverageBranches)"
displayName: Run Tests
- bash: .azure-pipelines/scripts/process-results.sh
condition: succeededOrFailed()
displayName: Process Results
# - bash: .azure-pipelines/scripts/aggregate-coverage.sh "$(Agent.TempDirectory)"
# condition: eq(variables.haveCoverageData, 'true')
# displayName: Aggregate Coverage Data
- bash: .azure-pipelines/scripts/aggregate-coverage.sh "$(Agent.TempDirectory)"
condition: eq(variables.haveCoverageData, 'true')
displayName: Aggregate Coverage Data
- task: PublishTestResults@2
condition: eq(variables.haveTestResults, 'true')
inputs:

View File

@ -45,7 +45,7 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@v7
uses: actions/checkout@v6
with:
persist-credentials: false

View File

@ -15,11 +15,6 @@ name: nox
- cron: '0 9 * * *'
workflow_dispatch:
concurrency:
# Make sure there is at most one active run per PR, but do not cancel any non-PR runs
group: ${{ github.workflow }}-${{ (github.head_ref && github.event.number) || github.run_id }}
cancel-in-progress: true
jobs:
nox:
uses: ansible-community/antsibull-nox/.github/workflows/reusable-nox-run.yml@main
@ -35,6 +30,29 @@ jobs:
upload-codecov-pr: false
upload-codecov-push: false
upload-codecov-schedule: true
allow-coverage-cd-override: true
max-ansible-core: "2.17"
# For some reason GitHub decided to bump Docker on the ubuntu-24.04 image,
# which is not compatible with podman and various other things.
pre-test-cmd-integration: |-
# See https://docs.docker.com/engine/install/ubuntu/.
# Add Docker's official GPG key:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt-get install -y --allow-downgrades docker-ce-cli=5:28.0.4-1~ubuntu.24.04~noble docker-ce=5:28.0.4-1~ubuntu.24.04~noble
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@ -9,10 +9,6 @@
"community.internal_test_tools" = "git+https://github.com/ansible-collections/community.internal_test_tools.git,main"
"community.library_inventory_filtering_v1" = "git+https://github.com/ansible-collections/community.library_inventory_filtering.git,stable-1"
[collection_sources_per_ansible.'2.17']
# community.general's main branch needs ansible-core >= 2.18
"community.general" = "git+https://github.com/ansible-collections/community.general.git,stable-12"
[vcs]
vcs = "git"
development_branch = "main"
@ -103,28 +99,13 @@ include_devel = true
[sessions.ansible_test_integration]
session_name_template = "ansible-test-integration-{ansible_core}{dash_docker_short}{dash_remote}{dash_python_version}{dash_target_dashized}"
display_name_template = "Ⓐ{ansible_core}{plus_docker_nice}{plus_remote_nice}{plus_py_python_version}{plus_target_nice}{plus_force_docker_sdk_for_python_dev}{plus_force_docker_sdk_for_python_pypi}"
description_template = "Run integration tests with ansible-core {ansible_core}{comma_docker_nice}{comma_remote_nice}{comma_py_python_version}{comma_target_nice}{comma_force_docker_sdk_for_python_dev}{comma_force_docker_sdk_for_python_pypi}"
retry_on_error = "in-ci"
display_name_template = "Ⓐ{ansible_core}{plus_docker_short}{plus_remote}{plus_py_python_version}{plus_target}{plus_force_docker_sdk_for_python_dev}{plus_force_docker_sdk_for_python_pypi}"
description_template = "Run integration tests with ansible-core {ansible_core}{comma_docker_short}{comma_remote}{comma_py_python_version}{comma_target}{comma_force_docker_sdk_for_python_dev}{comma_force_docker_sdk_for_python_pypi}"
[sessions.ansible_test_integration.ansible_vars]
force_docker_sdk_for_python_dev = { type = "value", value = false, template_value = "" }
force_docker_sdk_for_python_pypi = { type = "value", value = false, template_value = "" }
[sessions.ansible_test_integration.nice_target_names]
"azp/1/" = "group 1"
"azp/2/" = "group 2"
"azp/3/" = "group 3"
"azp/4/" = "group 4"
"azp/5/" = "group 5"
[sessions.ansible_test_integration.nice_docker_names]
"quay.io/ansible-community/test-image:debian-bullseye" = "Debian 11"
"quay.io/ansible-community/test-image:debian-bookworm" = "Debian 12"
"quay.io/ansible-community/test-image:debian-13-trixie" = "Debian 13"
"quay.io/ansible-community/test-image:archlinux" = "Arch Linux"
"quay.io/ansible-community/test-image:opensuse-tumbleweed" = "OpenSuSE Tumbleweed"
##################################################################################################
# Ansible-core 2.17:
@ -236,12 +217,6 @@ target = [ "azp/4/", "azp/5/" ]
python_version = "3.13"
docker = "quay.io/ansible-community/test-image:debian-13-trixie"
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "devel"
target = [ "azp/4/", "azp/5/" ]
python_version = "3.13"
docker = "quay.io/ansible-community/test-image:opensuse-tumbleweed"
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "devel"
target = [ "azp/4/", "azp/5/" ]
@ -268,14 +243,14 @@ remote = [
[sessions.ansible_lint]
[[sessions.ee_check.execution_environments]]
name = "devel-ubi-10"
description = "ansible-core devel @ RHEL UBI 10"
name = "devel-ubi-9"
description = "ansible-core devel @ RHEL UBI 9"
test_playbooks = ["tests/ee/all.yml"]
config.images.base_image.name = "docker.io/redhat/ubi10:latest"
config.images.base_image.name = "docker.io/redhat/ubi9:latest"
config.dependencies.ansible_core.package_pip = "https://github.com/ansible/ansible/archive/devel.tar.gz"
config.dependencies.ansible_runner.package_pip = "ansible-runner"
config.dependencies.python_interpreter.package_system = "python3.14 python3.14-pip python3.14-cryptography"
config.dependencies.python_interpreter.python_path = "/usr/bin/python3.14"
config.dependencies.python_interpreter.package_system = "python3.12 python3.12-pip python3.12-wheel python3.12-cryptography"
config.dependencies.python_interpreter.python_path = "/usr/bin/python3.12"
runtime_environment = {"ANSIBLE_PRIVATE_ROLE_VARS" = "true"}
runtime_container_options = [
# Mount Docker socket into the container so we can talk to Docker outside the container

View File

@ -7,7 +7,7 @@
namespace: community
name: docker
version: 5.3.0
version: 5.2.1
readme: README.md
authors:
- Ansible Docker Working Group

View File

@ -12,7 +12,6 @@ import nox
try:
import antsibull_nox
from antsibull_nox.cli import run as run_antsibull_nox
except ImportError:
print("You need to install antsibull-nox in the same Python environment as nox.")
sys.exit(1)
@ -21,24 +20,6 @@ except ImportError:
antsibull_nox.load_antsibull_nox_toml()
@nox.session(name="update-azp-config", python=False)
def update_azp_config(session: nox.Session) -> None:
command = [
"antsibull-nox",
"update-azp-config",
"--exclude-tags",
"docker",
"--min-ansible-core",
"2.19",
]
if antsibull_nox.IN_CI:
command.append("--fail-on-change")
session.debug(" ".join(command))
result = run_antsibull_nox(command)
if result != 0:
session.error(f"Execution failed with status code {result}")
# Allow to run the noxfile with `python noxfile.py`, `pipx run noxfile.py`, or similar.
# Requires nox >= 2025.02.09
if __name__ == "__main__":

View File

@ -7,3 +7,4 @@
ansible.builtin.file:
path: "{{ remote_tmp_dir }}"
state: absent
no_log: true

View File

@ -20,7 +20,7 @@ from ansible_collections.community.docker.plugins.inventory.docker_containers im
)
if t.TYPE_CHECKING:
from collections.abc import Callable # pragma: no cover
from collections.abc import Callable
@pytest.fixture(scope="module", name="templar")

View File

@ -43,7 +43,7 @@ from ansible_collections.community.docker.tests.unit.plugins.module_utils._api.c
from .. import fake_api
if t.TYPE_CHECKING:
from ansible_collections.community.docker.plugins.module_utils._api.auth import ( # pragma: no cover
from ansible_collections.community.docker.plugins.module_utils._api.auth import (
AuthConfig,
)

View File

@ -18,7 +18,7 @@ from ansible_collections.community.docker.tests.unit.plugins.module_utils._api.c
from . import fake_stat
if t.TYPE_CHECKING:
from collections.abc import Callable # pragma: no cover
from collections.abc import Callable
CURRENT_VERSION = f"v{DEFAULT_DOCKER_API_VERSION}"

View File

@ -13,9 +13,9 @@ from ansible_collections.community.docker.plugins.module_utils._copy import (
)
if t.TYPE_CHECKING:
from collections.abc import Sequence # pragma: no cover
from collections.abc import Sequence
T = t.TypeVar("T") # pragma: no cover
T = t.TypeVar("T")
def _simple_generator(sequence: Sequence[T]) -> t.Generator[T]:

View File

@ -61,10 +61,12 @@ def test_archived_image_manifest_extracts_nothing_when_file_not_present(
def test_archived_image_manifest_raises_when_file_not_a_tar() -> None:
with pytest.raises(ImageArchiveInvalidException, match=__file__) as exc_info:
try:
archived_image_manifest(__file__)
assert isinstance(exc_info.value.__cause__, tarfile.ReadError)
assert str(__file__) in str(exc_info.value)
raise AssertionError()
except ImageArchiveInvalidException as e:
assert isinstance(e.__cause__, tarfile.ReadError)
assert str(__file__) in str(e)
def test_archived_image_manifest_raises_when_tar_missing_manifest(
@ -72,10 +74,12 @@ def test_archived_image_manifest_raises_when_tar_missing_manifest(
) -> None:
write_irrelevant_tar(tar_file_name)
with pytest.raises(ImageArchiveInvalidException) as exc_info:
try:
archived_image_manifest(tar_file_name)
assert isinstance(exc_info.value.__cause__, KeyError)
assert "manifest.json" in str(exc_info.value.__cause__)
raise AssertionError()
except ImageArchiveInvalidException as e:
assert isinstance(e.__cause__, KeyError)
assert "manifest.json" in str(e.__cause__)
def test_archived_image_manifest_raises_when_manifest_missing_id(
@ -85,7 +89,9 @@ def test_archived_image_manifest_raises_when_manifest_missing_id(
write_imitation_archive_with_manifest(tar_file_name, manifest)
with pytest.raises(ImageArchiveInvalidException) as exc_info:
try:
archived_image_manifest(tar_file_name)
assert isinstance(exc_info.value.__cause__, KeyError)
assert "Config" in str(exc_info.value.__cause__)
raise AssertionError()
except ImageArchiveInvalidException as e:
assert isinstance(e.__cause__, KeyError)
assert "Config" in str(e.__cause__)

View File

@ -17,12 +17,12 @@ from ansible_collections.community.docker.plugins.module_utils._util import (
if t.TYPE_CHECKING:
class DAMSpec(t.TypedDict): # pragma: no cover
class DAMSpec(t.TypedDict):
av: dict[str, t.Any]
bv: dict[str, t.Any]
result: bool
class Spec(t.TypedDict): # pragma: no cover
class Spec(t.TypedDict):
a: t.Any
b: t.Any
method: t.Literal["strict", "ignore", "allow_more_present"]

View File

@ -21,13 +21,11 @@ from ..test_support.docker_image_archive_stubbing import (
)
if t.TYPE_CHECKING:
from collections.abc import Callable # pragma: no cover
from collections.abc import Callable
def assert_no_logging(msg: str) -> t.NoReturn:
raise AssertionError(
f"Should not have logged anything but logged {msg}"
) # pragma: no cover
raise AssertionError(f"Should not have logged anything but logged {msg}")
def capture_logging(messages: list[str]) -> Callable[[str], None]:

View File

@ -12,8 +12,7 @@ from ansible_collections.community.docker.plugins.modules import (
docker_swarm_service,
)
docker_errors = pytest.importorskip("docker.errors")
APIError = docker_errors.APIError
APIError = pytest.importorskip("docker.errors.APIError")
def test_retry_on_out_of_sequence_error(mocker: t.Any) -> None:

View File

@ -0,0 +1 @@
remote.sh

View File

@ -0,0 +1 @@
remote.sh

View File

@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
set -o pipefail -eux
declare -a args
IFS='/:' read -ra args <<< "$1"
image="${args[1]}"
python="${args[2]}"
if [ "${#args[@]}" -gt 3 ]; then
target="azp/${args[3]}/"
else
target="azp/"
fi
if [[ "${python}" =~ -pypi-latest$ ]]; then
python="${python/-pypi-latest}"
echo 'force_docker_sdk_for_python_pypi: true' >> tests/integration/integration_config.yml
fi
if [[ "${python}" =~ -dev-latest$ ]]; then
python="${python/-dev-latest}"
echo 'force_docker_sdk_for_python_dev: true' >> tests/integration/integration_config.yml
fi
# shellcheck disable=SC2086
ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \
--docker "quay.io/ansible-community/test-image:${image}" --python "${python}"

30
tests/utils/shippable/linux.sh Executable file
View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
set -o pipefail -eux
declare -a args
IFS='/:' read -ra args <<< "$1"
image="${args[1]}"
if [ "${#args[@]}" -gt 2 ]; then
target="azp/${args[2]}/"
else
target="azp/"
fi
if [[ "${image}" =~ -pypi-latest$ ]]; then
image="${image/-pypi-latest}"
echo 'force_docker_sdk_for_python_pypi: true' >> tests/integration/integration_config.yml
fi
if [[ "${image}" =~ -dev-latest$ ]]; then
image="${image/-dev-latest}"
echo 'force_docker_sdk_for_python_dev: true' >> tests/integration/integration_config.yml
fi
# shellcheck disable=SC2086
ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \
--docker "${image}"

View File

@ -1,53 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
set -o pipefail -eux
nox_session="$1"
docker images ansible/ansible
docker images quay.io/ansible/*
docker ps
for container in $(docker ps --format '{{.Image}} {{.ID}}' | grep -v -e '^drydock/' -e '^quay.io/ansible/azure-pipelines-test-container:' | sed 's/^.* //'); do
docker rm -f "${container}" || true # ignore errors
done
docker ps
command -v python
python -V
function retry
{
# shellcheck disable=SC2034
for repetition in 1 2 3; do
set +e
"$@"
result=$?
set -e
if [ ${result} == 0 ]; then
return ${result}
fi
echo "@* -> ${result}"
done
echo "Command '@*' failed 3 times!"
exit 255
}
command -v pip
pip --version
pip list --disable-pip-version-check
retry pip install https://github.com/ansible-community/antsibull-nox/archive/main.tar.gz --disable-pip-version-check
export PYTHONIOENCODING='utf-8'
export FORCE_COLOR=1
export ANTSIBULL_NOX_IGNORE_INSTALLED_COLLECTIONS="true"
if [ "${nox_session}" == "extra-sanity-tests" ]; then
nox --verbose --install-only
else
nox --verbose --install-only -e "${nox_session}"
fi

View File

@ -1,64 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
set -o pipefail -eux
nox_session="$1"
export PYTHONIOENCODING='utf-8'
if [ -n "${COVERAGE:-}" ]; then
# on-demand coverage reporting triggered by setting the COVERAGE environment variable to a non-empty value
export COVERAGE="--coverage"
elif [[ "${COMMIT_MESSAGE}" =~ ci_coverage ]]; then
# on-demand coverage reporting triggered by having 'ci_coverage' in the latest commit message
export COVERAGE="--coverage"
else
# on-demand coverage reporting disabled (default behavior, always-on coverage reporting remains enabled)
export COVERAGE="--coverage-check"
fi
if [ -n "${COMPLETE:-}" ]; then
# disable change detection triggered by setting the COMPLETE environment variable to a non-empty value
export ANTSIBULL_CHANGE_DETECTION=""
elif [[ "${COMMIT_MESSAGE}" =~ ci_complete ]]; then
# disable change detection triggered by having 'ci_complete' in the latest commit message
export ANTSIBULL_CHANGE_DETECTION=""
elif [ "${IS_PULL_REQUEST:-}" == "true" ]; then
# enable change detection for PRs (default behavior)
export ANTSIBULL_CHANGE_DETECTION="true"
export ANTSIBULL_BASE_BRANCH="${SYSTEM_PULLREQUEST_TARGETBRANCH}"
# Create a branch for the current HEAD, which happens to be a merge commit
git checkout -b "pull-request-branch"
# Name the target branch
git branch "${SYSTEM_PULLREQUEST_TARGETBRANCH}" --track "origin/${SYSTEM_PULLREQUEST_TARGETBRANCH}"
# Show branches
git branch -vv
else
# disable change detection for pushes and scheduled runs
export ANTSIBULL_CHANGE_DETECTION=""
fi
if [[ "${COVERAGE:-}" == "--coverage" ]]; then
export ANTSIBULL_NOX_TIMEOUT=60
else
export ANTSIBULL_NOX_TIMEOUT=50
fi
if [ "${IS_PULL_REQUEST:-}" == "true" ]; then
export ANTSIBULL_NOX_INTEGRATION_ALLOW_UNSTABLE_CHANGED="true"
fi
export FORCE_COLOR=1
export ANTSIBULL_NOX_IGNORE_INSTALLED_COLLECTIONS="true"
export ANTSIBULL_NOX_COVERAGE_DESTINATION="${COVERAGE_DESTINATION_DIRECTORY}"
export ANTSIBULL_NOX_COVERAGE_ANALYSIS_FILE="${COVERAGE_DESTINATION_DIRECTORY}/coverage-analyze-targets.json"
export ANTSIBULL_NOX_COVERAGE_NO_XML="true"
if [ "${nox_session}" == "extra-sanity-tests" ]; then
nox --reuse-existing-virtualenvs --no-install
else
nox --reuse-existing-virtualenvs --no-install -e "${nox_session}" -- ${COVERAGE}
fi

48
tests/utils/shippable/remote.sh Executable file
View File

@ -0,0 +1,48 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
set -o pipefail -eux
declare -a args
IFS='/:' read -ra args <<< "$1"
platform="${args[0]}"
version="${args[1]}"
pyver=default
# check for explicit python version like 8.3@3.8
declare -a splitversion
IFS='@' read -ra splitversion <<< "$version"
if [ "${#splitversion[@]}" -gt 1 ]; then
version="${splitversion[0]}"
pyver="${splitversion[1]}"
fi
if [ "${#args[@]}" -gt 2 ]; then
target="azp/${args[2]}/"
else
target="azp/"
fi
if [[ "${version}" =~ -pypi-latest$ ]]; then
version="${version/-pypi-latest}"
echo 'force_docker_sdk_for_python_pypi: true' >> tests/integration/integration_config.yml
fi
if [[ "${version}" =~ -dev-latest$ ]]; then
version="${version/-dev-latest}"
echo 'force_docker_sdk_for_python_dev: true' >> tests/integration/integration_config.yml
fi
stage="${S:-prod}"
provider="${P:-default}"
if [ "${platform}" == "rhel" ] && [[ "${version}" =~ ^8\. ]]; then
echo "pynacl >= 1.4.0, < 1.5.0; python_version == '3.6'" >> tests/utils/constraints.txt
fi
# shellcheck disable=SC2086
ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \
--python "${pyver}" --remote "${platform}/${version}" --remote-terminate always --remote-stage "${stage}" --remote-provider "${provider}"

View File

@ -0,0 +1 @@
remote.sh

17
tests/utils/shippable/sanity.sh Executable file
View File

@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
set -o pipefail -eux
if [ "${BASE_BRANCH:-}" ]; then
base_branch="origin/${BASE_BRANCH}"
else
base_branch=""
fi
# shellcheck disable=SC2086
ansible-test sanity --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \
--docker --base-branch "${base_branch}" \
--allow-disabled

View File

@ -0,0 +1,234 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
set -o pipefail -eux
declare -a args
IFS='/:' read -ra args <<< "$1"
ansible_version="${args[0]}"
script="${args[1]}"
after_script="${args[2]}"
function join {
local IFS="$1";
shift;
echo "$*";
}
# Ensure we can write other collections to this dir
sudo chown -R "$(whoami)" "${PWD}/../../../"
test="$(join / "${args[@]:1}")"
docker images ansible/ansible
docker images quay.io/ansible/*
docker ps
for container in $(docker ps --format '{{.Image}} {{.ID}}' | grep -v -e '^drydock/' -e '^quay.io/ansible/azure-pipelines-test-container:' | sed 's/^.* //'); do
docker rm -f "${container}" || true # ignore errors
done
docker ps
if [ -d /home/shippable/cache/ ]; then
ls -la /home/shippable/cache/
fi
command -v python
python -V
function retry
{
# shellcheck disable=SC2034
for repetition in 1 2 3; do
set +e
"$@"
result=$?
set -e
if [ ${result} == 0 ]; then
return ${result}
fi
echo "@* -> ${result}"
done
echo "Command '@*' failed 3 times!"
exit 255
}
command -v pip
pip --version
pip list --disable-pip-version-check
if [ "${ansible_version}" == "devel" ]; then
retry pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
else
retry pip install "https://github.com/ansible/ansible/archive/stable-${ansible_version}.tar.gz" --disable-pip-version-check
fi
export ANSIBLE_COLLECTIONS_PATHS="${PWD}/../../../"
# START: HACK
COMMUNITY_CRYPTO_BRANCH=main
if [ "${ansible_version}" == "2.16" ]; then
COMMUNITY_CRYPTO_BRANCH=stable-2
fi
if [ "${script}" == "linux" ] && [ "$after_script" == "ubuntu2004" ]; then
COMMUNITY_CRYPTO_BRANCH=stable-2
fi
retry git clone --depth=1 --single-branch --branch stable-1 https://github.com/ansible-collections/community.library_inventory_filtering.git "${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/community/library_inventory_filtering_v1"
# NOTE: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
# retry ansible-galaxy -vvv collection install community.library_inventory_filtering_v1
if [ "${test}" == "units/1" ]; then
# Nothing further should be added to this list.
# This is to prevent modules or plugins in this collection having a runtime dependency on other collections.
retry git clone --depth=1 --single-branch https://github.com/ansible-collections/community.internal_test_tools.git "${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/community/internal_test_tools"
# NOTE: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
# retry ansible-galaxy -vvv collection install community.internal_test_tools
fi
if [ "${script}" != "sanity/1" ] && [ "${script}" != "units/1" ]; then
# To prevent Python dependencies on other collections only install other collections for integration tests
retry git clone --depth=1 --single-branch https://github.com/ansible-collections/ansible.posix.git "${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/ansible/posix"
retry git clone --depth=1 --single-branch --branch "${COMMUNITY_CRYPTO_BRANCH}" https://github.com/ansible-collections/community.crypto.git "${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/community/crypto"
retry git clone --depth=1 --single-branch https://github.com/ansible-collections/community.general.git "${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/community/general"
# NOTE: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
# retry ansible-galaxy -vvv collection install ansible.posix
# retry ansible-galaxy -vvv collection install community.crypto
# retry ansible-galaxy -vvv collection install community.general
fi
# END: HACK
export PYTHONIOENCODING='utf-8'
if [ "${JOB_TRIGGERED_BY_NAME:-}" == "nightly-trigger" ]; then
COVERAGE=yes
COMPLETE=yes
fi
if [ -n "${COVERAGE:-}" ]; then
# on-demand coverage reporting triggered by setting the COVERAGE environment variable to a non-empty value
export COVERAGE="--coverage"
elif [[ "${COMMIT_MESSAGE}" =~ ci_coverage ]]; then
# on-demand coverage reporting triggered by having 'ci_coverage' in the latest commit message
export COVERAGE="--coverage"
else
# on-demand coverage reporting disabled (default behavior, always-on coverage reporting remains enabled)
export COVERAGE="--coverage-check"
fi
if [ -n "${COMPLETE:-}" ]; then
# disable change detection triggered by setting the COMPLETE environment variable to a non-empty value
export CHANGED=""
elif [[ "${COMMIT_MESSAGE}" =~ ci_complete ]]; then
# disable change detection triggered by having 'ci_complete' in the latest commit message
export CHANGED=""
else
# enable change detection (default behavior)
export CHANGED="--changed"
fi
if [ "${IS_PULL_REQUEST:-}" == "true" ]; then
# run unstable tests which are targeted by focused changes on PRs
export UNSTABLE="--allow-unstable-changed"
else
# do not run unstable tests outside PRs
export UNSTABLE=""
fi
# remove empty core/extras module directories from PRs created prior to the repo-merge
find plugins -type d -empty -print -delete
function cleanup
{
# for complete on-demand coverage generate a report for all files with no coverage on the "sanity/5" job so we only have one copy
if [ "${COVERAGE}" == "--coverage" ] && [ "${CHANGED}" == "" ] && [ "${test}" == "sanity/5" ]; then
stub="--stub"
# trigger coverage reporting for stubs even if no other coverage data exists
mkdir -p tests/output/coverage/
else
stub=""
fi
if [ -d tests/output/coverage/ ]; then
if find tests/output/coverage/ -mindepth 1 -name '.*' -prune -o -print -quit | grep -q .; then
process_coverage='yes' # process existing coverage files
elif [ "${stub}" ]; then
process_coverage='yes' # process coverage when stubs are enabled
else
process_coverage=''
fi
if [ "${process_coverage}" ]; then
# use python 3.7 for coverage to avoid running out of memory during coverage xml processing
# only use it for coverage to avoid the additional overhead of setting up a virtual environment for a potential no-op job
virtualenv --python /usr/bin/python3.7 ~/ansible-venv
set +ux
. ~/ansible-venv/bin/activate
set -ux
# shellcheck disable=SC2086
ansible-test coverage xml --color -v --requirements --group-by command --group-by version ${stub:+"$stub"}
cp -a tests/output/reports/coverage=*.xml "$SHIPPABLE_RESULT_DIR/codecoverage/"
if [ "${ansible_version}" != "2.9" ]; then
# analyze and capture code coverage aggregated by integration test target
ansible-test coverage analyze targets generate -v "$SHIPPABLE_RESULT_DIR/testresults/coverage-analyze-targets.json"
fi
# upload coverage report to codecov.io only when using complete on-demand coverage
if [ "${COVERAGE}" == "--coverage" ] && [ "${CHANGED}" == "" ]; then
for file in tests/output/reports/coverage=*.xml; do
flags="${file##*/coverage=}"
flags="${flags%-powershell.xml}"
flags="${flags%.xml}"
# remove numbered component from stub files when converting to tags
flags="${flags//stub-[0-9]*/stub}"
flags="${flags//=/,}"
flags="${flags//[^a-zA-Z0-9_,]/_}"
bash <(curl -s https://ansible-ci-files.s3.us-east-1.amazonaws.com/codecov/codecov.sh) \
-f "${file}" \
-F "${flags}" \
-n "${test}" \
-t 8450ed26-4e94-4d07-8831-d2023d6d20a3 \
-X coveragepy \
-X gcov \
-X fix \
-X search \
-X xcode \
|| echo "Failed to upload code coverage report to codecov.io: ${file}"
done
fi
fi
fi
if [ -d tests/output/junit/ ]; then
cp -aT tests/output/junit/ "$SHIPPABLE_RESULT_DIR/testresults/"
fi
if [ -d tests/output/data/ ]; then
cp -a tests/output/data/ "$SHIPPABLE_RESULT_DIR/testresults/"
fi
if [ -d tests/output/bot/ ]; then
cp -aT tests/output/bot/ "$SHIPPABLE_RESULT_DIR/testresults/"
fi
}
if [ "${SHIPPABLE_BUILD_ID:-}" ]; then trap cleanup EXIT; fi
if [[ "${COVERAGE:-}" == "--coverage" ]]; then
timeout=60
else
timeout=50
fi
ansible-test env --dump --show --timeout "${timeout}" --color -v
if [ "${SHIPPABLE_BUILD_ID:-}" ]; then "tests/utils/shippable/check_matrix.py"; fi
"tests/utils/shippable/${script}.sh" "${test}"

View File

@ -0,0 +1 @@
remote.sh

29
tests/utils/shippable/units.sh Executable file
View File

@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
set -o pipefail -eux
declare -a args
IFS='/:' read -ra args <<< "$1"
group="${args[1]}"
if [[ "${COVERAGE:-}" == "--coverage" ]]; then
timeout=90
else
timeout=30
fi
group1=()
case "${group}" in
1) options=("${group1[@]:+${group1[@]}}") ;;
esac
ansible-test env --timeout "${timeout}" --color -v
# shellcheck disable=SC2086
ansible-test units --color -v --docker default ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \
"${options[@]:+${options[@]}}" \