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)";
128 * Write to the socket before adding the event. This way we can verify that
129 * enabling a triggered kevent causes the event to be returned immediately.
131 kevent_socket_fill();
133 /* Add a disabled event. */
134 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISABLE, 0, 0, &sockfd[0]);
135 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
136 err(1, "%s", test_id);
140 /* Re-enable the knote, then see if an event is generated */
141 kev.flags = EV_ENABLE;
142 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
143 err(1, "%s", test_id);
146 kevent_cmp(&kev, kevent_get(kqfd));
148 kevent_socket_drain();
150 kev.flags = EV_DELETE;
151 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
152 err(1, "%s", test_id);
158 test_kevent_socket_del(void)
160 const char *test_id = "kevent(EVFILT_READ, EV_DELETE)";
165 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
166 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
167 err(1, "%s", test_id);
169 kevent_socket_fill();
171 kevent_socket_drain();
177 test_kevent_socket_oneshot(void)
179 const char *test_id = "kevent(EVFILT_READ, EV_ONESHOT)";
184 /* Re-add the watch and make sure no events are pending */
185 puts("-- re-adding knote");
186 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &sockfd[0]);
187 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
188 err(1, "%s", test_id);
191 puts("-- getting one event");
192 kevent_socket_fill();
194 kevent_cmp(&kev, kevent_get(kqfd));
196 puts("-- checking knote disabled");
199 /* Try to delete the knote, it should already be deleted */
200 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
201 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) == 0)
202 err(1, "%s", test_id);
204 kevent_socket_drain();
212 test_kevent_socket_dispatch(void)
214 const char *test_id = "kevent(EVFILT_READ, EV_DISPATCH)";
220 /* Re-add the watch and make sure no events are pending */
221 puts("-- re-adding knote");
222 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISPATCH, 0, 0, &sockfd[0]);
223 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
224 err(1, "%s", test_id);
227 /* The event will occur only once, even though EV_CLEAR is not
229 kevent_socket_fill();
231 kevent_cmp(&kev, kevent_get(kqfd));
234 /* Since the knote is disabled, the EV_DELETE operation succeeds. */
235 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
236 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
237 err(1, "%s", test_id);
239 kevent_socket_drain();
243 #endif /* HAVE_EV_DISPATCH */
247 test_kevent_socket_lowat(void)
249 const char *test_id = "kevent(EVFILT_READ, NOTE_LOWAT)";
254 /* Re-add the watch and make sure no events are pending */
255 puts("-- re-adding knote, setting low watermark to 2 bytes");
256 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, NOTE_LOWAT, 2, &sockfd[0]);
257 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
258 err(1, "%s", test_id);
261 puts("-- checking that one byte does not trigger an event..");
262 kevent_socket_fill();
265 puts("-- checking that two bytes triggers an event..");
266 kevent_socket_fill();
267 if (kevent(kqfd, NULL, 0, &kev, 1, NULL) != 1)
268 err(1, "%s", test_id);
269 KEV_CMP(kev, sockfd[0], EVFILT_READ, 0);
272 kevent_socket_drain();
273 kevent_socket_drain();
280 test_kevent_socket_eof(void)
282 const char *test_id = "kevent(EVFILT_READ, EV_EOF)";
287 /* Re-add the watch and make sure no events are pending */
288 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
289 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
290 err(1, "%s", test_id);
293 if (close(sockfd[1]) < 0)
297 kevent_cmp(&kev, kevent_get(kqfd));
299 /* Delete the watch */
300 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
301 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
302 err(1, "%s", test_id);
310 /* Create a connected pair of full-duplex sockets for testing socket events */
311 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0)
315 test_kevent_socket_add();
316 test_kevent_socket_del();
317 test_kevent_socket_get();
318 test_kevent_socket_disable_and_enable();
319 test_kevent_socket_oneshot();
320 test_kevent_socket_clear();
322 test_kevent_socket_dispatch();
324 test_kevent_socket_eof();