[tor-commits] [tor/master] test/parseconf: Refactor and standardise, stage 1
nickm at torproject.org
nickm at torproject.org
Thu Nov 14 14:58:58 UTC 2019
commit 39046019ec1192bd8222821a6b8677fabc0a9968
Author: teor <teor at torproject.org>
Date: Wed Nov 13 16:37:32 2019 +1000
test/parseconf: Refactor and standardise, stage 1
Remove duplicate code, and standardise similar behaviour.
Add some additional error checking.
Cleanup after 32451.
---
src/test/test_parseconf.sh | 400 ++++++++++++++++++++++++++++++---------------
1 file changed, 272 insertions(+), 128 deletions(-)
diff --git a/src/test/test_parseconf.sh b/src/test/test_parseconf.sh
index 237bf33ce..edda6c3ef 100755
--- a/src/test/test_parseconf.sh
+++ b/src/test/test_parseconf.sh
@@ -128,7 +128,7 @@ fi
TOR_BINARY="$(abspath "$TOR_BINARY")"
-echo "TOR BINARY IS $TOR_BINARY"
+echo "Using Tor binary '$TOR_BINARY'."
# make a safe space for temporary files
DATA_DIR=$(mktemp -d -t tor_parseconf_tests.XXXXXX)
@@ -157,23 +157,32 @@ else
fi
FINAL_EXIT=0
-
NEXT_TEST=
-fail_printf() { printf "FAIL: " >&2;
- # The first argument is a printf string, so this warning is
- # spurious
- # shellcheck disable=SC2059
- printf "$@" >&2;
- printf "\\n" >&2;
- NEXT_TEST="yes"
- FINAL_EXIT=$EXITCODE; }
-die_printf() { printf "FAIL: CRITICAL error in '%s':" "$MYNAME" >&2;
- # The first argument is a printf string, so this warning is
- # spurious
- # shellcheck disable=SC2059
- printf "$@" >&2;
- printf "\\n" >&2;
- exit $EXITCODE; }
+
+# Log a failure message to stderr, using $@ as a printf string and arguments
+# Set NEXT_TEST to "yes" and FINAL_EXIT to $EXITCODE.
+fail_printf()
+{
+ printf "FAIL: " >&2
+ # The first argument is a printf string, so this warning is spurious
+ # shellcheck disable=SC2059
+ printf "$@" >&2
+ printf "\\n" >&2
+ NEXT_TEST="yes"
+ FINAL_EXIT=$EXITCODE
+}
+
+# Log a failure message to stderr, using $@ as a printf string and arguments
+# Exit with status $EXITCODE.
+die_printf()
+{
+ printf "FAIL: CRITICAL error in '%s':" "$MYNAME" >&2
+ # The first argument is a printf string, so this warning is spurious
+ # shellcheck disable=SC2059
+ printf "$@" >&2
+ printf "\\n" >&2
+ exit $EXITCODE
+}
if test "$WINDOWS" = 1; then
FILTER="dos2unix"
@@ -182,9 +191,12 @@ else
fi
EMPTY="${DATA_DIR}/EMPTY"
-
touch "$EMPTY" || die_printf "Couldn't create empty file '%s'." \
"$EMPTY"
+NON_EMPTY="${DATA_DIR}/NON_EMPTY"
+echo "This pattern should not match any log messages" \
+ > "$NON_EMPTY" || die_printf "Couldn't create non-empty file '%s'." \
+ "$NON_EMPTY"
STANDARD_LIBS="libevent\\|openssl\\|zlib"
# Lib names are restricted to [a-z0-9]* at the moment
@@ -230,6 +242,178 @@ if test "$TOR_LIBS_ENABLED"; then
fi
echo "Disabled Modules: ${TOR_MODULES_DISABLED:-(None)}"
+# Yes, unix uses "0" for a successful command
+TRUE=0
+FALSE=1
+
+# Run tor --verify-config on the torrc $1, and defaults torrc $2, which may
+# be $EMPTY. Pass tor the extra command line arguments $3, which will be
+# passed unquoted.
+# Send tor's standard output to stderr.
+log_verify_config()
+{
+ # We need cmdline unquoted
+ # shellcheck disable=SC2086
+ "$TOR_BINARY" --verify-config \
+ -f "$1" \
+ --defaults-torrc "$2" \
+ $3 \
+ >&2 \
+ || true
+}
+
+# Run "tor --dump-config short" on the torrc $1, and defaults torrc $2, which
+# may be $EMPTY. Pass tor the extra command line arguments $3, which will be
+# passed unquoted.
+# Send the standard output to $4.
+# If tor fails, fail_printf() using the file name $5, and context $6,
+# which may be an empty string. Then run "tor --verify-config", and log tor's
+# error messages to stderr.
+dump_config()
+{
+ if test "$6"; then
+ CONTEXT=" $6"
+ else
+ CONTEXT=""
+ fi
+
+ # We need cmdline unquoted
+ # shellcheck disable=SC2086
+ if ! "$TOR_BINARY" --dump-config short \
+ -f "$1" \
+ --defaults-torrc "$2" \
+ $3 \
+ > "$4"; then
+ fail_printf "'%s': Tor --dump-config reported an error%s. Tor said:" \
+ "$5" \
+ "$CONTEXT"
+ log_verify_config "$1" \
+ "$2" \
+ "$3"
+ fi
+}
+
+# Run "$FILTER" on the input $1.
+# Send the standard output to $2.
+# If tor fails, log a failure message using the file name $3, and context $4,
+# which may be an empty string.
+filter()
+{
+ if test "$4"; then
+ CONTEXT=" $4"
+ else
+ CONTEXT=""
+ fi
+
+ "$FILTER" "$1" \
+ > "$2" \
+ || fail_printf "'%s': Filter '%s' reported an error%s." \
+ "$3" \
+ "$FILTER" \
+ "$CONTEXT"
+}
+
+# Compare the input file $1, and output file $2.
+#
+# If they are different, fail. If this is the first step that failed in this
+# test, run log_verify_config with torrc $3, defaults torrc $4, and command
+# line $5, to log Tor's error messages. Finally, log the differences between
+# the files.
+#
+# If the file contents are identical, returns true. Otherwise, return false.
+#
+# Log failure messages using fail_printf(), with the file name $6, and
+# context $7, which may be an empty string.
+check_diff()
+{
+ if test "$7"; then
+ CONTEXT=" $=7"
+ else
+ CONTEXT=""
+ fi
+
+ if cmp "$1" "$2" > /dev/null; then
+ return "$TRUE"
+ else
+ # If this is the first step that failed in this test,
+ # show tor's logs
+ if test -z "$NEXT_TEST"; then
+ fail_printf "'%s': Tor said%s:" \
+ "$6" \
+ "$CONTEXT"
+ log_verify_config "$3" \
+ "$4" \
+ "$5"
+ fi
+ fail_printf "'%s' did not match%s:" \
+ "$6" \
+ "$CONTEXT"
+ diff -u "$1" "$2" >&2 \
+ || true
+ return "$FALSE"
+ fi
+}
+
+# Check if $1 is an empty file.
+# If it is, fail_printf() using $2 as the type of file.
+# Returns true if the file is empty, false otherwise.
+check_empty_pattern()
+{
+ if ! test -s "$1"; then
+ fail_printf "%s file '%s' is empty, and will match any output." \
+ "$2" \
+ "$1"
+ return "$TRUE"
+ else
+ return "$FALSE"
+ fi
+}
+
+# Run tor --verify-config on the torrc $1, and defaults torrc $2, which may
+# be $EMPTY. Pass tor the extra command line arguments $3, which will be
+# passed unquoted.
+# Send tor's standard output to $4.
+# If tor's exit status does not match the boolean $5, fail_printf()
+# using the file name $6, and context $7, which is required.
+verify_config()
+{
+ RESULT=$TRUE
+ # We need cmdline unquoted
+ # shellcheck disable=SC2086
+ "$TOR_BINARY" --verify-config \
+ -f "$1" \
+ --defaults-torrc "$2" \
+ $3 \
+ > "$4" || RESULT=$FALSE
+
+ # Convert the actual and expected results to boolean, and compare
+ if test $((! (! RESULT))) -ne $((! (! $5))); then
+ fail_printf "'%s': Tor --verify-config did not %s." \
+ "$6" \
+ "$7"
+ fi
+}
+
+# Check for the pattern in file $1, in the lines in the output file $2.
+# Uses grep with the entire contents of $1 as the pattern. (Not "grep -f".)
+#
+# If the pattern does not match any lines in the output file, fail.
+# Log the pattern, and the entire contents of the output file.
+#
+# Log failure messages using fail_printf(), with the file name $1, and
+# context $3, which is required.
+check_pattern()
+{
+ expect_log="$(cat "$1")"
+ if ! grep "$expect_log" "$2" > /dev/null; then
+ fail_printf "Expected %s '%s':\\n%s\\nTor said:" \
+ "$3" \
+ "$1" \
+ "$expect_log"
+ cat "$2" >&2
+ fi
+}
+
for dir in "${EXAMPLEDIR}"/*; do
NEXT_TEST=
@@ -306,140 +490,100 @@ for dir in "${EXAMPLEDIR}"/*; do
# This case should succeed: run dump-config and see if it does.
if test -f "$EXPECTED_LOG"; then
- if ! test -s "$EXPECTED_LOG"; then
- fail_printf "Expected log file '%s' is empty.%s" \
- "$EXPECTED_LOG" \
- "(Empty expected log files match any output.)"
+ if check_empty_pattern "$EXPECTED_LOG" "Expected log"; then
continue
fi
fi
- "$TOR_BINARY" -f "./torrc" \
- --defaults-torrc "$DEFAULTS" \
- --dump-config short \
- $CMDLINE > "${DATA_DIR}/output_raw.${testname}" \
- || fail_printf "'%s': Tor --dump-config reported an error." \
- "$EXPECTED"
-
- "$FILTER" "${DATA_DIR}/output_raw.${testname}" \
- > "${DATA_DIR}/output.${testname}" \
- || fail_printf "'%s': Filter '%s' reported an error." \
- "$EXPECTED" \
- "$FILTER"
-
- if cmp "$EXPECTED" "${DATA_DIR}/output.${testname}" > /dev/null; then
+ dump_config "./torrc" \
+ "$DEFAULTS" \
+ "$CMDLINE" \
+ "${DATA_DIR}/output_raw.${testname}" \
+ "$EXPECTED" \
+ ""
+
+ filter "${DATA_DIR}/output_raw.${testname}" \
+ "${DATA_DIR}/output.${testname}" \
+ "$EXPECTED" \
+ ""
+
+ if check_diff "$EXPECTED" \
+ "${DATA_DIR}/output.${testname}" \
+ "./torrc" \
+ "$DEFAULTS" \
+ "$CMDLINE" \
+ "$EXPECTED" \
+ ""; then
# Check round-trip.
- "$TOR_BINARY" -f "${DATA_DIR}/output.${testname}" \
- --defaults-torrc "$EMPTY" \
- --dump-config short \
- > "${DATA_DIR}/output_2_raw.${testname}" \
- || fail_printf "'%s': Tor --dump-config reported an %s." \
- "$EXPECTED" \
- "error on round-trip"
-
- "$FILTER" "${DATA_DIR}/output_2_raw.${testname}" \
- > "${DATA_DIR}/output_2.${testname}" \
- || fail_printf "'%s': Filter '%s' reported an error." \
- "$EXPECTED" \
- "$FILTER"
-
- if ! cmp "${DATA_DIR}/output.${testname}" \
- "${DATA_DIR}/output_2.${testname}"; then
- fail_printf "'%s': did not match on round-trip:" \
- "$EXPECTED"
- diff -u "${DATA_DIR}/output.${testname}" \
- "${DATA_DIR}/output_2.${testname}" >&2 \
- || true
- fi
- else
- if test "$(wc -c < "${DATA_DIR}/output.${testname}")" = 0; then
- # There was no output -- probably we failed.
- fail_printf "'%s': Tor said:" \
- "$EXPECTED"
- "$TOR_BINARY" -f "./torrc" \
- --defaults-torrc "$DEFAULTS" \
- --verify-config \
- $CMDLINE >&2 \
- || true
- fi
- fail_printf "'%s' did not match:" \
- "$EXPECTED"
- diff -u "$EXPECTED" "${DATA_DIR}/output.${testname}" >&2 \
- || true
+ dump_config "${DATA_DIR}/output.${testname}" \
+ "$EMPTY" \
+ "" \
+ "${DATA_DIR}/output_2_raw.${testname}" \
+ "$EXPECTED" \
+ "on round-trip"
+
+ filter "${DATA_DIR}/output_2_raw.${testname}" \
+ "${DATA_DIR}/output_2.${testname}" \
+ "$EXPECTED" \
+ "on round-trip"
+
+ check_diff "${DATA_DIR}/output.${testname}" \
+ "${DATA_DIR}/output_2.${testname}" \
+ "${DATA_DIR}/output.${testname}" \
+ "$EMPTY" \
+ "" \
+ "$EXPECTED" \
+ "on round-trip" || true
fi
- if test -f "$EXPECTED_LOG" || test "$NEXT_TEST"; then
+ if test -f "$EXPECTED_LOG"; then
# This case should succeed: run verify-config and see if it does.
- #
- # As a temporary hack, we also use this code when --dump-config
- # has failed, to display the error logs.
- if ! test -f "$EXPECTED_LOG"; then
- NON_EMPTY="${DATA_DIR}/NON_EMPTY"
- echo "This pattern should not match any log messages" \
- > "$NON_EMPTY"
- EXPECTED_LOG=$NON_EMPTY
- fi
- "$TOR_BINARY" --verify-config \
- -f ./torrc \
- --defaults-torrc "$DEFAULTS" \
- $CMDLINE \
- > "${DATA_DIR}/output_log.${testname}" \
- || fail_printf "'%s': Tor --verify-config reported an error." \
- "$EXPECTED_LOG"
-
- expect_log="$(cat "${EXPECTED_LOG}")"
- if grep "$expect_log" "${DATA_DIR}/output_log.${testname}" \
- > /dev/null; then
- :
- else
- fail_printf "Expected '%s':\\n%s\\nTor said:" \
- "$EXPECTED_LOG" \
- "$expect_log"
- cat "${DATA_DIR}/output_log.${testname}" >&2
- fi
- fi
-
- if test -z "$NEXT_TEST"; then
- echo "OK"
+ verify_config "./torrc" \
+ "$DEFAULTS" \
+ "$CMDLINE" \
+ "${DATA_DIR}/output_log.${testname}" \
+ "$TRUE" \
+ "$EXPECTED_LOG" \
+ "succeed"
+
+ check_pattern "$EXPECTED_LOG" \
+ "${DATA_DIR}/output_log.${testname}" \
+ "log"
fi
elif test -f "$ERROR"; then
# This case should fail: run verify-config and see if it does.
if ! test -s "$ERROR"; then
- fail_printf "Error file '%s' is empty.%s" \
- "$ERROR" \
- "(Empty error files match any output.)"
- continue
- fi
-
- "$TOR_BINARY" --verify-config \
- -f ./torrc \
- --defaults-torrc "$DEFAULTS" \
- $CMDLINE \
- > "${DATA_DIR}/output.${testname}" \
- && fail_printf "'%s': Tor did not report an error." \
- "$ERROR"
-
- expect_err="$(cat "${ERROR}")"
- if grep "$expect_err" "${DATA_DIR}/output.${testname}" > /dev/null; then
- echo "OK"
- else
- fail_printf "Expected '%s':\\n%s\\nTor said:" \
- "$ERROR" \
- "$expect_err"
- cat "${DATA_DIR}/output.${testname}" >&2
+ if check_empty_pattern "$ERROR" "Error"; then
+ continue
+ fi
fi
+ verify_config "./torrc" \
+ "$DEFAULTS" \
+ "$CMDLINE" \
+ "${DATA_DIR}/output.${testname}" \
+ "$FALSE" \
+ "$ERROR" \
+ "report an error"
+
+ check_pattern "$ERROR" \
+ "${DATA_DIR}/output.${testname}" \
+ "error"
else
# This case is not actually configured with a success or a failure.
# call that an error.
fail_printf "Did not find ${dir}/*expected or ${dir}/*error."
fi
+ if test -z "$NEXT_TEST"; then
+ echo "OK"
+ fi
+
cd "$PREV_DIR"
done
-exit $FINAL_EXIT
+exit "$FINAL_EXIT"
More information about the tor-commits
mailing list