basic.sh 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. # GNU Shepherd --- Test basic communication capabilities.
  2. # Copyright © 2013, 2014, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
  3. # Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
  4. # Copyright © 2014 Alex Sassmannshausen <alex.sassmannshausen@gmail.com>
  5. #
  6. # This file is part of the GNU Shepherd.
  7. #
  8. # The GNU Shepherd is free software; you can redistribute it and/or modify it
  9. # under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 3 of the License, or (at
  11. # your option) any later version.
  12. #
  13. # The GNU Shepherd is distributed in the hope that it will be useful, but
  14. # WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with the GNU Shepherd. If not, see <http://www.gnu.org/licenses/>.
  20. shepherd --version
  21. herd --version
  22. socket="t-socket-$$"
  23. conf="t-conf-$$"
  24. confdir="t-confdir-$$"
  25. datadir="t-datadir-$$"
  26. log="t-log-$$"
  27. stamp="t-stamp-$$"
  28. pid="t-pid-$$"
  29. herd="herd -s $socket"
  30. trap "cat $log || true; rm -f $socket $conf $stamp $log;
  31. test -f $pid && kill \`cat $pid\` || true; rm -f $pid" EXIT
  32. cat > "$conf"<<EOF
  33. (use-modules (srfi srfi-26))
  34. (register-services
  35. (make <service>
  36. #:provides '(test)
  37. #:start (lambda _
  38. (call-with-output-file "$stamp"
  39. (cut display "foo" <>))
  40. #t)
  41. #:stop (lambda _
  42. (delete-file "$stamp"))
  43. #:respawn? #f)
  44. (make <service>
  45. #:provides '(test-2)
  46. #:requires '(test)
  47. #:start (lambda _
  48. (call-with-output-file "$stamp-2"
  49. (cut display "bar" <>))
  50. #t)
  51. #:stop (lambda _
  52. (delete-file "$stamp-2"))
  53. #:actions (make-actions (hi "Say hi."
  54. (lambda _
  55. (display "start\n\nend\n")
  56. #t))
  57. (fail "Fail." (const #f)))
  58. #:respawn? #f)
  59. (make <service>
  60. #:provides '(broken)
  61. #:requires '()
  62. #:start (lambda _
  63. (mkdir "/this/throws/a/system/error"))
  64. #:stop (const #f)
  65. #:respawn? #f))
  66. EOF
  67. rm -f "$pid"
  68. shepherd -I -s "$socket" -c "$conf" -l "$log" --pid="$pid" &
  69. # Wait till it's ready.
  70. while ! test -f "$pid" ; do sleep 0.3 ; done
  71. shepherd_pid="`cat $pid`"
  72. kill -0 $shepherd_pid
  73. test -S "$socket"
  74. pristine_status=`$herd status root` # Prep for 'reload' test.
  75. echo $pristine_status | grep -E '(Start.*root|Stop.*test)'
  76. $herd start test
  77. test -f "$stamp"
  78. $herd status test | grep started
  79. $herd stop test
  80. ! test -f "$stamp"
  81. $herd status test | grep stopped
  82. # Stopping a stopped service should be a no-op.
  83. $herd stop test
  84. test -z "`$herd stop test 2>&1`"
  85. # Disable a service and make sure it cannot be started.
  86. $herd disable test-2
  87. if $herd start test-2
  88. then false; else true; fi
  89. $herd enable test-2
  90. $herd start test-2
  91. # Make sure we didn't emit empty lines in the log (strip the timestamp that
  92. # prefixes each line.)
  93. test `wc -l < "$log"` -gt 0
  94. test `cut -c 21- < "$log" | grep "^$" | wc -l` -eq 0
  95. # Try a custom action; make sure we get all the lines, including the empty
  96. # lines (this was not the case in 0.4.0.)
  97. $herd doc test-2 action hi | grep "Say hi\."
  98. $herd hi test-2
  99. $herd hi test-2 | grep '^start$'
  100. $herd hi test-2 | grep '^end$'
  101. test `$herd hi test-2 | wc -l` -eq 3
  102. # An action that returns false must lead to a non-zero exit code.
  103. if $herd fail test-2; then false; else true; fi
  104. # This used to crash shepherd: <http://bugs.gnu.org/24684>.
  105. if $herd enable test-2 with extra arguments
  106. then false; else true; fi
  107. $herd status test-2 | grep started
  108. # Make sure extra arguments lead to an error.
  109. if $herd status test-2 something else that is useless
  110. then false; else true; fi
  111. for action in status start stop
  112. do
  113. if $herd $action does-not-exist
  114. then false; else true; fi
  115. $herd $action does-not-exist 2>&1 | grep "does-not-exist.*not.*found"
  116. done
  117. if $herd an-action-that-does-not-exist root
  118. then false; else true; fi
  119. if $herd start broken
  120. then false; else true; fi
  121. # Wrong number of arguments for an action.
  122. if $herd status root foo bar baz;
  123. then false; else true; fi
  124. # Asking for the doc of specific actions.
  125. $herd doc root action status
  126. if $herd doc root action an-action-that-does-not-exist
  127. then false; else true; fi
  128. # Make sure the error message is correct.
  129. $herd doc root action an-action-that-does-not-exist 2>&1 | \
  130. grep "does not have an action 'an-action-that-does-not-exist'"
  131. # Loading nonexistent file.
  132. if $herd load root /does/not/exist.scm;
  133. then false; else true; fi
  134. # Unload two services, make sure the other it still around.
  135. $herd unload root broken
  136. $herd unload root test
  137. $herd status | grep -e "- test-2"
  138. $herd reload root "$conf"
  139. test "`$herd status`" == "$pristine_status"
  140. # Dynamically loading code.
  141. mkdir -p "$confdir"
  142. cat > "$confdir/some-conf.scm" <<EOF
  143. (register-services
  144. (make <service>
  145. #:provides '(test-loaded)
  146. #:start (const 'abc)
  147. #:stop (const #f)))
  148. EOF
  149. if $herd status test-loaded
  150. then false; else true; fi
  151. # Pass a relative file name and makes sure it's properly resolved.
  152. (cd "$confdir" && herd -s "../$socket" load root "some-conf.scm")
  153. rm "$confdir/some-conf.scm"
  154. # The new service should be loaded now.
  155. $herd status test-loaded
  156. $herd status test-loaded | grep stopped
  157. $herd start test-loaded
  158. $herd status test-loaded | grep -i 'running.*abc'
  159. $herd stop test-loaded
  160. $herd unload root test-loaded
  161. # Load a service whose running value does not have a valid read syntax, and
  162. # make sure that the running value is clamped before being sent over the wire.
  163. cat > "$confdir/some-conf.scm" <<EOF
  164. (register-services
  165. (make <service>
  166. #:provides '(test-loaded)
  167. #:start (const (if #f #f)) ;#<undefined>
  168. #:stop (const #f)))
  169. EOF
  170. $herd load root "$confdir/some-conf.scm"
  171. $herd start test-loaded
  172. $herd status test-loaded | grep -i "running.*#<unspecified>"
  173. $herd stop test-loaded
  174. # Deregister 'test-loaded' via 'eval'.
  175. $herd eval root "(action root-service 'unload \"test-loaded\")"
  176. if $herd status test-loaded
  177. then false; else true; fi
  178. # Load code that triggers a syntax error and make sure that shepherd survives.
  179. cat > "$confdir/some-conf.scm" <<EOF
  180. (define x y z)
  181. EOF
  182. if $herd load root "$confdir/some-conf.scm"
  183. then false; else true; fi
  184. $herd status # still here?
  185. # Load code that throws an object with no read syntax.
  186. cat > "$confdir/some-conf.scm" <<EOF
  187. (use-modules (srfi srfi-9))
  188. (define-record-type <something> (something) something?)
  189. (throw 'what?! (something))
  190. EOF
  191. if $herd load root "$confdir/some-conf.scm"
  192. then false; else true; fi
  193. $herd status # still here?
  194. # Evaluate silly code, make sure nothing breaks.
  195. if $herd eval root '(/ 0 0)'
  196. then false; else true; fi
  197. if $herd eval root '(no closing paren'
  198. then false; else true; fi
  199. # Unload everything and make sure only 'root' is left.
  200. $herd unload root all
  201. if $herd status | grep "Stopped:"
  202. then false; else true; fi
  203. $herd status | grep -e "+ root"
  204. $herd stop root
  205. ! kill -0 $shepherd_pid
  206. test -f "$log"
  207. ## ------------------------ ##
  208. ## Usage of XDG variables. ##
  209. ## ------------------------ ##
  210. # Set XDG_CONFIG_HOME for configuration files.
  211. export XDG_CONFIG_HOME=$confdir
  212. export XDG_DATA_DIR=$datadir
  213. mkdir -p $confdir/shepherd
  214. mkdir -p $datadir/shepherd
  215. mv $conf $confdir/shepherd/init.scm
  216. rm -f "$pid" "$socket"
  217. shepherd -I -s "$socket" --pid="$pid" &
  218. # Wait till it's ready.
  219. while ! test -f "$pid" ; do sleep 0.3 ; done
  220. # Launch a service from $confdir/shepherd/init.scm.
  221. $herd start test
  222. test -f "$stamp"
  223. $herd status test | grep started
  224. $herd stop test
  225. ! test -f "$stamp"
  226. shepherd_pid="`cat $pid`"
  227. $herd stop root
  228. ! kill -0 $shepherd_pid
  229. rm -rf $confdir
  230. rm -rf $datadir