Small sh "framework" to test some server responses
sh
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

check.sh 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. #!/bin/sh
  2. #check.sh : functionnal check functions for various server
  3. #Copyright (C) 2016 Weber Yann
  4. #
  5. #This program is free software; you can redistribute it and/or modify
  6. #it under the terms of the GNU General Public License as published by
  7. #the Free Software Foundation; either version 3 of the License, or
  8. #any later version.
  9. #
  10. #This program is distributed in the hope that it will be useful,
  11. #but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. #GNU General Public License for more details.
  14. #
  15. #You should have received a copy of the GNU General Public License
  16. #along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. if [ -z "$color" ]
  18. then
  19. color=1
  20. fi
  21. if [ -z "$verbose" ]
  22. then
  23. verbose=1
  24. fi
  25. if [ -z "$exit_on_fail" ]
  26. then
  27. exit_on_fail=1
  28. fi
  29. alias echo="/bin/echo -e"
  30. col_reset() {
  31. if [ "$color" -gt 0 ]
  32. then
  33. tput sgr0
  34. fi
  35. }
  36. col_set() {
  37. if [ -z "$1" ]
  38. then
  39. return
  40. fi
  41. if [ "$color" -gt 0 ]
  42. then
  43. tput setaf $1
  44. fi
  45. }
  46. log() {
  47. echo "$(col_set $3)[$(printf "%7s" "$1")]$(col_reset) $2"
  48. }
  49. datetime() {
  50. date -Iseconds
  51. }
  52. logdate() {
  53. echo "$(date -Iseconds) $(col_set $3)[$(printf "%7s" "$1")]$(col_reset) $2"
  54. }
  55. fail() {
  56. if [ "$verbose" -lt 2 ]
  57. then
  58. echo "" #for the dot printed with -n
  59. fi
  60. test_msg="$1"
  61. test_status=1
  62. }
  63. err() {
  64. msg="$(log ERR "$1" 1)"
  65. test_msg="$1"
  66. test_status=-1
  67. }
  68. success() {
  69. msg="$(log OK "$1" 2)"
  70. test_msg="$1"
  71. test_status=0
  72. }
  73. #
  74. # Tests & testcase functions
  75. #
  76. tc_name=""
  77. tc_infos=""
  78. tc_fail=0
  79. tc_run=0
  80. total_fail=0
  81. total_run=0
  82. test_msg=""
  83. test_status=0
  84. _test_setup() {
  85. test_status=0
  86. test_msg=""
  87. }
  88. TC_INIT() {
  89. tc_name=$1
  90. tc_infos=$2
  91. tc_fail=0
  92. tc_run=0
  93. msg="Running testcase '$tc_name'"
  94. if [ -n "$tc_infos" ]
  95. then
  96. msg="${msg} ($tc_infos)"
  97. fi
  98. if [ "$verbose" -gt 0 ]
  99. then
  100. logdate TESTCASE "$msg" 4
  101. fi
  102. }
  103. TC_END() {
  104. if [ "$tc_fail" -gt 0 ]
  105. then
  106. if [ "$verbose" -gt 1 ]
  107. then
  108. logdate TESTCASE "-------------$tc_name END------------" 1
  109. fi
  110. logdate FAIL "Testcase '$tc_name' tests: ${tc_run} fails: $(col_set 1)${tc_fail}$(col_reset)" 1
  111. if [ "$exit_on_fail" -ne 0 ]
  112. then
  113. CHECK_REPORT
  114. fi
  115. elif [ "$verbose" -eq 1 ]
  116. then
  117. echo "" #for the dot printed with -n
  118. logdate TESTCASE "Testcase '$tc_name' tests:${tc_run} fails: $tc_fail" 2
  119. elif [ "$verbose" -gt 1 ]
  120. then
  121. logdate TESTCASE "-------------$tc_name END------------" 4
  122. fi
  123. tc_name=""
  124. tc_infos=""
  125. tc_fail=0
  126. tc_run=0
  127. }
  128. TC_RUN() {
  129. _test_setup
  130. cmd=$1
  131. shift
  132. args=""
  133. case $#
  134. in
  135. 1)$cmd "$1";;
  136. 2)$cmd "$1" "$2";;
  137. 3)$cmd "$1" "$2" "$3";;
  138. 4)$cmd "$1" "$2" "$3" "$4";;
  139. *)fail "To many arguments for $cmd"
  140. esac
  141. #$cmd $args
  142. tc_run=$(expr $tc_run + 1)
  143. total_run=$(expr $total_run + 1)
  144. if [ "$test_status" -ne 0 ]
  145. then
  146. err_type="FAIL"
  147. if [ "$test_status" -lt 0 ]
  148. then
  149. err_type="ERR"
  150. fi
  151. tc_fail=$(expr $tc_fail + 1)
  152. total_fail=$(expr $total_fail + 1)
  153. logdate $err_type "$tc_name: $test_msg" 1 >&2
  154. elif [ "$verbose" -gt 1 ]
  155. then
  156. logdate OK "$tc_name: $test_msg" 2
  157. else
  158. echo -n '.'
  159. fi
  160. }
  161. CHECK_START() {
  162. logdate STATUS "Starting tests" 3
  163. }
  164. CHECK_REPORT() {
  165. if [ "$verbose" -eq 0 -a "$tc_fail" -eq "0" ]
  166. then
  167. echo "" # for dot printed with -n
  168. fi
  169. if [ "$verbose" -gt 0 ]
  170. then
  171. logdate STATUS "All tests done" 3
  172. fi
  173. if [ "$total_fail" -gt 0 ]
  174. then
  175. logdate FAIL "Summary : tests: ${total_run} fails: $(col_set 1)${total_fail}$(col_reset)" 1
  176. exit 1
  177. else
  178. logdate OK "Summary : tests:${total_run} fails: $total_fail" 2
  179. exit 0
  180. fi
  181. }
  182. #
  183. # HTTP/HTTPS tests
  184. #
  185. _check_http_status() {
  186. # $1 url
  187. # $2 status
  188. # $* curl options
  189. url=$1
  190. shift 1
  191. expt=$1
  192. if [ -z "$1" ]
  193. then
  194. expt=200
  195. fi
  196. shift 1
  197. status=$(curl -s -o /dev/null -w "%{http_code}" $* $url)
  198. if [ "$status" -ne "$expt" ]
  199. then
  200. fail "Check http status $expt for $url : $status returned"
  201. elif [ "$verbose" -gt 0 ]
  202. then
  203. success "Check http status $status for $url"
  204. fi
  205. }
  206. check_http_status() {
  207. # $1 url
  208. # $2 status
  209. _check_http_status $1 $2
  210. }
  211. check_http_200() {
  212. _check_http_status $1 200
  213. }
  214. check_https_cert() {
  215. # Check that SSL Cert is valid
  216. # $1 URL
  217. status=$(curl -s -o /dev/null -w "%{http_code}" https://$1)
  218. rep=$?
  219. if [ "$rep" -eq 0 ]
  220. then
  221. success "https://$1 cert verified"
  222. return
  223. fi
  224. status=$(curl -k -s -o /dev/null -q "%{http_code}" https://$1)
  225. rep=$?
  226. if [ "$rep" -eq 0 ]
  227. then
  228. fail "https://$1 cert invalid"
  229. else
  230. err "Unable to curl https://$1"
  231. fi
  232. }
  233. check_html_title() {
  234. url="$1"
  235. expt="$2"
  236. tmpxsl=$(mktemp -t XSL.XXXXXXXXXXX)
  237. echo '<?xml version="1.0"?>
  238. <xsl:stylesheet version="1.0"
  239. xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  240. <xsl:output method = "text"/>
  241. <xsl:template match="/">
  242. <xsl:value-of select="/html/head/title"/>
  243. </xsl:template>
  244. </xsl:stylesheet>' > $tmpxsl
  245. tmphtml=$(mktemp -t html.XXXXXXXXX)
  246. curl --silent $url > $tmphtml
  247. title=$(xsltproc --html --novalid $tmpxsl $tmphtml 2>/dev/null)
  248. if [ "$?" -ne "0" ]
  249. then
  250. title=$(xsltproc --novalid $tmpxsl $tmphtml 2>/dev/null)
  251. fi
  252. if [ "$title" = "$expt" ]
  253. then
  254. success "$url HTML title is '$expt'"
  255. else
  256. fail "$url HTML title is '$title' but '$expt' expected"
  257. fi
  258. rm $tmpxsl $tmphtml 2>/dev/null
  259. }
  260. check_audiostream() {
  261. # Uses mplayer to fetch 128Kb of stream
  262. # $1 Stream URL
  263. # $2 size
  264. MPLAYER=$(whereis mplayer|cut -d' ' -f2)
  265. MPV=$(whereis mpv|cut -d' ' -f2)
  266. if [ -x $MPLAYER ]
  267. then
  268. check_audiostream_mplayer "$1" "$2"
  269. elif [ -x $MPV ]
  270. then
  271. check_audiostream_mpv "$1" "$2"
  272. else
  273. fail "Unable to find mplayer nor mpv"
  274. fi
  275. }
  276. check_audiostream_mplayer() {
  277. # Uses mplayer to fetch 128Kb of stream
  278. # $1 Stream URL
  279. # $2 size
  280. tmpfile=$(mktemp -t check_audiostream.XXXXXXXXX)
  281. sz="$2"
  282. if [ -z "$sz" ]
  283. then
  284. sz="128"
  285. fi
  286. sz_kb="${sz}kb"
  287. expt_sz="`expr $sz \* 8`"
  288. if [ "$verbose" -gt 1 ]
  289. then
  290. logdate INFO "$tc_name: Running mplayer on '$1' for $sz" 3
  291. fi
  292. $MPLAYER -endpos $sz_kb -ao pcm:file=$tmpfile "$1" 1>/dev/null 2>/dev/null
  293. res=$?
  294. bytes=$(du $tmpfile | cut -f1)
  295. rm $tmpfile 2>/dev/null
  296. logdate INFO "$bytes $sz" 3
  297. if [ "$bytes" -lt $expt_sz ]
  298. then
  299. fail "mplayer retrieved ${bytes}B of stream instead of expected $sz"
  300. return
  301. fi
  302. echo "$bytes / $sz"
  303. if [ "$res" -eq 0 ]
  304. then
  305. success "mplayer retrieved $sz of stream on $1"
  306. else
  307. fail "mplayer failed to retrieve stream on $1"
  308. fi
  309. }
  310. check_audiostream_mpv() {
  311. # Uses mpv to fetch 128Kb of stream
  312. # $1 Stream URL
  313. # $2 size
  314. tmpfile=$(mktemp -t check_audiostream.XXXXXXXXX)
  315. sz="$2"
  316. if [ -z "$sz" ]
  317. then
  318. sz="128kb"
  319. fi
  320. if [ "$verbose" -gt 1 ]
  321. then
  322. logdate INFO "$tc_name: Running mpv on '$1' for $sz" 3
  323. fi
  324. $MPV --vo=null --ao=null --o=$tmpfile --of=wav --length 1 "$1" &> /dev/null
  325. bytes=$(du $tmpfile | cut -f1)
  326. rm $tmpfile 2>/dev/null
  327. if [ "$bytes" -ge 1 ]
  328. then
  329. success "mpv read successfully $1"
  330. else
  331. fail "mpv could not read $1"
  332. fi
  333. }
  334. check_ping() {
  335. ns=$1
  336. count=$2
  337. if [ -z "$count" ]
  338. then
  339. count=5
  340. fi
  341. ping -i 0.2 -c $count $ns 2>/dev/null >/dev/null
  342. res=$?
  343. if [ "$res" -ne 0 ]
  344. then
  345. fail "unable to ping '$ns'"
  346. else
  347. success "successfully send $count ping to '$ns'"
  348. fi
  349. }
  350. check_git_repo() {
  351. tmpdir=$(mktemp -d -t check_git.XXXXXXXXX)
  352. git clone $1 $tmpdir 2>/dev/null 1>/dev/null
  353. res=$?
  354. rm -Rf $tmpdir
  355. if [ "$res" -ne 0 ]
  356. then
  357. fail "unable to clone git repo '$1'"
  358. else
  359. success "git repo '$1' cloned'"
  360. fi
  361. }
  362. #
  363. # Jabber XMPP checks
  364. #
  365. __xmpp_probe() {
  366. serv=$1
  367. timeout=$2
  368. type=$3
  369. 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"
  370. if [ "$verbose" -gt 2 ]
  371. then
  372. echo -e $payload | sed -e "s/^/$(datetime) [ DEBUG] Sent : /" >&2
  373. fi
  374. echo -e $payload
  375. sleep $timeout
  376. }
  377. _xmpp_probe() {
  378. serv=$1
  379. port=$2
  380. timeout=$3
  381. type=$4
  382. tmpres=$(mktemp -t xmpp_probe.XXXXXXXXX)
  383. echo "$(__xmpp_probe $serv $timeout $type| nc -q2 $serv $port)</stream:stream>" | xmllint --format - > $tmpres
  384. if [ "$verbose" -gt 2 ]
  385. then
  386. cat $tmpres | sed -e "s/^/$(datetime) [ DEBUG] Recv : /" >&2
  387. fi
  388. cat $tmpres
  389. rm $tmpres
  390. }
  391. _check_xmpp_ns() {
  392. ns1=$1
  393. expt_ns=$2
  394. expt_port=$3
  395. dnsq="_xmpp-${4}._tcp.$1"
  396. rep="$(dig $dnsq srv +short | cut -d" " -f3,4)"
  397. if [ "$rep" = "$expt_port ${expt_ns}." ]
  398. then
  399. success "$dnsq = '$rep'"
  400. else
  401. fail "$dnsq = '$rep' but '$expt_port ${expt_ns}.' expected"
  402. fi
  403. }
  404. check_xmpp_serv_ns() {
  405. _check_xmpp_ns "$1" "$2" "$3" "server"
  406. }
  407. check_xmpp_client_ns() {
  408. _check_xmpp_ns "$1" "$2" "$3" "client"
  409. }
  410. _check_xmpp_server() {
  411. serv=$1
  412. port=$2
  413. timeout=$3
  414. type=$4
  415. if [ -z "$port" ]
  416. then
  417. port=5222
  418. fi
  419. if [ -z "$timeout" ]
  420. then
  421. timeout=2
  422. fi
  423. if [ "$verbose" -gt 1 ]
  424. then
  425. tpe="client"
  426. if [ "$type" = "server" ]
  427. then
  428. tpe="S2S"
  429. fi
  430. logdate INFO "$tc_name: Connecting to XMPP $serv $tpe port $port (timeout=${timeout}s)" 3
  431. fi
  432. stream=$(_xmpp_probe $serv $port $timeout $type| head -n2 | tail -n1)
  433. if [ -z "$stream" ]
  434. then
  435. fail "Empty reply from $serv:$port"
  436. return
  437. fi
  438. if [ "$type" = "client" ]
  439. then
  440. infos=$(echo $stream | sed -E 's/^<([^ ]+).* xmlns="([^"]+)".* from="([^"]+)" .*$/\1 \2 \3/')
  441. else
  442. infos="$(echo $stream | sed -E 's/^<([^ ]+).* xmlns="([^"]+)" .*$/\1 \2/') $serv"
  443. fi
  444. if [ "$(echo $infos | cut -d ' ' -f1,2)" = "stream:stream jabber:$type" ]
  445. then
  446. if [ "$(echo $infos | cut -d ' ' -f3)" = "$serv" ]
  447. then
  448. success "Successfully connected to XMPP $type $serv:$port"
  449. else
  450. fail "Server $serv:$port announce itself as $(echo $infos | cut -f3)"
  451. fi
  452. else
  453. fail "Unexpected reply from $serv:$port : $infos"
  454. fi
  455. }
  456. check_xmpp_server_client() {
  457. _check_xmpp_server "$1" "$2" "$3" "client"
  458. }
  459. check_xmpp_server_s2s() {
  460. _check_xmpp_server "$1" "$2" "$3" "server"
  461. }
  462. check_xmpp_ssl() {
  463. serv=$1
  464. port=$2
  465. if [ -z "$port" ]
  466. then
  467. port=5222
  468. fi
  469. openssl s_client -connect $serv:$port </dev/null -starttls xmpp >/dev/null 2>/dev/null
  470. rep=$?
  471. if [ "$rep" -eq 0 ]
  472. then
  473. success "Openssl successfully negociating XMPP ssl with $serv:$port"
  474. else
  475. fail "Openssl failed negociating XMPP ssl with $serv:$port"
  476. fi
  477. }
  478. #
  479. # SSH checks
  480. #
  481. check_ssh_nc() {
  482. host=$1
  483. port=$2
  484. if [ -z "$port" ]
  485. then
  486. port=22
  487. fi
  488. rep="$(nc -w1 $host $port </dev/null)"
  489. res=$?
  490. if [ "$res" -ne "0" ]
  491. then
  492. fail "Netcat unable to connect to $host:$port"
  493. return
  494. fi
  495. if echo $rep | grep "^SSH-2.0-OpenSSH" >/dev/null
  496. then
  497. success "OpenSSH replied on $host:$port"
  498. else
  499. fail "Bad reply from $host:$port : '$rep'"
  500. fi
  501. }
  502. check_ssh_key() {
  503. host="$1"
  504. testkey="$2"
  505. keytype="$3"
  506. port="$4"
  507. if [ -z "$port" ]
  508. then
  509. port=22
  510. fi
  511. if [ -z "$keytype" ]
  512. then
  513. keytype="rsa"
  514. fi
  515. key=$(ssh-keyscan -p $port -t $keytype $host 2>/dev/null | cut -d " " -f3)
  516. if [ -z "$key" ]
  517. then
  518. fail "SSH server not responding"
  519. return
  520. elif [ "$key" = "$testkey" ]
  521. then
  522. success "OpenSSH $host:$port key is $testkey"
  523. return
  524. else
  525. fail "OpenSSH $host:$port missmatch : "
  526. logdate ERR "Expected : $testkey" 1
  527. logdate ERR "Received : $key" 1
  528. return
  529. fi
  530. }
  531. check_mpc() {
  532. # check_mpc [$host [$port] ]
  533. # tests if you can contact an MPD server in a client way
  534. # returns the current state of the server
  535. host=$1
  536. port=$2
  537. if [ -z "$host" ]
  538. then
  539. host=127.0.0.1
  540. fi
  541. if [ -z "$port" ]
  542. then
  543. port=6600
  544. fi
  545. if echo "status" | nc -w 1 "$host" "$port" | head -1 | grep "^OK MPD"
  546. then
  547. success "MPD server can be contacted on $host:$port"
  548. status=$(echo "status" | nc -w 1 "$host" "$port" | grep "^state:"|cut -d: -f2)
  549. success "It's state is : $status"
  550. fi
  551. }