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.
22 kevent_socket_drain(void)
26 /* Drain the read buffer, then make sure there are no more events. */
27 puts("draining the read buffer");
28 if (read(sockfd[0], &buf[0], 1) < 1)
33 kevent_socket_fill(void)
35 puts("filling the read buffer");
36 if (write(sockfd[1], ".", 1) < 1)
42 test_kevent_socket_add(void)
44 const char *test_id = "kevent(EVFILT_READ, EV_ADD)";
48 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
49 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
50 err(1, "%s", test_id);
56 test_kevent_socket_get(void)
58 const char *test_id = "kevent(EVFILT_READ) wait";
63 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
64 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
65 err(1, "%s", test_id);
70 kevent_cmp(&kev, kevent_get(kqfd));
72 kevent_socket_drain();
75 kev.flags = EV_DELETE;
76 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
77 err(1, "%s", test_id);
83 test_kevent_socket_clear(void)
85 const char *test_id = "kevent(EVFILT_READ, EV_CLEAR)";
92 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, &sockfd[0]);
93 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
94 err(1, "%s", test_id);
100 kevent_cmp(&kev, kevent_get(kqfd));
102 /* We filled twice, but drain once. Edge-triggered would not generate
105 kevent_socket_drain();
108 kevent_socket_drain();
109 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
110 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
111 err(1, "%s", test_id);
117 test_kevent_socket_disable_and_enable(void)
119 const char *test_id = "kevent(EVFILT_READ, EV_DISABLE)";
125 * Write to the socket before adding the event. This way we can verify that
126 * enabling a triggered kevent causes the event to be returned immediately.
128 kevent_socket_fill();
130 /* Add a disabled event. */
131 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISABLE, 0, 0, &sockfd[0]);
132 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
133 err(1, "%s", test_id);
137 /* Re-enable the knote, then see if an event is generated */
138 kev.flags = EV_ENABLE;
139 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
140 err(1, "%s", test_id);
143 kevent_cmp(&kev, kevent_get(kqfd));
145 kevent_socket_drain();
147 kev.flags = EV_DELETE;
148 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
149 err(1, "%s", test_id);
155 test_kevent_socket_del(void)
157 const char *test_id = "kevent(EVFILT_READ, EV_DELETE)";
162 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
163 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
164 err(1, "%s", test_id);
166 kevent_socket_fill();
168 kevent_socket_drain();
174 test_kevent_socket_oneshot(void)
176 const char *test_id = "kevent(EVFILT_READ, EV_ONESHOT)";
181 /* Re-add the watch and make sure no events are pending */
182 puts("-- re-adding knote");
183 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &sockfd[0]);
184 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
185 err(1, "%s", test_id);
188 puts("-- getting one event");
189 kevent_socket_fill();
191 kevent_cmp(&kev, kevent_get(kqfd));
193 puts("-- checking knote disabled");
196 /* Try to delete the knote, it should already be deleted */
197 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
198 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) == 0)
199 err(1, "%s", test_id);
201 kevent_socket_drain();
209 test_kevent_socket_dispatch(void)
211 const char *test_id = "kevent(EVFILT_READ, EV_DISPATCH)";
217 /* Re-add the watch and make sure no events are pending */
218 puts("-- re-adding knote");
219 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISPATCH, 0, 0, &sockfd[0]);
220 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
221 err(1, "%s", test_id);
224 /* The event will occur only once, even though EV_CLEAR is not
226 kevent_socket_fill();
228 kevent_cmp(&kev, kevent_get(kqfd));
231 /* Since the knote is disabled, the EV_DELETE operation succeeds. */
232 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
233 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
234 err(1, "%s", test_id);
236 kevent_socket_drain();
240 #endif /* HAVE_EV_DISPATCH */
244 test_kevent_socket_lowat(void)
246 const char *test_id = "kevent(EVFILT_READ, NOTE_LOWAT)";
251 /* Re-add the watch and make sure no events are pending */
252 puts("-- re-adding knote, setting low watermark to 2 bytes");
253 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, NOTE_LOWAT, 2, &sockfd[0]);
254 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
255 err(1, "%s", test_id);
258 puts("-- checking that one byte does not trigger an event..");
259 kevent_socket_fill();
262 puts("-- checking that two bytes triggers an event..");
263 kevent_socket_fill();
264 if (kevent(kqfd, NULL, 0, &kev, 1, NULL) != 1)
265 err(1, "%s", test_id);
266 KEV_CMP(kev, sockfd[0], EVFILT_READ, 0);
269 kevent_socket_drain();
270 kevent_socket_drain();
277 test_kevent_socket_eof(void)
279 const char *test_id = "kevent(EVFILT_READ, EV_EOF)";
284 /* Re-add the watch and make sure no events are pending */
285 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]);
286 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
287 err(1, "%s", test_id);
290 if (close(sockfd[1]) < 0)
294 kevent_cmp(&kev, kevent_get(kqfd));
296 /* Delete the watch */
297 EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);
298 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
299 err(1, "%s", test_id);
305 test_evfilt_read(void)
307 /* Create a connected pair of full-duplex sockets for testing socket events */
308 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0)
312 test_kevent_socket_add();
313 test_kevent_socket_del();
314 test_kevent_socket_get();
315 test_kevent_socket_disable_and_enable();
316 test_kevent_socket_oneshot();
317 test_kevent_socket_clear();
319 test_kevent_socket_dispatch();
321 test_kevent_socket_eof();