pax_global_header00006660000000000000000000000064152252371520014516gustar00rootroot0000000000000052 comment=1ebfc2c78c4a2a9a565cdc6c8397dd28d8d92bc4 ansible-2.21.2/000077500000000000000000000000001522523715200132175ustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/000077500000000000000000000000001522523715200164115ustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/azure-pipelines.yml000066400000000000000000000160471522523715200222600ustar00rootroot00000000000000trigger: batch: true branches: include: - devel - stable-* pr: autoCancel: true branches: include: - devel - stable-* schedules: - cron: 0 7 * * * displayName: Nightly always: true branches: include: - devel - stable-* variables: - name: checkoutPath value: ansible - name: coverageBranches value: devel - name: entryPoint value: .azure-pipelines/commands/entry-point.sh - name: fetchDepth value: 500 - name: defaultContainer value: quay.io/ansible/azure-pipelines-test-container:8.0.0 pool: Standard stages: - stage: Sanity dependsOn: [] jobs: - template: templates/matrix.yml parameters: nameFormat: Test {0} testFormat: sanity/{0} targets: - test: 1 - test: 2 - stage: Units dependsOn: [] jobs: - template: templates/matrix.yml parameters: nameFormat: Python {0} testFormat: units/{0} targets: - test: 3.9 - test: '3.10' - test: 3.11 - test: 3.12 - test: 3.13 - test: 3.14 - stage: Windows dependsOn: [] jobs: - template: templates/matrix.yml parameters: nameFormat: Server {0} testFormat: windows/{0}/1 targets: - name: 2016 WinRM HTTP WinPS test: 2016/winrm/http/5.1 - name: 2019 WinRM HTTPS WinPS test: 2019/winrm/https/5.1 - name: 2022 WinRM HTTPS WinPS test: 2022/winrm/https/5.1 - name: 2022 PSRP HTTP WinPS test: 2022/psrp/http/5.1 - name: 2022 SSH Key WinPS test: 2022/ssh/key/5.1 - name: 2025 PSRP HTTP WinPS test: 2025/psrp/http/5.1 - name: 2025 SSH Key WinPS test: 2025/ssh/key/5.1 - name: 2025 WinRM HTTP Pwsh test: 2025/winrm/http/7.6 - name: 2025 PSRP HTTP Pwsh test: 2025/psrp/http/7.6 - name: 2025 SSH Key Pwsh test: 2025/ssh/key/7.6 - stage: Remote dependsOn: [] jobs: - template: templates/matrix.yml # context/target parameters: targets: - name: macOS 26.3 test: macos/26.3 - name: RHEL 9.7 py39 test: rhel/9.7@3.9 - name: RHEL 9.7 py312 test: rhel/9.7@3.12 - name: RHEL 10.1 test: rhel/10.1 - name: FreeBSD 14.4 test: freebsd/14.4 - name: FreeBSD 15.0 test: freebsd/15.0 groups: - 1 - 2 - template: templates/matrix.yml # context/controller parameters: targets: - name: macOS 26.3 test: macos/26.3 - name: RHEL 9.7 test: rhel/9.7 - name: RHEL 10.1 test: rhel/10.1 - name: FreeBSD 14.4 test: freebsd/14.4 - name: FreeBSD 15.0 test: freebsd/15.0 groups: - 3 - 4 - 5 - template: templates/matrix.yml # context/controller (ansible-test container management) parameters: targets: - name: Alpine 3.23 test: alpine/3.23 - name: Fedora 43 test: fedora/43 - name: RHEL 9.7 test: rhel/9.7 - name: RHEL 10.1 test: rhel/10.1 - name: Ubuntu 24.04 test: ubuntu/24.04 groups: - 6 - stage: Remote_Targeted displayName: Remote Targeted dependsOn: [] jobs: - template: templates/matrix.yml # targeted tests parameters: testFormat: "{0}/targeted" targets: - name: RHEL 8.10 test: rhel/8.10/rhel8 - stage: Docker dependsOn: [] jobs: - template: templates/matrix.yml # context/target parameters: testFormat: linux/{0} targets: - name: Alpine 3.23 test: alpine323 - name: Fedora 43 test: fedora43 - name: Ubuntu 22.04 test: ubuntu2204 - name: Ubuntu 24.04 test: ubuntu2404 groups: - 1 - 2 - template: templates/matrix.yml # context/controller parameters: testFormat: linux/{0} targets: - name: Alpine 3.23 test: alpine323 - name: Fedora 43 test: fedora43 - name: Ubuntu 24.04 test: ubuntu2404 groups: - 3 - 4 - 5 - template: templates/matrix.yml # context/target (dnf-oldest, dnf-latest) parameters: testFormat: linux/{0} targets: - name: Fedora 43 test: fedora43 groups: - 7 - stage: PowerShell dependsOn: [] jobs: - template: templates/matrix.yml parameters: nameFormat: PowerShell {0} testFormat: powershell/{0}/1 targets: - name: 7.6 - stage: Galaxy dependsOn: [] jobs: - template: templates/matrix.yml parameters: nameFormat: Python {0} testFormat: galaxy/{0}/1 targets: - test: 3.12 - test: 3.13 - test: 3.14 - stage: Generic dependsOn: [] jobs: - template: templates/matrix.yml parameters: nameFormat: Python {0} testFormat: generic/{0}/1 targets: - test: 3.12 - test: 3.13 - test: 3.14 - stage: Incidental_Windows displayName: Incidental Windows dependsOn: [] jobs: - template: templates/matrix.yml parameters: nameFormat: Server {0} testFormat: i/windows/{0} targets: - name: 2016 WinRM HTTP WinPS test: 2016/winrm/http/5.1 - name: 2019 WinRM HTTPS WinPS test: 2019/winrm/https/5.1 - name: 2022 WinRM HTTPS WinPS test: 2022/winrm/https/5.1 - name: 2022 PSRP HTTP WinPS test: 2022/psrp/http/5.1 - name: 2022 SSH Key WinPS test: 2022/ssh/key/5.1 - name: 2025 PSRP HTTP WinPS test: 2025/psrp/http/5.1 - name: 2025 SSH Key WinPS test: 2025/ssh/key/5.1 - name: 2025 WinRM HTTP Pwsh test: 2025/winrm/http/7.6 - name: 2025 PSRP HTTP Pwsh test: 2025/psrp/http/7.6 - name: 2025 SSH Key Pwsh test: 2025/ssh/key/7.6 - stage: Summary condition: succeededOrFailed() dependsOn: - Sanity - Units - Windows - Remote - Remote_Targeted - Docker - PowerShell - Galaxy - Generic - Incidental_Windows jobs: - template: templates/coverage.yml ansible-2.21.2/.azure-pipelines/commands/000077500000000000000000000000001522523715200202125ustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/commands/alpine.sh000077700000000000000000000000001522523715200236402remote.shustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/commands/cloud.sh000077500000000000000000000017311522523715200216610ustar00rootroot00000000000000#!/usr/bin/env bash set -o pipefail -eux declare -a args IFS='/:' read -ra args <<< "$1" cloud="${args[0]}" python="${args[1]}" group="${args[2]}" target="shippable/${cloud}/group${group}/" stage="${S:-prod}" changed_all_target="shippable/${cloud}/smoketest/" if ! ansible-test integration "${changed_all_target}" --list-targets > /dev/null 2>&1; then # no smoketest tests are available for this cloud changed_all_target="none" fi if [ "${group}" == "1" ]; then # only run smoketest tests for group1 changed_all_mode="include" else # smoketest tests already covered by group1 changed_all_mode="exclude" fi # shellcheck disable=SC2086 ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \ --remote-terminate always --remote-stage "${stage}" \ --docker --python "${python}" --changed-all-target "${changed_all_target}" --changed-all-mode "${changed_all_mode}" ansible-2.21.2/.azure-pipelines/commands/entry-point.sh000077500000000000000000000034221522523715200230420ustar00rootroot00000000000000#!/usr/bin/env bash set -o pipefail -eux declare -a args IFS='/:' read -ra args <<< "$1" script="${args[0]}" test="$1" docker images docker ps for container in $(docker ps --format '{{.Image}} {{.ID}}' | grep -v -e '^quay.io/ansible/azure-pipelines-test-container:' | sed 's/^.* //'); do docker rm -f "${container}" || true # ignore errors done docker ps export PATH="${PWD}/bin:${PATH}" 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 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 if [[ "${COVERAGE:-}" == "--coverage" ]]; then timeout=60 else timeout=50 fi ansible-test env --dump --show --timeout "${timeout}" --color -v ".azure-pipelines/commands/${script}.sh" "${test}" ansible-2.21.2/.azure-pipelines/commands/fedora.sh000077700000000000000000000000001522523715200236302remote.shustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/commands/freebsd.sh000077700000000000000000000000001522523715200240022remote.shustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/commands/galaxy.sh000077700000000000000000000000001522523715200234702cloud.shustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/commands/generic.sh000077500000000000000000000010131522523715200221600ustar00rootroot00000000000000#!/usr/bin/env bash set -o pipefail -eux declare -a args IFS='/:' read -ra args <<< "$1" python="${args[1]}" if [ "${#args[@]}" -gt 2 ]; then target="shippable/generic/group${args[2]}/" else target="shippable/generic/" fi stage="${S:-prod}" # shellcheck disable=SC2086 ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \ --remote-terminate always --remote-stage "${stage}" \ --docker default --python "${python}" ansible-2.21.2/.azure-pipelines/commands/i.sh000077500000000000000000000006111522523715200207770ustar00rootroot00000000000000#!/usr/bin/env bash # Temporary script to support side-by-side testing for incidental code coverage. # Once collection migration has been completed the incidental tests can be combined with the regular tests. set -o pipefail -eux declare -a args IFS='/:' read -ra args <<< "$1" script="${args[1]}" IFS='/' test="${args[*]:1}" ".azure-pipelines/commands/incidental/${script}.sh" "${test}" ansible-2.21.2/.azure-pipelines/commands/incidental/000077500000000000000000000000001522523715200223245ustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/commands/incidental/windows.sh000077500000000000000000000034261522523715200243620ustar00rootroot00000000000000#!/usr/bin/env bash set -o pipefail -eux declare -a args IFS='/:' read -ra args <<< "$1" version="${args[1]}" connection="${args[2]}" connection_setting="${args[3]}" target="shippable/windows/incidental/" stage="${S:-prod}" provider="${P:-default}" # python version to run full tests on while other versions run minimal tests python_default="$(PYTHONPATH="${PWD}/test/lib" python -c 'from ansible_test._internal import constants; print(constants.CONTROLLER_MIN_PYTHON_VERSION)')" # version to test when only testing a single version single_version=2022 # shellcheck disable=SC2086 ansible-test windows-integration --list-targets -v ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} > /tmp/explain.txt 2>&1 || { cat /tmp/explain.txt && false; } { grep ' windows-integration: .* (targeted)$' /tmp/explain.txt || true; } > /tmp/windows.txt if [ -s /tmp/windows.txt ] || [ "${CHANGED:+$CHANGED}" == "" ]; then echo "Detected changes requiring integration tests specific to Windows:" cat /tmp/windows.txt echo "Running Windows integration tests for the version ${version}." else echo "No changes requiring integration tests specific to Windows were detected." echo "Running Windows integration tests for a single version only: ${single_version}" if [ "${version}" != "${single_version}" ]; then echo "Skipping this job since it is for: ${version}" exit 0 fi fi # shellcheck disable=SC2086 ansible-test windows-integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \ --controller "docker:default,python=${python_default}" \ --target "remote:windows/${version},connection=${connection}+${connection_setting},provider=${provider}" \ --remote-terminate always --remote-stage "${stage}" ansible-2.21.2/.azure-pipelines/commands/linux.sh000077500000000000000000000006461522523715200217160ustar00rootroot00000000000000#!/usr/bin/env bash set -o pipefail -eux declare -a args IFS='/:' read -ra args <<< "$1" image="${args[1]}" if [ "${#args[@]}" -gt 2 ]; then target="shippable/posix/group${args[2]}/" else target="shippable/posix/" fi # shellcheck disable=SC2086 ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \ --docker "${image}" ansible-2.21.2/.azure-pipelines/commands/macos.sh000077700000000000000000000000001522523715200234722remote.shustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/commands/powershell.sh000077500000000000000000000010071522523715200227330ustar00rootroot00000000000000#!/usr/bin/env bash set -o pipefail -eux declare -a args IFS='/:' read -ra args <<< "$1" powershell="${args[1]}" if [ "${#args[@]}" -gt 2 ]; then target="shippable/powershell/group${args[2]}/" else target="shippable/powershell/" fi # shellcheck disable=SC2086 ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \ --controller "docker:default,python=default" \ --target "docker:default,powershell=${powershell}" ansible-2.21.2/.azure-pipelines/commands/remote.sh000077500000000000000000000016461522523715200220530ustar00rootroot00000000000000#!/usr/bin/env bash 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 3 ]; then target="shippable/${args[3]}/${args[2]}/" elif [ "${#args[@]}" -gt 2 ]; then target="shippable/posix/group${args[2]}/" else target="shippable/posix/" fi stage="${S:-prod}" provider="${P:-default}" # 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}" \ ansible-2.21.2/.azure-pipelines/commands/rhel.sh000077700000000000000000000000001522523715200233222remote.shustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/commands/sanity.sh000077500000000000000000000013121522523715200220550ustar00rootroot00000000000000#!/usr/bin/env bash set -o pipefail -eux declare -a args IFS='/:' read -ra args <<< "$1" group="${args[1]}" group2_include=( ansible-doc changelog package-data pep8 pylint validate-modules ) group1_exclude=( "${group2_include[@]}" ) options=() case "${group}" in 1) for name in "${group1_exclude[@]}"; do options+=(--skip-test "${name}") done ;; 2) for name in "${group2_include[@]}"; do options+=(--test "${name}") done ;; esac # shellcheck disable=SC2086 ansible-test sanity --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \ --docker \ "${options[@]}" --allow-disabled ansible-2.21.2/.azure-pipelines/commands/ubuntu.sh000077700000000000000000000000001522523715200237122remote.shustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/commands/units.sh000077500000000000000000000004051522523715200217120ustar00rootroot00000000000000#!/usr/bin/env bash set -o pipefail -eux declare -a args IFS='/:' read -ra args <<< "$1" version="${args[1]}" # shellcheck disable=SC2086 ansible-test units --color -v --docker default --python "${version}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \ ansible-2.21.2/.azure-pipelines/commands/windows.sh000077500000000000000000000067271522523715200222570ustar00rootroot00000000000000#!/usr/bin/env bash set -o pipefail -eux declare -a args IFS='/:' read -ra args <<< "$1" version="${args[1]}" connection="${args[2]}" connection_setting="${args[3]}" powershell="${args[4]}" group="${args[5]}" target="shippable/windows/group${group}/" stage="${S:-prod}" provider="${P:-default}" # python versions to test in order IFS=' ' read -r -a python_versions <<< \ "$(PYTHONPATH="${PWD}/test/lib" python -c 'from ansible_test._internal import constants; print(" ".join(constants.CONTROLLER_PYTHON_VERSIONS))')" # python version to run full tests on while other versions run minimal tests python_default="$(PYTHONPATH="${PWD}/test/lib" python -c 'from ansible_test._internal import constants; print(constants.CONTROLLER_MIN_PYTHON_VERSION)')" # version to test when only testing a single version single_version=2022 # shellcheck disable=SC2086 ansible-test windows-integration --list-targets -v ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} > /tmp/explain.txt 2>&1 || { cat /tmp/explain.txt && false; } { grep ' windows-integration: .* (targeted)$' /tmp/explain.txt || true; } > /tmp/windows.txt if [ -s /tmp/windows.txt ] || [ "${CHANGED:+$CHANGED}" == "" ]; then echo "Detected changes requiring integration tests specific to Windows:" cat /tmp/windows.txt echo "Running Windows integration tests for the version ${version}." else echo "No changes requiring integration tests specific to Windows were detected." echo "Running Windows integration tests for a single version only: ${single_version}" if [ "${version}" != "${single_version}" ]; then echo "Skipping this job since it is for: ${version}" exit 0 fi fi for py_version in "${python_versions[@]}"; do changed_all_target="all" changed_all_mode="default" if [ "${py_version}" == "${python_default}" ]; then # smoketest tests if [ "${CHANGED}" ]; then # with change detection enabled run tests for anything changed # use the smoketest tests for any change that triggers all tests ci="${target}" changed_all_target="shippable/windows/smoketest/" if [ "${target}" == "shippable/windows/group1/" ]; then # only run smoketest tests for group1 changed_all_mode="include" else # smoketest tests already covered by group1 changed_all_mode="exclude" fi else # without change detection enabled run entire test group ci="${target}" fi else # only run minimal tests for group1 if [ "${target}" != "shippable/windows/group1/" ]; then continue; fi # minimal tests for other python versions ci="shippable/windows/minimal/" fi # terminate remote instances on the final python version tested if [ "${py_version}" = "${python_versions[-1]}" ]; then terminate="always" else terminate="never" fi # shellcheck disable=SC2086 ansible-test windows-integration --color -v --retry-on-error "${ci}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \ --changed-all-target "${changed_all_target}" --changed-all-mode "${changed_all_mode}" \ --controller "docker:default,python=${py_version}" \ --target "remote:windows/${version},connection=${connection}+${connection_setting},provider=${provider},powershell=${powershell}" \ --remote-terminate "${terminate}" --remote-stage "${stage}" done ansible-2.21.2/.azure-pipelines/scripts/000077500000000000000000000000001522523715200201005ustar00rootroot00000000000000ansible-2.21.2/.azure-pipelines/scripts/aggregate-coverage.sh000077500000000000000000000013131522523715200241540ustar00rootroot00000000000000#!/usr/bin/env bash # Aggregate code coverage results for later processing. set -o pipefail -eu agent_temp_directory="$1" PATH="${PWD}/bin:${PATH}" mkdir "${agent_temp_directory}/coverage/" options=(--venv --color -v) ansible-test coverage combine --group-by command --export "${agent_temp_directory}/coverage/" "${options[@]}" if ansible-test coverage analyze targets generate --help >/dev/null 2>&1; then # Only analyze coverage if the installed version of ansible-test supports it. # Doing so allows this script to work unmodified for multiple Ansible versions. ansible-test coverage analyze targets generate "${agent_temp_directory}/coverage/coverage-analyze-targets.json" "${options[@]}" fi ansible-2.21.2/.azure-pipelines/scripts/combine-coverage.py000077500000000000000000000041111522523715200236570ustar00rootroot00000000000000#!/usr/bin/env python """ Combine coverage data from multiple jobs, keeping the data only from the most recent attempt from each job. Coverage artifacts must be named using the format: "Coverage $(System.JobAttempt) {StableUniqueNameForEachJob}" The recommended coverage artifact name format is: Coverage $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName) Keep in mind that Azure Pipelines does not enforce unique job display names (only names). It is up to pipeline authors to avoid name collisions when deviating from the recommended format. """ from __future__ import annotations import os import re import shutil import sys def main(): """Main program entry point.""" source_directory = sys.argv[1] if '/ansible_collections/' in os.getcwd(): output_path = "tests/output" else: output_path = "test/results" destination_directory = os.path.join(output_path, 'coverage') if not os.path.exists(destination_directory): os.makedirs(destination_directory) jobs = {} count = 0 for name in os.listdir(source_directory): match = re.search('^Coverage (?P[0-9]+) (?P