git: d6d4f9b45e0b - main - kqueue tests: Add new EVFILT_TIMER regression tests from upstream
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 25 May 2022 00:18:19 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=d6d4f9b45e0be306bdaf53b2133b2cd0f7642167
commit d6d4f9b45e0be306bdaf53b2133b2cd0f7642167
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-05-25 00:16:32 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-05-25 00:16:32 +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
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
---
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);
}