mirror of
https://github.com/troglobit/finit.git
synced 2026-10-14 10:19:36 +00:00
test: cover org.finit.Device1 end to end
Introspection, queue-state properties, immediate and bus-first settle, Info by devpath, Trigger(add, net) observed via the DeviceProcessed signal, and RulesReload -- driven by dummy interface hotplug like keventd.sh. New call-ss and call-u client modes, and getprop learns the b and t variants. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
3 files changed
+174
-1
No files matched your search
@@ -83,6 +83,7 @@ EXTRA_DIST += dbus-service.sh
|
||||
EXTRA_DIST += dbus-cond.sh
|
||||
EXTRA_DIST += dbus-initctl.sh
|
||||
EXTRA_DIST += dbus-introspect.sh
|
||||
EXTRA_DIST += dbus-device.sh
|
||||
|
||||
AM_TESTS_ENVIRONMENT = SYSROOT='$(abs_builddir)/sysroot/';
|
||||
AM_TESTS_ENVIRONMENT += export SYSROOT;
|
||||
@@ -150,6 +151,9 @@ TESTS += dbus-service.sh
|
||||
TESTS += dbus-cond.sh
|
||||
TESTS += dbus-initctl.sh
|
||||
TESTS += dbus-introspect.sh
|
||||
if KEVENTD
|
||||
TESTS += dbus-device.sh
|
||||
endif
|
||||
TESTS += fuzz-msg-parse.sh
|
||||
# Needs the plugin to bring up the bus, not just the built-in one
|
||||
if BUILD_DBUS_PLUGIN
|
||||
|
||||
Executable
+135
@@ -0,0 +1,135 @@
|
||||
#!/bin/sh
|
||||
# keventd: org.finit.Device1 on /run/keventd/bus.
|
||||
#
|
||||
# Covers the device manager's own bus: introspection, queue-state
|
||||
# properties, Settle, Info by devpath, RulesReload, Trigger, and the
|
||||
# DeviceProcessed signal. Network interfaces are the one device class
|
||||
# the unprivileged sandbox can hotplug, see keventd.sh.
|
||||
|
||||
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"
|
||||
# shellcheck source=/dev/null
|
||||
. "$TEST_DIR/lib/dbus-setup.sh"
|
||||
|
||||
DEVBUS=/run/keventd/bus
|
||||
|
||||
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"
|
||||
|
||||
say "keventd readiness"
|
||||
retry 'assert_ready "keventd"' 50 0.2
|
||||
retry "texec test -S $DEVBUS"
|
||||
|
||||
say "Device1 introspects with methods, properties, and signal"
|
||||
xml=$(texec "$CLIENT" introspect "$DEVBUS" /org/finit/device)
|
||||
for m in Settle Trigger Info RulesReload; do
|
||||
case "$xml" in
|
||||
*"<method name=\"$m\">"*) assert "$m declared" 0 -eq 0 ;;
|
||||
*) fail "$m missing from Device1 XML" ;;
|
||||
esac
|
||||
done
|
||||
case "$xml" in
|
||||
*'<property name="QueueEmpty" type="b"'*'<signal name="DeviceProcessed">'*)
|
||||
assert "QueueEmpty property and DeviceProcessed signal declared" 0 -eq 0 ;;
|
||||
*) fail "property/signal declarations missing: $xml" ;;
|
||||
esac
|
||||
|
||||
say "Queue-state properties are readable"
|
||||
seq1=$(texec "$CLIENT" getprop "$DEVBUS" /org/finit/device \
|
||||
org.finit.Device1 SeqnumProcessed)
|
||||
assert "SeqnumProcessed is numeric (got: $seq1)" "$seq1" -ge 0
|
||||
qe=$(texec "$CLIENT" getprop "$DEVBUS" /org/finit/device \
|
||||
org.finit.Device1 QueueEmpty)
|
||||
case "$qe" in
|
||||
true|false) assert "QueueEmpty reads $qe" 0 -eq 0 ;;
|
||||
*) fail "Unexpected QueueEmpty value: $qe" ;;
|
||||
esac
|
||||
|
||||
say "Device1.Settle answers within its timeout"
|
||||
texec "$CLIENT" call-u "$DEVBUS" /org/finit/device \
|
||||
org.finit.Device1 Settle 15 >/dev/null \
|
||||
|| fail "Settle returned non-zero"
|
||||
assert "Settle completed" 0 -eq 0
|
||||
|
||||
say "Interface add advances SeqnumProcessed and Info answers"
|
||||
run "ip link add dummy0 type dummy"
|
||||
retry 'assert_cond "class/net/dummy0"'
|
||||
seq2=$(texec "$CLIENT" getprop "$DEVBUS" /org/finit/device \
|
||||
org.finit.Device1 SeqnumProcessed)
|
||||
assert "SeqnumProcessed advanced ($seq1 -> $seq2)" "$seq2" -gt "$seq1"
|
||||
|
||||
info=$(texec "$CLIENT" call-s "$DEVBUS" /org/finit/device \
|
||||
org.finit.Device1 Info /devices/virtual/net/dummy0 2>&1) \
|
||||
|| fail "Info failed: $info"
|
||||
assert "Info answered for dummy0" 0 -eq 0
|
||||
|
||||
say "keventd -S settles via the bus"
|
||||
run "/libexec/finit/keventd -S -t 15" || fail "keventd -S failed"
|
||||
assert "bus-first settle ok" 0 -eq 0
|
||||
|
||||
say "Trigger(add, net) re-emits events, DeviceProcessed observed"
|
||||
rm -f /tmp/dbus-dev-sig.out
|
||||
( texec "$CLIENT" monitor-signal "$DEVBUS" \
|
||||
"type='signal',interface='org.finit.Device1',member='DeviceProcessed'" \
|
||||
5000 > /tmp/dbus-dev-sig.out 2>&1 ) &
|
||||
mon_pid=$!
|
||||
sleep 0.5
|
||||
texec "$CLIENT" call-ss "$DEVBUS" /org/finit/device \
|
||||
org.finit.Device1 Trigger add net >/dev/null 2>&1 \
|
||||
|| fail "Trigger returned non-zero"
|
||||
set +e
|
||||
wait "$mon_pid"
|
||||
mon_rc=$?
|
||||
set -e
|
||||
assert "monitor saw DeviceProcessed (rc=$mon_rc)" "$mon_rc" -eq 0
|
||||
case "$(cat /tmp/dbus-dev-sig.out)" in
|
||||
*"DeviceProcessed"*net*) assert "Signal payload names a net device" 0 -eq 0 ;;
|
||||
*) fail "Unexpected signal output: $(cat /tmp/dbus-dev-sig.out)" ;;
|
||||
esac
|
||||
|
||||
say "RulesReload succeeds and Trigger rejects a bogus action"
|
||||
texec "$CLIENT" call-void "$DEVBUS" /org/finit/device \
|
||||
org.finit.Device1 RulesReload >/dev/null \
|
||||
|| fail "RulesReload failed"
|
||||
assert "RulesReload ok" 0 -eq 0
|
||||
|
||||
set +e
|
||||
texec "$CLIENT" call-ss "$DEVBUS" /org/finit/device \
|
||||
org.finit.Device1 Trigger frobnicate "" >/tmp/dbus-trg.out 2>&1
|
||||
trg_rc=$?
|
||||
set -e
|
||||
assert "Bogus action rejected (rc=$trg_rc)" "$trg_rc" -eq 1
|
||||
case "$(cat /tmp/dbus-trg.out)" in
|
||||
*InvalidArgs*) assert "Error is InvalidArgs" 0 -eq 0 ;;
|
||||
*) fail "Unexpected reply: $(cat /tmp/dbus-trg.out)" ;;
|
||||
esac
|
||||
|
||||
say "Device1.RulesReload from non-root is rejected with AccessDenied"
|
||||
texec chmod 0666 "$DEVBUS"
|
||||
set +e
|
||||
texec "$CLIENT" call-void-as-uid 1 "$DEVBUS" /org/finit/device \
|
||||
org.finit.Device1 RulesReload >/tmp/dbus-devauthz.out 2>&1
|
||||
dauthz_rc=$?
|
||||
set -e
|
||||
assert "Non-root RulesReload rejected (rc=$dauthz_rc)" "$dauthz_rc" -eq 1
|
||||
case "$(cat /tmp/dbus-devauthz.out)" in
|
||||
*AccessDenied*) assert "Device1 authz fires" 0 -eq 0 ;;
|
||||
*) fail "Unexpected reply: $(cat /tmp/dbus-devauthz.out)" ;;
|
||||
esac
|
||||
@@ -342,6 +342,24 @@ static int do_call_u(const char *sock, const char *obj, const char *iface,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mode_call_ss(int argc, char *argv[])
|
||||
{
|
||||
link_client_t *c;
|
||||
int rc;
|
||||
|
||||
if (argc != 8) return 2;
|
||||
c = link_client_open(argv[2]);
|
||||
if (!c) return 2;
|
||||
|
||||
rc = link_client_call_v(c, argv[3], argv[4], argv[5],
|
||||
"ss", argv[6], argv[7]);
|
||||
rc = report_rc(c, rc);
|
||||
if (rc == 0)
|
||||
printf("OK\n");
|
||||
link_client_close(c);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mode_call_u(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 7) return 2;
|
||||
@@ -409,7 +427,7 @@ static int mode_get_service(int argc, char *argv[])
|
||||
|
||||
/*
|
||||
* getprop BUS PATH IFACE PROP -- Properties.Get, prints the variant
|
||||
* value; dispatches on the wire signature, "s" and "u" supported.
|
||||
* value; dispatches on the wire signature: s, u, b, and t.
|
||||
*/
|
||||
static int mode_getprop(int argc, char *argv[])
|
||||
{
|
||||
@@ -439,6 +457,21 @@ static int mode_getprop(int argc, char *argv[])
|
||||
printf("%s\n", s);
|
||||
else if (type == 'u' && link_r_u32(&reader, &u) == 0)
|
||||
printf("%u\n", u);
|
||||
else if (type == 'b') {
|
||||
int b;
|
||||
|
||||
if (link_r_bool(&reader, &b) == 0)
|
||||
printf("%s\n", b ? "true" : "false");
|
||||
else
|
||||
rc = 2;
|
||||
} else if (type == 't') {
|
||||
uint64_t t;
|
||||
|
||||
if (link_r_u64(&reader, &t) == 0)
|
||||
printf("%llu\n", (unsigned long long)t);
|
||||
else
|
||||
rc = 2;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "unsupported variant type '%c'\n", type);
|
||||
rc = 2;
|
||||
@@ -547,6 +580,7 @@ int main(int argc, char *argv[])
|
||||
if (!strcmp(argv[1], "introspect")) return mode_introspect (argc, argv);
|
||||
if (!strcmp(argv[1], "liststrings")) return mode_liststrings (argc, argv);
|
||||
if (!strcmp(argv[1], "call-s")) return mode_call_s (argc, argv);
|
||||
if (!strcmp(argv[1], "call-ss")) return mode_call_ss (argc, argv);
|
||||
if (!strcmp(argv[1], "call-u")) return mode_call_u (argc, argv);
|
||||
if (!strcmp(argv[1], "call-su")) return mode_call_su (argc, argv);
|
||||
if (!strcmp(argv[1], "call-void")) return mode_call_void (argc, argv);
|
||||
|
||||
Reference in new issue
Block a user