summaryrefslogtreecommitdiffstats
path: root/ansible_collections/microsoft/ad/.azure-pipelines/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/microsoft/ad/.azure-pipelines/scripts')
-rwxr-xr-xansible_collections/microsoft/ad/.azure-pipelines/scripts/aggregate-coverage.sh20
-rwxr-xr-xansible_collections/microsoft/ad/.azure-pipelines/scripts/combine-coverage.py60
-rwxr-xr-xansible_collections/microsoft/ad/.azure-pipelines/scripts/process-results.sh24
-rwxr-xr-xansible_collections/microsoft/ad/.azure-pipelines/scripts/publish-codecov.sh27
-rwxr-xr-xansible_collections/microsoft/ad/.azure-pipelines/scripts/report-coverage.sh17
-rwxr-xr-xansible_collections/microsoft/ad/.azure-pipelines/scripts/run-tests.sh34
-rwxr-xr-xansible_collections/microsoft/ad/.azure-pipelines/scripts/time-command.py25
7 files changed, 207 insertions, 0 deletions
diff --git a/ansible_collections/microsoft/ad/.azure-pipelines/scripts/aggregate-coverage.sh b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/aggregate-coverage.sh
new file mode 100755
index 000000000..f3113dd0a
--- /dev/null
+++ b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/aggregate-coverage.sh
@@ -0,0 +1,20 @@
+#!/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 --venv-system-site-packages --color -v)
+
+ansible-test coverage combine --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
diff --git a/ansible_collections/microsoft/ad/.azure-pipelines/scripts/combine-coverage.py b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/combine-coverage.py
new file mode 100755
index 000000000..506ade646
--- /dev/null
+++ b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/combine-coverage.py
@@ -0,0 +1,60 @@
+#!/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 (absolute_import, division, print_function)
+__metaclass__ = type
+
+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<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 = '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('"%s" -> "%s"' % (source_path, destination_path))
+ shutil.copyfile(source_path, destination_path)
+ count += 1
+
+ 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__':
+ main()
diff --git a/ansible_collections/microsoft/ad/.azure-pipelines/scripts/process-results.sh b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/process-results.sh
new file mode 100755
index 000000000..f3f1d1bae
--- /dev/null
+++ b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/process-results.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+# Check the test results and set variables for use in later steps.
+
+set -o pipefail -eu
+
+if [[ "$PWD" =~ /ansible_collections/ ]]; then
+ output_path="tests/output"
+else
+ output_path="test/results"
+fi
+
+echo "##vso[task.setVariable variable=outputPath]${output_path}"
+
+if compgen -G "${output_path}"'/junit/*.xml' > /dev/null; then
+ echo "##vso[task.setVariable variable=haveTestResults]true"
+fi
+
+if compgen -G "${output_path}"'/bot/ansible-test-*' > /dev/null; then
+ echo "##vso[task.setVariable variable=haveBotResults]true"
+fi
+
+if compgen -G "${output_path}"'/coverage/*' > /dev/null; then
+ echo "##vso[task.setVariable variable=haveCoverageData]true"
+fi
diff --git a/ansible_collections/microsoft/ad/.azure-pipelines/scripts/publish-codecov.sh b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/publish-codecov.sh
new file mode 100755
index 000000000..6d184f0b8
--- /dev/null
+++ b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/publish-codecov.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# Upload code coverage reports to codecov.io.
+# Multiple coverage files from multiple languages are accepted and aggregated after upload.
+# Python coverage, as well as PowerShell and Python stubs can all be uploaded.
+
+set -o pipefail -eu
+
+output_path="$1"
+
+curl --silent --show-error https://ansible-ci-files.s3.us-east-1.amazonaws.com/codecov/codecov.sh > codecov.sh
+
+for file in "${output_path}"/reports/coverage*.xml; do
+ name="${file}"
+ name="${name##*/}" # remove path
+ name="${name##coverage=}" # remove 'coverage=' prefix if present
+ name="${name%.xml}" # remove '.xml' suffix
+
+ bash codecov.sh \
+ -f "${file}" \
+ -n "${name}" \
+ -X coveragepy \
+ -X gcov \
+ -X fix \
+ -X search \
+ -X xcode \
+ || echo "Failed to upload code coverage report to codecov.io: ${file}"
+done
diff --git a/ansible_collections/microsoft/ad/.azure-pipelines/scripts/report-coverage.sh b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/report-coverage.sh
new file mode 100755
index 000000000..050464be3
--- /dev/null
+++ b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/report-coverage.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+# Generate code coverage reports for uploading to Azure Pipelines and codecov.io.
+
+set -o pipefail -eu
+
+PATH="${PWD}/bin:${PATH}"
+
+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).
+ # Since a version of ansible-test is required that can work the output from multiple older releases, the devel version is used.
+ pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
+fi
+
+# Generate stubs using docker (if supported) otherwise fall back to using a virtual environment instead.
+# The use of docker is required when Powershell code is present, but Ansible 2.12 was the first version to support --docker with coverage.
+ansible-test coverage xml --stub --docker --color -v || ansible-test coverage xml --stub --venv --venv-system-site-packages --color -v
diff --git a/ansible_collections/microsoft/ad/.azure-pipelines/scripts/run-tests.sh b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/run-tests.sh
new file mode 100755
index 000000000..a947fdf01
--- /dev/null
+++ b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/run-tests.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+# 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
+
+export COMMIT_MESSAGE
+export COMPLETE
+export COVERAGE
+export IS_PULL_REQUEST
+
+if [ "${SYSTEM_PULLREQUEST_TARGETBRANCH:-}" ]; then
+ IS_PULL_REQUEST=true
+ COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD^2)
+else
+ IS_PULL_REQUEST=
+ COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD)
+fi
+
+COMPLETE=
+COVERAGE=
+
+if [ "${BUILD_REASON}" = "Schedule" ]; then
+ COMPLETE=yes
+
+ if printf '%s\n' "${coverage_branches[@]}" | grep -q "^${BUILD_SOURCEBRANCHNAME}$"; then
+ COVERAGE=yes
+ fi
+fi
+
+"${entry_point}" "${test}" 2>&1 | "$(dirname "$0")/time-command.py"
diff --git a/ansible_collections/microsoft/ad/.azure-pipelines/scripts/time-command.py b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/time-command.py
new file mode 100755
index 000000000..5e8eb8d4c
--- /dev/null
+++ b/ansible_collections/microsoft/ad/.azure-pipelines/scripts/time-command.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+"""Prepends a relative timestamp to each input line from stdin and writes it to stdout."""
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import sys
+import time
+
+
+def main():
+ """Main program entry point."""
+ start = time.time()
+
+ sys.stdin.reconfigure(errors='surrogateescape')
+ sys.stdout.reconfigure(errors='surrogateescape')
+
+ for line in sys.stdin:
+ seconds = time.time() - start
+ sys.stdout.write('%02d:%02d %s' % (seconds // 60, seconds % 60, line))
+ sys.stdout.flush()
+
+
+if __name__ == '__main__':
+ main()