From 6793129d369dee182d9260620d1db9188f09d986 Mon Sep 17 00:00:00 2001
From: Ethan Jackson <ethan@nicira.com>
Date: Wed, 22 Sep 2010 21:59:02 -0700
Subject: [PATCH] tests: Test that children restart with special exit code

Added a test which checks that the python daemon code properly
restarts child processes which exit with RESTART_EXIT_CODE.
---
 tests/daemon-py.at   | 43 +++++++++++++++++++++++++++++++++++++++++++
 tests/test-daemon.py | 15 ++++++++++++++-
 2 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/tests/daemon-py.at b/tests/daemon-py.at
index 9e5f2793b..9a2549c11 100644
--- a/tests/daemon-py.at
+++ b/tests/daemon-py.at
@@ -61,6 +61,49 @@ OVS_WAIT_WHILE([kill -0 `cat parent` || kill -0 `cat newpid` || test -e pid],
   [kill `cat parent`])
 AT_CLEANUP
 
+AT_SETUP([daemon --monitor restart exit code - Python])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+AT_CAPTURE_FILE([pid])
+AT_CAPTURE_FILE([parent])
+AT_CAPTURE_FILE([parentpid])
+AT_CAPTURE_FILE([newpid])
+# Start the daemon and wait for the pidfile to get created.
+AT_CHECK([$PYTHON $srcdir/test-daemon.py --pidfile-name=$PWD/pid --monitor& echo $! > parent], [0], [ignore], [ignore])
+OVS_WAIT_UNTIL([test -s pid], [kill `cat parent`])
+# Check that the pidfile names a running process,
+# and that the parent process of that process is our child process.
+AT_CHECK([kill -0 `cat pid`], [0], [], [], [kill `cat parent`])
+AT_CHECK([ps -o ppid= -p `cat pid` > parentpid],
+  [0], [], [], [kill `cat parent`])
+AT_CHECK(
+  [parentpid=`cat parentpid` &&
+   parent=`cat parent` &&
+   test $parentpid = $parent],
+  [0], [], [], [kill `cat parent`])
+# HUP the daemon process causing it to throw an exception,
+# and wait for a new child process to get spawned.
+AT_CHECK([cp pid oldpid], [0], [], [], [kill `cat parent`])
+AT_CHECK([kill -HUP `cat pid`], [0], [], [ignore], [kill `cat parent`])
+OVS_WAIT_WHILE([kill -0 `cat oldpid`], [kill `cat parent`])
+OVS_WAIT_UNTIL([test -s pid && test `cat pid` != `cat oldpid`],
+  [kill `cat parent`])
+AT_CHECK([cp pid newpid], [0], [], [], [kill `cat parent`])
+# Check that the pidfile names a running process,
+# and that the parent process of that process is our child process.
+AT_CHECK([ps -o ppid= -p `cat pid` > parentpid],
+  [0], [], [], [kill `cat parent`])
+AT_CHECK(
+  [parentpid=`cat parentpid` &&
+   parent=`cat parent` &&
+   test $parentpid = $parent],
+  [0], [], [], [kill `cat parent`])
+# Kill the daemon process with SIGTERM, and wait for the daemon
+# and the monitor processes to go away and the pidfile to get deleted.
+AT_CHECK([kill `cat pid`], [0], [], [ignore], [kill `cat parent`])
+OVS_WAIT_WHILE([kill -0 `cat parent` || kill -0 `cat newpid` || test -e pid],
+  [kill `cat parent`])
+AT_CLEANUP
+
 AT_SETUP([daemon --detach - Python])
 AT_SKIP_IF([test $HAVE_PYTHON = no])
 AT_CAPTURE_FILE([pid])
diff --git a/tests/test-daemon.py b/tests/test-daemon.py
index 98a516580..386445d44 100644
--- a/tests/test-daemon.py
+++ b/tests/test-daemon.py
@@ -13,13 +13,20 @@
 # limitations under the License.
 
 import getopt
+import signal
 import sys
 import time
 
 import ovs.daemon
 import ovs.util
 
+def handler(signum, frame):
+    raise Exception("Signal handler called with %d" % signum)
+
 def main(argv):
+
+    signal.signal(signal.SIGHUP, handler)
+
     try:
         options, args = getopt.gnu_getopt(
             argv[1:], 'b', ["bail", "help"] + ovs.daemon.LONG_OPTIONS)
@@ -63,4 +70,10 @@ Other options:
     sys.exit(0)
 
 if __name__ == '__main__':
-    main(sys.argv)
+    try:
+        main(sys.argv)
+    except SystemExit:
+        # Let system.exit() calls complete normally
+        raise
+    except:
+        sys.exit(ovs.daemon.RESTART_EXIT_CODE)
-- 
2.47.0