Tizen 2.1 base
[platform/upstream/gcd.git] / kqueue-1.0.4 / test / read.c
1 /*
2  * Copyright (c) 2009 Mark Heily <mark@heily.com>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <arpa/inet.h>
18 #include <sys/socket.h>
19 #include "common.h"
20
21 static int __thread kqfd;
22 static int __thread sockfd[2];
23
24 static void
25 kevent_socket_drain(void)
26 {
27     char buf[1];
28
29     /* Drain the read buffer, then make sure there are no more events. */
30     if (read(sockfd[0], &buf[0], 1) < 1)
31         die("read(2)");
32 }
33
34 static void
35 kevent_socket_fill(void)
36 {
37     if (write(sockfd[1], ".", 1) < 1)
38         die("write(2)");
39 }
40
41
42 void
43 test_kevent_socket_add(void)
44 {
45     struct kevent kev;
46
47     kevent_add(kqfd, &kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
48 }
49
50 void
51 test_kevent_socket_add_without_ev_add(void)
52 {
53     struct kevent kev;
54
55     /* Try to add a kevent without specifying EV_ADD */
56     EV_SET(&kev, sockfd[0], EVFILT_READ, 0, 0, 0, &sockfd[0]);
57     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) == 0)
58         die("kevent should have failed");
59
60     kevent_socket_fill();
61     test_no_kevents(kqfd);
62     kevent_socket_drain();
63
64     /* Try to delete a kevent which does not exist */
65     kev.flags = EV_DELETE;
66     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) == 0)
67         die("kevent should have failed");
68 }
69
70 void
71 test_kevent_socket_get(void)
72 {
73     struct kevent kev;
74
75     EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
76     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
77         die("kevent");
78
79     kevent_socket_fill();
80
81     kev.data = 1;
82     kevent_cmp(&kev, kevent_get(kqfd));
83
84     kevent_socket_drain();
85     test_no_kevents(kqfd);
86
87     kev.flags = EV_DELETE;
88     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
89         die("kevent");
90 }
91
92 void
93 test_kevent_socket_clear(void)
94 {
95     struct kevent kev;
96
97     test_no_kevents(kqfd);
98     kevent_socket_drain();
99
100     EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, &sockfd[0]);
101     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
102         die("kevent");
103
104     kevent_socket_fill();
105     kevent_socket_fill();
106
107 /* Solaris does not offer a way to get the amount of data pending */
108 #if defined(__sun__)
109     kev.data = 1;
110 #else
111     kev.data = 2;
112 #endif
113     kevent_cmp(&kev, kevent_get(kqfd)); 
114
115     /* We filled twice, but drain once. Edge-triggered would not generate
116        additional events.
117      */
118     kevent_socket_drain();
119     test_no_kevents(kqfd);
120
121     kevent_socket_drain();
122     EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
123     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
124         die("kevent");
125 }
126
127 void
128 test_kevent_socket_disable_and_enable(void)
129 {
130     struct kevent kev;
131
132     /* Add an event, then disable it. */
133     EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
134     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
135         die("kevent");
136     EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DISABLE, 0, 0, &sockfd[0]);
137     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
138         die("kevent");
139
140     kevent_socket_fill();
141     test_no_kevents(kqfd);
142
143     /* Re-enable the knote, then see if an event is generated */
144     kev.flags = EV_ENABLE;
145     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
146         die("kevent");
147     kev.flags = EV_ADD;
148     kev.data = 1;
149     kevent_cmp(&kev, kevent_get(kqfd));
150
151     kevent_socket_drain();
152
153     kev.flags = EV_DELETE;
154     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
155         die("kevent");
156 }
157
158 void
159 test_kevent_socket_del(void)
160 {
161     struct kevent kev;
162
163     EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
164     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
165         die("kevent");
166
167     kevent_socket_fill();
168     test_no_kevents(kqfd);
169     kevent_socket_drain();
170 }
171
172 void
173 test_kevent_socket_oneshot(void)
174 {
175     struct kevent kev;
176
177     /* Re-add the watch and make sure no events are pending */
178     kevent_add(kqfd, &kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &sockfd[0]);
179     test_no_kevents(kqfd);
180
181     kevent_socket_fill();
182     kev.data = 1;
183     kevent_cmp(&kev, kevent_get(kqfd));
184
185     test_no_kevents(kqfd);
186
187     /* Verify that the event has been deleted */
188     kevent_socket_fill();
189     test_no_kevents(kqfd);
190     kevent_socket_drain();
191 }
192
193 /*
194  * Test if the data field returns 1 when a listen(2) socket has
195  * a pending connection.
196  */
197 void
198 test_kevent_socket_listen_backlog(void)
199 {
200     struct kevent kev;
201     struct sockaddr_in sain;
202     socklen_t sa_len = sizeof(sain);
203     int one = 1;
204     const short port = 14973;
205     int clnt, srvr;
206
207     /* Create a passive socket */
208     memset(&sain, 0, sizeof(sain));
209     sain.sin_family = AF_INET;
210     sain.sin_port = htons(port);
211     if ((srvr = socket(PF_INET, SOCK_STREAM, 0)) < 0) abort();
212     if (setsockopt(srvr, SOL_SOCKET, SO_REUSEADDR, 
213                 (char *) &one, sizeof(one)) != 0) abort();
214     if (bind(srvr, (struct sockaddr *) &sain, sa_len) < 0) abort();
215     if (listen(srvr, 100) < 0) abort();
216
217     /* Watch for events on the socket */
218     test_no_kevents(kqfd);
219     kevent_add(kqfd, &kev, srvr, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, NULL);
220     test_no_kevents(kqfd);
221
222     /* Simulate a client connecting to the server */
223     sain.sin_family = AF_INET;
224     sain.sin_port = htons(port);
225     sain.sin_addr.s_addr = inet_addr("127.0.0.1");
226     if ((clnt = socket(AF_INET, SOCK_STREAM, 0)) < 0) abort();
227     if (connect(clnt, (struct sockaddr *) &sain, sa_len) < 0) abort();
228
229     /* Verify that data=1 */
230     kev.data = 1;
231     kevent_cmp(&kev, kevent_get(kqfd));
232     test_no_kevents(kqfd);
233 }
234
235 #if HAVE_EV_DISPATCH
236 void
237 test_kevent_socket_dispatch(void)
238 {
239     struct kevent kev;
240
241     /* Re-add the watch and make sure no events are pending */
242     kevent_add(kqfd, &kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISPATCH, 0, 0, &sockfd[0]);
243     test_no_kevents(kqfd);
244
245     /* The event will occur only once, even though EV_CLEAR is not
246        specified. */
247     kevent_socket_fill();
248     kev.data = 1;
249     kevent_cmp(&kev, kevent_get(kqfd));
250     test_no_kevents(kqfd);
251
252     /* Re-enable the kevent */
253     /* FIXME- is EV_DISPATCH needed when rearming ? */
254     kevent_add(kqfd, &kev, sockfd[0], EVFILT_READ, EV_ENABLE | EV_DISPATCH, 0, 0, &sockfd[0]);
255     kev.data = 1;
256     kev.flags = EV_ADD | EV_DISPATCH;   /* FIXME: may not be portable */
257     kevent_cmp(&kev, kevent_get(kqfd));
258     test_no_kevents(kqfd);
259
260     /* Since the knote is disabled, the EV_DELETE operation succeeds. */
261     kevent_add(kqfd, &kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
262
263     kevent_socket_drain();
264 }
265 #endif  /* HAVE_EV_DISPATCH */
266
267 #if BROKEN_ON_LINUX
268 void
269 test_kevent_socket_lowat(void)
270 {
271     struct kevent kev;
272
273     test_begin(test_id);
274
275     /* Re-add the watch and make sure no events are pending */
276     puts("-- re-adding knote, setting low watermark to 2 bytes");
277     EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, NOTE_LOWAT, 2, &sockfd[0]);
278     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
279         die("%s", test_id);
280     test_no_kevents();
281
282     puts("-- checking that one byte does not trigger an event..");
283     kevent_socket_fill();
284     test_no_kevents();
285
286     puts("-- checking that two bytes triggers an event..");
287     kevent_socket_fill();
288     if (kevent(kqfd, NULL, 0, &kev, 1, NULL) != 1)
289         die("%s", test_id);
290     KEV_CMP(kev, sockfd[0], EVFILT_READ, 0);
291     test_no_kevents();
292
293     kevent_socket_drain();
294     kevent_socket_drain();
295 }
296 #endif
297
298 void
299 test_kevent_socket_eof(void)
300 {
301     struct kevent kev;
302
303     /* Re-add the watch and make sure no events are pending */
304     kevent_add(kqfd, &kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
305     test_no_kevents(kqfd);
306
307     if (close(sockfd[1]) < 0)
308         die("close(2)");
309
310     kev.flags |= EV_EOF;
311     kevent_cmp(&kev, kevent_get(kqfd));
312
313     /* Delete the watch */
314     kevent_add(kqfd, &kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
315 }
316
317 void
318 test_evfilt_read(int _kqfd)
319 {
320     /* Create a connected pair of full-duplex sockets for testing socket events */
321     if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0) 
322         die("socketpair");
323
324     kqfd = _kqfd;
325     test(kevent_socket_add);
326     test(kevent_socket_del);
327     test(kevent_socket_add_without_ev_add);
328     test(kevent_socket_get);
329     test(kevent_socket_disable_and_enable);
330     test(kevent_socket_oneshot);
331     test(kevent_socket_clear);
332 #if HAVE_EV_DISPATCH
333     test(kevent_socket_dispatch);
334 #endif
335     test(kevent_socket_listen_backlog);
336     test(kevent_socket_eof);
337     close(sockfd[0]);
338     close(sockfd[1]);
339 }