You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
5.0 KiB
192 lines
5.0 KiB
#! /bin/sh
|
|
# vim:et:ft=sh:sts=2:sw=2
|
|
#
|
|
# Unit test suite runner.
|
|
#
|
|
# Copyright 2008-2020 Kate Ward. All Rights Reserved.
|
|
# Released under the Apache 2.0 license.
|
|
#
|
|
# Author: kate.ward@forestent.com (Kate Ward)
|
|
# https://github.com/kward/shlib
|
|
#
|
|
# This script runs all the unit tests that can be found, and generates a nice
|
|
# report of the tests.
|
|
#
|
|
### Sample usage:
|
|
#
|
|
# Run all tests for all shells.
|
|
# $ ./test_runner
|
|
#
|
|
# Run all tests for single shell.
|
|
# $ ./test_runner -s /bin/bash
|
|
#
|
|
# Run single test for all shells.
|
|
# $ ./test_runner -t shunit_asserts_test.sh
|
|
#
|
|
# Run single test for single shell.
|
|
# $ ./test_runner -s /bin/bash -t shunit_asserts_test.sh
|
|
#
|
|
### ShellCheck (http://www.shellcheck.net/)
|
|
# Disable source following.
|
|
# shellcheck disable=SC1090,SC1091
|
|
# expr may be antiquated, but it is the only solution in some cases.
|
|
# shellcheck disable=SC2003
|
|
# $() are not fully portable (POSIX != portable).
|
|
# shellcheck disable=SC2006
|
|
|
|
# Return if test_runner already loaded.
|
|
[ -z "${RUNNER_LOADED:-}" ] || return 0
|
|
RUNNER_LOADED=0
|
|
|
|
RUNNER_ARGV0=`basename "$0"`
|
|
RUNNER_SHELLS='/bin/sh ash /bin/bash /bin/dash /bin/ksh /bin/mksh /bin/zsh'
|
|
RUNNER_TEST_SUFFIX='_test.sh'
|
|
true; RUNNER_TRUE=$?
|
|
false; RUNNER_FALSE=$?
|
|
|
|
runner_warn() { echo "runner:WARN $*" >&2; }
|
|
runner_error() { echo "runner:ERROR $*" >&2; }
|
|
runner_fatal() { echo "runner:FATAL $*" >&2; exit 1; }
|
|
|
|
runner_usage() {
|
|
echo "usage: ${RUNNER_ARGV0} [-e key=val ...] [-s shell(s)] [-t test(s)]"
|
|
}
|
|
|
|
_runner_tests() { echo ./*${RUNNER_TEST_SUFFIX} |sed 's#\./##g'; }
|
|
_runner_testName() {
|
|
# shellcheck disable=SC1117
|
|
_runner_testName_=`expr "${1:-}" : "\(.*\)${RUNNER_TEST_SUFFIX}"`
|
|
if [ -n "${_runner_testName_}" ]; then
|
|
echo "${_runner_testName_}"
|
|
else
|
|
echo 'unknown'
|
|
fi
|
|
unset _runner_testName_
|
|
}
|
|
|
|
main() {
|
|
# Find and load versions library.
|
|
for _runner_dir_ in . ${LIB_DIR:-lib}; do
|
|
if [ -r "${_runner_dir_}/versions" ]; then
|
|
_runner_lib_dir_="${_runner_dir_}"
|
|
break
|
|
fi
|
|
done
|
|
[ -n "${_runner_lib_dir_}" ] || runner_fatal 'Unable to find versions library.'
|
|
. "${_runner_lib_dir_}/versions" || runner_fatal 'Unable to load versions library.'
|
|
unset _runner_dir_ _runner_lib_dir_
|
|
|
|
# Process command line flags.
|
|
env=''
|
|
while getopts 'e:hs:t:' opt; do
|
|
case ${opt} in
|
|
e) # set an environment variable
|
|
key=`expr "${OPTARG}" : '\([^=]*\)='`
|
|
val=`expr "${OPTARG}" : '[^=]*=\(.*\)'`
|
|
# shellcheck disable=SC2166
|
|
if [ -z "${key}" -o -z "${val}" ]; then
|
|
runner_usage
|
|
exit 1
|
|
fi
|
|
eval "${key}='${val}'"
|
|
eval "export ${key}"
|
|
env="${env:+${env} }${key}"
|
|
;;
|
|
h) runner_usage; exit 0 ;; # help output
|
|
s) shells=${OPTARG} ;; # list of shells to run
|
|
t) tests=${OPTARG} ;; # list of tests to run
|
|
*) runner_usage; exit 1 ;;
|
|
esac
|
|
done
|
|
shift "`expr ${OPTIND} - 1`"
|
|
|
|
# Fill shells and/or tests.
|
|
shells=${shells:-${RUNNER_SHELLS}}
|
|
[ -z "${tests}" ] && tests=`_runner_tests`
|
|
|
|
# Error checking.
|
|
if [ -z "${tests}" ]; then
|
|
runner_error 'no tests found to run; exiting'
|
|
exit 1
|
|
fi
|
|
|
|
cat <<EOF
|
|
#------------------------------------------------------------------------------
|
|
# System data.
|
|
#
|
|
|
|
$ uname -mprsv
|
|
`uname -mprsv`
|
|
|
|
OS Name: `versions_osName`
|
|
OS Version: `versions_osVersion`
|
|
|
|
### Test run info.
|
|
shells: ${shells}
|
|
tests: ${tests}
|
|
EOF
|
|
for key in ${env}; do
|
|
eval "echo \"${key}=\$${key}\""
|
|
done
|
|
|
|
# Run tests.
|
|
runner_passing_=${RUNNER_TRUE}
|
|
for shell in ${shells}; do
|
|
echo
|
|
|
|
cat <<EOF
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Running the test suite with ${shell}.
|
|
#
|
|
EOF
|
|
|
|
# Check for existence of shell.
|
|
shell_bin=${shell}
|
|
shell_name=''
|
|
shell_present=${RUNNER_FALSE}
|
|
case ${shell} in
|
|
ash)
|
|
shell_bin=`command -v busybox`
|
|
[ $? -eq "${RUNNER_TRUE}" ] && shell_present="${RUNNER_TRUE}"
|
|
shell_bin="${shell_bin:+${shell_bin} }ash"
|
|
shell_name=${shell}
|
|
;;
|
|
*)
|
|
[ -x "${shell_bin}" ] && shell_present="${RUNNER_TRUE}"
|
|
shell_name=`basename "${shell}"`
|
|
;;
|
|
esac
|
|
if [ "${shell_present}" -eq "${RUNNER_FALSE}" ]; then
|
|
runner_warn "unable to run tests with the ${shell_name} shell"
|
|
continue
|
|
fi
|
|
|
|
shell_version=`versions_shellVersion "${shell}"`
|
|
|
|
echo "shell name: ${shell_name}"
|
|
echo "shell version: ${shell_version}"
|
|
|
|
# Execute the tests.
|
|
for t in ${tests}; do
|
|
echo
|
|
echo "--- Executing the '`_runner_testName "${t}"`' test suite. ---"
|
|
# ${shell_bin} needs word splitting.
|
|
# shellcheck disable=SC2086
|
|
( exec ${shell_bin} "./${t}" 2>&1; )
|
|
shell_passing=$?
|
|
if [ "${shell_passing}" -ne "${RUNNER_TRUE}" ]; then
|
|
runner_warn "${shell_bin} not passing"
|
|
fi
|
|
test "${runner_passing_}" -eq ${RUNNER_TRUE} -a ${shell_passing} -eq ${RUNNER_TRUE}
|
|
runner_passing_=$?
|
|
done
|
|
done
|
|
return ${runner_passing_}
|
|
}
|
|
|
|
# Execute main() if this is run in standalone mode (i.e. not from a unit test).
|
|
if [ -z "${SHUNIT_VERSION}" ]; then
|
|
main "$@"
|
|
fi
|