diff options
Diffstat (limited to 'tests/sys/kqueue')
-rw-r--r-- | tests/sys/kqueue/Makefile | 28 | ||||
-rw-r--r-- | tests/sys/kqueue/libkqueue/Makefile | 21 | ||||
-rw-r--r-- | tests/sys/kqueue/libkqueue/Makefile.depend | 18 | ||||
-rw-r--r-- | tests/sys/kqueue/libkqueue/common.h (renamed from tests/sys/kqueue/common.h) | 0 | ||||
-rw-r--r-- | tests/sys/kqueue/libkqueue/config.h (renamed from tests/sys/kqueue/config.h) | 0 | ||||
-rwxr-xr-x | tests/sys/kqueue/libkqueue/kqueue_test.sh (renamed from tests/sys/kqueue/kqueue_test.sh) | 4 | ||||
-rw-r--r-- | tests/sys/kqueue/libkqueue/main.c | 323 | ||||
-rw-r--r-- | tests/sys/kqueue/libkqueue/proc.c (renamed from tests/sys/kqueue/proc.c) | 0 | ||||
-rw-r--r-- | tests/sys/kqueue/libkqueue/read.c | 326 | ||||
-rw-r--r-- | tests/sys/kqueue/libkqueue/signal.c (renamed from tests/sys/kqueue/signal.c) | 0 | ||||
-rw-r--r-- | tests/sys/kqueue/libkqueue/timer.c (renamed from tests/sys/kqueue/timer.c) | 0 | ||||
-rw-r--r-- | tests/sys/kqueue/libkqueue/user.c (renamed from tests/sys/kqueue/user.c) | 0 | ||||
-rw-r--r-- | tests/sys/kqueue/libkqueue/vnode.c (renamed from tests/sys/kqueue/vnode.c) | 22 |
13 files changed, 712 insertions, 30 deletions
diff --git a/tests/sys/kqueue/Makefile b/tests/sys/kqueue/Makefile index 43277ca..40f892d 100644 --- a/tests/sys/kqueue/Makefile +++ b/tests/sys/kqueue/Makefile @@ -1,26 +1,20 @@ # $FreeBSD$ -# -# svn://mark.heily.com/libkqueue/trunk/test -# Last update: r114 -# -# libkqueue and test suite by Mark Heily <mark@heily.com> -# -TAP_TESTS_SH= kqueue_test +TESTSRC= ${SRCTOP}/contrib/netbsd-tests/kernel/kqueue TESTSDIR= ${TESTSBASE}/sys/kqueue BINDIR= ${TESTSDIR} -PROGS= kqtest +NETBSD_ATF_TESTS_C= proc1_test +# XXX: fails `ke.fflags & NOTE_TRACKERR` invariant +#NETBSD_ATF_TESTS_C+= proc2_test +NETBSD_ATF_TESTS_C+= proc3_test +NETBSD_ATF_TESTS_C+= sig_test +NETBSD_ATF_TESTS_C+= vnode_test -SRCS.kqtest= \ - main.c \ - read.c \ - timer.c \ - vnode.c \ - proc.c \ - signal.c \ - user.c -WARNS?= 2 +WARNS?= 3 +TESTS_SUBDIRS+= libkqueue + +.include <netbsd-tests.test.mk> .include <bsd.test.mk> diff --git a/tests/sys/kqueue/libkqueue/Makefile b/tests/sys/kqueue/libkqueue/Makefile new file mode 100644 index 0000000..94d198b --- /dev/null +++ b/tests/sys/kqueue/libkqueue/Makefile @@ -0,0 +1,21 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/sys/kqueue/libkqueue +BINDIR= ${TESTSDIR} + +# libkqueue and test suite by Mark Heily <mark@heily.com> +TAP_TESTS_SH= kqueue_test + +PROGS= kqtest + +SRCS.kqtest= \ + main.c \ + read.c \ + timer.c \ + vnode.c \ + proc.c \ + signal.c \ + user.c +WARNS?= 2 + +.include <bsd.test.mk> diff --git a/tests/sys/kqueue/libkqueue/Makefile.depend b/tests/sys/kqueue/libkqueue/Makefile.depend new file mode 100644 index 0000000..3646e2e --- /dev/null +++ b/tests/sys/kqueue/libkqueue/Makefile.depend @@ -0,0 +1,18 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + gnu/lib/libgcc \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/tests/sys/kqueue/common.h b/tests/sys/kqueue/libkqueue/common.h index 89a4029..89a4029 100644 --- a/tests/sys/kqueue/common.h +++ b/tests/sys/kqueue/libkqueue/common.h diff --git a/tests/sys/kqueue/config.h b/tests/sys/kqueue/libkqueue/config.h index a204092..a204092 100644 --- a/tests/sys/kqueue/config.h +++ b/tests/sys/kqueue/libkqueue/config.h diff --git a/tests/sys/kqueue/kqueue_test.sh b/tests/sys/kqueue/libkqueue/kqueue_test.sh index 62a7e23..3185d82 100755 --- a/tests/sys/kqueue/kqueue_test.sh +++ b/tests/sys/kqueue/libkqueue/kqueue_test.sh @@ -1,8 +1,8 @@ #!/bin/sh +# $FreeBSD$ -cd $(dirname $0) i=1 -./kqtest | while read line; do +"$(dirname $0)/kqtest" | while read line; do echo $line | grep -q passed if [ $? -eq 0 ]; then echo "ok - $i $line" diff --git a/tests/sys/kqueue/libkqueue/main.c b/tests/sys/kqueue/libkqueue/main.c new file mode 100644 index 0000000..26e8f91 --- /dev/null +++ b/tests/sys/kqueue/libkqueue/main.c @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2009 Mark Heily <mark@heily.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> + +#include "config.h" +#include "common.h" + +int testnum = 1; +char *cur_test_id = NULL; +int kqfd; + +extern void test_evfilt_read(); +extern void test_evfilt_signal(); +extern void test_evfilt_vnode(); +extern void test_evfilt_timer(); +extern void test_evfilt_proc(); +#if HAVE_EVFILT_USER +extern void test_evfilt_user(); +#endif + +/* Checks if any events are pending, which is an error. */ +void +test_no_kevents(void) +{ + int nfds; + struct timespec timeo; + struct kevent kev; + + puts("confirming that there are no events pending"); + memset(&timeo, 0, sizeof(timeo)); + nfds = kevent(kqfd, NULL, 0, &kev, 1, &timeo); + if (nfds != 0) { + puts("\nUnexpected event:"); + puts(kevent_to_str(&kev)); + errx(1, "%d event(s) pending, but none expected:", nfds); + } +} + +/* Retrieve a single kevent */ +struct kevent * +kevent_get(int kqfd) +{ + int nfds; + struct kevent *kev; + + if ((kev = calloc(1, sizeof(*kev))) == NULL) + err(1, "out of memory"); + + nfds = kevent(kqfd, NULL, 0, kev, 1, NULL); + if (nfds < 1) + err(1, "kevent(2)"); + + return (kev); +} + +/* Retrieve a single kevent, specifying a maximum time to wait for it. */ +struct kevent * +kevent_get_timeout(int kqfd, int seconds) +{ + int nfds; + struct kevent *kev; + struct timespec timeout = {seconds, 0}; + + if ((kev = calloc(1, sizeof(*kev))) == NULL) + err(1, "out of memory"); + + nfds = kevent(kqfd, NULL, 0, kev, 1, &timeout); + if (nfds < 0) { + err(1, "kevent(2)"); + } else if (nfds == 0) { + free(kev); + kev = NULL; + } + + return (kev); +} + +char * +kevent_fflags_dump(struct kevent *kev) +{ + char *buf; + +#define KEVFFL_DUMP(attrib) \ + if (kev->fflags & attrib) \ + strncat(buf, #attrib" ", 64); + + if ((buf = calloc(1, 1024)) == NULL) + abort(); + + /* Not every filter has meaningful fflags */ + if (kev->filter == EVFILT_PROC) { + snprintf(buf, 1024, "fflags = %x (", kev->fflags); + KEVFFL_DUMP(NOTE_EXIT); + KEVFFL_DUMP(NOTE_FORK); + KEVFFL_DUMP(NOTE_EXEC); + KEVFFL_DUMP(NOTE_CHILD); + KEVFFL_DUMP(NOTE_TRACKERR); + KEVFFL_DUMP(NOTE_TRACK); + buf[strlen(buf) - 1] = ')'; + } else if (kev->filter == EVFILT_VNODE) { + snprintf(buf, 1024, "fflags = %x (", kev->fflags); + KEVFFL_DUMP(NOTE_DELETE); + KEVFFL_DUMP(NOTE_WRITE); + KEVFFL_DUMP(NOTE_EXTEND); +#if HAVE_NOTE_TRUNCATE + KEVFFL_DUMP(NOTE_TRUNCATE); +#endif + KEVFFL_DUMP(NOTE_ATTRIB); + KEVFFL_DUMP(NOTE_LINK); + KEVFFL_DUMP(NOTE_RENAME); +#if HAVE_NOTE_REVOKE + KEVFFL_DUMP(NOTE_REVOKE); +#endif + buf[strlen(buf) - 1] = ')'; + } else { + snprintf(buf, 1024, "fflags = %x", kev->fflags); + } + + return (buf); +} + +char * +kevent_flags_dump(struct kevent *kev) +{ + char *buf; + +#define KEVFL_DUMP(attrib) \ + if (kev->flags & attrib) \ + strncat(buf, #attrib" ", 64); + + if ((buf = calloc(1, 1024)) == NULL) + abort(); + + snprintf(buf, 1024, "flags = %d (", kev->flags); + KEVFL_DUMP(EV_ADD); + KEVFL_DUMP(EV_ENABLE); + KEVFL_DUMP(EV_DISABLE); + KEVFL_DUMP(EV_DELETE); + KEVFL_DUMP(EV_ONESHOT); + KEVFL_DUMP(EV_CLEAR); + KEVFL_DUMP(EV_EOF); + KEVFL_DUMP(EV_ERROR); +#if HAVE_EV_DISPATCH + KEVFL_DUMP(EV_DISPATCH); +#endif +#if HAVE_EV_RECEIPT + KEVFL_DUMP(EV_RECEIPT); +#endif + buf[strlen(buf) - 1] = ')'; + + return (buf); +} + +/* Copied from ../kevent.c kevent_dump() and improved */ +const char * +kevent_to_str(struct kevent *kev) +{ + char buf[512]; + + snprintf(&buf[0], sizeof(buf), + "[ident=%d, filter=%d, %s, %s, data=%d, udata=%p]", + (u_int) kev->ident, + kev->filter, + kevent_flags_dump(kev), + kevent_fflags_dump(kev), + (int) kev->data, + kev->udata); + + return (strdup(buf)); +} + +void +kevent_add(int kqfd, struct kevent *kev, + uintptr_t ident, + short filter, + u_short flags, + u_int fflags, + intptr_t data, + void *udata) +{ + EV_SET(kev, ident, filter, flags, fflags, data, NULL); + if (kevent(kqfd, kev, 1, NULL, 0, NULL) < 0) { + printf("Unable to add the following kevent:\n%s\n", + kevent_to_str(kev)); + err(1, "kevent(): %s", strerror(errno)); + } +} + +void +kevent_cmp(struct kevent *k1, struct kevent *k2) +{ +/* XXX- + Workaround for inconsistent implementation of kevent(2) + */ +#ifdef __FreeBSD__ + if (k1->flags & EV_ADD) + k2->flags |= EV_ADD; +#endif + if (memcmp(k1, k2, sizeof(*k1)) != 0) { + printf("kevent_cmp: mismatch:\n %s !=\n %s\n", + kevent_to_str(k1), kevent_to_str(k2)); + abort(); + } +} + +void +test_begin(const char *func) +{ + if (cur_test_id) + free(cur_test_id); + cur_test_id = strdup(func); + if (!cur_test_id) + err(1, "strdup failed"); + + printf("\n\nTest %d: %s\n", testnum++, func); +} + +void +success(void) +{ + printf("%-70s %s\n", cur_test_id, "passed"); + free(cur_test_id); + cur_test_id = NULL; +} + +void +test_kqueue(void) +{ + test_begin("kqueue()"); + if ((kqfd = kqueue()) < 0) + err(1, "kqueue()"); + test_no_kevents(); + success(); +} + +void +test_kqueue_close(void) +{ + test_begin("close(kq)"); + if (close(kqfd) < 0) + err(1, "close()"); + success(); +} + +int +main(int argc, char **argv) +{ + int test_proc = 1; + int test_socket = 1; + int test_signal = 1; + int test_vnode = 1; + int test_timer = 1; +#ifdef __FreeBSD__ + int test_user = 1; +#else + /* XXX-FIXME temporary */ + int test_user = 0; +#endif + + while (argc) { + if (strcmp(argv[0], "--no-proc") == 0) + test_proc = 0; + if (strcmp(argv[0], "--no-socket") == 0) + test_socket = 0; + if (strcmp(argv[0], "--no-timer") == 0) + test_timer = 0; + if (strcmp(argv[0], "--no-signal") == 0) + test_signal = 0; + if (strcmp(argv[0], "--no-vnode") == 0) + test_vnode = 0; + if (strcmp(argv[0], "--no-user") == 0) + test_user = 0; + argv++; + argc--; + } + + /* + * Some tests fork. If output is fully buffered, + * the children inherit some buffered data and flush + * it when they exit, causing some data to be printed twice. + * Use line buffering to avoid this problem. + */ + setlinebuf(stdout); + setlinebuf(stderr); + + test_kqueue(); + test_kqueue_close(); + + if (test_socket) + test_evfilt_read(); + if (test_signal) + test_evfilt_signal(); + if (test_vnode) + test_evfilt_vnode(); +#if HAVE_EVFILT_USER + if (test_user) + test_evfilt_user(); +#endif + if (test_timer) + test_evfilt_timer(); + if (test_proc) + test_evfilt_proc(); + + printf("\n---\n" + "+OK All %d tests completed.\n", testnum - 1); + return (0); +} diff --git a/tests/sys/kqueue/proc.c b/tests/sys/kqueue/libkqueue/proc.c index 79b8d35..79b8d35 100644 --- a/tests/sys/kqueue/proc.c +++ b/tests/sys/kqueue/libkqueue/proc.c diff --git a/tests/sys/kqueue/libkqueue/read.c b/tests/sys/kqueue/libkqueue/read.c new file mode 100644 index 0000000..2837144 --- /dev/null +++ b/tests/sys/kqueue/libkqueue/read.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2009 Mark Heily <mark@heily.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#include "common.h" + +int kqfd; +int sockfd[2]; + +static void +kevent_socket_drain(void) +{ + char buf[1]; + + /* Drain the read buffer, then make sure there are no more events. */ + puts("draining the read buffer"); + if (read(sockfd[0], &buf[0], 1) < 1) + err(1, "read(2)"); +} + +static void +kevent_socket_fill(void) +{ + puts("filling the read buffer"); + if (write(sockfd[1], ".", 1) < 1) + err(1, "write(2)"); +} + + +void +test_kevent_socket_add(void) +{ + const char *test_id = "kevent(EVFILT_READ, EV_ADD)"; + struct kevent kev; + + test_begin(test_id); + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + success(); +} + +void +test_kevent_socket_get(void) +{ + const char *test_id = "kevent(EVFILT_READ) wait"; + struct kevent kev; + + test_begin(test_id); + + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + kevent_socket_fill(); + + kev.data = 1; + kevent_cmp(&kev, kevent_get(kqfd)); + + kevent_socket_drain(); + test_no_kevents(); + + kev.flags = EV_DELETE; + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + success(); +} + +void +test_kevent_socket_clear(void) +{ + const char *test_id = "kevent(EVFILT_READ, EV_CLEAR)"; + struct kevent kev; + + test_begin(test_id); + + test_no_kevents(); + + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + kevent_socket_fill(); + kevent_socket_fill(); + + kev.data = 2; + kevent_cmp(&kev, kevent_get(kqfd)); + + /* We filled twice, but drain once. Edge-triggered would not generate + additional events. + */ + kevent_socket_drain(); + test_no_kevents(); + + kevent_socket_drain(); + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + success(); +} + +void +test_kevent_socket_disable_and_enable(void) +{ + const char *test_id = "kevent(EVFILT_READ, EV_DISABLE)"; + struct kevent kev; + + test_begin(test_id); + + /* + * Write to the socket before adding the event. This way we can verify that + * enabling a triggered kevent causes the event to be returned immediately. + */ + kevent_socket_fill(); + + /* Add a disabled event. */ + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISABLE, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + test_no_kevents(); + + /* Re-enable the knote, then see if an event is generated */ + kev.flags = EV_ENABLE; + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + kev.flags = EV_ADD; + kev.data = 1; + kevent_cmp(&kev, kevent_get(kqfd)); + + kevent_socket_drain(); + + kev.flags = EV_DELETE; + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + success(); +} + +void +test_kevent_socket_del(void) +{ + const char *test_id = "kevent(EVFILT_READ, EV_DELETE)"; + struct kevent kev; + + test_begin(test_id); + + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + kevent_socket_fill(); + test_no_kevents(); + kevent_socket_drain(); + + success(); +} + +void +test_kevent_socket_oneshot(void) +{ + const char *test_id = "kevent(EVFILT_READ, EV_ONESHOT)"; + struct kevent kev; + + test_begin(test_id); + + /* Re-add the watch and make sure no events are pending */ + puts("-- re-adding knote"); + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + test_no_kevents(); + + puts("-- getting one event"); + kevent_socket_fill(); + kev.data = 1; + kevent_cmp(&kev, kevent_get(kqfd)); + + puts("-- checking knote disabled"); + test_no_kevents(); + + /* Try to delete the knote, it should already be deleted */ + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) == 0) + err(1, "%s", test_id); + + kevent_socket_drain(); + + success(); +} + + +#if HAVE_EV_DISPATCH +void +test_kevent_socket_dispatch(void) +{ + const char *test_id = "kevent(EVFILT_READ, EV_DISPATCH)"; + + test_begin(test_id); + + struct kevent kev; + + /* Re-add the watch and make sure no events are pending */ + puts("-- re-adding knote"); + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISPATCH, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + test_no_kevents(); + + /* The event will occur only once, even though EV_CLEAR is not + specified. */ + kevent_socket_fill(); + kev.data = 1; + kevent_cmp(&kev, kevent_get(kqfd)); + test_no_kevents(); + + /* Since the knote is disabled, the EV_DELETE operation succeeds. */ + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + kevent_socket_drain(); + + success(); +} +#endif /* HAVE_EV_DISPATCH */ + +#if BROKEN +void +test_kevent_socket_lowat(void) +{ + const char *test_id = "kevent(EVFILT_READ, NOTE_LOWAT)"; + struct kevent kev; + + test_begin(test_id); + + /* Re-add the watch and make sure no events are pending */ + puts("-- re-adding knote, setting low watermark to 2 bytes"); + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, NOTE_LOWAT, 2, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + test_no_kevents(); + + puts("-- checking that one byte does not trigger an event.."); + kevent_socket_fill(); + test_no_kevents(); + + puts("-- checking that two bytes triggers an event.."); + kevent_socket_fill(); + if (kevent(kqfd, NULL, 0, &kev, 1, NULL) != 1) + err(1, "%s", test_id); + KEV_CMP(kev, sockfd[0], EVFILT_READ, 0); + test_no_kevents(); + + kevent_socket_drain(); + kevent_socket_drain(); + + success(); +} +#endif + +void +test_kevent_socket_eof(void) +{ + const char *test_id = "kevent(EVFILT_READ, EV_EOF)"; + struct kevent kev; + + test_begin(test_id); + + /* Re-add the watch and make sure no events are pending */ + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + test_no_kevents(); + + if (close(sockfd[1]) < 0) + err(1, "close(2)"); + + kev.flags |= EV_EOF; + kevent_cmp(&kev, kevent_get(kqfd)); + + /* Delete the watch */ + EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + success(); +} + +void +test_evfilt_read() +{ + /* Create a connected pair of full-duplex sockets for testing socket events */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0) + abort(); + + kqfd = kqueue(); + test_kevent_socket_add(); + test_kevent_socket_del(); + test_kevent_socket_get(); + test_kevent_socket_disable_and_enable(); + test_kevent_socket_oneshot(); + test_kevent_socket_clear(); +#if HAVE_EV_DISPATCH + test_kevent_socket_dispatch(); +#endif + test_kevent_socket_eof(); + close(kqfd); +} diff --git a/tests/sys/kqueue/signal.c b/tests/sys/kqueue/libkqueue/signal.c index 14e751d..14e751d 100644 --- a/tests/sys/kqueue/signal.c +++ b/tests/sys/kqueue/libkqueue/signal.c diff --git a/tests/sys/kqueue/timer.c b/tests/sys/kqueue/libkqueue/timer.c index 766125d..766125d 100644 --- a/tests/sys/kqueue/timer.c +++ b/tests/sys/kqueue/libkqueue/timer.c diff --git a/tests/sys/kqueue/user.c b/tests/sys/kqueue/libkqueue/user.c index 9ba25f9..9ba25f9 100644 --- a/tests/sys/kqueue/user.c +++ b/tests/sys/kqueue/libkqueue/user.c diff --git a/tests/sys/kqueue/vnode.c b/tests/sys/kqueue/libkqueue/vnode.c index dfa0b5e..55d5b3f 100644 --- a/tests/sys/kqueue/vnode.c +++ b/tests/sys/kqueue/libkqueue/vnode.c @@ -25,12 +25,12 @@ void test_kevent_vnode_add(void) { const char *test_id = "kevent(EVFILT_VNODE, EV_ADD)"; - const char *testfile = "/tmp/kqueue-test.tmp"; + const char *testfile = "./kqueue-test.tmp"; struct kevent kev; test_begin(test_id); - system("touch /tmp/kqueue-test.tmp"); + system("touch ./kqueue-test.tmp"); vnode_fd = open(testfile, O_RDONLY); if (vnode_fd < 0) err(1, "open of %s", testfile); @@ -57,7 +57,7 @@ test_kevent_vnode_note_delete(void) if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); - if (unlink("/tmp/kqueue-test.tmp") < 0) + if (unlink("./kqueue-test.tmp") < 0) err(1, "unlink"); kevent_cmp(&kev, kevent_get(kqfd)); @@ -77,7 +77,7 @@ test_kevent_vnode_note_write(void) if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); - if (system("echo hello >> /tmp/kqueue-test.tmp") < 0) + if (system("echo hello >> ./kqueue-test.tmp") < 0) err(1, "system"); /* BSD kqueue adds NOTE_EXTEND even though it was not requested */ @@ -102,7 +102,7 @@ test_kevent_vnode_note_attrib(void) if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); - if (system("touch /tmp/kqueue-test.tmp") < 0) + if (system("touch ./kqueue-test.tmp") < 0) err(1, "system"); nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL); @@ -130,7 +130,7 @@ test_kevent_vnode_note_rename(void) if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); - if (system("mv /tmp/kqueue-test.tmp /tmp/kqueue-test2.tmp") < 0) + if (system("mv ./kqueue-test.tmp ./kqueue-test2.tmp") < 0) err(1, "system"); nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL); @@ -142,7 +142,7 @@ test_kevent_vnode_note_rename(void) err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)", test_id, (unsigned int)kev.ident, kev.filter, kev.flags); - if (system("mv /tmp/kqueue-test2.tmp /tmp/kqueue-test.tmp") < 0) + if (system("mv ./kqueue-test2.tmp ./kqueue-test.tmp") < 0) err(1, "system"); success(); @@ -183,7 +183,7 @@ test_kevent_vnode_disable_and_enable(void) err(1, "%s", test_id); /* Confirm that the watch is disabled */ - if (system("touch /tmp/kqueue-test.tmp") < 0) + if (system("touch ./kqueue-test.tmp") < 0) err(1, "system"); test_no_kevents(); @@ -191,7 +191,7 @@ test_kevent_vnode_disable_and_enable(void) kev.flags = EV_ENABLE; if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); - if (system("touch /tmp/kqueue-test.tmp") < 0) + if (system("touch ./kqueue-test.tmp") < 0) err(1, "system"); nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL); if (nfds < 1) @@ -221,7 +221,7 @@ test_kevent_vnode_dispatch(void) if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) err(1, "%s", test_id); - if (system("touch /tmp/kqueue-test.tmp") < 0) + if (system("touch ./kqueue-test.tmp") < 0) err(1, "system"); nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL); @@ -235,7 +235,7 @@ test_kevent_vnode_dispatch(void) /* Confirm that the watch is disabled automatically */ puts("-- checking that watch is disabled"); - if (system("touch /tmp/kqueue-test.tmp") < 0) + if (system("touch ./kqueue-test.tmp") < 0) err(1, "system"); test_no_kevents(); |