diff --git a/.travis.yml b/.travis.yml index bece3e9..f81b161 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,4 @@ python: sudo: false script: - - ./test/test_travis + - ./test/test diff --git a/test/README.md b/test/README.md index 993a753..9ec79f5 100644 --- a/test/README.md +++ b/test/README.md @@ -36,14 +36,24 @@ git submodule update --init --recursive Running the Tests ----------------- -Before running the tests, the virtual machine must be running. It can be -started by running `vagrant up`. +Before running the tests, you must SSH into the VM. Start it with `vagrant up` +and SSH in with `vagrant ssh`. All following commands must be run inside the +VM. -The test suite can be run by running `./test`. Selected tests can be run by -passing paths to the tests as arguments to `./test`. +First, you must install a version of Python to test against, using `pyenv +install -s {version}`. You can choose any version you like, e.g. `3.8.1`. It +isn't particularly important to test against all supported versions of Python +in the VM, because they will be tested by CI. Once you've installed a specific +version of Python, activate it with `pyenv global {version}`. -Tests can be run with a specific Python version by running `./test --version -` - for example, `./test --version 3.4.3`. +The VM mounts the Dotbot directory in `/dotbot` as read-only (you can make +edits on your host machine). You can run the test suite by `cd /dotbot/test` +and then running `./test`. Selected tests can be run by passing paths to the +tests as arguments, e.g. `./test tests/create.bash tests/defaults.bash`. + +To debug tests, you can prepend the line `DEBUG=true` as the first line to any +individual test (a `.bash` file inside `test/tests`). This will enable printing +stdout/stderr. When finished with testing, it is good to shut down the virtual machine by running `vagrant halt`. diff --git a/test/Vagrantfile b/test/Vagrantfile index 347c402..fbdfe39 100644 --- a/test/Vagrantfile +++ b/test/Vagrantfile @@ -1,8 +1,8 @@ Vagrant.configure(2) do |config| - config.vm.box = 'debian/buster64' + config.vm.box = 'ubuntu/bionic64' # sync by copying for isolation - config.vm.synced_folder "..", "/dotbot", type: "rsync" + config.vm.synced_folder "..", "/dotbot", mount_options: ["ro"] # disable default synced folder config.vm.synced_folder ".", "/vagrant", disabled: true diff --git a/test/driver-lib.bash b/test/driver-lib.bash index 02a71a5..dcbcba6 100644 --- a/test/driver-lib.bash +++ b/test/driver-lib.bash @@ -1,6 +1,3 @@ -MAXRETRY=5 -TIMEOUT=1 - red() { if [ -t 1 ]; then printf "\033[31m%s\033[0m\n" "$*" @@ -26,52 +23,35 @@ yellow() { } -check_prereqs() { - if ! (vagrant ssh -c 'exit') >/dev/null 2>&1; then - >&2 echo "vagrant vm must be running." - return 1 +check_env() { + if [[ "$(whoami)" != "vagrant" && ( "${TRAVIS}" != true || "${CI}" != true ) ]]; then + die "tests must be run inside Travis or Vagrant" fi } -until_success() { - local timeout=${TIMEOUT} - local attempt=0 - while [ $attempt -lt $MAXRETRY ]; do - if ($@) >/dev/null 2>&1; then - return 0 - fi - sleep $timeout - timeout=$((timeout * 2)) - attempt=$((attempt + 1)) - done - - return 1 -} - -wait_for_vagrant() { - until_success vagrant ssh -c 'exit' -} - cleanup() { - vagrant ssh -c " - find . -not \\( \ + ( + if [ "$(whoami)" == "vagrant" ]; then + cd $HOME + find . -not \( \ -path './.pyenv' -o \ -path './.pyenv/*' -o \ -path './.bashrc' -o \ -path './.profile' -o \ -path './.ssh' -o \ -path './.ssh/*' \ - \\) -delete" >/dev/null 2>&1 + \) -delete >/dev/null 2>&1 + else + find ~ -mindepth 1 -newermt "${date_stamp}" \ + -not \( -path ~ -o -path "${BASEDIR}/*" \ + -o -path ~/dotfiles \) \ + -exec rm -rf {} + + fi + ) || true } initialize() { echo "initializing." - if ! vagrant ssh -c "pyenv local ${2}" >/dev/null 2>&1; then - if ! vagrant ssh -c "pyenv install -s ${2} && pyenv local ${2}" >/dev/null 2>&1; then - die "could not install python ${2}" - fi - fi - vagrant rsync >/dev/null 2>&1 tests_run=0 tests_passed=0 tests_failed=0 @@ -96,8 +76,7 @@ run_test() { tests_run=$((tests_run + 1)) printf '[%d/%d] (%s)\n' "${tests_run}" "${tests_total}" "${1}" cleanup - vagrant ssh -c "pyenv local ${2}" >/dev/null 2>&1 - if vagrant ssh -c "cd /dotbot/test/tests && bash ${1}" 2>/dev/null; then + if (cd "${BASEDIR}/test/tests" && DOTBOT_TEST=true bash "${1}"); then pass else fail diff --git a/test/test b/test/test index c018c32..f944512 100755 --- a/test/test +++ b/test/test @@ -1,37 +1,21 @@ #!/usr/bin/env bash set -e -BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd "${BASEDIR}" +export BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "${BASEDIR}/test" . "./driver-lib.bash" +date_stamp="$(date --rfc-3339=ns)" start="$(date +%s)" -check_prereqs || die "prerequisites unsatsfied." - -# command line options -while [[ $# > 1 ]] -do - key="${1}" - case $key in - -v|--version) - VERSION="${2}" - shift && shift - ;; - *) - # unknown option - break - ;; - esac -done -VERSION="${VERSION:-3.6.4}" +check_env declare -a tests=() if [ $# -eq 0 ]; then while read file; do tests+=("${file}") - done < <(find tests -type f -name '*.bash') + done < <(find tests -type f -name '*.bash' | sort) else tests=("$@") fi diff --git a/test/test-lib.bash b/test/test-lib.bash index e4d9a4e..fba9aa0 100644 --- a/test/test-lib.bash +++ b/test/test-lib.bash @@ -1,6 +1,5 @@ DEBUG=${DEBUG:-false} -USE_VAGRANT=${USE_VAGRANT:-true} -DOTBOT_EXEC=${DOTBOT_EXEC:-"python /dotbot/bin/dotbot"} +DOTBOT_EXEC="${BASEDIR}/bin/dotbot" DOTFILES="/home/$(whoami)/dotfiles" INSTALL_CONF='install.conf.yaml' INSTALL_CONF_JSON='install.conf.json' @@ -29,17 +28,15 @@ test_expect_failure() { fi } -check_vm() { - if [ "$(whoami)" != "vagrant" ]; then - >&2 echo "test can't run outside vm!" +check_env() { + if [ "${DOTBOT_TEST}" != "true" ]; then + >&2 echo "test must be run by test driver" exit 1 fi } initialize() { - if ${USE_VAGRANT}; then - check_vm - fi + check_env echo "${test_description}" mkdir -p "${DOTFILES}" cd diff --git a/test/test_travis b/test/test_travis deleted file mode 100755 index 79439e1..0000000 --- a/test/test_travis +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env bash -set -e - -# For debug only: -# export DEBUG=true -# set -x -# set -v - -export BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" - -# Prevent execution outside of Travis CI builds -if [[ "${TRAVIS}" != true || "${CI}" != true ]]; then - echo "Error: `basename "$0"` should only be used on Travis" - exit 2 -fi - -# Travis runs do not rely on Vagrant -export USE_VAGRANT=false -export DOTBOT_EXEC="${BASEDIR}/bin/dotbot" - -cd "${BASEDIR}" -. "test/driver-lib.bash" - -travis_initialize() { - echo "initializing." - 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}" -} - -travis_cleanup() { - # Remove all dotfiles installed since the start, ignoring the main - # dotfiles directory, and the dotbot source directory - find ~ -mindepth 1 -newermt "${date_stamp}" \ - -not \( -path ~ -o -path "${BASEDIR}/*" \ - -o -path ~/dotfiles \) \ - -exec rm -rf {} + -} - -travis_run_test() { - tests_run=$((tests_run + 1)) - printf '[%d/%d] (%s)\n' "${tests_run}" "${tests_total}" "${1}" - cd ${BASEDIR}/test/tests - if bash ${1} ; then - pass - else - fail - fi - travis_cleanup || die "unable to clean up system." -} - -date_stamp="$(date --rfc-3339=ns)" -start="$(date +%s)" - -declare -a tests=() - -if [ $# -eq 0 ]; then - while read file; do - tests+=("${file}") - done < <(find ${BASEDIR}/test/tests -type f -name '*.bash') -else - tests=("$@") -fi - -travis_initialize "${#tests[@]}" - -for file in "${tests[@]}"; do - travis_run_test "$(basename "${file}")" -done - -if report; then - ret=0 -else - ret=1 -fi - -echo "(tests run in $(($(date +%s) - start)) seconds)" -exit ${ret} diff --git a/test/tests/find-python-executable.bash b/test/tests/find-python-executable.bash index 9a91a74..561b882 100644 --- a/test/tests/find-python-executable.bash +++ b/test/tests/find-python-executable.bash @@ -1,18 +1,16 @@ test_description='can find python executable with different names' . '../test-lib.bash' -if ${USE_VAGRANT}; then - DOTBOT_EXEC="/dotbot/bin/dotbot" # revert to calling it as a shell script -fi - # the test machine needs to have a binary named `python` test_expect_success 'setup' ' mkdir ~/tmp_bin && ( IFS=: for p in $PATH; do - find $p -maxdepth 1 -mindepth 1 -exec sh -c \ + if [ -d $p ]; then + find $p -maxdepth 1 -mindepth 1 -exec sh -c \ '"'"'ln -sf {} $HOME/tmp_bin/$(basename {})'"'"' \; + fi done ) && rm -f ~/tmp_bin/python && diff --git a/test/tests/shim.bash b/test/tests/shim.bash index 2ed7d54..ddacae3 100644 --- a/test/tests/shim.bash +++ b/test/tests/shim.bash @@ -4,11 +4,7 @@ test_description='install shim works' test_expect_success 'setup' ' cd ${DOTFILES} git init -if ${USE_VAGRANT}; then - git submodule add /dotbot dotbot -else - git submodule add ${BASEDIR} dotbot -fi +git submodule add ${BASEDIR} dotbot cp ./dotbot/tools/git-submodule/install . echo "pear" > ${DOTFILES}/foo ' @@ -18,9 +14,6 @@ cat > ${DOTFILES}/install.conf.yaml <