123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550 |
- #!/bin/sh
- #check.sh : functionnal check functions for various server
- #Copyright (C) 2016 Weber Yann
- #
- #This program is free software; you can redistribute it and/or modify
- #it under the terms of the GNU General Public License as published by
- #the Free Software Foundation; either version 3 of the License, or
- #any later version.
- #
- #This program is distributed in the hope that it will be useful,
- #but WITHOUT ANY WARRANTY; without even the implied warranty of
- #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- #GNU General Public License for more details.
- #
- #You should have received a copy of the GNU General Public License
- #along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
- if [ -z "$color" ]
- then
- color=1
- fi
- if [ -z "$verbose" ]
- then
- verbose=1
- fi
- if [ -z "$exit_on_fail" ]
- then
- exit_on_fail=1
- fi
-
- alias echo="/bin/echo -e"
-
- col_reset() {
- if [ "$color" -gt 0 ]
- then
- tput sgr0
- fi
- }
-
- col_set() {
- if [ -z "$1" ]
- then
- return
- fi
- if [ "$color" -gt 0 ]
- then
- tput setaf $1
- fi
- }
-
- log() {
- echo "$(col_set $3)[$(printf "%7s" "$1")]$(col_reset) $2"
- }
-
- datetime() {
- date -Iseconds
- }
-
- logdate() {
- echo "$(date -Iseconds) $(col_set $3)[$(printf "%7s" "$1")]$(col_reset) $2"
- }
-
- fail() {
- if [ "$verbose" -lt 2 ]
- then
- echo "" #for the dot printed with -n
- fi
- test_msg="$1"
- test_status=1
- }
-
- err() {
- msg="$(log ERR "$1" 1)"
- test_msg="$1"
- test_status=-1
- }
-
- success() {
- msg="$(log OK "$1" 2)"
- test_msg="$1"
- test_status=0
- }
-
- #
- # Tests & testcase functions
- #
-
- tc_name=""
- tc_infos=""
- tc_fail=0
- tc_run=0
-
- total_fail=0
- total_run=0
-
- test_msg=""
- test_status=0
-
- _test_setup() {
- test_status=0
- test_msg=""
- }
-
- TC_INIT() {
- tc_name=$1
- tc_infos=$2
- tc_fail=0
- tc_run=0
-
- msg="Running testcase '$tc_name'"
- if [ -n "$tc_infos" ]
- then
- msg="${msg} ($tc_infos)"
- fi
- if [ "$verbose" -gt 0 ]
- then
- logdate TESTCASE "$msg" 4
- fi
- }
-
- TC_END() {
-
- if [ "$tc_fail" -gt 0 ]
- then
- if [ "$verbose" -gt 1 ]
- then
- logdate TESTCASE "-------------$tc_name END------------" 1
- fi
- logdate FAIL "Testcase '$tc_name' tests: ${tc_run} fails: $(col_set 1)${tc_fail}$(col_reset)" 1
- if [ "$exit_on_fail" -ne 0 ]
- then
- CHECK_REPORT
- fi
- elif [ "$verbose" -eq 1 ]
- then
- echo "" #for the dot printed with -n
- logdate TESTCASE "Testcase '$tc_name' tests:${tc_run} fails: $tc_fail" 2
- elif [ "$verbose" -gt 1 ]
- then
- logdate TESTCASE "-------------$tc_name END------------" 4
- fi
- tc_name=""
- tc_infos=""
- tc_fail=0
- tc_run=0
- }
-
- TC_RUN() {
- _test_setup
- cmd=$1
- shift
- args=""
- case $#
- in
- 1)$cmd "$1";;
- 2)$cmd "$1" "$2";;
- 3)$cmd "$1" "$2" "$3";;
- 4)$cmd "$1" "$2" "$3" "$4";;
- *)fail "To many arguments for $cmd"
- esac
- #$cmd $args
-
- tc_run=$(expr $tc_run + 1)
- total_run=$(expr $total_run + 1)
- if [ "$test_status" -ne 0 ]
- then
- err_type="FAIL"
- if [ "$test_status" -lt 0 ]
- then
- err_type="ERR"
- fi
- tc_fail=$(expr $tc_fail + 1)
- total_fail=$(expr $total_fail + 1)
- logdate $err_type "$tc_name: $test_msg" 1 >&2
- elif [ "$verbose" -gt 1 ]
- then
- logdate OK "$tc_name: $test_msg" 2
- else
- echo -n '.'
- fi
- }
-
- CHECK_START() {
- logdate STATUS "Starting tests" 3
- }
-
- CHECK_REPORT() {
- if [ "$verbose" -eq 0 -a "$tc_fail" -eq "0" ]
- then
- echo "" # for dot printed with -n
- fi
- if [ "$verbose" -gt 0 ]
- then
- logdate STATUS "All tests done" 3
- fi
- if [ "$total_fail" -gt 0 ]
- then
- logdate FAIL "Summary : tests: ${total_run} fails: $(col_set 1)${total_fail}$(col_reset)" 1
- exit 1
- else
- logdate OK "Summary : tests:${total_run} fails: $total_fail" 2
- exit 0
- fi
- }
-
- #
- # HTTP/HTTPS tests
- #
-
- _check_http_status() {
- # $1 url
- # $2 status
- # $* curl options
- url=$1
- shift 1
- expt=$1
- if [ -z "$1" ]
- then
- expt=200
- fi
- shift 1
-
- status=$(curl -s -o /dev/null -w "%{http_code}" $* $url)
- if [ "$status" -ne "$expt" ]
- then
- fail "Check http status $expt for $url : $status returned"
- elif [ "$verbose" -gt 0 ]
- then
- success "Check http status $status for $url"
- fi
- }
-
- check_http_status() {
- # $1 url
- # $2 status
- _check_http_status $1 $2
- }
-
- check_http_200() {
- _check_http_status $1 200
- }
-
- check_https_cert() {
- # Check that SSL Cert is valid
- # $1 URL
- status=$(curl -s -o /dev/null -w "%{http_code}" https://$1)
- rep=$?
- if [ "$rep" -eq 0 ]
- then
- success "https://$1 cert verified"
- return
- fi
- status=$(curl -k -s -o /dev/null -q "%{http_code}" https://$1)
- rep=$?
- if [ "$rep" -eq 0 ]
- then
- fail "https://$1 cert invalid"
- else
- err "Unable to curl https://$1"
- fi
- }
-
- check_html_title() {
- url="$1"
- expt="$2"
-
- tmpxsl=$(mktemp -t XSL.XXXXXXXXXXX)
- echo '<?xml version="1.0"?>
- <xsl:stylesheet version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
- <xsl:output method = "text"/>
- <xsl:template match="/">
- <xsl:value-of select="/html/head/title"/>
- </xsl:template>
- </xsl:stylesheet>' > $tmpxsl
-
- tmphtml=$(mktemp -t html.XXXXXXXXX)
-
- curl --silent $url > $tmphtml
- title=$(xsltproc --html --novalid $tmpxsl $tmphtml 2>/dev/null)
- if [ "$?" -ne "0" ]
- then
- title=$(xsltproc --novalid $tmpxsl $tmphtml 2>/dev/null)
- fi
-
- if [ "$title" = "$expt" ]
- then
- success "$url HTML title is '$expt'"
- else
- fail "$url HTML title is '$title' but '$expt' expected"
- fi
-
- rm $tmpxsl $tmphtml 2>/dev/null
- }
-
- check_audiostream() {
- # Uses mplayer to fetch 128Kb of stream
- # $1 Stream URL
- # $2 size
- tmpfile=$(mktemp -t check_audiostream.XXXXXXXXX)
-
- sz="$2"
- if [ -z "$sz" ]
- then
- sz="128kb"
- fi
- if [ "$verbose" -gt 1 ]
- then
- logdate INFO "$tc_name: Running mplayer on '$1' for $sz" 3
- fi
-
- mplayer -endpos $sz -ao pcm:file=$tmpfile "$1" 1>/dev/null 2>/dev/null
- res=$?
- bytes=$(du $tmpfile | cut -f1)
- rm $tmpfile 2>/dev/null
-
- if [ "$bytes" -lt 1024 ]
- then
- fail "mplayer retrieved ${bytes}B of stream instead of expected $sz"
- return
- fi
- if [ "$res" -eq 0 ]
- then
- success "mplayer retrieved $sz of stream on $1"
- else
- fail "mplayer failed to retrieve stream on $1"
- fi
- }
-
- check_ping() {
- ns=$1
- count=$2
- if [ -z "$count" ]
- then
- count=5
- fi
- ping -i 0.2 -c $count $ns 2>/dev/null >/dev/null
- res=$?
- if [ "$res" -ne 0 ]
- then
- fail "unable to ping '$ns'"
- else
- success "successfully send $count ping to '$ns'"
- fi
- }
-
- check_git_repo() {
- tmpdir=$(mktemp -d -t check_git.XXXXXXXXX)
- git clone $1 $tmpdir 2>/dev/null 1>/dev/null
- res=$?
- rm -Rf $tmpdir
- if [ "$res" -ne 0 ]
- then
- fail "unable to clone git repo '$1'"
- else
- success "git repo '$1' cloned'"
- fi
- }
-
- #
- # Jabber XMPP checks
- #
-
- __xmpp_probe() {
- serv=$1
- timeout=$2
- type=$3
-
- payload="<?xml version=\"1.0\"?>\n<stream:stream xmlns:stream=\"http://etherx.jabber.org/streams\" version=\"1.0\" xmlns=\"jabber:$type\" to=\"${1}\" xml:lang=\"en\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\">\n"
- if [ "$verbose" -gt 2 ]
- then
- echo -e $payload | sed -e "s/^/$(datetime) [ DEBUG] Sent : /" >&2
- fi
- echo -e $payload
- sleep $timeout
- }
-
- _xmpp_probe() {
- serv=$1
- port=$2
- timeout=$3
- type=$4
-
- tmpres=$(mktemp -t xmpp_probe.XXXXXXXXX)
-
- echo "$(__xmpp_probe $serv $timeout $type| nc -q2 $serv $port)</stream:stream>" | xmllint --format - > $tmpres
- if [ "$verbose" -gt 2 ]
- then
- cat $tmpres | sed -e "s/^/$(datetime) [ DEBUG] Recv : /" >&2
- fi
- cat $tmpres
- rm $tmpres
- }
-
- _check_xmpp_ns() {
- ns1=$1
- expt_ns=$2
- expt_port=$3
- dnsq="_xmpp-${4}._tcp.$1"
- rep="$(dig $dnsq srv +short | cut -d" " -f3,4)"
- if [ "$rep" = "$expt_port ${expt_ns}." ]
- then
- success "$dnsq = '$rep'"
- else
- fail "$dnsq = '$rep' but '$expt_port ${expt_ns}.' expected"
- fi
- }
-
- check_xmpp_serv_ns() {
- _check_xmpp_ns "$1" "$2" "$3" "server"
- }
-
- check_xmpp_client_ns() {
- _check_xmpp_ns "$1" "$2" "$3" "client"
- }
-
- _check_xmpp_server() {
- serv=$1
- port=$2
- timeout=$3
- type=$4
-
- if [ -z "$port" ]
- then
- port=5222
- fi
- if [ -z "$timeout" ]
- then
- timeout=2
- fi
-
- if [ "$verbose" -gt 1 ]
- then
- tpe="client"
- if [ "$type" = "server" ]
- then
- tpe="S2S"
- fi
- logdate INFO "$tc_name: Connecting to XMPP $serv $tpe port $port (timeout=${timeout}s)" 3
- fi
-
- stream=$(_xmpp_probe $serv $port $timeout $type| head -n2 | tail -n1)
- if [ -z "$stream" ]
- then
- fail "Empty reply from $serv:$port"
- return
- fi
-
- if [ "$type" = "client" ]
- then
- infos=$(echo $stream | sed -E 's/^<([^ ]+).* xmlns="([^"]+)".* from="([^"]+)" .*$/\1 \2 \3/')
- else
- infos="$(echo $stream | sed -E 's/^<([^ ]+).* xmlns="([^"]+)" .*$/\1 \2/') $serv"
- fi
-
- if [ "$(echo $infos | cut -d ' ' -f1,2)" = "stream:stream jabber:$type" ]
- then
- if [ "$(echo $infos | cut -d ' ' -f3)" = "$serv" ]
- then
- success "Successfully connected to XMPP $type $serv:$port"
- else
- fail "Server $serv:$port announce itself as $(echo $infos | cut -f3)"
- fi
- else
- fail "Unexpected reply from $serv:$port : $infos"
- fi
- }
-
- check_xmpp_server_client() {
- _check_xmpp_server "$1" "$2" "$3" "client"
- }
-
- check_xmpp_server_s2s() {
- _check_xmpp_server "$1" "$2" "$3" "server"
- }
-
- check_xmpp_ssl() {
- serv=$1
- port=$2
-
- if [ -z "$port" ]
- then
- port=5222
- fi
-
- openssl s_client -connect $serv:$port </dev/null -starttls xmpp >/dev/null 2>/dev/null
- rep=$?
- if [ "$rep" -eq 0 ]
- then
- success "Openssl successfully negociating XMPP ssl with $serv:$port"
- else
- fail "Openssl failed negociating XMPP ssl with $serv:$port"
- fi
- }
-
- #
- # SSH checks
- #
-
- check_ssh_nc() {
- host=$1
- port=$2
-
- if [ -z "$port" ]
- then
- port=22
- fi
-
- rep="$(nc -q1 $host $port </dev/null)"
- res=$?
- if [ "$res" -ne "0" ]
- then
- fail "Netcat unable to connect to $host:$port"
- return
- fi
- if echo $rep | grep "^SSH-2.0-OpenSSH" >/dev/null
- then
- success "OpenSSH replied on $host:$port"
- else
- fail "Bad replie from $host:$port : '$rep'"
- fi
- }
-
-
- check_mpc() {
- # check_mpc [$host [$port] ]
- # tests if you can contact an MPD server in a client way
- # returns the current state of the server
-
- host=$1
- port=$2
-
- if [ -z "$host" ]
- then
- host=127.0.0.1
- fi
-
- if [ -z "$port" ]
- then
- port=6600
- fi
-
- if echo "status" | nc -w 1 "$host" "$port" | head -1 | grep "^OK MPD"
- then
- success "MPD server can be contacted on $host:$port"
- status=$(echo "status" | nc -w 1 "$host" "$port" | grep "^state:"|cut -d: -f2)
- success "It's state is : $status"
- fi
- }
|