Small sh "framework" to test some server responses
sh
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

check.sh 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  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. tmpfile=$(mktemp -t check_audiostream.XXXXXXXXX)
  269. sz="$2"
  270. if [ -z "$sz" ]
  271. then
  272. sz="128kb"
  273. fi
  274. if [ "$verbose" -gt 1 ]
  275. then
  276. logdate INFO "$tc_name: Running mplayer on '$1' for $sz" 3
  277. fi
  278. $MPLAYER -endpos $sz -ao pcm:file=$tmpfile "$1" 1>/dev/null 2>/dev/null
  279. res=$?
  280. bytes=$(du $tmpfile | cut -f1)
  281. rm $tmpfile 2>/dev/null
  282. if [ "$bytes" -lt 1024 ]
  283. then
  284. fail "mplayer retrieved ${bytes}B of stream instead of expected $sz"
  285. return
  286. fi
  287. if [ "$res" -eq 0 ]
  288. then
  289. success "mplayer retrieved $sz of stream on $1"
  290. else
  291. fail "mplayer failed to retrieve stream on $1"
  292. fi
  293. elif [ -x $MPV ]
  294. then
  295. if [ "$verbose" -gt 1 ]
  296. then
  297. logdate INFO "$tc_name: Running mpv on '$1' for $sz" 3
  298. fi
  299. tmpfile=$(mktemp -t check_audiostream.XXXXXXXXX)
  300. $MPV --vo=null --ao=null --o=$tmpfile --of=wav --length 1 "$1" &> /dev/null
  301. bytes=$(du $tmpfile | cut -f1)
  302. rm $tmpfile 2>/dev/null
  303. if [ "$bytes" -ge 1 ]
  304. then
  305. success "mpv read successfully $1"
  306. else
  307. fail "mpv could not read $1"
  308. fi
  309. fi
  310. }
  311. check_ping() {
  312. ns=$1
  313. count=$2
  314. if [ -z "$count" ]
  315. then
  316. count=5
  317. fi
  318. ping -i 0.2 -c $count $ns 2>/dev/null >/dev/null
  319. res=$?
  320. if [ "$res" -ne 0 ]
  321. then
  322. fail "unable to ping '$ns'"
  323. else
  324. success "successfully send $count ping to '$ns'"
  325. fi
  326. }
  327. check_git_repo() {
  328. tmpdir=$(mktemp -d -t check_git.XXXXXXXXX)
  329. git clone $1 $tmpdir 2>/dev/null 1>/dev/null
  330. res=$?
  331. rm -Rf $tmpdir
  332. if [ "$res" -ne 0 ]
  333. then
  334. fail "unable to clone git repo '$1'"
  335. else
  336. success "git repo '$1' cloned'"
  337. fi
  338. }
  339. #
  340. # Jabber XMPP checks
  341. #
  342. __xmpp_probe() {
  343. serv=$1
  344. timeout=$2
  345. type=$3
  346. 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"
  347. if [ "$verbose" -gt 2 ]
  348. then
  349. echo -e $payload | sed -e "s/^/$(datetime) [ DEBUG] Sent : /" >&2
  350. fi
  351. echo -e $payload
  352. sleep $timeout
  353. }
  354. _xmpp_probe() {
  355. serv=$1
  356. port=$2
  357. timeout=$3
  358. type=$4
  359. tmpres=$(mktemp -t xmpp_probe.XXXXXXXXX)
  360. echo "$(__xmpp_probe $serv $timeout $type| nc -q2 $serv $port)</stream:stream>" | xmllint --format - > $tmpres
  361. if [ "$verbose" -gt 2 ]
  362. then
  363. cat $tmpres | sed -e "s/^/$(datetime) [ DEBUG] Recv : /" >&2
  364. fi
  365. cat $tmpres
  366. rm $tmpres
  367. }
  368. _check_xmpp_ns() {
  369. ns1=$1
  370. expt_ns=$2
  371. expt_port=$3
  372. dnsq="_xmpp-${4}._tcp.$1"
  373. rep="$(dig $dnsq srv +short | cut -d" " -f3,4)"
  374. if [ "$rep" = "$expt_port ${expt_ns}." ]
  375. then
  376. success "$dnsq = '$rep'"
  377. else
  378. fail "$dnsq = '$rep' but '$expt_port ${expt_ns}.' expected"
  379. fi
  380. }
  381. check_xmpp_serv_ns() {
  382. _check_xmpp_ns "$1" "$2" "$3" "server"
  383. }
  384. check_xmpp_client_ns() {
  385. _check_xmpp_ns "$1" "$2" "$3" "client"
  386. }
  387. _check_xmpp_server() {
  388. serv=$1
  389. port=$2
  390. timeout=$3
  391. type=$4
  392. if [ -z "$port" ]
  393. then
  394. port=5222
  395. fi
  396. if [ -z "$timeout" ]
  397. then
  398. timeout=2
  399. fi
  400. if [ "$verbose" -gt 1 ]
  401. then
  402. tpe="client"
  403. if [ "$type" = "server" ]
  404. then
  405. tpe="S2S"
  406. fi
  407. logdate INFO "$tc_name: Connecting to XMPP $serv $tpe port $port (timeout=${timeout}s)" 3
  408. fi
  409. stream=$(_xmpp_probe $serv $port $timeout $type| head -n2 | tail -n1)
  410. if [ -z "$stream" ]
  411. then
  412. fail "Empty reply from $serv:$port"
  413. return
  414. fi
  415. if [ "$type" = "client" ]
  416. then
  417. infos=$(echo $stream | sed -E 's/^<([^ ]+).* xmlns="([^"]+)".* from="([^"]+)" .*$/\1 \2 \3/')
  418. else
  419. infos="$(echo $stream | sed -E 's/^<([^ ]+).* xmlns="([^"]+)" .*$/\1 \2/') $serv"
  420. fi
  421. if [ "$(echo $infos | cut -d ' ' -f1,2)" = "stream:stream jabber:$type" ]
  422. then
  423. if [ "$(echo $infos | cut -d ' ' -f3)" = "$serv" ]
  424. then
  425. success "Successfully connected to XMPP $type $serv:$port"
  426. else
  427. fail "Server $serv:$port announce itself as $(echo $infos | cut -f3)"
  428. fi
  429. else
  430. fail "Unexpected reply from $serv:$port : $infos"
  431. fi
  432. }
  433. check_xmpp_server_client() {
  434. _check_xmpp_server "$1" "$2" "$3" "client"
  435. }
  436. check_xmpp_server_s2s() {
  437. _check_xmpp_server "$1" "$2" "$3" "server"
  438. }
  439. check_xmpp_ssl() {
  440. serv=$1
  441. port=$2
  442. if [ -z "$port" ]
  443. then
  444. port=5222
  445. fi
  446. openssl s_client -connect $serv:$port </dev/null -starttls xmpp >/dev/null 2>/dev/null
  447. rep=$?
  448. if [ "$rep" -eq 0 ]
  449. then
  450. success "Openssl successfully negociating XMPP ssl with $serv:$port"
  451. else
  452. fail "Openssl failed negociating XMPP ssl with $serv:$port"
  453. fi
  454. }
  455. #
  456. # SSH checks
  457. #
  458. check_ssh_nc() {
  459. host=$1
  460. port=$2
  461. if [ -z "$port" ]
  462. then
  463. port=22
  464. fi
  465. rep="$(nc -w1 $host $port </dev/null)"
  466. res=$?
  467. if [ "$res" -ne "0" ]
  468. then
  469. fail "Netcat unable to connect to $host:$port"
  470. return
  471. fi
  472. if echo $rep | grep "^SSH-2.0-OpenSSH" >/dev/null
  473. then
  474. success "OpenSSH replied on $host:$port"
  475. else
  476. fail "Bad reply from $host:$port : '$rep'"
  477. fi
  478. }
  479. check_ssh_key() {
  480. host="$1"
  481. testkey="$2"
  482. keytype="$3"
  483. port="$4"
  484. if [ -z "$port" ]
  485. then
  486. port=22
  487. fi
  488. if [ -z "$keytype" ]
  489. then
  490. keytype="rsa"
  491. fi
  492. key=$(ssh-keyscan -p $port -t $keytype $host 2>/dev/null | cut -d " " -f3)
  493. if [ -z "$key" ]
  494. then
  495. fail "SSH server not responding"
  496. return
  497. elif [ "$key" = "$testkey" ]
  498. then
  499. success "OpenSSH $host:$port key is $testkey"
  500. return
  501. else
  502. fail "OpenSSH $host:$port missmatch : "
  503. logdate ERR "Expected : $testkey" 1
  504. logdate ERR "Received : $key" 1
  505. return
  506. fi
  507. }
  508. check_mpc() {
  509. # check_mpc [$host [$port] ]
  510. # tests if you can contact an MPD server in a client way
  511. # returns the current state of the server
  512. host=$1
  513. port=$2
  514. if [ -z "$host" ]
  515. then
  516. host=127.0.0.1
  517. fi
  518. if [ -z "$port" ]
  519. then
  520. port=6600
  521. fi
  522. if echo "status" | nc -w 1 "$host" "$port" | head -1 | grep "^OK MPD"
  523. then
  524. success "MPD server can be contacted on $host:$port"
  525. status=$(echo "status" | nc -w 1 "$host" "$port" | grep "^state:"|cut -d: -f2)
  526. success "It's state is : $status"
  527. fi
  528. }