Files
finit/test/conf-provides.sh
Joachim Wiberg 6b77a16f8b conf: add missing passenv to tty blocks
The line-based format has had the flag since v4.4 (issue #286), where
it prepends -p to the built-in getty, which turns it into login -p and
passes the environment on.  The block format was written from the three
documented tty variants and the flags listed in the tty documentation,
and passenv was in neither, so it was left out.  Converting a tty line
that used it therefore lost it, with nothing said.

It only reaches the built-in getty.  An external getty is handed its
arguments through command, so there is nowhere to put a -p, and the
setting is refused with a warning rather than quietly ignored.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-05 17:59:11 +02:00

138 lines
5.2 KiB
Bash
Executable File

#!/bin/sh
# Verify 'provides': a block asserts conditions beyond its own
# pid/<ident>, so variants with distinct titles can supply one
# barrier. A claim on a condition somebody already owns is refused,
# with the service itself still registered.
set -eu
TEST_DIR=$(dirname "$0")
# shellcheck disable=SC2034
# Only the udev variant qualifies, mdevd is not a known service here,
# so syslogd:udev is the one that gets to supply pid/syslogd.
BOOTSTRAP="service anchor {
runlevel = \"S12345\"
command = \"serv -np -i anchor\"
}
service syslogd:udev {
runlevel = \"S12345\"
if = \"anchor\"
provides = \"pid/syslogd\"
command = \"serv -np -i sysudev\"
}
service syslogd:mdev {
runlevel = \"S12345\"
if = \"mdevd\"
provides = \"pid/syslogd\"
command = \"serv -np -i sysmdev\"
}
service downstream {
runlevel = \"S12345\"
conditions = { \"pid/syslogd\" }
command = \"serv -np -i downstream\"
}"
# The IDENT column of 'initctl cond dump' names the owner of a
# condition, which for a provided one is the service that claimed it.
assert_provider()
{
assert "Condition $1 provided by $2" \
"$(texec initctl cond dump | awk -v c="<$1>" '$4 == c {print $2}')" = "$2"
}
test_teardown()
{
say "Running test teardown."
run "rm -f $FINIT_CONF"
}
# shellcheck source=/dev/null
. "$TEST_DIR/lib/setup.sh"
say 'The qualifying variant is loaded, the other is pruned by if'
retry 'assert_status syslogd:udev running'
assert_loaded syslogd:mdev 0
say 'It asserts the condition it provides, on top of its own'
retry 'assert_cond pid/syslogd'
assert_cond pid/syslogd:udev
say 'A service waiting on the provided condition starts'
retry 'assert_status downstream running'
say 'initctl cond dump names the provider, not "unknown"'
assert_provider pid/syslogd syslogd:udev
say 'Stopping the provider clears what it provided'
run "initctl stop syslogd:udev"
retry 'assert_nocond pid/syslogd'
run "initctl start syslogd:udev"
retry 'assert_cond pid/syslogd'
# With a BOOTSTRAP the test is released in runlevel S, where a reload
# is ignored, so wait for the runlevel change before rewriting.
say 'Waiting for bootstrap to finish before rewriting the configuration'
retry "test \"\$(texec sh -c \"initctl runlevel | awk '{print \\\$2;}'\")\" = 2" 20 1
# The claim is refused, but the service is still registered and runs.
# Both blocks qualify here, which is the configuration bug the warning
# exists for.
say 'A second claim on the same condition is refused, the service still runs'
run "echo 'service first {' > $FINIT_CONF"
run "echo ' provides = \"usr/barrier\"' >> $FINIT_CONF"
run "echo ' command = \"serv -np -i first\"' >> $FINIT_CONF"
run "echo '}' >> $FINIT_CONF"
run "echo 'service second {' >> $FINIT_CONF"
run "echo ' provides = \"usr/barrier\"' >> $FINIT_CONF"
run "echo ' command = \"serv -np -i second\"' >> $FINIT_CONF"
run "echo '}' >> $FINIT_CONF"
run "initctl reload"
retry 'assert_status first running'
assert_status second running
assert_provider usr/barrier first
# A real service by that identity outranks a claim on it.
say 'An identity beats a claim on the same condition'
run "echo 'service realsvc {' > $FINIT_CONF"
run "echo ' command = \"serv -np -i realsvc\"' >> $FINIT_CONF"
run "echo '}' >> $FINIT_CONF"
run "echo 'service pretender {' >> $FINIT_CONF"
run "echo ' provides = \"pid/realsvc\"' >> $FINIT_CONF"
run "echo ' command = \"serv -np -i pretender\"' >> $FINIT_CONF"
run "echo '}' >> $FINIT_CONF"
run "initctl reload"
retry 'assert_status pretender running'
assert_provider pid/realsvc realsvc
say 'A value without a namespace is rejected, the service still runs'
run "echo 'service nonamespace {' > $FINIT_CONF"
run "echo ' provides = \"syslogd\"' >> $FINIT_CONF"
run "echo ' command = \"serv -np -i nonamespace\"' >> $FINIT_CONF"
run "echo '}' >> $FINIT_CONF"
run "initctl reload"
retry 'assert_status nonamespace running'
# Claims are dropped before the .conf files are re-read, so a service
# re-registering cannot lose to a claim another one has not yet
# dropped. Without that, ownership flips on every reload.
say 'Ownership survives a reload, it does not flip between variants'
run "echo 'service keeper {' > $FINIT_CONF"
run "echo ' provides = \"usr/kept\"' >> $FINIT_CONF"
run "echo ' command = \"serv -np -i keeper\"' >> $FINIT_CONF"
run "echo '}' >> $FINIT_CONF"
run "echo 'service loser {' >> $FINIT_CONF"
run "echo ' provides = \"usr/kept\"' >> $FINIT_CONF"
run "echo ' command = \"serv -np -i loser\"' >> $FINIT_CONF"
run "echo '}' >> $FINIT_CONF"
run "initctl reload"
retry 'assert_provider usr/kept keeper'
run "initctl reload"
retry 'assert_provider usr/kept keeper'
run "initctl reload"
retry 'assert_provider usr/kept keeper'