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 9.9KB

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