test: add keventd device manager test

The unified keventd has no automated coverage, only the devmon
fallback is exercised by the test suite.  Network interfaces are
the one device class an unprivileged test can hotplug: the sandbox
has its own network namespace, so 'ip link add' makes the kernel
emit genuine uevents.

Verify keventd readiness, <class/net/IFNAME> driving a service --
and <dev/IFNAME> NOT asserted, interfaces are not device nodes --
libudev-compatible n<ifindex> keying in /run/udev/data, conditions
surviving initctl reload, and cleanup on interface remove.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2026-08-16 22:03:36 +02:00
parent b3a206a28c
commit 864a13460c
2 changed files with 77 additions and 0 deletions
+4
View File
@@ -49,6 +49,7 @@ EXTRA_DIST += failing-sysv.sh
EXTRA_DIST += svc-env.sh
EXTRA_DIST += global-envs.sh
EXTRA_DIST += initctl-status-subset.sh
EXTRA_DIST += keventd.sh
EXTRA_DIST += notify.sh
EXTRA_DIST += pidfile.sh
EXTRA_DIST += stale-pidfile.sh
@@ -112,6 +113,9 @@ TESTS += failing-sysv.sh
TESTS += svc-env.sh
TESTS += global-envs.sh
TESTS += initctl-status-subset.sh
if KEVENTD
TESTS += keventd.sh
endif
TESTS += notify.sh
TESTS += pidfile.sh
TESTS += stale-pidfile.sh
+73
View File
@@ -0,0 +1,73 @@
#!/bin/sh
#
# Verify keventd, the bundled device manager. Network interfaces are
# the only devices an unprivileged test can hotplug: the sandbox has
# its own network namespace, so `ip link add` makes the kernel emit
# genuine uevents for keventd to process.
#
# Verifies that keventd signals readiness, that an interface add event
# asserts <class/net/IFNAME> to start a dependent service -- but never
# <dev/IFNAME>, interfaces are not device nodes -- that the
# /run/udev/data entry uses libudev-style n<ifindex> keying, and that
# the remove event reverses it all.
#
set -eu
TEST_DIR=$(dirname "$0")
test_teardown()
{
say "Running test teardown."
run "ip link del dummy0 2>/dev/null || true"
run "rm -f $FINIT_CONF"
}
# shellcheck source=/dev/null
. "$TEST_DIR/lib/setup.sh"
if ! texec initctl -p status keventd >/dev/null 2>&1; then
skip "keventd not enabled in this build"
fi
if ! run "ip link add probe0 type dummy 2>/dev/null"; then
skip "cannot create dummy interfaces in test namespace"
fi
run "ip link del probe0"
sep "keventd readiness"
retry 'assert_ready "keventd"' 50 0.2
sep "interface add asserts <class/net/dummy0>"
cat >> "$SYSROOT$FINIT_CONF" <<EOF
service serv {
log { file = "/dev/null" }
conditions = { "class/net/dummy0" }
command = "serv -np"
}
EOF
run "cat $FINIT_CONF"
run "initctl reload"
assert_status "serv" "waiting"
run "ip link add dummy0 type dummy"
retry 'assert_cond "class/net/dummy0"'
assert_nocond "dev/dummy0"
retry 'assert_status "serv" "running"'
sep "udev database uses n<ifindex> keying"
ifindex=$(texec cat /sys/class/net/dummy0/ifindex)
assert_file_exists "/run/udev/data/n$ifindex"
assert_file_contains "/run/udev/data/n$ifindex" "E:INTERFACE=dummy0"
sep "conditions survive initctl reload"
run "initctl reload"
retry 'assert_cond "class/net/dummy0"'
retry 'assert_status "serv" "running"'
sep "interface remove clears <class/net/dummy0>"
run "ip link del dummy0"
retry 'assert_nocond "class/net/dummy0"'
retry 'assert_status "serv" "waiting"'
retry "texec test ! -e /run/udev/data/n$ifindex"