2 * Copyright (c) 2009 Mark Heily <mark@heily.com>
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.
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.
25 kevent_socket_drain(void)
29 /* Drain the read buffer, then make sure there are no more events. */
30 puts("draining the read buffer");
31 if (read(sockfd[0], &buf[0], 1) < 1)
36 kevent_socket_fill(void)
38 puts("filling the read buffer");
39 if (write(sockfd[1], ".", 1) < 1)
45 test_kevent_socket_add(void)
47 const char *test_id = "kevent(EVFILT_READ, EV_ADD)";
51 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
52 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
53 err(1, "%s", test_id);
59 test_kevent_socket_get(void)
61 const char *test_id = "kevent(EVFILT_READ) wait";
66 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
67 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
68 err(1, "%s", test_id);
73 kevent_cmp(&kev, kevent_get(kqfd));
75 kevent_socket_drain();
78 kev.flags = EV_DELETE;
79 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
80 err(1, "%s", test_id);
86 test_kevent_socket_clear(void)
88 const char *test_id = "kevent(EVFILT_READ, EV_CLEAR)";
95 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, &sockfd[0]);
96 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
97 err(1, "%s", test_id);
100 kevent_socket_fill();
103 kevent_cmp(&kev, kevent_get(kqfd));
105 /* We filled twice, but drain once. Edge-triggered would not generate
108 kevent_socket_drain();
111 kevent_socket_drain();
112 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
113 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
114 err(1, "%s", test_id);
120 test_kevent_socket_disable_and_enable(void)
122 const char *test_id = "kevent(EVFILT_READ, EV_DISABLE)";
127 /* Add an event, then disable it. */
128 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
129 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
130 err(1, "%s", test_id);
131 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DISABLE, 0, 0, &sockfd[0]);
132 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
133 err(1, "%s", test_id);
135 kevent_socket_fill();
138 /* Re-enable the knote, then see if an event is generated */
139 kev.flags = EV_ENABLE;
140 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
141 err(1, "%s", test_id);
144 kevent_cmp(&kev, kevent_get(kqfd));
146 kevent_socket_drain();
148 kev.flags = EV_DELETE;
149 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
150 err(1, "%s", test_id);
156 test_kevent_socket_del(void)
158 const char *test_id = "kevent(EVFILT_READ, EV_DELETE)";
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 err(1, "%s", test_id);
167 kevent_socket_fill();
169 kevent_socket_drain();
175 test_kevent_socket_oneshot(void)
177 const char *test_id = "kevent(EVFILT_READ, EV_ONESHOT)";
182 /* Re-add the watch and make sure no events are pending */
183 puts("-- re-adding knote");
184 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &sockfd[0]);
185 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
186 err(1, "%s", test_id);
189 puts("-- getting one event");
190 kevent_socket_fill();
192 kevent_cmp(&kev, kevent_get(kqfd));
194 puts("-- checking knote disabled");
197 /* Try to delete the knote, it should already be deleted */
198 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
199 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) == 0)
200 err(1, "%s", test_id);
202 kevent_socket_drain();
210 test_kevent_socket_dispatch(void)
212 const char *test_id = "kevent(EVFILT_READ, EV_DISPATCH)";
218 /* Re-add the watch and make sure no events are pending */
219 puts("-- re-adding knote");
220 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISPATCH, 0, 0, &sockfd[0]);
221 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
222 err(1, "%s", test_id);
225 /* The event will occur only once, even though EV_CLEAR is not
227 kevent_socket_fill();
229 kevent_cmp(&kev, kevent_get(kqfd));
232 /* Since the knote is disabled, the EV_DELETE operation succeeds. */
233 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
234 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
235 err(1, "%s", test_id);
237 kevent_socket_drain();
241 #endif /* HAVE_EV_DISPATCH */
245 test_kevent_socket_lowat(void)
247 const char *test_id = "kevent(EVFILT_READ, NOTE_LOWAT)";
252 /* Re-add the watch and make sure no events are pending */
253 puts("-- re-adding knote, setting low watermark to 2 bytes");
254 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, NOTE_LOWAT, 2, &sockfd[0]);
255 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
256 err(1, "%s", test_id);
259 puts("-- checking that one byte does not trigger an event..");
260 kevent_socket_fill();
263 puts("-- checking that two bytes triggers an event..");
264 kevent_socket_fill();
265 if (kevent(kqfd, NULL, 0, &kev, 1, NULL) != 1)
266 err(1, "%s", test_id);
267 KEV_CMP(kev, sockfd[0], EVFILT_READ, 0);
270 kevent_socket_drain();
271 kevent_socket_drain();
278 test_kevent_socket_eof(void)
280 const char *test_id = "kevent(EVFILT_READ, EV_EOF)";
285 /* Re-add the watch and make sure no events are pending */
286 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
287 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
288 err(1, "%s", test_id);
291 if (close(sockfd[1]) < 0)
295 kevent_cmp(&kev, kevent_get(kqfd));
297 /* Delete the watch */
298 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
299 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
300 err(1, "%s", test_id);
308 /* Create a connected pair of full-duplex sockets for testing socket events */
309 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0)
313 test_kevent_socket_add();
314 test_kevent_socket_del();
315 test_kevent_socket_get();
316 test_kevent_socket_disable_and_enable();
317 test_kevent_socket_oneshot();
318 test_kevent_socket_clear();
320 test_kevent_socket_dispatch();
322 test_kevent_socket_eof();