diff --git a/test/README.md b/test/README.md index c4abddc..68efe33 100644 --- a/test/README.md +++ b/test/README.md @@ -1,27 +1,45 @@ Testing ======= -Dotbot testing code uses [Vagrant][vagrant] to run all tests inside a virtual -machine to have tests be completely isolated from the host machine. The test -driver relies on the [Sahara][sahara] plugin to snapshot and roll back virtual -machine state. The tests are deterministic, and each test is run in a virtual -machine with fresh state, ensuring that tests that modify system state are -easily repeatable. +Dotbot testing code can use [Docker][docker] or [Vagrant][vagrant] to run all tests inside a virtual +environment to have tests be completely isolated from the host machine. The tests are deterministic, +and each test is run in a virtual environment with fresh state, ensuring that tests that modify +system state are easily repeatable. + +**NOTE:** [Vagrant][vagrant] test driver relies on the [Sahara][sahara] plugin to snapshot and roll back virtual +machine state. Running the Tests ----------------- - +### Vagrant Before running the tests, the virtual machine must be running. It can be -started by running `vagrant up`. +started by running ```vagrant up```. -The test suite can be run by running `./test`. Selected tests can be run by -passing paths to the tests as arguments to `./test`. +The test suite can be executed by running ```./test```. -Tests can be run with a specific Python version by running `./test --version -` - for example, `./test --version 3.4.3`. +Selected tests can be run by passing paths to the tests as arguments to ```./test```. Example: ```./test defaults.bash``` + +Tests can be run with a specific Python version by passing it's version as argument with key ```--version``` or ```-v```. Examples: ```./test --version 2.7.13```, ```./test -v 3.5```. + +You can also combine both of this for sure. Example: ```./test --version 3.6.0 clean-outsude.bash```. When finished with testing, it is good to shut down the virtual machine by -running `vagrant halt`. +running ```vagrant halt```. +### Docker +Before running the tests, ensure that you have [Docker][docker] installed. + +The test suite can be executed by running ```./test_docker``` (with appropriate rights for running docker binary). + +Selected tests can be run by passing paths to the tests as arguments to ```./test_docker```. Example: ```./test defaults.bash``` + +Tests can be run with a specific Python version by passing it's version as argument with key ```--version``` or ```-v```. Examples: ```./test_docker --version 2.7.13```, ```./test_docker -v 3.5```. + +You can also combine both of this for sure. Example: ```./test_docker --version 3.6.0 clean-outsude.bash```. + +When finished, container will be deleted. But you have to manually remove unnecessary docker images (```docker rmi python:tag```), where *tag* - version of Python, that you've passed to the script (```docker rmi python:2.7.9``` by default, if no version was specified). + + +[docker]: https://www.docker.com/ [vagrant]: https://www.vagrantup.com/ [sahara]: https://github.com/jedi4ever/sahara diff --git a/test/test-lib.bash b/test/test-lib.bash index affb5c9..4d57235 100644 --- a/test/test-lib.bash +++ b/test/test-lib.bash @@ -1,7 +1,7 @@ DEBUG=${DEBUG:-false} USE_VAGRANT=${USE_VAGRANT:-true} DOTBOT_EXEC=${DOTBOT_EXEC:-"/dotbot/bin/dotbot"} -DOTFILES="/home/$(whoami)/dotfiles" +DOTFILES="${HOME:-/home/$(whoami)}/dotfiles" INSTALL_CONF='install.conf.yaml' INSTALL_CONF_JSON='install.conf.json' diff --git a/test/test_docker b/test/test_docker new file mode 100755 index 0000000..d148586 --- /dev/null +++ b/test/test_docker @@ -0,0 +1,125 @@ +#!/usr/bin/env bash + +set -e + +DEBUG=false +# set -x +# set -v + + +BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +cd $BASE_DIR +. "${BASE_DIR}/driver-lib.bash" + +start="$(date +%s)" + +CONTAINER="dotbot_test" + +system_check_docker () { + if [[ ! "$(which docker)" ]]; then + return 1 + fi +} + +container_command_remove () { + docker rm -f ${CONTAINER} > /dev/null 2>&1 +} + +container_command_run () { + docker run \ + -v $PWD/../:/dotbot \ + -e USE_VAGRANT='false' \ + -e DEBUG="${DEBUG:-false}" \ + --name "${CONTAINER}" \ + -d "python:${1}" \ + tail -f /dev/null \ + > /dev/null 2>&1 +} + +container_execute () { + docker exec $CONTAINER /bin/bash -c "${1}" +} + +die() { + >&2 echo $@ + >&2 echo "Aborting..." + return 1 +} + +docker_start_container () { + IMAGE_TAG="${1}" + if [[ $(docker ps -q -f name=${CONTAINER}) ]]; then + container_command_remove + fi + system_check_docker || die "Could not find docker binary" + container_command_run "${IMAGE_TAG}" || die "Could not find python image with tag: ${IMAGE_TAG}" +} + + +while [[ $# > 1 ]] +do + key="${1}" + case $key in + -v|--version) + VERSION="${2}" + shift && shift + ;; + *) + # unknown option + break + ;; + esac +done + +initialize () { + echo "Initializing" + docker_start_container "${2}" + tests_run=0 + tests_passed=0 + tests_failed=0 + tests_total="${1}" + local plural="" && [ "${tests_total}" -gt 1 ] && plural="s" + printf -- "Running %d test%s...\n\n" "${tests_total}" "${plural}" +} + +run_test() { + tests_run=$((tests_run + 1)) + printf '[%d/%d] (%s)\n' "${tests_run}" "${tests_total}" "${1}" + docker_start_container "${2}" + if container_execute "cd /dotbot/test/tests && bash ${1}" 2>/dev/null; then + pass + else + fail + fi +} + +VERSION="${VERSION:-2.7.9}" + +declare -a tests=() + +if [ $# -eq 0 ]; then + while read file; do + tests+=("${file}") + done < <(find ${BASE_DIR}/tests -type f -name '*.bash') +else + tests=("$@") +fi + +initialize "${#tests[@]}" "${VERSION}" + + +for file in "${tests[@]}"; do + run_test "$(basename "${file}")" "${VERSION}" +done + +container_command_remove + +if report; then + ret=0 +else + ret=1 +fi + +echo "(tests run in $(($(date +%s) - start)) seconds)" +exit ${ret}