"Fossies" - the Fresh Open Source Software Archive

Member "hitch-1.7.2/src/tests/hitch_test.sh" (29 Nov 2021, 7716 Bytes) of package /linux/www/hitch-1.7.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Bash source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "hitch_test.sh": 1.7.0_vs_1.7.2.

    1 #
    2 # This file contains test helpers for the Hitch test suite, reusable bits of
    3 # code shared by at least two test cases.
    4 #
    5 # To run tests manually, do:
    6 # export TESTDIR=`pwd`/; export PATH=$PATH:`pwd`/../:`pwd`/../util/
    7 #
    8 
    9 #-
   10 # We want the shell to catch errors for us and fail as soon as a command
   11 # fails or an undefined variable is used (often typos for the latter).
   12 
   13 set -e
   14 set -u
   15 
   16 #-
   17 # We give each test its own directory to simplify file management, this
   18 # directory is then removed by the exit trap below.
   19 
   20 cd "$(mktemp -d)"
   21 readonly TEST_TMPDIR=$(pwd)
   22 
   23 #-
   24 # This was part of the old setup, and should be ported to something more
   25 # robust in the future.
   26 
   27 export LC_ALL=C
   28 
   29 LISTENPORT=`expr $$ % 62000 + 1024`
   30 CERTSDIR="${TESTDIR}/certs"
   31 CONFDIR="${TESTDIR}/configs"
   32 
   33 
   34 #-
   35 # When a test fails, give as much context as possible for troubleshooting. It
   36 # looks for file in the test's directory, but not recursively. The dump is
   37 # currently done when an explicit failure triggers, and could leave us in the
   38 # dark if we a "naked" command fails and is caught by `set -e`. We can wrap
   39 # any command with the `run_cmd` helper to trigger a failure.
   40 
   41 dump() {
   42     for LOG in *.log
   43     do
   44         test -f "$LOG" || continue
   45 
   46         printf '\nFound log file %s:\n\n' "$LOG"
   47         cat -v "$LOG" | sed -e 's/^/> /'
   48     done >&2
   49 
   50     for DUMP in *.dump
   51     do
   52         test -f "$DUMP" || continue
   53 
   54         printf '\nFound dump file %s:\n\n' "$DUMP"
   55         cat -v "$DUMP" | sed -e 's/^/> /'
   56     done >&2
   57 }
   58 
   59 #-
   60 # The exit trap removes the test directory before the shell exits.
   61 
   62 cleanup() {
   63     for PID in *.pid
   64     do
   65         test -f "$PID" &&
   66         kill "$(cat "$PID")"
   67     done
   68 
   69     rm -rf "$TEST_TMPDIR"
   70 }
   71 
   72 trap cleanup EXIT
   73 
   74 #-
   75 # Explicit failures, following-ish automake conventions for exit statuses.
   76 # Using any of these commands in a sub-shell is pointless because the
   77 # exit status would be that of the sub-shell instead of the test itself.
   78 #
   79 # This however, is OK:
   80 #
   81 # some --command |
   82 # something --else ||
   83 # fail "some message"
   84 
   85 fail() {
   86     echo "FAIL: $*" >&2
   87     dump
   88     exit 255
   89 }
   90 
   91 skip() {
   92     echo "SKIP: $*" >&2
   93     dump
   94     exit 77
   95 }
   96 
   97 error() {
   98     echo "ERROR: $*" >&2
   99     dump
  100     exit 99
  101 }
  102 
  103 #-
  104 # Usage: cmd arg
  105 #
  106 # Short-hand for `command -v arg >/dev/null`.
  107 
  108 cmd() {
  109     command -v "$1" >/dev/null
  110 }
  111 
  112 #-
  113 # Usage: run_cmd [-s status] command [args...]
  114 #
  115 # By default expect a zero exit status, takes care of explicitly failing if
  116 # the exit status doesn't match expectations.
  117 #
  118 # Should not be used in a sub-shell.
  119 
  120 run_cmd() (
  121     set -e
  122     set -u
  123 
  124     OPTIND=1
  125     CMD_STATUS=0
  126 
  127     while getopts s: OPT
  128     do
  129         case $OPT in
  130         s) CMD_STATUS=$OPTARG ;;
  131         *) return 1 ;;
  132         esac
  133     done
  134 
  135     shift $((OPTIND - 1))
  136 
  137     printf 'Running: %s\n' "$*" >&2
  138 
  139     RUN_STATUS=0
  140     "$@" || RUN_STATUS=$?
  141 
  142     if [ "$RUN_STATUS" -ne "$CMD_STATUS" ]
  143     then
  144         fail "expected exit status $CMD_STATUS got $RUN_STATUS"
  145     fi
  146 )
  147 
  148 #-
  149 # Usage: start_hitch [args...]
  150 #
  151 # Start a hitch daemon, taking care of the common parameters, with the
  152 # possibility to add more parameters. Only one hitch daemon can be started
  153 # in a single test case.
  154 #
  155 # Should not be used in a sub-shell.
  156 
  157 start_hitch() {
  158     TEST_UID=$(id -u)
  159     HITCH_USER=
  160     test "$TEST_UID" -eq 0 && HITCH_USER=--user=nobody
  161 
  162     run_cmd hitch \
  163         --pidfile="$TEST_TMPDIR/hitch.pid" \
  164         --log-filename=hitch.log \
  165         --daemon \
  166         --dbg-listen="$TEST_TMPDIR/hitch_hosts" \
  167         $HITCH_USER \
  168         "$@"
  169     run_cmd sleep 1
  170 }
  171 
  172 #-
  173 # Usage: stop_hitch
  174 #
  175 # Kill a hitch daemon started with `start_hitch`, waiting for the
  176 # process to terminate.
  177 
  178 stop_hitch() {
  179     HITCH_PID=$(hitch_pid)
  180     kill -TERM "$HITCH_PID"
  181 
  182     while kill -0 "$HITCH_PID"
  183     do
  184         sleep 1
  185     done
  186 }
  187 
  188 #-
  189 # Usage: hitch_pid
  190 #
  191 # Print the PID of the daemon started with `start_hitch`, usually in a
  192 # sub-shell for a different command.
  193 #
  194 # Example
  195 #
  196 # kill -HUP $(hitch_pid)
  197 
  198 hitch_pid() {
  199     cat "$TEST_TMPDIR/hitch.pid"
  200 }
  201 
  202 #-
  203 # Usage: hitch_hosts
  204 #
  205 # Print a list of hosts for the daemon started with `start_hitch`, usually in
  206 # a loop. Only IPv4 listen addresses are listed.
  207 
  208 hitch_hosts() {
  209     if [ -f "$TEST_TMPDIR/hitch_hosts" ]
  210     then
  211         cat "$TEST_TMPDIR/hitch_hosts"
  212         return
  213     fi
  214 
  215     fail "$TEST_TMPDIR/hitch_hosts not found. Hitch started without --dbg-listen?"
  216 }
  217 
  218 #-
  219 # Usage: curl_hitch [opts...] [-- arg [args...]]
  220 #
  221 # Send an HTTPS request to a hitch server. If an option is not supported by
  222 # curl the test is skipped. When `--` is missing, a URL using the first
  223 # address reported by `hitch_host` is used. It includes all the common options
  224 # needed by test cases. The test fail if the response status is different than
  225 # ${CURL_STATUS} (or 200 if it isn't set).
  226 #
  227 # Should not be used in a sub-shell.
  228 
  229 curl_hitch() {
  230     printf 'Running: curl %s\n' "$*" >&2
  231 
  232     HAS_SPECIFIC_ARG=false
  233 
  234     for ARG
  235     do
  236         test "$ARG" = -- && HAS_SPECIFIC_ARG=true
  237 
  238         # ignore non-option arguments
  239         test "${ARG#-}" = "$ARG" && continue
  240 
  241         curl --help |
  242         grep -q -e "$ARG" ||
  243         skip "curl: unknown option $ARG"
  244     done
  245 
  246     if ! $HAS_SPECIFIC_ARG
  247     then
  248         HITCH_HOST=$(hitch_hosts | sed 1q)
  249         curl_hitch "$@" -- "https://$HITCH_HOST/"
  250         return $?
  251     fi
  252 
  253     CURL_STATUS=${CURL_STATUS:-200}
  254     EXIT_STATUS=0
  255     RESP_STATUS=$(curl \
  256         --head \
  257         --max-time 5 \
  258         --silent \
  259         --verbose \
  260         --insecure \
  261         --output /dev/null \
  262         --write-out '%{http_code}' \
  263         "$@") || EXIT_STATUS=$?
  264 
  265     # XXX: how to handle the cases where we expect an error?
  266     test $EXIT_STATUS -ne 0 &&
  267     error "curl request failed or timed out (exit status: $EXIT_STATUS)"
  268 
  269     test "$CURL_STATUS" = "$RESP_STATUS" ||
  270     fail "expected status $CURL_STATUS got $RESP_STATUS"
  271 }
  272 
  273 #-
  274 # Usage: [!] s_client [args...]
  275 #
  276 # Frontend to `openssl s_client` with the common options we usually need. It
  277 # specifies the `-connect` option unless it was part of the arguments. A new
  278 # line is sent via the standard input. It doesn't use `run_cmd` because some
  279 # executions are expected to yield a non-zero exit status, in that case just
  280 # negate the result.
  281 #
  282 # A special -delay=<seconds> option can be used as the first argument to
  283 # prevent races from `openssl s_client` that could lead to missing output.
  284 #
  285 # Expect a success:
  286 #
  287 # s_client [...]
  288 #
  289 # Expect a failure:
  290 #
  291 # ! s_client [...]
  292 #
  293 # When we expect a failure, it's usually to then inspect the output, and for
  294 # convenience the standard error is redirected to the standard output.
  295 #
  296 # Should not be used in a sub-shell.
  297 
  298 s_client() {
  299     printf 'Running: s_client %s\n' "$*" >&2
  300 
  301     HAS_CONNECT_OPT=false
  302     DELAY=0
  303 
  304     for ARG
  305     do
  306         # ignore non-option arguments
  307         test "${ARG#-}" = "$ARG" && continue
  308 
  309         # ignore -delay=<seconds> homebrew option
  310         test "${ARG#-delay=}" != "$ARG" && continue
  311 
  312         test "$ARG" = -connect && HAS_CONNECT_OPT=true
  313 
  314         openssl s_client -help 2>&1 |
  315         grep -q -e "$ARG" ||
  316         skip "openssl s_client: unknown option $ARG"
  317     done
  318 
  319     if ! $HAS_CONNECT_OPT
  320     then
  321         HITCH_HOST=$(hitch_hosts | sed 1q)
  322         s_client "$@" -connect "$HITCH_HOST"
  323         return $?
  324     fi
  325 
  326     if [ "${1#-delay=}" != "$1" ]
  327     then
  328         DELAY=${1#-delay=}
  329         shift
  330     fi
  331 
  332     (sleep "$DELAY"; printf '\n') |
  333     openssl s_client -prexit "$@" 2>&1
  334 }
  335 
  336 # Extract a field from a subject line read from standard input.
  337 #
  338 # openssl < 1.1.1:
  339 #   subject=/CN=site1.example.com
  340 #   subject=/C=NO/ST=Oslo/O=Varnish Software/L=Oslo/CN=*.example.com/OU=...
  341 # openssl >= 1.1.1:
  342 #   subject=CN = site1.example.com
  343 #   subject=C = NO, ST = Oslo, O = Varnish Software, L = Oslo, CN = *.example.com, ...
  344 #
  345 _subject_field() {
  346     sed -n 's/ *subject=//p' |
  347     tr ,/ '\n' |
  348     awk -F '[= ]*' -v RS='\n *' -v FIELD="$1" '$1 == FIELD {print $2; exit}'
  349 }
  350 
  351 #-
  352 # Usage: subject_field_eq FIELD VALUE FILE
  353 #
  354 # Extract the field FIELD from a subject line found in FILE and compare it
  355 # with VALUE.
  356 #
  357 # Example:
  358 #
  359 # subject_field_eq CN site1.example.com client.dump
  360 
  361 subject_field_eq() {
  362     SUBJECT_NAME=$(_subject_field "$1" <"$3")
  363     run_cmd test "$SUBJECT_NAME" = "$2"
  364 }