]> git.ozlabs.org Git - petitboot/blob - test/lib/test-process-both.c
test/lib: Implement process_init change in testcases
[petitboot] / test / lib / test-process-both.c
1
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #include <fcntl.h>
6 #include <sys/stat.h>
7
8 #include <process/process.h>
9 #include <waiter/waiter.h>
10 #include <talloc/talloc.h>
11
12 static const char *async_fifo = "/tmp/test-process-both.fifo";
13
14 static int do_sync_child(void)
15 {
16         return 42;
17 }
18
19 static int do_async_child(void)
20 {
21         char c;
22         int fd;
23
24         fd = open(async_fifo, O_RDONLY);
25         assert(fd >= 0);
26
27         read(fd, &c, 1);
28
29         assert(c == 1);
30
31         return 43;
32 }
33
34 struct test {
35         int             async_fd;
36         struct process  *sync_process;
37         struct process  *async_process;
38
39         bool            async_exited;
40         int             async_exit_status;
41
42 };
43
44 static void async_exit_cb(struct process *process)
45 {
46         struct test *test = process->data;
47         test->async_exited = true;
48         test->async_exit_status = process->exit_status;
49 }
50
51 int main(int argc, char **argv)
52 {
53         const char *sync_child_argv[3], *async_child_argv[3];
54         struct waitset *waitset;
55         struct test *test;
56         char c;
57         int rc;
58
59         if (argc == 2 && !strcmp(argv[1], "sync-child"))
60                 return do_sync_child();
61
62         if (argc == 2 && !strcmp(argv[1], "async-child"))
63                 return do_async_child();
64
65         test = talloc_zero(NULL, struct test);
66
67         unlink(async_fifo);
68         rc = mkfifo(async_fifo, 0600);
69         assert(rc == 0);
70
71         waitset = waitset_create(test);
72
73         process_init(test, waitset, false);
74
75         sync_child_argv[0] = argv[0];
76         sync_child_argv[1] = "sync-child";
77         sync_child_argv[2] = NULL;
78
79         test->sync_process = process_create(test);
80         test->sync_process->path = sync_child_argv[0];
81         test->sync_process->argv = sync_child_argv;
82
83         async_child_argv[0] = argv[0];
84         async_child_argv[1] = "async-child";
85         async_child_argv[2] = NULL;
86
87         test->async_process = process_create(test);
88         test->async_process->path = async_child_argv[0];
89         test->async_process->argv = async_child_argv;
90         test->async_process->exit_cb = async_exit_cb;
91         test->async_process->data = test;
92
93         process_run_async(test->async_process);
94
95         process_run_sync(test->sync_process);
96
97         assert(WIFEXITED(test->sync_process->exit_status));
98         assert(WEXITSTATUS(test->sync_process->exit_status) == 42);
99
100         /* now that the sync process has completed, let the async process
101          * exit */
102         test->async_fd = open(async_fifo, O_WRONLY);
103         assert(test->async_fd >= 0);
104         c = 1;
105         write(test->async_fd, &c, 1);
106
107         for (;;) {
108                 waiter_poll(waitset);
109
110                 if (test->async_exited)
111                         break;
112         }
113
114         assert(WIFEXITED(test->async_exit_status));
115         assert(WEXITSTATUS(test->async_exit_status) == 43);
116
117         talloc_free(test);
118
119         unlink(async_fifo);
120
121         return EXIT_SUCCESS;
122 }