"Fossies" - the Fresh Open Source Software Archive

Member "hitch-1.5.2/src/tests/hitch_test.sh" (27 Aug 2019, 7759 Bytes) of package /linux/www/hitch-1.5.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. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "hitch_test.sh": 1.4.8_vs_1.5.0.

    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         $HITCH_USER \
  167         "$@"
  168 }
  169 
  170 #-
  171 # Usage: stop_hitch
  172 #
  173 # Kill a hitch daemon started with `start_hitch`, waiting for the
  174 # process to terminate.
  175 
  176 stop_hitch() {
  177     HITCH_PID=$(hitch_pid)
  178     kill -TERM "$HITCH_PID"
  179 
  180     while kill -0 "$HITCH_PID"
  181     do
  182         sleep 1
  183     done
  184 }
  185 
  186 #-
  187 # Usage: hitch_pid
  188 #
  189 # Print the PID of the daemon started with `start_hitch`, usually in a
  190 # sub-shell for a different command.
  191 #
  192 # Example
  193 #
  194 # kill -HUP $(hitch_pid)
  195 
  196 hitch_pid() {
  197     cat "$TEST_TMPDIR/hitch.pid"
  198 }
  199 
  200 #-
  201 # Usage: hitch_hosts
  202 #
  203 # Print a list of hosts for the daemon started with `start_hitch`, usually in
  204 # a loop. Only IPv4 listen addresses are listed.
  205 
  206 hitch_hosts() {
  207     if cmd lsof
  208     then
  209         lsof -F -P -n -a -p "$(hitch_pid)" -i 4 -i TCP -s TCP:LISTEN |
  210         awk '/^n/ {
  211             sub("\\*", "127.0.0.1", $1)
  212             print substr($1,2)
  213         }'
  214         return
  215     fi
  216 
  217     if cmd sockstat && test "$(uname)" = FreeBSD
  218     then
  219         sockstat -P tcp -4 |
  220         awk '$3 == '"$(hitch_pid)"' {
  221             sub("\\*", "127.0.0.1", $6)
  222             print $6
  223         }'
  224         return
  225     fi
  226 
  227     if cmd fstat && test "$(uname)" = OpenBSD
  228     then
  229         fstat -p "$(hitch_pid)" |
  230         awk '$5 == "internet" && $7 == "tcp" && NF == 9 {
  231             sub("\\*", "127.0.0.1", $9)
  232             print $9
  233         }'
  234         return
  235     fi
  236 
  237     fail "none of supported lsof, sockstat or fstat available"
  238 }
  239 
  240 #-
  241 # Usage: curl_hitch [opts...] [-- arg [args...]]
  242 #
  243 # Send an HTTPS request to a hitch server. If an option is not supported by
  244 # curl the test is skipped. When `--` is missing, a URL using the first
  245 # address reported by `hitch_host` is used. It includes all the common options
  246 # needed by test cases. The test fail if the response status is different than
  247 # ${CURL_STATUS} (or 200 if it isn't set).
  248 #
  249 # Should not be used in a sub-shell.
  250 
  251 curl_hitch() {
  252     printf 'Running: curl %s\n' "$*" >&2
  253 
  254     HAS_SPECIFIC_ARG=false
  255 
  256     for ARG
  257     do
  258         test "$ARG" = -- && HAS_SPECIFIC_ARG=true
  259 
  260         # ignore non-option arguments
  261         test "${ARG#-}" = "$ARG" && continue
  262 
  263         curl --help |
  264         grep -q -e "$ARG" ||
  265         skip "curl: unknown option $ARG"
  266     done
  267 
  268     if ! $HAS_SPECIFIC_ARG
  269     then
  270         HITCH_HOST=$(hitch_hosts | sed 1q)
  271         curl_hitch "$@" -- "https://$HITCH_HOST/"
  272         return $?
  273     fi
  274 
  275     CURL_STATUS=${CURL_STATUS:-200}
  276     EXIT_STATUS=0
  277     RESP_STATUS=$(curl \
  278         --head \
  279         --max-time 5 \
  280         --silent \
  281         --verbose \
  282         --insecure \
  283         --output /dev/null \
  284         --write-out '%{http_code}' \
  285         "$@") || EXIT_STATUS=$?
  286 
  287     # XXX: how to handle the cases where we expect an error?
  288     test $EXIT_STATUS -ne 0 &&
  289     error "curl request failed or timed out (exit status: $EXIT_STATUS)"
  290 
  291     test "$CURL_STATUS" = "$RESP_STATUS" ||
  292     fail "expected status $CURL_STATUS got $RESP_STATUS"
  293 }
  294 
  295 #-
  296 # Usage: [!] s_client [args...]
  297 #
  298 # Frontend to `openssl s_client` with the common options we usually need. It
  299 # specifies the `-connect` option unless it was part of the arguments. A new
  300 # line is sent via the standard input. It doesn't use `run_cmd` because some
  301 # executions are expected to yield a non-zero exit status, in that case just
  302 # negate the result.
  303 #
  304 # Expect a success:
  305 #
  306 # s_client [...]
  307 #
  308 # Expect a failure:
  309 #
  310 # ! s_client [...]
  311 #
  312 # When we expect a failure, it usually to then inspect the output, and for
  313 # convenience the standard error is redirected to the standard output.
  314 #
  315 # Should not be used in a sub-shell.
  316 
  317 s_client() {
  318     printf 'Running: s_client %s\n' "$*" >&2
  319 
  320     HAS_CONNECT_OPT=false
  321 
  322     for ARG
  323     do
  324         # ignore non-option arguments
  325         test "${ARG#-}" = "$ARG" && continue
  326 
  327         test "$ARG" = -connect && HAS_CONNECT_OPT=true
  328 
  329         openssl s_client -help 2>&1 |
  330         grep -q -e "$ARG" ||
  331         skip "openssl s_client: unknown option $ARG"
  332     done
  333 
  334     if ! $HAS_CONNECT_OPT
  335     then
  336         HITCH_HOST=$(hitch_hosts | sed 1q)
  337         s_client "$@" -connect "$HITCH_HOST"
  338         return $?
  339     fi
  340 
  341     printf '\n' |
  342     openssl s_client -prexit "$@" 2>&1
  343 }
  344 
  345 s_client_parse() {
  346 
  347     # input examples we need to support here:
  348     #
  349     # openssl < 1.1.1:
  350     #   subject=/CN=site1.example.com
  351     #   subject=/C=NO/ST=Oslo/O=Varnish Software/L=Oslo/CN=*.example.com/OU=Varnish Software/emailAddress=foobar@example.com
  352     # openssl >= 1.1.1:
  353     #   subject=CN = site1.example.com
  354     #   subject=C = NO, ST = Oslo, O = Varnish Software, L = Oslo, CN = *.example.com, OU = Varnish Software, emailAddress = foobar@example.com
  355     #
  356     # subject=/C=NO/ST=Oslo/O=Varnish Software/L=Oslo/CN=*.example.com/OU=Varnish Software/emailAddress=foobar@example.com
  357 
  358     SUBJECT_NAME=$(grep "subject=" $1 | head -1 | cut -d= -f2- | sed -e 's/[,/]/\n/g' |
  359               grep CN | cut -d'=' -f2 | tr -d '[:space:]')
  360 }
  361 
  362 subj_name_eq() {
  363     s_client_parse "$2"
  364     test "$SUBJECT_NAME" = "$1"
  365 }