summaryrefslogtreecommitdiff
path: root/util/sidparse_test.sh
diff options
context:
space:
mode:
Diffstat (limited to 'util/sidparse_test.sh')
-rwxr-xr-xutil/sidparse_test.sh344
1 files changed, 344 insertions, 0 deletions
diff --git a/util/sidparse_test.sh b/util/sidparse_test.sh
new file mode 100755
index 0000000..feeb9ce
--- /dev/null
+++ b/util/sidparse_test.sh
@@ -0,0 +1,344 @@
+#!/usr/bin/env bash
+
+set -u
+
+declare -r SELF=$(basename $0)
+declare testme="sidparse.native"
+declare verbose=no
+declare current_test=""
+declare -A tests=()
+declare -a failed=()
+declare -r default_timeout=5 # s
+
+declare -r tput_bin=$(command -v tput)
+
+if [ -t 1 ] && [ -n "${tput_bin:-}" ]; then
+ declare -rA colors=( \
+ [blk]=$("${tput_bin}" setaf 0) \
+ [red]=$("${tput_bin}" setaf 1) \
+ [grn]=$("${tput_bin}" setaf 2) \
+ [ylw]=$("${tput_bin}" setaf 3) \
+ [blu]=$("${tput_bin}" setaf 4) \
+ [pur]=$("${tput_bin}" setaf 5) \
+ [cyn]=$("${tput_bin}" setaf 6) \
+ [wht]=$("${tput_bin}" setaf 7) \
+ [nil]="" \
+ [rst]=$("${tput_bin}" sgr0) \
+ )
+
+ msg () {
+ local col="${colors[$1]}"
+ local tag="$2"
+ local msg="$3"
+
+ printf "[${col}%s${colors[rst]}] %s\n" "${tag}" "${msg}"
+ }
+else
+ msg () {
+ local _void="$1"
+ local tag="$2"
+ local msg="$3"
+
+ printf "[%s] %s\n" "${tag}" "${msg}"
+ }
+fi
+
+msg_noise () {
+ if [ "${verbose:-uhgno}" = yes ]; then
+ msg pur info "$*" >&2
+ fi
+}
+
+msg_error () {
+ msg red error "$*" >&2
+}
+
+msg_fatal () {
+ msg_error $@
+ exit -1
+}
+
+msg_failed () {
+ local tag="$1"
+ shift
+
+ msg red "${tag}" "$*" >&2
+}
+
+msg_good () {
+ msg grn nice "$*" >&2
+}
+
+fail () {
+ local name="$1"
+ local condition="$2"
+ local cmd=""
+
+ shift 2
+ if [ $# -ne 0 ]; then
+ cmd=": [$*]"
+ fi
+
+ local entry="${name} (${condition})${cmd}"
+
+ failed+=( "${entry}" )
+}
+
+fail_ret () {
+ local name="$1"
+ local expect="$2"
+ local retval="$3"
+ local reason="$4"
+ local cmd=""
+
+ shift 4
+ if [ $# -ne 0 ]; then
+ cmd=": [$@]"
+ fi
+
+ local entry="$(printf "%s (returned=%d, expected=%d, reason=%s)%s" \
+ "${name}" ${retval} ${expect} "${reason}" \
+ "${cmd}" )"
+
+ failed+=( "${entry}" )
+}
+
+exit_handler () {
+ if [ -n "${current_test}" ]; then
+ msg_error "caught exit while test “${current_test}” was in progress"
+ fail "${current_test}" exit
+ fi
+
+ current_test=""
+}
+
+trap exit_handler exit
+
+assert_equal () {
+ local name"$1"
+ local a="$2"
+ local b="$3"
+
+ if [ "$a" != "$b" ]; then
+ fail "${name}" "failed comparison; [$a] <> [$b]"
+ fi
+}
+
+assert_int_equal () {
+ local name"$1"
+ local a=$2
+ local b=$3
+
+ if [ $a -ne $b ]; then
+ fail "${name}" "failed integer comparison; $a <> $b"
+ fi
+}
+
+register_test () {
+ local name="$1"
+
+ if [ -n "${tests[${name}]:-}" ]; then
+ msg_fatal "cannot register test «${name}»: already registered"
+ fi
+
+ tests["${name}"]="test_${name}"
+}
+
+test_parse_simple () {
+ local name="$1"
+ local ret
+ local cmd=( "./${testme}" S-1-0 )
+
+ timeout ${default_timeout} ${cmd[@]} &>/dev/null
+ ret=$?
+
+ case ${ret} in
+ 0) msg_noise "${name}: success" ;;
+ 124) fail_ret "${name}" 0 ${ret} "timeout" ${cmd[@]} ;;
+ 127) fail_ret "${name}" 0 ${ret} "command" ${cmd[@]} ;;
+ *) fail_ret "${name}" 0 ${ret} "invalid" ${cmd[@]} ;;
+ esac
+}
+register_test parse_simple
+
+test_parse_stdin () {
+ local name="$1"
+ local ret
+ local cmd=( "./${testme}" )
+
+ timeout ${default_timeout} ${cmd[@]} &>/dev/null <<-STOPTHAT
+ S-1-0
+ S-1-1
+ S-1-42-2187-1337
+ STOPTHAT
+
+ ret=$?
+
+ case ${ret} in
+ 0) msg_noise "${name}: success" ;;
+ 124) fail_ret "${name}" 0 ${ret} "timeout" ${cmd[@]} ;;
+ 127) fail_ret "${name}" 0 ${ret} "command" ${cmd[@]} ;;
+ *) fail_ret "${name}" 0 ${ret} "invalid" ${cmd[@]} ;;
+ esac
+}
+register_test parse_stdin
+
+test_parse_garbage_fail () {
+ local name="$1"
+ local ret
+ local cmd=( "./${testme}" )
+
+ timeout ${default_timeout} ${cmd[@]} "Ook!" &>/dev/null
+ ret=$?
+
+ case ${ret} in
+ 255) msg_noise "${name}: success" ;;
+ 0) fail_ret "${name}" 255 ${ret} "unexpected" ${cmd[@]} ;;
+ 124) fail_ret "${name}" 255 ${ret} "timeout" ${cmd[@]} ;;
+ 127) fail_ret "${name}" 255 ${ret} "command" ${cmd[@]} ;;
+ *) fail_ret "${name}" 255 ${ret} "invalid" ${cmd[@]} ;;
+ esac
+}
+register_test parse_garbage_fail
+
+test_count_output () {
+ local name="$1"
+ local ret
+ local count
+ local cmd=( "./${testme}" \
+ "S-1-42-1337" \
+ "S-1-1-2-3-4-5-6-7-8-9" \
+ )
+
+ count=$( timeout ${default_timeout} ${cmd[@]} \
+ |wc -l )
+ ret=$?
+
+ case ${ret} in
+ 0) msg_noise "${name}: success" ;;
+ 124) fail_ret "${name}" 0 ${ret} "timeout" ${cmd[@]} ;;
+ 127) fail_ret "${name}" 0 ${ret} "command" ${cmd[@]} ;;
+ *) fail_ret "${name}" 0 ${ret} "invalid" ${cmd[@]} ;;
+ esac
+
+ assert_int_equal "${name}" ${count} 3
+}
+register_test count_output
+
+test_count_output_quiet () {
+ # no output at all, even errors
+ local name="$1"
+ local count
+ local cmd=( "./${testme}" --quiet \
+ "S-1-42-1337" \
+ "Smite you with thunderbolts!" \
+ "S-1-1-2-3-4-5-6-7-8-9" \
+ )
+
+ count=$( timeout ${default_timeout} ${cmd[@]} \
+ |&wc -c )
+ assert_int_equal "${name}" ${count} 0
+}
+register_test count_output_quiet
+
+test_count_output_validate () {
+ # only error lines
+ local name="$1"
+ local count
+ local wcfd
+ local cmd=( "./${testme}" --validate \
+ "S-1-42-1337" \
+ "Smite you with thunderbolts!" \
+ "S-1-1-2-3-4-5-6-7-8-9" \
+ )
+
+ count=$( timeout ${default_timeout} "${cmd[@]}" \
+ |&wc -l )
+
+ assert_int_equal "${name}" ${count} 2
+}
+register_test count_output_validate
+
+test_parse_stdin_empty () {
+ local name="$1"
+ local ret
+ local cmd=( "./${testme}" )
+
+ <<<"" timeout ${default_timeout} "${cmd[@]}" &>/dev/null
+ ret=$?
+
+ case ${ret} in
+ 0) msg_noise "${name}: success" ;;
+ 124) fail_ret "${name}" 0 ${ret} "timeout" ${cmd[@]} ;;
+ *) fail_ret "${name}" 0 ${ret} "invalid" ${cmd[@]} ;;
+ esac
+}
+register_test parse_stdin_empty
+
+report () {
+ local n=${#failed[@]}
+
+ if [ $n -eq 0 ]; then
+ msg_good "all tests completed successfully"
+ return
+ fi
+
+ msg_failed report "detected $n failures"
+
+ for f in "${failed[@]}"; do
+ msg_failed failure "$f"
+ done
+}
+
+exit_with_status () {
+ [[ ${#failed[@]} -ne 0 ]] && exit -1 || exit 0
+}
+
+parse_argv () {
+ while [ -n "${1:-}" ]; do
+ case "$1" in
+ -v|--verbose)
+ verbose=yes
+ ;;
+ -*)
+ msg_fatal "unknown argument “$1”"
+ ;;
+ *)
+ testme="$1"
+ ;;
+ esac
+
+ shift
+ done
+}
+
+run_test () {
+ local i=$1
+ local name="$2"
+
+ msg_noise "[$i] test «$name»"
+ current_test="${name}"
+ "test_${name}" "${name}"
+ current_test=""
+}
+
+main () {
+ local i=0
+
+ parse_argv $@
+
+ msg_noise "${SELF}: commencing tests for «${testme}»"
+
+ for tst in ${!tests[@]}; do
+ (( ++i ))
+ run_test $i "${tst}"
+ done
+
+ report
+
+ msg_noise "${SELF}: completed $i tests for «${testme}»"
+ exit_with_status
+}
+
+main $@
+