respawn.sh 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. # GNU Shepherd --- Test respawnable services.
  2. # Copyright © 2013, 2014, 2016 Ludovic Courtès <ludo@gnu.org>
  3. #
  4. # This file is part of the GNU Shepherd.
  5. #
  6. # The GNU Shepherd is free software; you can redistribute it and/or modify it
  7. # under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 3 of the License, or (at
  9. # your option) any later version.
  10. #
  11. # The GNU Shepherd is distributed in the hope that it will be useful, but
  12. # WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with the GNU Shepherd. If not, see <http://www.gnu.org/licenses/>.
  18. shepherd --version
  19. herd --version
  20. socket="t-socket-$$"
  21. conf="t-conf-$$"
  22. log="t-log-$$"
  23. stamp="t-stamp-$$"
  24. service1_pid="t-service1-pid-$$"
  25. service2_pid="t-service2-pid-$$"
  26. pid="t-pid-$$"
  27. herd="herd -s $socket"
  28. trap "cat $log || true ;
  29. rm -f $socket $conf $stamp $log ;
  30. test -f $pid && kill \`cat $pid\` || true ; rm -f $pid ;
  31. test -f $service1_pid && kill \`cat $service1_pid\` || true ;
  32. test -f $service2_pid && kill \`cat $service2_pid\` || true ;
  33. rm -f $service1_pid $service2_pid" EXIT
  34. function wait_for_file
  35. {
  36. i=0
  37. while ! test -f "$1" && test $i -lt 20
  38. do
  39. sleep 0.3
  40. i=`expr $i + 1`
  41. done
  42. test -f "$1"
  43. }
  44. function assert_killed_service_is_respawned
  45. {
  46. old_pid="`cat "$1"`"
  47. rm "$1"
  48. kill $old_pid
  49. wait_for_file "$1"
  50. test -f "$1"
  51. new_pid="`cat "$1"`"
  52. test "$old_pid" -ne "$new_pid"
  53. kill -0 "$new_pid"
  54. }
  55. cat > "$conf"<<EOF
  56. (register-services
  57. (make <service>
  58. #:provides '(test1)
  59. #:start (make-forkexec-constructor
  60. '("$SHELL" "-c"
  61. "echo \$\$ > $PWD/$service1_pid ; while true ; do sleep 1 ; done"))
  62. #:stop (make-kill-destructor)
  63. #:respawn? #t)
  64. (make <service>
  65. #:provides '(test2)
  66. #:start (make-forkexec-constructor
  67. ;; The 'sleep' below is just to make it more likely
  68. ;; that synchronization issues in handling #:pid-file
  69. ;; would be caught.
  70. '("$SHELL" "-c"
  71. "sleep 0.7 ; echo \$\$ > $PWD/$service2_pid ; while true ; do sleep 1 ; done")
  72. #:pid-file "$PWD/$service2_pid")
  73. #:stop (make-kill-destructor)
  74. #:respawn? #t))
  75. (start 'test1)
  76. EOF
  77. rm -f "$pid"
  78. shepherd -I -s "$socket" -c "$conf" -l "$log" --pid="$pid" &
  79. # Wait till it's ready.
  80. wait_for_file "$pid"
  81. shepherd_pid="`cat $pid`"
  82. kill -0 $shepherd_pid
  83. test -S "$socket"
  84. $herd status
  85. $herd status test1 | grep started
  86. $herd start test2
  87. $herd status test2 | grep started
  88. # When 'herd start test2' returns, the PID file must already be created.
  89. test -f "$service2_pid"
  90. # Conversely, 'test1' may not have written its PID file yet, so use
  91. # 'wait_for_file' rather than 'test -f'.
  92. wait_for_file "$service1_pid"
  93. # Make sure the PIDs are valid.
  94. kill -0 `cat "$service1_pid"`
  95. kill -0 `cat "$service2_pid"`
  96. # Now, kill the services, and make sure they both get respawned.
  97. assert_killed_service_is_respawned "$service1_pid"
  98. assert_killed_service_is_respawned "$service2_pid"
  99. assert_killed_service_is_respawned "$service1_pid"
  100. assert_killed_service_is_respawned "$service2_pid"
  101. assert_killed_service_is_respawned "$service1_pid"
  102. assert_killed_service_is_respawned "$service2_pid"
  103. # Make sure the respawnable service can be stopped.
  104. pid="`cat "$service1_pid"`"
  105. rm "$service1_pid"
  106. $herd stop test1
  107. $herd status test1 | grep stopped
  108. ! test -f "$service1_pid"
  109. ! kill -0 "$pid"
  110. cat $service2_pid
  111. $herd stop root