ctdb-tests: Make sure child processes are waited on after termination
[Samba.git] / ctdb / tests / src / sock_daemon_test.c
blob5641d37bcd1d9410d8121b3035e9a32481bf9c0c
1 /*
2 sock daemon tests
4 Copyright (C) Amitay Isaacs 2016
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but 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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "replace.h"
21 #include "system/filesys.h"
22 #include "system/network.h"
23 #include "system/wait.h"
25 #include <assert.h>
27 #include "common/logging.c"
28 #include "common/pkt_read.c"
29 #include "common/pkt_write.c"
30 #include "common/comm.c"
31 #include "common/pidfile.c"
32 #include "common/sock_daemon.c"
33 #include "common/sock_io.c"
35 struct dummy_wait_state {
38 static struct tevent_req *dummy_wait_send(TALLOC_CTX *mem_ctx,
39 struct tevent_context *ev,
40 void *private_data)
42 struct tevent_req *req;
43 struct dummy_wait_state *state;
44 const char *sockpath = (const char *)private_data;
45 struct stat st;
46 int ret;
48 ret = stat(sockpath, &st);
49 assert(ret == 0);
50 assert(S_ISSOCK(st.st_mode));
52 req = tevent_req_create(mem_ctx, &state, struct dummy_wait_state);
53 if (req == NULL) {
54 return NULL;
57 tevent_req_done(req);
58 return tevent_req_post(req, ev);
61 static bool dummy_wait_recv(struct tevent_req *req, int *perr)
63 return true;
66 static int test1_startup_fail(void *private_data)
68 return 1;
71 static int test1_startup(void *private_data)
73 const char *sockpath = (const char *)private_data;
74 struct stat st;
75 int ret;
77 ret = stat(sockpath, &st);
78 assert(ret == -1);
80 return 0;
83 struct test1_startup_state {
86 static struct tevent_req *test1_startup_send(TALLOC_CTX *mem_ctx,
87 struct tevent_context *ev,
88 void *private_data)
90 struct tevent_req *req;
91 struct test1_startup_state *state;
93 req = tevent_req_create(mem_ctx, &state, struct test1_startup_state);
94 if (req == NULL) {
95 return NULL;
98 tevent_req_error(req, 2);
99 return tevent_req_post(req, ev);
102 static bool test1_startup_recv(struct tevent_req *req, int *perr)
104 if (tevent_req_is_unix_error(req, perr)) {
105 return false;
108 return true;
111 static struct tevent_req *dummy_read_send(TALLOC_CTX *mem_ctx,
112 struct tevent_context *ev,
113 struct sock_client_context *client,
114 uint8_t *buf, size_t buflen,
115 void *private_data)
117 return NULL;
120 static bool dummy_read_recv(struct tevent_req *req, int *perr)
122 if (perr != NULL) {
123 *perr = EINVAL;
125 return false;
128 static struct sock_socket_funcs dummy_socket_funcs = {
129 .read_send = dummy_read_send,
130 .read_recv = dummy_read_recv,
134 * test1
136 * Check setup without actually running daemon
139 static void test1(TALLOC_CTX *mem_ctx, const char *pidfile,
140 const char *sockpath)
142 struct tevent_context *ev;
143 struct sock_daemon_context *sockd;
144 struct sock_daemon_funcs test1_funcs;
145 struct stat st;
146 int ret;
148 ev = tevent_context_init(mem_ctx);
149 assert(ev != NULL);
151 test1_funcs = (struct sock_daemon_funcs){
152 .startup = test1_startup_fail,
155 ret = sock_daemon_setup(mem_ctx, "test1", "file:", "NOTICE",
156 &test1_funcs, NULL, &sockd);
157 assert(ret == 0);
158 assert(sockd != NULL);
160 ret = stat(pidfile, &st);
161 assert(ret == -1);
163 ret = sock_daemon_run(ev, sockd, NULL, false, false, -1);
164 assert(ret == EIO);
165 talloc_free(sockd);
167 test1_funcs = (struct sock_daemon_funcs){
168 .startup_send = test1_startup_send,
169 .startup_recv = test1_startup_recv,
172 ret = sock_daemon_setup(mem_ctx, "test1", "file:", "NOTICE",
173 &test1_funcs, NULL, &sockd);
174 assert(ret == 0);
175 assert(sockd != NULL);
177 ret = stat(pidfile, &st);
178 assert(ret == -1);
180 ret = sock_daemon_run(ev, sockd, NULL, false, false, -1);
181 assert(ret == EIO);
182 talloc_free(sockd);
184 test1_funcs = (struct sock_daemon_funcs){
185 .startup = test1_startup,
186 .wait_send = dummy_wait_send,
187 .wait_recv = dummy_wait_recv,
190 ret = sock_daemon_setup(mem_ctx, "test1", "file:", "NOTICE",
191 &test1_funcs, discard_const(sockpath), &sockd);
192 assert(ret == 0);
193 assert(sockd != NULL);
195 ret = sock_daemon_add_unix(sockd, sockpath, &dummy_socket_funcs, NULL);
196 assert(ret == 0);
198 ret = stat(sockpath, &st);
199 assert(ret == -1);
201 ret = sock_daemon_run(ev, sockd, NULL, false, false, -1);
202 assert(ret == 0);
204 talloc_free(mem_ctx);
208 * test2
210 * Start daemon, check PID file, sock daemon functions, termination,
211 * exit code
214 static int test2_startup(void *private_data)
216 int fd = *(int *)private_data;
217 int ret = 1;
218 ssize_t nwritten;
220 nwritten = write(fd, &ret, sizeof(ret));
221 assert(nwritten == sizeof(ret));
222 return 0;
225 static int test2_reconfigure(void *private_data)
227 static bool first_time = true;
228 int fd = *(int *)private_data;
229 int ret = 2;
230 ssize_t nwritten;
232 nwritten = write(fd, &ret, sizeof(ret));
233 assert(nwritten == sizeof(ret));
235 if (first_time) {
236 first_time = false;
237 return 1;
240 return 0;
243 struct test2_reconfigure_state {
244 int fd;
247 static struct tevent_req *test2_reconfigure_send(TALLOC_CTX *mem_ctx,
248 struct tevent_context *ev,
249 void *private_data)
251 struct tevent_req *req;
252 struct test2_reconfigure_state *state;
253 static bool first_time = true;
255 req = tevent_req_create(mem_ctx, &state,
256 struct test2_reconfigure_state);
257 if (req == NULL) {
258 return NULL;
261 state->fd = *(int *)private_data;
263 if (first_time) {
264 first_time = false;
265 tevent_req_error(req, 2);
266 } else {
267 tevent_req_done(req);
270 return tevent_req_post(req, ev);
273 static bool test2_reconfigure_recv(struct tevent_req *req, int *perr)
275 struct test2_reconfigure_state *state = tevent_req_data(
276 req, struct test2_reconfigure_state);
277 int ret = 2;
278 ssize_t nwritten;
280 nwritten = write(state->fd, &ret, sizeof(ret));
281 assert(nwritten == sizeof(ret));
283 if (tevent_req_is_unix_error(req, perr)) {
284 return false;
287 return true;
290 static void test2_shutdown(void *private_data)
292 int fd = *(int *)private_data;
293 int ret = 3;
294 ssize_t nwritten;
296 nwritten = write(fd, &ret, sizeof(ret));
297 assert(nwritten == sizeof(ret));
300 struct test2_shutdown_state {
301 int fd;
304 static struct tevent_req *test2_shutdown_send(TALLOC_CTX *mem_ctx,
305 struct tevent_context *ev,
306 void *private_data)
308 struct tevent_req *req;
309 struct test2_shutdown_state *state;
311 req = tevent_req_create(mem_ctx, &state,
312 struct test2_shutdown_state);
313 if (req == NULL) {
314 return NULL;
317 state->fd = *(int *)private_data;
319 tevent_req_done(req);
320 return tevent_req_post(req, ev);
323 static void test2_shutdown_recv(struct tevent_req *req)
325 struct test2_shutdown_state *state = tevent_req_data(
326 req, struct test2_shutdown_state);
327 int ret = 3;
328 ssize_t nwritten;
330 nwritten = write(state->fd, &ret, sizeof(ret));
331 assert(nwritten == sizeof(ret));
334 static void test2(TALLOC_CTX *mem_ctx, const char *pidfile,
335 const char *sockpath)
337 struct stat st;
338 int fd[2];
339 pid_t pid, pid2;
340 int ret;
341 ssize_t n;
342 int pidfile_fd;
343 char pidstr[20] = { 0 };
345 ret = pipe(fd);
346 assert(ret == 0);
348 pid = fork();
349 assert(pid != -1);
351 if (pid == 0) {
352 struct tevent_context *ev;
353 struct sock_daemon_context *sockd;
354 struct sock_daemon_funcs test2_funcs = {
355 .startup = test2_startup,
356 .reconfigure = test2_reconfigure,
357 .shutdown = test2_shutdown,
360 close(fd[0]);
362 ev = tevent_context_init(mem_ctx);
363 assert(ev != NULL);
365 ret = sock_daemon_setup(mem_ctx, "test2", "file:", "NOTICE",
366 &test2_funcs, &fd[1], &sockd);
367 assert(ret == 0);
369 ret = sock_daemon_add_unix(sockd, sockpath,
370 &dummy_socket_funcs, NULL);
371 assert(ret == 0);
373 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
374 assert(ret == EINTR);
376 exit(0);
379 close(fd[1]);
381 n = read(fd[0], &ret, sizeof(ret));
382 assert(n == sizeof(ret));
383 assert(ret == 1);
385 pidfile_fd = open(pidfile, O_RDONLY, 0644);
386 assert(pidfile_fd != -1);
387 ret = fstat(pidfile_fd, &st);
388 assert(ret == 0);
389 assert(S_ISREG(st.st_mode));
390 n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
391 assert(n != -1);
392 pid2 = (pid_t)atoi(pidstr);
393 assert(pid == pid2);
394 close(pidfile_fd);
396 ret = kill(pid, SIGHUP);
397 assert(ret == 0);
399 n = read(fd[0], &ret, sizeof(ret));
400 assert(n == sizeof(ret));
401 assert(ret == 2);
403 ret = kill(pid, SIGUSR1);
404 assert(ret == 0);
406 n = read(fd[0], &ret, sizeof(ret));
407 assert(n == sizeof(ret));
408 assert(ret == 2);
410 ret = kill(pid, SIGTERM);
411 assert(ret == 0);
413 n = read(fd[0], &ret, sizeof(ret));
414 assert(n == sizeof(ret));
415 assert(ret == 3);
417 pid2 = waitpid(pid, &ret, 0);
418 assert(pid2 == pid);
419 assert(WEXITSTATUS(ret) == 0);
421 close(fd[0]);
423 ret = stat(pidfile, &st);
424 assert(ret == -1);
426 ret = stat(sockpath, &st);
427 assert(ret == -1);
429 ret = pipe(fd);
430 assert(ret == 0);
432 pid = fork();
433 assert(pid != -1);
435 if (pid == 0) {
436 struct tevent_context *ev;
437 struct sock_daemon_context *sockd;
438 struct sock_daemon_funcs test2_funcs = {
439 .startup = test2_startup,
440 .reconfigure_send = test2_reconfigure_send,
441 .reconfigure_recv = test2_reconfigure_recv,
442 .shutdown_send = test2_shutdown_send,
443 .shutdown_recv = test2_shutdown_recv,
446 close(fd[0]);
448 ev = tevent_context_init(mem_ctx);
449 assert(ev != NULL);
451 ret = sock_daemon_setup(mem_ctx, "test2", "file:", "NOTICE",
452 &test2_funcs, &fd[1], &sockd);
453 assert(ret == 0);
455 ret = sock_daemon_add_unix(sockd, sockpath,
456 &dummy_socket_funcs, NULL);
457 assert(ret == 0);
459 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
460 assert(ret == EINTR);
462 exit(0);
465 close(fd[1]);
467 n = read(fd[0], &ret, sizeof(ret));
468 assert(n == sizeof(ret));
469 assert(ret == 1);
471 ret = kill(pid, SIGUSR1);
472 assert(ret == 0);
474 n = read(fd[0], &ret, sizeof(ret));
475 assert(n == sizeof(ret));
476 assert(ret == 2);
478 ret = kill(pid, SIGHUP);
479 assert(ret == 0);
481 n = read(fd[0], &ret, sizeof(ret));
482 assert(n == sizeof(ret));
483 assert(ret == 2);
485 ret = kill(pid, SIGTERM);
486 assert(ret == 0);
488 n = read(fd[0], &ret, sizeof(ret));
489 assert(n == sizeof(ret));
490 assert(ret == 3);
492 pid2 = waitpid(pid, &ret, 0);
493 assert(pid2 == pid);
494 assert(WEXITSTATUS(ret) == 0);
496 close(fd[0]);
500 * test3
502 * Start daemon, test watching of (parent) PID
505 static void test3(TALLOC_CTX *mem_ctx, const char *pidfile,
506 const char *sockpath)
508 struct stat st;
509 pid_t pid_watch, pid, pid2;
510 int ret;
512 pid_watch = fork();
513 assert(pid_watch != -1);
515 if (pid_watch == 0) {
516 sleep(10);
517 exit(0);
520 pid = fork();
521 assert(pid != -1);
523 if (pid == 0) {
524 struct tevent_context *ev;
525 struct sock_daemon_context *sockd;
527 ev = tevent_context_init(mem_ctx);
528 assert(ev != NULL);
530 ret = sock_daemon_setup(mem_ctx, "test3", "file:", "NOTICE",
531 NULL, NULL, &sockd);
532 assert(ret == 0);
534 ret = sock_daemon_add_unix(sockd, sockpath,
535 &dummy_socket_funcs, NULL);
536 assert(ret == 0);
538 ret = sock_daemon_run(ev, sockd, NULL, false, false, pid_watch);
539 assert(ret == ESRCH);
541 exit(0);
544 pid2 = waitpid(pid_watch, &ret, 0);
545 assert(pid2 == pid_watch);
546 assert(WEXITSTATUS(ret) == 0);
548 pid2 = waitpid(pid, &ret, 0);
549 assert(pid2 == pid);
550 assert(WEXITSTATUS(ret) == 0);
552 ret = stat(pidfile, &st);
553 assert(ret == -1);
555 ret = stat(sockpath, &st);
556 assert(ret == -1);
560 * test4
562 * Start daemon, test termination via wait_send function
565 struct test4_wait_state {
568 static void test4_wait_done(struct tevent_req *subreq);
570 static struct tevent_req *test4_wait_send(TALLOC_CTX *mem_ctx,
571 struct tevent_context *ev,
572 void *private_data)
574 struct tevent_req *req, *subreq;
575 struct test4_wait_state *state;
577 req = tevent_req_create(mem_ctx, &state, struct test4_wait_state);
578 if (req == NULL) {
579 return NULL;
582 subreq = tevent_wakeup_send(state, ev,
583 tevent_timeval_current_ofs(10,0));
584 if (tevent_req_nomem(subreq, req)) {
585 return tevent_req_post(req, ev);
587 tevent_req_set_callback(subreq, test4_wait_done, req);
589 return req;
592 static void test4_wait_done(struct tevent_req *subreq)
594 struct tevent_req *req = tevent_req_callback_data(
595 subreq, struct tevent_req);
596 bool status;
598 status = tevent_wakeup_recv(subreq);
599 TALLOC_FREE(subreq);
601 if (! status) {
602 tevent_req_error(req, EIO);
603 } else {
604 tevent_req_done(req);
608 static bool test4_wait_recv(struct tevent_req *req, int *perr)
610 int ret;
612 if (tevent_req_is_unix_error(req, &ret)) {
613 if (perr != NULL) {
614 *perr = ret;
616 return false;
619 return true;
622 static struct sock_daemon_funcs test4_funcs = {
623 .wait_send = test4_wait_send,
624 .wait_recv = test4_wait_recv,
627 static void test4(TALLOC_CTX *mem_ctx, const char *pidfile,
628 const char *sockpath)
630 struct stat st;
631 pid_t pid, pid2;
632 int ret;
634 pid = fork();
635 assert(pid != -1);
637 if (pid == 0) {
638 struct tevent_context *ev;
639 struct sock_daemon_context *sockd;
641 ev = tevent_context_init(mem_ctx);
642 assert(ev != NULL);
644 ret = sock_daemon_setup(mem_ctx, "test4", "file:", "NOTICE",
645 &test4_funcs, NULL, &sockd);
646 assert(ret == 0);
648 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
649 assert(ret == 0);
651 exit(0);
654 pid2 = waitpid(pid, &ret, 0);
655 assert(pid2 == pid);
656 assert(WEXITSTATUS(ret) == 0);
658 ret = stat(pidfile, &st);
659 assert(ret == -1);
661 ret = stat(sockpath, &st);
662 assert(ret == -1);
666 * test5
668 * Start daemon, multiple client connects, requests, disconnects
671 #define TEST5_MAX_CLIENTS 10
673 struct test5_pkt {
674 uint32_t len;
675 int data;
678 struct test5_client_state {
679 int id;
680 int fd;
681 bool done;
684 static void test5_client_callback(uint8_t *buf, size_t buflen,
685 void *private_data)
687 struct test5_client_state *state =
688 (struct test5_client_state *)private_data;
689 struct test5_pkt *pkt;
690 ssize_t n;
691 int ret;
693 if (buf == NULL) {
694 assert(buflen == 0);
696 ret = 0;
697 } else {
698 assert(buflen == sizeof(struct test5_pkt));
699 pkt = (struct test5_pkt *)buf;
700 assert(pkt->len == sizeof(struct test5_pkt));
702 ret = pkt->data;
705 assert(state->fd != -1);
707 n = write(state->fd, (void *)&ret, sizeof(int));
708 assert(n == sizeof(int));
710 state->done = true;
713 static int test5_client(const char *sockpath, int id)
715 pid_t pid;
716 int fd[2];
717 int ret;
718 ssize_t n;
720 ret = pipe(fd);
721 assert(ret == 0);
723 pid = fork();
724 assert(pid != -1);
726 if (pid == 0) {
727 struct tevent_context *ev;
728 struct test5_client_state state;
729 struct sock_queue *queue;
730 struct test5_pkt pkt;
731 int conn;
733 close(fd[0]);
735 ev = tevent_context_init(NULL);
736 assert(ev != NULL);
738 conn = sock_connect(sockpath);
739 assert(conn != -1);
741 state.id = id;
742 state.fd = fd[1];
743 state.done = false;
745 queue = sock_queue_setup(ev, ev, conn,
746 test5_client_callback, &state);
747 assert(queue != NULL);
749 pkt.len = 8;
750 pkt.data = 0xbaba;
752 ret = sock_queue_write(queue, (uint8_t *)&pkt,
753 sizeof(struct test5_pkt));
754 assert(ret == 0);
756 while (! state.done) {
757 tevent_loop_once(ev);
760 close(fd[0]);
761 state.fd = -1;
763 sleep(10);
764 exit(0);
767 close(fd[1]);
769 ret = 0;
770 n = read(fd[0], &ret, sizeof(ret));
771 if (n == 0) {
772 fprintf(stderr, "client id %d read 0 bytes\n", id);
774 assert(n == 0 || n == sizeof(ret));
776 close(fd[0]);
778 return ret;
781 struct test5_server_state {
782 int num_clients;
785 static bool test5_connect(struct sock_client_context *client,
786 void *private_data)
788 struct test5_server_state *state =
789 (struct test5_server_state *)private_data;
791 if (state->num_clients == TEST5_MAX_CLIENTS) {
792 return false;
795 state->num_clients += 1;
796 assert(state->num_clients <= TEST5_MAX_CLIENTS);
797 return true;
800 static void test5_disconnect(struct sock_client_context *client,
801 void *private_data)
803 struct test5_server_state *state =
804 (struct test5_server_state *)private_data;
806 state->num_clients -= 1;
807 assert(state->num_clients >= 0);
810 struct test5_read_state {
811 struct test5_pkt reply;
814 static void test5_read_done(struct tevent_req *subreq);
816 static struct tevent_req *test5_read_send(TALLOC_CTX *mem_ctx,
817 struct tevent_context *ev,
818 struct sock_client_context *client,
819 uint8_t *buf, size_t buflen,
820 void *private_data)
822 struct test5_server_state *server_state =
823 (struct test5_server_state *)private_data;
824 struct tevent_req *req, *subreq;
825 struct test5_read_state *state;
826 struct test5_pkt *pkt;
828 req = tevent_req_create(mem_ctx, &state, struct test5_read_state);
829 assert(req != NULL);
831 assert(buflen == sizeof(struct test5_pkt));
833 pkt = (struct test5_pkt *)buf;
834 assert(pkt->data == 0xbaba);
836 state->reply.len = sizeof(struct test5_pkt);
837 state->reply.data = server_state->num_clients;
839 subreq = sock_socket_write_send(state, ev, client,
840 (uint8_t *)&state->reply,
841 state->reply.len);
842 assert(subreq != NULL);
844 tevent_req_set_callback(subreq, test5_read_done, req);
846 return req;
849 static void test5_read_done(struct tevent_req *subreq)
851 struct tevent_req *req = tevent_req_callback_data(
852 subreq, struct tevent_req);
853 int ret;
854 bool status;
856 status = sock_socket_write_recv(subreq, &ret);
857 TALLOC_FREE(subreq);
858 if (! status) {
859 tevent_req_error(req, ret);
860 return;
863 tevent_req_done(req);
866 static bool test5_read_recv(struct tevent_req *req, int *perr)
868 int ret;
870 if (tevent_req_is_unix_error(req, &ret)) {
871 if (perr != NULL) {
872 *perr = ret;
874 return false;
877 return true;
880 static struct sock_socket_funcs test5_client_funcs = {
881 .connect = test5_connect,
882 .disconnect = test5_disconnect,
883 .read_send = test5_read_send,
884 .read_recv = test5_read_recv,
887 struct test5_wait_state {
890 static struct tevent_req *test5_wait_send(TALLOC_CTX *mem_ctx,
891 struct tevent_context *ev,
892 void *private_data)
894 struct tevent_req *req;
895 struct test5_wait_state *state;
896 int fd = *(int *)private_data;
897 int ret = 1;
898 ssize_t nwritten;
900 nwritten = write(fd, &ret, sizeof(ret));
901 assert(nwritten == sizeof(ret));
902 close(fd);
904 req = tevent_req_create(mem_ctx, &state, struct test5_wait_state);
905 if (req == NULL) {
906 return NULL;
909 return req;
912 static bool test5_wait_recv(struct tevent_req *req, int *perr)
914 return true;
917 static struct sock_daemon_funcs test5_funcs = {
918 .wait_send = test5_wait_send,
919 .wait_recv = test5_wait_recv,
922 static void test5(TALLOC_CTX *mem_ctx, const char *pidfile,
923 const char *sockpath)
925 pid_t pid_server, pid;
926 int fd[2], ret, i;
927 ssize_t n;
929 pid = getpid();
931 ret = pipe(fd);
932 assert(ret == 0);
934 pid_server = fork();
935 assert(pid_server != -1);
937 if (pid_server == 0) {
938 struct tevent_context *ev;
939 struct sock_daemon_context *sockd;
940 struct test5_server_state state;
942 close(fd[0]);
944 ev = tevent_context_init(mem_ctx);
945 assert(ev != NULL);
947 ret = sock_daemon_setup(mem_ctx, "test5", "file:", "NOTICE",
948 &test5_funcs, &fd[1], &sockd);
949 assert(ret == 0);
951 state.num_clients = 0;
953 ret = sock_daemon_add_unix(sockd, sockpath,
954 &test5_client_funcs, &state);
955 assert(ret == 0);
957 ret = sock_daemon_run(ev, sockd, pidfile, false, false, pid);
958 assert(ret == EINTR);
960 exit(0);
963 close(fd[1]);
965 n = read(fd[0], &ret, sizeof(ret));
966 assert(n == sizeof(ret));
967 assert(ret == 1);
969 close(fd[0]);
971 for (i=0; i<100; i++) {
972 ret = test5_client(sockpath, i);
973 if (i < TEST5_MAX_CLIENTS) {
974 assert(ret == i+1);
975 } else {
976 assert(ret == 0);
980 for (i=0; i<100; i++) {
981 pid = wait(&ret);
982 assert(pid != -1);
985 ret = kill(pid_server, SIGTERM);
986 assert(ret == 0);
988 pid = waitpid(pid_server, &ret, 0);
989 assert(pid == pid_server);
990 assert(WEXITSTATUS(ret) == 0);
994 * test6
996 * Start daemon, test client connects, requests, replies, disconnects
999 struct test6_pkt {
1000 uint32_t len;
1001 uint32_t data;
1004 struct test6_client_state {
1005 bool done;
1008 static void test6_client_callback(uint8_t *buf, size_t buflen,
1009 void *private_data)
1011 struct test6_client_state *state =
1012 (struct test6_client_state *)private_data;
1013 struct test6_pkt *pkt;
1015 assert(buflen == sizeof(struct test6_pkt));
1016 pkt = (struct test6_pkt *)buf;
1017 assert(pkt->len == sizeof(struct test6_pkt));
1018 assert(pkt->data == 0xffeeddcc);
1020 state->done = true;
1023 static void test6_client(const char *sockpath)
1025 struct tevent_context *ev;
1026 struct test6_client_state state;
1027 struct sock_queue *queue;
1028 struct test6_pkt pkt;
1029 int conn, ret;
1031 ev = tevent_context_init(NULL);
1032 assert(ev != NULL);
1034 conn = sock_connect(sockpath);
1035 assert(conn != -1);
1037 state.done = false;
1039 queue = sock_queue_setup(ev, ev, conn,
1040 test6_client_callback, &state);
1041 assert(queue != NULL);
1043 pkt.len = 8;
1044 pkt.data = 0xaabbccdd;
1046 ret = sock_queue_write(queue, (uint8_t *)&pkt,
1047 sizeof(struct test6_pkt));
1048 assert(ret == 0);
1050 while (! state.done) {
1051 tevent_loop_once(ev);
1054 talloc_free(ev);
1057 struct test6_server_state {
1058 struct sock_daemon_context *sockd;
1059 int fd, done;
1062 struct test6_read_state {
1063 struct test6_server_state *server_state;
1064 struct test6_pkt reply;
1067 static void test6_read_done(struct tevent_req *subreq);
1069 static struct tevent_req *test6_read_send(TALLOC_CTX *mem_ctx,
1070 struct tevent_context *ev,
1071 struct sock_client_context *client,
1072 uint8_t *buf, size_t buflen,
1073 void *private_data)
1075 struct test6_server_state *server_state =
1076 (struct test6_server_state *)private_data;
1077 struct tevent_req *req, *subreq;
1078 struct test6_read_state *state;
1079 struct test6_pkt *pkt;
1081 req = tevent_req_create(mem_ctx, &state, struct test6_read_state);
1082 assert(req != NULL);
1084 state->server_state = server_state;
1086 assert(buflen == sizeof(struct test6_pkt));
1088 pkt = (struct test6_pkt *)buf;
1089 assert(pkt->data == 0xaabbccdd);
1091 state->reply.len = sizeof(struct test6_pkt);
1092 state->reply.data = 0xffeeddcc;
1094 subreq = sock_socket_write_send(state, ev, client,
1095 (uint8_t *)&state->reply,
1096 state->reply.len);
1097 assert(subreq != NULL);
1099 tevent_req_set_callback(subreq, test6_read_done, req);
1101 return req;
1104 static void test6_read_done(struct tevent_req *subreq)
1106 struct tevent_req *req = tevent_req_callback_data(
1107 subreq, struct tevent_req);
1108 struct test6_read_state *state = tevent_req_data(
1109 req, struct test6_read_state);
1110 int ret;
1111 bool status;
1113 status = sock_socket_write_recv(subreq, &ret);
1114 TALLOC_FREE(subreq);
1115 if (! status) {
1116 tevent_req_error(req, ret);
1117 return;
1120 state->server_state->done = 1;
1121 tevent_req_done(req);
1124 static bool test6_read_recv(struct tevent_req *req, int *perr)
1126 int ret;
1128 if (tevent_req_is_unix_error(req, &ret)) {
1129 if (perr != NULL) {
1130 *perr = ret;
1132 return false;
1135 return true;
1138 static struct sock_socket_funcs test6_client_funcs = {
1139 .read_send = test6_read_send,
1140 .read_recv = test6_read_recv,
1143 struct test6_wait_state {
1144 struct test6_server_state *server_state;
1147 static void test6_wait_done(struct tevent_req *subreq);
1149 static struct tevent_req *test6_wait_send(TALLOC_CTX *mem_ctx,
1150 struct tevent_context *ev,
1151 void *private_data)
1153 struct test6_server_state *server_state =
1154 (struct test6_server_state *)private_data;
1155 struct tevent_req *req, *subreq;
1156 struct test6_wait_state *state;
1157 ssize_t nwritten;
1158 int ret = 1;
1160 nwritten = write(server_state->fd, &ret, sizeof(ret));
1161 assert(nwritten == sizeof(ret));
1162 close(server_state->fd);
1163 server_state->fd = -1;
1165 req = tevent_req_create(mem_ctx, &state, struct test6_wait_state);
1166 if (req == NULL) {
1167 return NULL;
1170 state->server_state = (struct test6_server_state *)private_data;
1172 subreq = tevent_wakeup_send(state, ev,
1173 tevent_timeval_current_ofs(10,0));
1174 if (tevent_req_nomem(subreq, req)) {
1175 return tevent_req_post(req, ev);
1177 tevent_req_set_callback(subreq, test6_wait_done, req);
1179 return req;
1182 static void test6_wait_done(struct tevent_req *subreq)
1184 struct tevent_req *req = tevent_req_callback_data(
1185 subreq, struct tevent_req);
1186 struct test6_wait_state *state = tevent_req_data(
1187 req, struct test6_wait_state);
1188 bool status;
1190 status = tevent_wakeup_recv(subreq);
1191 TALLOC_FREE(subreq);
1192 if (! status) {
1193 tevent_req_error(req, EIO);
1194 return;
1197 if (state->server_state->done == 0) {
1198 tevent_req_error(req, EIO);
1199 return;
1202 tevent_req_done(req);
1205 static bool test6_wait_recv(struct tevent_req *req, int *perr)
1207 int ret;
1209 if (tevent_req_is_unix_error(req, &ret)) {
1210 if (perr != NULL) {
1211 *perr = ret;
1213 return false;
1216 return true;
1219 static struct sock_daemon_funcs test6_funcs = {
1220 .wait_send = test6_wait_send,
1221 .wait_recv = test6_wait_recv,
1224 static void test6(TALLOC_CTX *mem_ctx, const char *pidfile,
1225 const char *sockpath)
1227 pid_t pid_server, pid;
1228 int fd[2], ret;
1229 ssize_t n;
1231 pid = getpid();
1233 ret = pipe(fd);
1234 assert(ret == 0);
1236 pid_server = fork();
1237 assert(pid_server != -1);
1239 if (pid_server == 0) {
1240 struct tevent_context *ev;
1241 struct sock_daemon_context *sockd;
1242 struct test6_server_state server_state = { 0 };
1244 close(fd[0]);
1246 ev = tevent_context_init(mem_ctx);
1247 assert(ev != NULL);
1249 server_state.fd = fd[1];
1251 ret = sock_daemon_setup(mem_ctx, "test6", "file:", "NOTICE",
1252 &test6_funcs, &server_state,
1253 &sockd);
1254 assert(ret == 0);
1256 server_state.sockd = sockd;
1257 server_state.done = 0;
1259 ret = sock_daemon_add_unix(sockd, sockpath,
1260 &test6_client_funcs, &server_state);
1261 assert(ret == 0);
1263 ret = sock_daemon_run(ev, sockd, pidfile, false, false, pid);
1264 assert(ret == 0);
1266 exit(0);
1269 close(fd[1]);
1271 n = read(fd[0], &ret, sizeof(ret));
1272 assert(n == sizeof(ret));
1273 assert(ret == 1);
1275 close(fd[0]);
1277 test6_client(sockpath);
1279 pid = waitpid(pid_server, &ret, 0);
1280 assert(pid == pid_server);
1281 assert(WEXITSTATUS(ret) == 0);
1285 * test7
1287 * Start daemon twice, confirm PID file contention
1290 static void test7(TALLOC_CTX *mem_ctx, const char *pidfile,
1291 const char *sockpath)
1293 struct sock_daemon_funcs test7_funcs;
1294 struct stat st;
1295 int fd[2];
1296 pid_t pid, pid2;
1297 int ret;
1298 struct tevent_context *ev;
1299 struct sock_daemon_context *sockd;
1300 ssize_t n;
1302 /* Reuse test2 funcs for the startup synchronisation */
1303 test7_funcs = (struct sock_daemon_funcs) {
1304 .startup = test2_startup,
1305 .reconfigure = test2_reconfigure,
1306 .shutdown = test2_shutdown,
1309 ret = pipe(fd);
1310 assert(ret == 0);
1312 pid = fork();
1313 assert(pid != -1);
1315 if (pid == 0) {
1316 close(fd[0]);
1318 ev = tevent_context_init(mem_ctx);
1319 assert(ev != NULL);
1321 ret = sock_daemon_setup(mem_ctx, "test7", "file:", "NOTICE",
1322 &test7_funcs, &fd[1], &sockd);
1323 assert(ret == 0);
1325 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1326 assert(ret == EINTR);
1328 exit(0);
1331 close(fd[1]);
1333 n = read(fd[0], &ret, sizeof(ret));
1334 assert(n == sizeof(ret));
1335 assert(ret == 1);
1337 ret = stat(pidfile, &st);
1338 assert(ret == 0);
1339 assert(S_ISREG(st.st_mode));
1341 ev = tevent_context_init(mem_ctx);
1342 assert(ev != NULL);
1344 ret = sock_daemon_setup(mem_ctx, "test7-parent", "file:", "NOTICE",
1345 &test7_funcs, &fd[1], &sockd);
1346 assert(ret == 0);
1348 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1349 assert(ret == EEXIST);
1351 ret = kill(pid, SIGTERM);
1352 assert(ret == 0);
1354 n = read(fd[0], &ret, sizeof(ret));
1355 assert(n == sizeof(ret));
1356 assert(ret == 3);
1358 pid2 = waitpid(pid, &ret, 0);
1359 assert(pid2 == pid);
1360 assert(WEXITSTATUS(ret) == 0);
1362 close(fd[0]);
1366 * test8
1368 * Start daemon, confirm that create_session argument works as expected
1371 static void test8(TALLOC_CTX *mem_ctx, const char *pidfile,
1372 const char *sockpath)
1374 int fd[2];
1375 pid_t pid, pid2, sid;
1376 int ret;
1377 struct tevent_context *ev;
1378 struct sock_daemon_context *sockd;
1379 ssize_t n;
1381 ret = pipe(fd);
1382 assert(ret == 0);
1384 pid = fork();
1385 assert(pid != -1);
1387 if (pid == 0) {
1388 /* Reuse test2 funcs for the startup synchronisation */
1389 struct sock_daemon_funcs test8_funcs = {
1390 .startup = test2_startup,
1393 close(fd[0]);
1395 ev = tevent_context_init(mem_ctx);
1396 assert(ev != NULL);
1398 ret = sock_daemon_setup(mem_ctx, "test8", "file:", "NOTICE",
1399 &test8_funcs, &fd[1], &sockd);
1400 assert(ret == 0);
1402 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1403 assert(ret == EINTR);
1405 exit(0);
1408 close(fd[1]);
1410 n = read(fd[0], &ret, sizeof(ret));
1411 assert(n == sizeof(ret));
1412 assert(ret == 1);
1414 /* create_session false above, so pid != sid */
1415 sid = getsid(pid);
1416 assert(pid != sid);
1418 ret = kill(pid, SIGTERM);
1419 assert(ret == 0);
1421 pid2 = waitpid(pid, &ret, 0);
1422 assert(pid2 == pid);
1423 assert(WEXITSTATUS(ret) == 0);
1425 close(fd[0]);
1427 ret = pipe(fd);
1428 assert(ret == 0);
1430 pid = fork();
1431 assert(pid != -1);
1433 if (pid == 0) {
1434 /* Reuse test2 funcs for the startup synchronisation */
1435 struct sock_daemon_funcs test8_funcs = {
1436 .startup = test2_startup,
1439 close(fd[0]);
1441 ev = tevent_context_init(mem_ctx);
1442 assert(ev != NULL);
1444 ret = sock_daemon_setup(mem_ctx, "test8", "file:", "NOTICE",
1445 &test8_funcs, &fd[1], &sockd);
1446 assert(ret == 0);
1448 ret = sock_daemon_run(ev, sockd, pidfile, false, true, -1);
1449 assert(ret == EINTR);
1451 exit(0);
1454 close(fd[1]);
1456 n = read(fd[0], &ret, sizeof(ret));
1457 assert(n == sizeof(ret));
1458 assert(ret == 1);
1460 /* create_session true above, so pid == sid */
1461 sid = getsid(pid);
1462 assert(pid == sid);
1464 ret = kill(pid, SIGTERM);
1465 assert(ret == 0);
1467 pid2 = waitpid(pid, &ret, 0);
1468 assert(pid2 == pid);
1469 assert(WEXITSTATUS(ret) == 0);
1471 close(fd[0]);
1475 * test9
1477 * Confirm that do_fork causes the daemon to be forked as a separate child
1480 static void test9(TALLOC_CTX *mem_ctx, const char *pidfile,
1481 const char *sockpath)
1483 int fd[2];
1484 pid_t pid, pid2;
1485 int ret;
1486 struct tevent_context *ev;
1487 struct sock_daemon_context *sockd;
1488 ssize_t n;
1489 int pidfile_fd;
1490 char pidstr[20] = { 0 };
1491 struct stat st;
1493 ret = pipe(fd);
1494 assert(ret == 0);
1496 pid = fork();
1497 assert(pid != -1);
1499 if (pid == 0) {
1500 /* Reuse test2 funcs for the startup synchronisation */
1501 struct sock_daemon_funcs test9_funcs = {
1502 .startup = test2_startup,
1505 close(fd[0]);
1507 ev = tevent_context_init(mem_ctx);
1508 assert(ev != NULL);
1510 ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
1511 &test9_funcs, &fd[1], &sockd);
1512 assert(ret == 0);
1514 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1515 assert(ret == EINTR);
1517 exit(0);
1520 close(fd[1]);
1522 n = read(fd[0], &ret, sizeof(ret));
1523 assert(n == sizeof(ret));
1524 assert(ret == 1);
1526 /* do_fork false above, so pid should be active */
1527 ret = kill(pid, 0);
1528 assert(ret == 0);
1530 ret = kill(pid, SIGTERM);
1531 assert(ret == 0);
1533 pid2 = waitpid(pid, &ret, 0);
1534 assert(pid2 == pid);
1535 assert(WEXITSTATUS(ret) == 0);
1537 close(fd[0]);
1539 ret = pipe(fd);
1540 assert(ret == 0);
1542 pid = fork();
1543 assert(pid != -1);
1545 if (pid == 0) {
1546 /* Reuse test2 funcs for the startup synchronisation */
1547 struct sock_daemon_funcs test9_funcs = {
1548 .startup = test2_startup,
1549 .shutdown = test2_shutdown,
1552 close(fd[0]);
1554 ev = tevent_context_init(mem_ctx);
1555 assert(ev != NULL);
1557 ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
1558 &test9_funcs, &fd[1], &sockd);
1559 assert(ret == 0);
1561 ret = sock_daemon_run(ev, sockd, pidfile, true, false, -1);
1562 assert(ret == EINTR);
1564 exit(0);
1567 close(fd[1]);
1569 n = read(fd[0], &ret, sizeof(ret));
1570 assert(n == sizeof(ret));
1571 assert(ret == 1);
1573 /* do_fork true above, so pid should have exited */
1574 pid2 = waitpid(pid, &ret, 0);
1575 assert(pid2 == pid);
1576 assert(WEXITSTATUS(ret) == 0);
1578 pidfile_fd = open(pidfile, O_RDONLY, 0644);
1579 assert(pidfile_fd != -1);
1580 n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
1581 assert(n != -1);
1582 pid2 = (pid_t)atoi(pidstr);
1583 assert(pid != pid2);
1584 close(pidfile_fd);
1586 ret = kill(pid2, SIGTERM);
1587 assert(ret == 0);
1589 n = read(fd[0], &ret, sizeof(ret));
1590 assert(n == sizeof(ret));
1591 assert(ret == 3);
1594 * pid2 isn't our child, so can't call waitpid(). kill(pid2, 0)
1595 * is unreliable - pid2 may have been recycled. Above indicates
1596 * that the shutdown function was called, so just do 1 final
1597 * check to see if pidfile has been removed.
1599 ret = stat(sockpath, &st);
1600 assert(ret == -1);
1602 close(fd[0]);
1605 static void test10_shutdown(void *private_data)
1607 int fd = *(int *)private_data;
1608 int ret = 3;
1609 ssize_t nwritten;
1611 nwritten = write(fd, &ret, sizeof(ret));
1612 assert(nwritten == sizeof(ret));
1615 struct test10_wait_state {
1618 static void test10_wait_done(struct tevent_req *subreq);
1620 static struct tevent_req *test10_wait_send(TALLOC_CTX *mem_ctx,
1621 struct tevent_context *ev,
1622 void *private_data)
1624 int fd = *(int *)private_data;
1625 struct tevent_req *req, *subreq;
1626 struct test10_wait_state *state;
1627 size_t nwritten;
1628 int ret = 1;
1630 req = tevent_req_create(mem_ctx, &state, struct test10_wait_state);
1631 if (req == NULL) {
1632 return NULL;
1635 subreq = tevent_wakeup_send(state, ev,
1636 tevent_timeval_current_ofs(10, 0));
1637 if (tevent_req_nomem(subreq, req)) {
1638 return tevent_req_post(req, ev);
1640 tevent_req_set_callback(subreq, test10_wait_done, req);
1642 nwritten = write(fd, &ret, sizeof(ret));
1643 assert(nwritten == sizeof(ret));
1645 return req;
1648 static void test10_wait_done(struct tevent_req *subreq)
1650 struct tevent_req *req = tevent_req_callback_data(
1651 subreq, struct tevent_req);
1652 bool status;
1654 status = tevent_wakeup_recv(subreq);
1655 if (! status) {
1656 tevent_req_error(req, EIO);
1657 return;
1660 tevent_req_done(req);
1663 static bool test10_wait_recv(struct tevent_req *req, int *perr)
1665 int ret;
1667 if (tevent_req_is_unix_error(req, &ret)) {
1668 if (perr != NULL) {
1669 *perr = ret;
1671 return false;
1674 return true;
1677 static struct sock_daemon_funcs test10_funcs = {
1678 .shutdown = test10_shutdown,
1679 .wait_send = test10_wait_send,
1680 .wait_recv = test10_wait_recv,
1684 * test10
1686 * Confirm that the daemon starts successfully if there is a stale socket
1689 static void test10(TALLOC_CTX *mem_ctx, const char *pidfile,
1690 const char *sockpath)
1692 struct stat st;
1693 int fd[2];
1694 pid_t pid, pid2;
1695 int ret;
1696 ssize_t n;
1697 int pidfile_fd;
1698 char pidstr[20] = { 0 };
1700 ret = pipe(fd);
1701 assert(ret == 0);
1703 pid = fork();
1704 assert(pid != -1);
1706 if (pid == 0) {
1707 struct tevent_context *ev;
1708 struct sock_daemon_context *sockd;
1710 close(fd[0]);
1712 ev = tevent_context_init(mem_ctx);
1713 assert(ev != NULL);
1715 ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE",
1716 &test10_funcs, &fd[1], &sockd);
1717 assert(ret == 0);
1719 ret = sock_daemon_add_unix(sockd, sockpath,
1720 &dummy_socket_funcs, NULL);
1721 assert(ret == 0);
1723 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1724 assert(ret == EINTR);
1726 exit(0);
1729 close(fd[1]);
1731 n = read(fd[0], &ret, sizeof(ret));
1732 assert(n == sizeof(ret));
1733 assert(ret == 1);
1735 /* KILL will leave PID file and socket behind */
1736 ret = kill (pid, SIGKILL);
1737 assert(ret == 0);
1739 pid2 = waitpid(pid, &ret, 0);
1740 assert(pid2 == pid);
1741 assert(WEXITSTATUS(ret) == 0);
1743 ret = stat(sockpath, &st);
1744 assert(ret == 0);
1746 close(fd[0]);
1748 ret = pipe(fd);
1749 assert(ret == 0);
1751 pid = fork();
1752 assert(pid != -1);
1754 if (pid == 0) {
1755 struct tevent_context *ev;
1756 struct sock_daemon_context *sockd;
1758 close(fd[0]);
1760 ev = tevent_context_init(mem_ctx);
1761 assert(ev != NULL);
1763 ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE",
1764 &test10_funcs, &fd[1], &sockd);
1765 assert(ret == 0);
1767 ret = sock_daemon_add_unix(sockd, sockpath,
1768 &dummy_socket_funcs, NULL);
1769 assert(ret == 0);
1771 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1772 assert(ret == EINTR);
1774 exit(0);
1777 close(fd[1]);
1779 n = read(fd[0], &ret, sizeof(ret));
1780 assert(n == sizeof(ret));
1781 assert(ret == 1);
1783 pidfile_fd = open(pidfile, O_RDONLY, 0644);
1784 assert(pidfile_fd != -1);
1785 n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
1786 assert(n != -1);
1787 pid2 = (pid_t)atoi(pidstr);
1788 assert(pid == pid2);
1789 close(pidfile_fd);
1791 ret = kill(pid, SIGTERM);
1792 assert(ret == 0);
1794 n = read(fd[0], &ret, sizeof(ret));
1795 assert(n == sizeof(ret));
1796 assert(ret == 3);
1798 pid2 = waitpid(pid, &ret, 0);
1799 assert(pid2 == pid);
1800 assert(WEXITSTATUS(ret) == 0);
1802 close(fd[0]);
1804 ret = stat(pidfile, &st);
1805 assert(ret == -1);
1807 ret = stat(sockpath, &st);
1808 assert(ret == -1);
1811 int main(int argc, const char **argv)
1813 TALLOC_CTX *mem_ctx;
1814 const char *pidfile, *sockpath;
1815 int num;
1817 if (argc != 4) {
1818 fprintf(stderr, "%s <pidfile> <sockpath> <testnum>\n", argv[0]);
1819 exit(1);
1822 pidfile = argv[1];
1823 sockpath = argv[2];
1824 num = atoi(argv[3]);
1826 mem_ctx = talloc_new(NULL);
1827 assert(mem_ctx != NULL);
1829 switch (num) {
1830 case 1:
1831 test1(mem_ctx, pidfile, sockpath);
1832 break;
1834 case 2:
1835 test2(mem_ctx, pidfile, sockpath);
1836 break;
1838 case 3:
1839 test3(mem_ctx, pidfile, sockpath);
1840 break;
1842 case 4:
1843 test4(mem_ctx, pidfile, sockpath);
1844 break;
1846 case 5:
1847 test5(mem_ctx, pidfile, sockpath);
1848 break;
1850 case 6:
1851 test6(mem_ctx, pidfile, sockpath);
1852 break;
1854 case 7:
1855 test7(mem_ctx, pidfile, sockpath);
1856 break;
1858 case 8:
1859 test8(mem_ctx, pidfile, sockpath);
1860 break;
1862 case 9:
1863 test9(mem_ctx, pidfile, sockpath);
1864 break;
1866 case 10:
1867 test10(mem_ctx, pidfile, sockpath);
1868 break;
1870 default:
1871 fprintf(stderr, "Unknown test number %d\n", num);
1874 return 0;