42-archive/42sh/42ShellTester/lib/main.sh
2017-03-24 17:43:33 +01:00

280 lines
11 KiB
Bash

#!/bin/bash
# /*
# Main function
#
# run_main
# function that:
# - iterates over the spec folder
# - executes the tests and their callbacks
# - displays the results
# */
run_main()
{
local TEST
local TEST_NAME
local TEST_FULLNAME
local RESULT
local RESPONSE_STDOUT
local RESPONSE_STDERR
local EXIT_STATUS
local RESPONSE_REFERENCE_STDOUT
local RESPONSE_REFERENCE_STDERR
local REFERENCE_EXIT_STATUS
local RUN_TEST
local RUN_ASSERT
local TEST_STATUS
local ASSERT_STATUS
local LOG_CURRENT_TEST
local LOG_CURRENT_TEST_STDOUT
local LOG_CURRENT_TEST_STDERR
local LOG_CURRENT_TEST_MISC
local LOG_SUCCESS_TESTS
local LOG_FAILED_TESTS
local AWK_PATH="$(which "awk")"
local OLD_IFS="${IFS}"
local UNAME=`uname`
local FIND="find"
# Use find instead find -E on Linux
if [ {UNAME} == "Darwin" ]; then
FIND= "find -E"
fi
if [ ! -f "${GLOBAL_PROG}" ]
then
[ "${GLOBAL_PROG}" == "" ] && printf "%s\n" "Missing argument: specify the binary to test" && return
[ ! -f "${GLOBAL_PROG}" -a ! -f "$(which "${GLOBAL_PROG}")" ] && printf "%s\n" "Wrong argument: no such file '"${GLOBAL_PROG}"'" && return
fi
IFS=$'\n'
for TEST in $(${FIND} "${GLOBAL_INSTALLDIR}/spec" -type d -regex "${GLOBAL_INSTALLDIR}/spec/.*${GLOBAL_SPECS_FILTER}.*")
do
[ -f "${TEST}/pending" -a "${GLOBAL_RUN_PENDING_TESTS}" == "0" ] && (( GLOBAL_TOTAL_PENDING_TESTS = GLOBAL_TOTAL_PENDING_TESTS + 1 ))
if [ -f "${TEST}/stdin" ] && [ ! -f "${TEST}/non-posix" -o "${GLOBAL_RUN_POSIX_ONLY}" == "0" ] && [ ! -f "${TEST}/pending" -o "${GLOBAL_RUN_PENDING_TESTS}" == "1" -o "${GLOBAL_RUN_ALL_TESTS}" == "1" ] && [ ! -f "${TEST}/hard" -o "${GLOBAL_RUN_HARD_TESTS}" == "1" -o "${GLOBAL_RUN_ALL_TESTS}" == "1" ]
then
# compile support binaries
make -C "${GLOBAL_INSTALLDIR}/support/" TARGET_DIR=${GLOBAL_TMP_DIRECTORY} 1>- 2>-
TEST_NAME="${TEST##*/}"
TEST_FULLNAME="${TEST##*spec/}"
RUN_TEST=0
TEST_STATUS="0"
LOG_CURRENT_TEST="${TEST_FULLNAME}"
LOG_CURRENT_TEST_STDOUT=""
LOG_CURRENT_TEST_STDERR=""
LOG_CURRENT_TEST_MISC=""
RESPONSE_STDOUT="${GLOBAL_TMP_DIRECTORY}/${TEST_FULLNAME//\//-}.stdout"
RESPONSE_STDERR="${GLOBAL_TMP_DIRECTORY}/${TEST_FULLNAME//\//-}.stderr"
RESPONSE_REFERENCE_STDOUT="${GLOBAL_TMP_DIRECTORY}/${TEST_FULLNAME//\//-}.ref.stdout"
RESPONSE_REFERENCE_STDERR="${GLOBAL_TMP_DIRECTORY}/${TEST_FULLNAME//\//-}.ref.stderr"
rm -f "${GLOBAL_TMP_DIRECTORY}/stdin"
local INDEX=1
local LINE
local TOTAL=$(awk 'END {print NR+1}' "${TEST}/stdin")
while [ "$INDEX" -le "$TOTAL" ]
do
awk -v INDEX="${INDEX}" -v GLOBAL_TOKEN="${GLOBAL_TOKEN}" -v GLOBAL_INSTALLDIR="${GLOBAL_INSTALLDIR}" -v GLOBAL_TMP_DIRECTORY="${GLOBAL_TMP_DIRECTORY}" -v PATH="${PATH}" -v HOME="${HOME}" 'NR == INDEX {gsub(/\$\{GLOBAL_TOKEN\}/, GLOBAL_TOKEN); gsub(/\$\{GLOBAL_INSTALLDIR\}/, GLOBAL_INSTALLDIR); gsub(/\$\{GLOBAL_TMP_DIRECTORY\}/, GLOBAL_TMP_DIRECTORY); gsub(/\$\{PATH\}/, PATH); gsub(/\$\{HOME\}/, HOME); print; exit}' "${TEST}/stdin" >>"${GLOBAL_TMP_DIRECTORY}/stdin"
(( INDEX += 1 ))
done
(
SUBSHELL_EXIT_STATUS=
if [ -f "${TEST}/before_exec" ]
then
local INDEX=0
local TOTAL=$(${AWK_PATH} 'END {print NR+1}' "${TEST}/before_exec")
while [ "$INDEX" -le "$TOTAL" ]
do
eval $(${AWK_PATH} -v INDEX="${INDEX}" 'NR == INDEX {print $0; exit}' "${TEST}/before_exec")
(( INDEX += 1 ))
done
fi
eval "${GLOBAL_PROG}" < "${GLOBAL_TMP_DIRECTORY}/stdin" 1> "${RESPONSE_STDOUT}.raw" 2> "${RESPONSE_STDERR}.raw"
SUBSHELL_EXIT_STATUS=${?}
if [ -f "${TEST}/after_exec" ]
then
local INDEX=0
local TOTAL=$(${AWK_PATH} 'END {print NR+1}' "${TEST}/after_exec")
while [ "$INDEX" -le "$TOTAL" ]
do
eval $(${AWK_PATH} -v INDEX="${INDEX}" 'NR == INDEX {print $0; exit}' "${TEST}/after_exec")
(( INDEX += 1 ))
done
fi
exit "${SUBSHELL_EXIT_STATUS}"
)
EXIT_STATUS=${?}
awk '{gsub(/\033\[[0-9;]*m/, ""); print}' "${RESPONSE_STDOUT}.raw" > "${RESPONSE_STDOUT}"
awk '{gsub(/\033\[[0-9;]*m/, ""); print}' "${RESPONSE_STDERR}.raw" > "${RESPONSE_STDERR}"
if [ "${GLOBAL_PROG_REFERENCE}" != "" ]
then
(
SUBSHELL_EXIT_STATUS=
if [ -f "${TEST}/before_exec" ]
then
local INDEX=0
local TOTAL=$(${AWK_PATH} 'END {print NR+1}' "${TEST}/before_exec")
while [ "$INDEX" -le "$TOTAL" ]
do
eval $(${AWK_PATH} -v INDEX="${INDEX}" 'NR == INDEX {print $0; exit}' "${TEST}/before_exec")
(( INDEX += 1 ))
done
fi
eval "${GLOBAL_PROG_REFERENCE}" < "${GLOBAL_TMP_DIRECTORY}/stdin" 1> "${RESPONSE_REFERENCE_STDOUT}.raw" 2> "${RESPONSE_REFERENCE_STDERR}.raw"
SUBSHELL_EXIT_STATUS=${?}
if [ -f "${TEST}/after_exec" ]
then
local INDEX=0
local TOTAL=$(${AWK_PATH} 'END {print NR+1}' "${TEST}/after_exec")
while [ "$INDEX" -le "$TOTAL" ]
do
eval $(${AWK_PATH} -v INDEX="${INDEX}" 'NR == INDEX {print $0; exit}' "${TEST}/after_exec")
(( INDEX += 1 ))
done
fi
exit "${SUBSHELL_EXIT_STATUS}"
)
REFERENCE_EXIT_STATUS=${?}
awk '{gsub(/\033\[[0-9;]*m/, ""); print}' "${RESPONSE_REFERENCE_STDOUT}.raw" > "${RESPONSE_REFERENCE_STDOUT}"
awk '{gsub(/\033\[[0-9;]*m/, ""); print}' "${RESPONSE_REFERENCE_STDERR}.raw" > "${RESPONSE_REFERENCE_STDERR}"
fi
if [ -f "${TEST}/stdout" ]
then
RUN_ASSERT="0"
if [ "${GLOBAL_PROG_REFERENCE}" != "" ]
then
run_assert "REFERENCE_" "STDOUT" 1>- 2>-
RUN_ASSERT="${?}"
fi
if [ "${RUN_ASSERT}" == "0" ]
then
LOG_CURRENT_TEST_STDOUT="$(run_assert "" "STDOUT")"
ASSERT_STATUS="${?}"
if [ "${ASSERT_STATUS}" != "0" ]
then
[ "${TEST_STATUS}" == "0" -o "${TEST_STATUS}" == "2" ] && TEST_STATUS="${ASSERT_STATUS}"
fi
RUN_TEST=1
fi
fi
if [ -f "${TEST}/stderr" ]
then
RUN_ASSERT="0"
if [ "${GLOBAL_PROG_REFERENCE}" != "" ]
then
run_assert "REFERENCE_" "STDERR" 1>- 2>-
RUN_ASSERT="${?}"
fi
if [ "${RUN_ASSERT}" == "0" ]
then
LOG_CURRENT_TEST_STDERR="$(run_assert "" "STDERR")"
ASSERT_STATUS="${?}"
if [ "${ASSERT_STATUS}" != "0" ]
then
[ "${TEST_STATUS}" == "0" -o "${TEST_STATUS}" == "2" ] && TEST_STATUS="${ASSERT_STATUS}"
fi
RUN_TEST=1
fi
fi
if [ -f "${TEST}/misc" ]
then
RUN_ASSERT="0"
if [ "${GLOBAL_PROG_REFERENCE}" != "" ]
then
run_assert "REFERENCE_" "MISC" 1>- 2>-
RUN_ASSERT="${?}"
fi
if [ "${RUN_ASSERT}" == "0" ]
then
LOG_CURRENT_TEST_MISC="$(run_assert "" "MISC")"
ASSERT_STATUS="${?}"
if [ "${ASSERT_STATUS}" != "0" ]
then
[ "${TEST_STATUS}" == "0" -o "${TEST_STATUS}" == "2" ] && TEST_STATUS="${ASSERT_STATUS}"
fi
RUN_TEST=1
fi
fi
if [ "${RUN_TEST}" == "1" ]
then
(( GLOBAL_TOTAL_TESTS = GLOBAL_TOTAL_TESTS + 1 ))
if [ "${TEST_STATUS}" != "0" -o "${GLOBAL_SHOW_SUCCESS}" == "1" ]
then
GLOBAL_LOG="$(printf "%s\n\n%s\n\n${C_BOLD}%s${C_CLEAR}" "${GLOBAL_LOG}" "----------------------------------------------------------------" "${LOG_CURRENT_TEST}")"
case "${TEST_STATUS}" in
0) GLOBAL_LOG="$(printf "%s ${C_GREEN}%s${C_CLEAR}" "${GLOBAL_LOG}" "(SUCCESS)")" ;;
1) GLOBAL_LOG="$(printf "%s ${C_RED}%s${C_CLEAR}" "${GLOBAL_LOG}" "(FAILED)")" ;;
2) GLOBAL_LOG="$(printf "%s ${C_YELLOW}%s${C_CLEAR}" "${GLOBAL_LOG}" "(WARNING)")" ;;
255) GLOBAL_LOG="$(printf "%s ${C_RED}%s${C_CLEAR}" "${GLOBAL_LOG}" "(RUNTIME ERROR)")" ;;
esac
[ -f "${TEST}/description" ] && GLOBAL_LOG="$(printf "%s\n\n Description:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk '{printf " %s\n", $0}' "${TEST}/description")")"
[ -f "${TEST}/before_exec" ] && GLOBAL_LOG="$(printf "%s\n\n Before test:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk -v GLOBAL_TOKEN="${GLOBAL_TOKEN}" -v GLOBAL_INSTALLDIR="${GLOBAL_INSTALLDIR}" -v GLOBAL_TMP_DIRECTORY="${GLOBAL_TMP_DIRECTORY}" -v PATH="${PATH}" -v HOME="${HOME}" '{gsub(/\$\{GLOBAL_TOKEN\}/, GLOBAL_TOKEN); gsub(/\$\{GLOBAL_INSTALLDIR\}/, GLOBAL_INSTALLDIR); gsub(/\$\{GLOBAL_TMP_DIRECTORY\}/, GLOBAL_TMP_DIRECTORY); gsub(/\$\{PATH\}/, PATH); gsub(/\$\{HOME\}/, HOME); printf " %02s: %s\n", NR, $0}' "${TEST}/before_exec")")"
GLOBAL_LOG="$(printf " %s\n\n STDIN:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk '{printf " %02s: %s\n", NR, $0}' "${GLOBAL_TMP_DIRECTORY}/stdin")")"
if [ "${LOG_CURRENT_TEST_STDOUT}" != "" ]
then
GLOBAL_LOG="$(printf "%s\n\n STDOUT:\n%s\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "${LOG_CURRENT_TEST_STDOUT}" "$(awk '{printf " %02s: %s\n", NR, $0} END {if (NR==0) { print " (no output)" }}' "${RESPONSE_STDOUT}")")"
else
GLOBAL_LOG="$(printf "%s\n\n STDOUT:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk '{printf " %02s: %s\n", NR, $0} END {if (NR==0) { print " (no output)" }}' "${RESPONSE_STDOUT}")")"
fi
if [ "${LOG_CURRENT_TEST_STDERR}" != "" ]
then
GLOBAL_LOG="$(printf "%s\n\n STDERR:\n%s\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "${LOG_CURRENT_TEST_STDERR}" "$(awk '{printf " %02s: %s\n", NR, $0} END {if (NR==0) { print " (no output)" }}' "${RESPONSE_STDERR}")")"
else
GLOBAL_LOG="$(printf "%s\n\n STDERR:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk '{printf " %02s: %s\n", NR, $0} END {if (NR==0) { print " (no output)" }}' "${RESPONSE_STDERR}")")"
fi
[ "${LOG_CURRENT_TEST_MISC}" != "" ] && GLOBAL_LOG="$(printf "%s\n\n MISC:\n%s" "${GLOBAL_LOG}" "${LOG_CURRENT_TEST_MISC}")"
[ -f "${TEST}/after_exec" ] && GLOBAL_LOG="$(printf "%s\n\n After test:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk -v GLOBAL_TOKEN="${GLOBAL_TOKEN}" -v GLOBAL_INSTALLDIR="${GLOBAL_INSTALLDIR}" -v GLOBAL_TMP_DIRECTORY="${GLOBAL_TMP_DIRECTORY}" -v PATH="${PATH}" -v HOME="${HOME}" '{gsub(/\$\{GLOBAL_TOKEN\}/, GLOBAL_TOKEN); gsub(/\$\{GLOBAL_INSTALLDIR\}/, GLOBAL_INSTALLDIR); gsub(/\$\{GLOBAL_TMP_DIRECTORY\}/, GLOBAL_TMP_DIRECTORY); gsub(/\$\{PATH\}/, PATH); gsub(/\$\{HOME\}/, HOME); printf " %02s: %s\n", NR, $0}' "${TEST}/after_exec")")"
[ "${TEST_STATUS}" == "1" ] && (( GLOBAL_TOTAL_FAILED_TESTS = GLOBAL_TOTAL_FAILED_TESTS + 1 ))
fi
case "${TEST_STATUS}" in
0) printf "${C_GREEN}.${C_CLEAR}" ;;
1) printf "${C_RED}x${C_CLEAR}" ;;
2) printf "${C_YELLOW}~${C_CLEAR}" ;;
255) printf "${C_RED}!${C_CLEAR}" ;;
esac
fi
fi
done
IFS="${OLD_IFS}"
}