timewarrior/test/timemachine
Thomas Lauf 11a57e3cc5 Improve timemachine test-script
- Fix `--fail-at-end` option
- Collect errors and print report at end
- Make variable `tests` an array, add safeguards
- Combine cases
- Make variables `dates`, `hours`, `minutes` an array, add `pad_with_zero` function
- Execute test with specific 'runtime', so it picks up fake time
  - Python scripts are then executed as `faketime <date> python3 <test>`
  - Shell scripts as `faketime <date> bash <test>`
  - Everything else as `faketime <date> <test>`

Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
2021-11-12 21:59:07 +01:00

147 lines
2.7 KiB
Bash
Executable file

#!/bin/bash
function default_dates()
{
case "${OSTYPE}" in
darwin*)
date "+%Y-%m-%d"
;;
*)
date --rfc-3339=date
;;
esac
}
function default_minutes()
{
case "${OSTYPE}" in
darwin*)
pad_with_zero "$( jot -r 1 0 59 )"
;;
*)
pad_with_zero "$( rand -M 60 )"
;;
esac
}
function default_hours()
{
seq -w 0 23
}
function pad_with_zero()
{
case "${OSTYPE}" in
darwin*)
echo "0${1}" | sed -E "s|.+(..)|\1|g"
;;
*)
echo "0${1}" | sed "s|.\+\(..\)\$|\1|g"
;;
esac
}
function get_runtime_for()
{
local test_file="${1}"
case "$( file -b "${test_file}" )" in
"POSIX shell"*)
echo "bash"
;;
"Python script"*)
echo "python3"
;;
*)
;;
esac
}
if ! command -v faketime >/dev/null 2>&1 ; then
echo "timemachine requires libfaketime to be installed!"
exit 1
fi
declare -a tests=()
declare -a dates=()
declare -a hours=()
declare -a minutes=()
# parse options/arguments
until [[ -z "${1}" ]] ; do
case "${1}" in
--minute|--minutes)
shift
minutes=( "${minutes[@]}" "$( pad_with_zero "${1}" )" )
;;
--hour|--hours)
shift
hours=( "${hours[@]}" "$( pad_with_zero "${1}" )" )
;;
--date)
shift
dates=( "${dates[@]}" "${1}" )
;;
--fail-at-end)
fail_at_end="yes"
;;
-*)
echo "Unknown option '${1}'"
exit 1
;;
*)
tests=( "${tests[@]}" "${1}" )
;;
esac
shift
done
if [[ "${#tests[@]}" -eq 0 ]] ; then
echo "No tests specified!"
exit 1
fi
for single_test in "${tests[@]}" ; do
if [[ ! -e "${single_test}" ]] ; then
echo "Test '${single_test}' does not exist!"
exit 1
fi
done
if [[ "${#dates[@]}" -eq 0 ]] ; then
read -d '' -r -a dates <<< "$( default_dates )"
fi
if [[ "${#hours[@]}" -eq 0 ]] ; then
read -d '' -r -a hours <<< "$( default_hours )"
fi
if [[ "${#minutes[@]}" -eq 0 ]] ; then
read -d '' -r -a minutes <<< "$( default_minutes )"
fi
REPORT=
for date in "${dates[@]}" ; do
for hour in "${hours[@]}" ; do
for minute in "${minutes[@]}" ; do
date_time="${date}T${hour}:${minute}"
for single_test in "${tests[@]}" ; do
runtime=$( get_runtime_for "${single_test}" )
echo "Running test ${single_test} at ${date_time}${runtime:+" with ${runtime}"}"
if ! faketime "${date_time}" ${runtime} "${single_test}" ; then
REPORT+="${REPORT+$'\n'}Test ${single_test} broke at ${date_time}!"
[[ "${fail_at_end-"no"}" == "no" ]] && break 4
fi
done
done
done
done
if [[ -n "${REPORT}" ]] ; then
echo "There were test failures:"
echo -e "${REPORT}"
else
echo "All tests passed!"
fi