git: f2ce33a640fd - stable/13 - kqueue tests: Add new EVFILT_TIMER regression tests from upstream
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 08 Jun 2022 00:45:00 UTC
The branch stable/13 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=f2ce33a640fddeb0763d4114bc7f06aa521effd0 commit f2ce33a640fddeb0763d4114bc7f06aa521effd0 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2022-05-25 00:16:32 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2022-06-08 00:42:25 +0000 kqueue tests: Add new EVFILT_TIMER regression tests from upstream One of the tests exposes the regression reported in PR 264131. One test is disabled because FreeBSD does not support setting EV_ONESHOT on an already-added periodic timer. Though, in this case the flag is simply ignored, which isn't ideal. One test is slightly modified to set EV_ADD when reconfiguring a disabled timer per some commentary in PR 258412. Ideally we would re-import the test suite from libkqueue but there is a fair bit of divergence so this will require some effort. This just gets us one small step closer while increasing test coverage. PR: 258412 Sponsored by: The FreeBSD Foundation (cherry picked from commit d6d4f9b45e0be306bdaf53b2133b2cd0f7642167) --- tests/sys/kqueue/libkqueue/config.h | 1 + tests/sys/kqueue/libkqueue/timer.c | 129 +++++++++++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 2 deletions(-) diff --git a/tests/sys/kqueue/libkqueue/config.h b/tests/sys/kqueue/libkqueue/config.h index a204092a2ab2..41a67837efe8 100644 --- a/tests/sys/kqueue/libkqueue/config.h +++ b/tests/sys/kqueue/libkqueue/config.h @@ -7,6 +7,7 @@ #undef HAVE_NOTE_TRUNCATE #define HAVE_EVFILT_TIMER 1 #define HAVE_EVFILT_USER 1 +#define WITH_NATIVE_KQUEUE_BUGS 0 #define PROGRAM "libkqueue-test" #define VERSION "0.1" #define TARGET "freebsd" diff --git a/tests/sys/kqueue/libkqueue/timer.c b/tests/sys/kqueue/libkqueue/timer.c index 330c22c62bc5..aa9d41ce6bf8 100644 --- a/tests/sys/kqueue/libkqueue/timer.c +++ b/tests/sys/kqueue/libkqueue/timer.c @@ -182,7 +182,84 @@ test_periodic(void) } static void -disable_and_enable(void) +test_periodic_modify(void) +{ + const char *test_id = "kevent(EVFILT_TIMER, periodic_modify)"; + struct kevent kev; + + test_begin(test_id); + + test_no_kevents(); + + EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, 0, 1000, NULL); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + /* Retrieve the event */ + kev.flags = EV_ADD | EV_CLEAR; + kev.data = 1; + kevent_cmp(&kev, kevent_get(kqfd)); + + /* Check if the event occurs again */ + EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, 0, 500, NULL); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + kev.flags = EV_ADD | EV_CLEAR; + sleep(1); + kev.data = 2; /* Should have fired twice */ + + kevent_cmp(&kev, kevent_get(kqfd)); + + /* Delete the event */ + kev.flags = EV_DELETE; + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + success(); +} + +#if WITH_NATIVE_KQUEUE_BUGS +static void +test_periodic_to_oneshot(void) +{ + const char *test_id = "kevent(EVFILT_TIMER, period_to_oneshot)"; + struct kevent kev; + + test_begin(test_id); + + test_no_kevents(); + + EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, 0, 1000, NULL); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + /* Retrieve the event */ + kev.flags = EV_ADD | EV_CLEAR; + kev.data = 1; + kevent_cmp(&kev, kevent_get(kqfd)); + + /* Check if the event occurs again */ + sleep(1); + kevent_cmp(&kev, kevent_get(kqfd)); + + /* Switch to oneshot */ + EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 500, NULL); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT; + + sleep(1); + kev.data = 1; /* Should have fired once */ + + kevent_cmp(&kev, kevent_get(kqfd)); + + success(); +} +#endif + +static void +test_disable_and_enable(void) { const char *test_id = "kevent(EVFILT_TIMER, EV_DISABLE and EV_ENABLE)"; struct kevent kev; @@ -618,6 +695,49 @@ test_update_timing(void) success(); } +static void +test_dispatch(void) +{ + const char *test_id = "kevent(EVFILT_TIMER, EV_ADD | EV_DISPATCH)"; + struct kevent kev; + + test_no_kevents(); + + EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_DISPATCH, 0, 200, NULL); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + + /* Get one event */ + kev.flags = EV_ADD | EV_CLEAR | EV_DISPATCH; + kev.data = 1; + kevent_cmp(&kev, kevent_get(kqfd)); + + /* Confirm that the knote is disabled due to EV_DISPATCH */ + usleep(500000); + test_no_kevents(); + + /* Enable the knote and make sure no events are pending */ + EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ENABLE | EV_DISPATCH, 0, 200, NULL); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + test_no_kevents(); + + /* Get the next event */ + usleep(1100000); /* 1100 ms */ + kev.flags = EV_ADD | EV_CLEAR | EV_DISPATCH; + kev.data = 5; + kevent_cmp(&kev, kevent_get(kqfd)); + + /* Remove the knote and ensure the event no longer fires */ + EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) + err(1, "%s", test_id); + usleep(500000); /* 500ms */ + test_no_kevents(); + + success(); +} + void test_evfilt_timer(void) { @@ -627,6 +747,10 @@ test_evfilt_timer(void) test_kevent_timer_get(); test_oneshot(); test_periodic(); + test_periodic_modify(); +#if WITH_NATIVE_KQUEUE_BUGS + test_periodic_to_oneshot(); +#endif test_abstime(); test_abstime_epoch(); test_abstime_preboot(); @@ -636,6 +760,7 @@ test_evfilt_timer(void) test_update_expired(); test_update_timing(); test_update_periodic(); - disable_and_enable(); + test_disable_and_enable(); + test_dispatch(); close(kqfd); }