]> git.ozlabs.org Git - ccan-lca-2011.git/blob - ccan/oserver/test/run.c
a8eb6f24391042b064cddaa243fe2c3ac80c2762
[ccan-lca-2011.git] / ccan / oserver / test / run.c
1 #include <ccan/oserver/oserver.c>
2 #include <ccan/oserver/oserver_cdump.c>
3 #include <ccan/oserver/oserver.h>
4 #include <ccan/str/str.h>
5 #include <ccan/tap/tap.h>
6 #include <sys/types.h>
7 #include <sys/select.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include <string.h>
11
12 static void exit_quietly(struct tevent_context *ev,
13                          struct tevent_fd *fde, uint16_t flags, void *unused)
14 {
15         talloc_free(ev);
16         exit(0);
17 }
18
19 static void run_server(int readyfd, int exitfd)
20 {
21         struct tevent_context *ev = tevent_context_init(NULL);
22
23         if (oserver_setup(ev, OSERVER_PORT, NULL) == NULL)
24                 exit(1);
25
26         tevent_add_fd(ev, ev, exitfd, TEVENT_FD_READ, exit_quietly, NULL);
27         /* Tell parent we are ready to go. */
28         write(readyfd, "", 1);
29
30         while (tevent_loop_wait(ev) == 0);
31 }       
32
33 static bool write_sall(int fd, const char *str)
34 {
35         while (str[0]) {
36                 ssize_t len = write(fd, str, strlen(str));
37                 if (len < 0)
38                         return false;
39                 str += len;
40         }
41         return true;
42 }
43
44 static bool input_is(int fd, const char *str)
45 {
46         while (str[0]) {
47                 char buffer[1000];
48                 ssize_t len = read(fd, buffer, strlen(str));
49                 if (len < 0)
50                         return false;
51                 if (strncmp(str, buffer, len) != 0)
52                         return false;
53                 str += len;
54         }
55         return true;
56 }
57
58 static bool no_input(int fd)
59 {
60         fd_set set;
61         struct timeval t = { 0, 0 };
62
63         FD_ZERO(&set);
64         FD_SET(fd, &set);
65         return (select(fd+1, &set, NULL, NULL, &t) == 0);
66 }
67
68 int main(int argc, char *argv[])
69 {
70         int readyfd[2], exitfd[2];
71         union {
72                 struct sockaddr addr;
73                 struct sockaddr_in in;
74         } u;
75         int sfd1, sfd2;
76         char c;
77
78         /* This is how many tests you plan to run */
79         plan_tests(20);
80
81         pipe(readyfd);
82         pipe(exitfd);
83         if (fork() == 0) {
84                 close(exitfd[1]);
85                 close(readyfd[0]);
86                 run_server(readyfd[1], exitfd[0]);
87                 err(1, "Event loop failed");
88         }
89         close(exitfd[0]);
90         close(readyfd[1]);
91
92         sfd1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
93         sfd2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
94
95         u.in.sin_family = AF_INET;
96         u.in.sin_port = htons(OSERVER_PORT);
97         u.in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
98
99         /* Wait until child is ready... */
100         if (read(readyfd[0], &c, 1) != 1)
101                 errx(1, "Child problems");
102
103         /* Go! */
104         ok1(connect(sfd1, &u.addr, sizeof(u.in)) == 0);
105         ok1(connect(sfd2, &u.addr, sizeof(u.in)) == 0);
106
107         ok1(input_is(sfd1, "Welcome.  Please ask your question.\n"));
108         ok1(input_is(sfd2, "Welcome.  Please ask your question.\n"));
109
110         ok1(write_sall(sfd1, "QUESTION"));
111         ok1(write_sall(sfd2, "QUESTION"));
112         ok1(write_sall(sfd1, " 1\n"));
113
114         /* It can't ask a question yet, since client 2 isn't finished. */
115         ok1(no_input(sfd1));
116
117         /* Make sure that arrives first! */
118         sleep(1);
119         ok1(write_sall(sfd2, " 2\n"));
120
121         ok1(input_is(sfd1, "While the Oracle ponders,"
122                      " please answer the following question:\nQUESTION 2\n"));
123         ok1(input_is(sfd2, "While the Oracle ponders,"
124                      " please answer the following question:\nQUESTION 1\n"));
125
126         ok1(write_sall(sfd1, "ANSWER 2\n"));
127         ok1(write_sall(sfd2, "ANSWER 1"));
128
129         /* Nothing, until client 2 answers. */ 
130         ok1(no_input(sfd1));
131         ok1(write_sall(sfd2, "\n"));
132
133         ok1(input_is(sfd1, "The Oracle spake thus:\nANSWER 1\n"));
134         ok1(input_is(sfd2, "The Oracle spake thus:\nANSWER 2\n"));
135
136         /* Sockets should be dead now. */
137         ok1(read(sfd1, &c, 1) == 0);
138         ok1(read(sfd2, &c, 1) == 0);
139
140         /* Shut down server. */
141         write(exitfd[1], "", 1);
142
143         /* This will close once it's shut down, and return. */
144         ok1(read(readyfd[0], &c, 1) == 0);
145
146         /* This exits depending on whether all tests passed */
147         return exit_status();
148 }