-
-
Save mjanser/8e2ea2f84b8c828267c86d9745d175dd to your computer and use it in GitHub Desktop.
Ansible Role Test Shim Script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # | |
| # Ansible role test shim. | |
| # | |
| # Usage: [OPTIONS] ./tests/test.sh | |
| # | |
| # Options are defined as environment variables: | |
| # - DISTRO: a supported Docker distro version (default = "centos") | |
| # - RELEASE: the release of the distro to use (default = "7") | |
| # - ANSIBLE: version of Ansible to use (default = "2.5") | |
| # - PLAYBOOK: a playbook in the tests directory (default = "test.yml") | |
| # - ROLE_DIR: the directory where the role exists (default = $PWD) | |
| # - CLEANUP: whether to remove the Docker container (default = 1) | |
| # - TEST_IDEMPOTENCE: whether to test playbook's idempotence (default = 1) | |
| # - ALLOW_ERRORS: whether to allow errors in playbook (default = 0) | |
| # - ALLOW_WARNINGS: whether to allow warnings in playbook (default = 0) | |
| # | |
| # If you place a requirements.yml file in tests/requirements.yml, the | |
| # requirements listed inside that file will be installed via Ansible Galaxy | |
| # prior to running tests. | |
| # | |
| # License: MIT | |
| # Pretty colors. | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| NEUTRAL='\033[0m' | |
| # Allow environment variables to override defaults. | |
| DISTRO=${DISTRO:-"centos"} | |
| RELEASE=${RELEASE:-"7"} | |
| ANSIBLE=${ANSIBLE:-"2.5"} | |
| PLAYBOOK=${PLAYBOOK:-"test.yml"} | |
| ROLE_DIR=${ROLE_DIR:-"$PWD"} | |
| CLEANUP=${CLEANUP:-1} | |
| TEST_IDEMPOTENCE=${TEST_IDEMPOTENCE:-1} | |
| ALLOW_ERRORS=${ALLOW_ERRORS:-0} | |
| ALLOW_WARNINGS=${ALLOW_WARNINGS:-0} | |
| CONTAINER_CREATED=0 | |
| ## Set up vars for Docker setup. | |
| case "${DISTRO}" in | |
| "centos") | |
| IMAGE="geerlingguy/docker-${DISTRO}${RELEASE}-ansible:latest" | |
| INIT="/usr/lib/systemd/systemd" | |
| OPTS="--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" | |
| if [ "${RELEASE}" -lt 7 ]; then | |
| INIT="/sbin/init" | |
| OPTS="--privileged" | |
| fi | |
| ;; | |
| "debian") | |
| IMAGE="geerlingguy/docker-${DISTRO}${RELEASE}-ansible:latest" | |
| INIT="/lib/systemd/systemd" | |
| OPTS="--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" | |
| ;; | |
| "ubuntu") | |
| IMAGE="geerlingguy/docker-${DISTRO}${RELEASE}-ansible:latest" | |
| INIT="/lib/systemd/systemd" | |
| OPTS="--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" | |
| if [ "${RELEASE}" -lt 1604 ]; then | |
| INIT="/sbin/init" | |
| OPTS="--privileged" | |
| fi | |
| ;; | |
| "fedora") | |
| IMAGE="geerlingguy/docker-${DISTRO}${RELEASE}-ansible:latest" | |
| INIT="/usr/lib/systemd/systemd" | |
| OPTS="--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" | |
| ;; | |
| *) | |
| printf ${RED}"Specified distro ""${DISTRO}"" is not supported!"${NEUTRAL}\n | |
| exit 1 | |
| ;; | |
| esac | |
| error() { | |
| printf ${RED}"FAILED!"${NEUTRAL}" See above for the error...\n" | |
| cleanup | |
| exit 1 | |
| } | |
| abort() { | |
| cleanup | |
| exit | |
| } | |
| cleanup() { | |
| # Remove the Docker container (if configured). | |
| if [ "${CLEANUP}" -eq 1 -a "${CONTAINERID}" != "" -a $CONTAINER_CREATED -eq 1 ]; then | |
| printf "Removing Docker container ${CONTAINERID}...\n" | |
| docker rm -f $CONTAINERID || true | |
| fi | |
| } | |
| trap error ERR | |
| trap abort SIGHUP | |
| trap abort SIGINT | |
| trap abort SIGTERM | |
| # Run the container using the supplied OS. | |
| CONTAINERID=$(date +%s) | |
| printf ${GREEN}"Starting Docker container: ${IMAGE}, id: ${CONTAINERID}."${NEUTRAL}"\n" | |
| docker pull $IMAGE | |
| docker run --detach --volume="$ROLE_DIR":/etc/ansible/roles/role_under_test:rw --name $CONTAINERID $OPTS $IMAGE $INIT | |
| CONTAINER_CREATED=1 | |
| printf "\n" | |
| # Install ansible. | |
| printf ${GREEN}"Installing Ansible version ${ANSIBLE}."${NEUTRAL}"\n" | |
| docker exec --tty $CONTAINERID env TERM=xterm pip install ansible~=${ANSIBLE}.0 | |
| printf "\n" | |
| # Install requirements if `requirements.yml` is present. | |
| if [ -f "${ROLE_DIR}/tests/requirements.yml" ]; then | |
| printf ${GREEN}"Requirements file detected; installing dependencies."${NEUTRAL}"\n" | |
| docker exec --tty $CONTAINERID env TERM=xterm ansible-galaxy install -r /etc/ansible/roles/role_under_test/tests/requirements.yml | |
| fi | |
| printf "\n" | |
| # Test Ansible syntax. | |
| printf ${GREEN}"Checking Ansible playbook syntax."${NEUTRAL} | |
| docker exec --tty $CONTAINERID env TERM=xterm ansible-playbook /etc/ansible/roles/role_under_test/tests/$PLAYBOOK --syntax-check | |
| printf "\n" | |
| # Run Ansible playbook. | |
| printf ${GREEN}"Running command: docker exec $CONTAINERID env TERM=xterm ansible-playbook /etc/ansible/roles/role_under_test/tests/$PLAYBOOK"${NEUTRAL} | |
| log=$(mktemp) | |
| docker exec $CONTAINERID env TERM=xterm env ANSIBLE_FORCE_COLOR=1 ansible-playbook /etc/ansible/roles/role_under_test/tests/$PLAYBOOK 2>&1 | tee -a $log | |
| if [ "$ALLOW_ERRORS" -eq 0 ]; then | |
| # Look for errors in log output. | |
| grep 'ERROR\|FAILED' $log \ | |
| && { printf ${RED}'Errors test: fail'${NEUTRAL}"\n"; error; } \ | |
| || { printf ${GREEN}'Errors test: pass'${NEUTRAL}"\n"; } | |
| fi | |
| if [ "$ALLOW_WARNINGS" -eq 0 ]; then | |
| # Look for warnings in log output. | |
| grep 'WARNING' $log \ | |
| && { printf ${RED}'Warnings test: fail'${NEUTRAL}"\n"; error; } \ | |
| || { printf ${GREEN}'Warnings test: pass'${NEUTRAL}"\n"; } | |
| fi | |
| if [ "$TEST_IDEMPOTENCE" -eq 1 ]; then | |
| # Run Ansible playbook again (idempotence test). | |
| printf ${GREEN}"Running playbook again: idempotence test"${NEUTRAL} | |
| idempotence=$(mktemp) | |
| docker exec $CONTAINERID ansible-playbook /etc/ansible/roles/role_under_test/tests/$PLAYBOOK | tee -a $idempotence | |
| tail $idempotence \ | |
| | grep -q 'changed=0.*failed=0' \ | |
| && { printf ${GREEN}'Idempotence test: pass'${NEUTRAL}"\n"; } \ | |
| || { printf ${RED}'Idempotence test: fail'${NEUTRAL}"\n"; error; } | |
| fi | |
| cleanup |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment