ctdb-tests: Add sock daemon test for do_fork
authorMartin Schwenke <martin@meltin.net>
Wed, 23 Aug 2017 10:32:29 +0000 (20:32 +1000)
committerAmitay Isaacs <amitay@samba.org>
Tue, 29 Aug 2017 13:03:33 +0000 (15:03 +0200)
Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Autobuild-User(master): Amitay Isaacs <amitay@samba.org>
Autobuild-Date(master): Tue Aug 29 15:03:33 CEST 2017 on sn-devel-144

ctdb/tests/cunit/sock_daemon_test_001.sh
ctdb/tests/src/sock_daemon_test.c

index 671877d27d5da45032e6bc944ada8b5ee5335ab3..1d2607f36ea1ed9e874947492aa5f7a00a663cd9 100755 (executable)
@@ -82,3 +82,13 @@ test8[PID]: Received signal 15
 test8[PID]: Shutting down
 EOF
 unit_test sock_daemon_test "$pidfile" "$sockpath" 8
+
+ok <<EOF
+test9[PID]: daemon started, pid=PID
+test9[PID]: Received signal 15
+test9[PID]: Shutting down
+test9[PID]: daemon started, pid=PID
+test9[PID]: Received signal 15
+test9[PID]: Shutting down
+EOF
+unit_test sock_daemon_test "$pidfile" "$sockpath" 9
index 9adbab8c439f1e7f4c540dbb4dd25ab79a4883e2..95b0909b78e8f614c973aea9bb84a8f80e6b3274 100644 (file)
@@ -1174,6 +1174,131 @@ static void test8(TALLOC_CTX *mem_ctx, const char *pidfile,
        close(fd[0]);
 }
 
+/*
+ * test9
+ *
+ * Confirm that do_fork causes the daemon to be forked as a separate child
+ */
+
+static void test9(TALLOC_CTX *mem_ctx, const char *pidfile,
+                 const char *sockpath)
+{
+       int fd[2];
+       pid_t pid, pid2;
+       int ret;
+       struct tevent_context *ev;
+       struct sock_daemon_context *sockd;
+       ssize_t n;
+       int pidfile_fd;
+       char pidstr[20] = { 0 };
+       struct stat st;
+
+       ret = pipe(fd);
+       assert(ret == 0);
+
+       pid = fork();
+       assert(pid != -1);
+
+       if (pid == 0) {
+               close(fd[0]);
+
+               ev = tevent_context_init(mem_ctx);
+               assert(ev != NULL);
+
+               /* Reuse test2 funcs for the startup synchronisation */
+               ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
+                                       &test2_funcs, &fd[1], &sockd);
+               assert(ret == 0);
+
+               ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
+               assert(ret == EINTR);
+
+               exit(0);
+       }
+
+       close(fd[1]);
+
+       n = read(fd[0], &ret, sizeof(ret));
+       assert(n == sizeof(ret));
+       assert(ret == 1);
+
+       /* do_fork false above, so pid should be active */
+       ret = kill(pid, 0);
+       assert(ret == 0);
+
+       ret = kill(pid, SIGTERM);
+       assert(ret == 0);
+
+       n = read(fd[0], &ret, sizeof(ret));
+       assert(n == sizeof(ret));
+       assert(ret == 3);
+
+       pid2 = waitpid(pid, &ret, 0);
+       assert(pid2 == pid);
+       assert(WEXITSTATUS(ret) == 0);
+
+       close(fd[0]);
+
+       ret = pipe(fd);
+       assert(ret == 0);
+
+       pid = fork();
+       assert(pid != -1);
+
+       if (pid == 0) {
+               close(fd[0]);
+
+               ev = tevent_context_init(mem_ctx);
+               assert(ev != NULL);
+
+               /* Reuse test2 funcs for the startup synchronisation */
+               ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
+                                       &test2_funcs, &fd[1], &sockd);
+               assert(ret == 0);
+
+               ret = sock_daemon_run(ev, sockd, pidfile, true, false, -1);
+               assert(ret == EINTR);
+
+               exit(0);
+       }
+
+       close(fd[1]);
+
+       n = read(fd[0], &ret, sizeof(ret));
+       assert(n == sizeof(ret));
+       assert(ret == 1);
+
+       /* do_fork true above, so pid should have exited */
+       pid2 = waitpid(pid, &ret, 0);
+       assert(pid2 == pid);
+       assert(WEXITSTATUS(ret) == 0);
+
+       pidfile_fd = open(pidfile, O_RDONLY, 0644);
+       assert(pidfile_fd != -1);
+       n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
+       assert(n != -1);
+       pid2 = (pid_t)atoi(pidstr);
+       assert(pid != pid2);
+
+       ret = kill(pid2, SIGTERM);
+       assert(ret == 0);
+
+       n = read(fd[0], &ret, sizeof(ret));
+       assert(n == sizeof(ret));
+       assert(ret == 3);
+
+       /*
+        * pid2 isn't our child, so can't call waitpid().  kill(pid2, 0)
+        * is unreliable - pid2 may have been recycled.  Above indicates
+        * that the shutdown function was called, so just do 1 final
+        * check to see if pidfile has been removed.
+        */
+       ret = stat(sockpath, &st);
+       assert(ret == -1);
+
+       close(fd[0]);
+}
+
 int main(int argc, const char **argv)
 {
        TALLOC_CTX *mem_ctx;
@@ -1225,6 +1350,10 @@ int main(int argc, const char **argv)
                test8(mem_ctx, pidfile, sockpath);
                break;
 
+       case 9:
+               test9(mem_ctx, pidfile, sockpath);
+               break;
+
        default:
                fprintf(stderr, "Unknown test number %d\n", num);
        }