App-OpenHAP
view release on metacpan or search on metacpan
t/openhap/integration/sandbox.t view on Meta::CPAN
#!/usr/bin/env perl
# ex:ts=8 sw=4:
# Integration test: the daemon really pledges and unveils.
#
# A pledge violation kills the process. Thus a correctly pledged
# daemon and a completely unpledged one both satisfy "the daemon is
# alive and its trace shows no violation". That check is a null
# test. The syscall itself is observable. This file traces the
# daemon from exec with ktrace(1). It asserts that the daemon calls
# pledge(2) with exactly the production promise set. It asserts that
# the daemon calls unveil(2) for the inventory and then locks the
# view. It asserts that startup still succeeds in the configurations
# that worked before the sandbox existed. If you remove the pledge
# or unveil call from bin/openhapd, the corresponding syscall is
# absent from the trace.
#
# The Fugu repository's sandbox test proves the enforcement
# semantics: a violation aborts, and a path outside the view is
# unreachable. No operator-supplied read path exists to probe
# enforcement through the running daemon itself. Thus this file
# deliberately makes no such probe. The trace proves the daemon's
# participation. The unit tier proves the kernel's.
#
# The inventory itself lives in bin/openhapd, beside the pledge
# policy. A script is not loadable, so no unit test can call the
# builder. This file holds that coverage instead, and it holds it
# better: the trace shows the rows the kernel really got.
use v5.36;
use Test::More;
use FindBin qw($RealBin);
use lib "$RealBin/../../../lib";
use App::OpenHAP::Test::Integration;
use Time::HiRes qw(sleep);
my $env = App::OpenHAP::Test::Integration->new;
$env->setup;
my $config_file = '/etc/openhapd.conf';
my $trace = "/tmp/openhapd-ktrace-$$";
my $daemon = -x '/usr/local/bin/openhapd'
? '/usr/local/bin/openhapd'
: '/usr/local/sbin/openhapd';
# The traced instance needs the HAP port. Stop the rc daemon first.
system('rcctl stop openhapd >/dev/null 2>&1');
sleep 1;
# Run the daemon in the foreground under ktrace. The -i flag follows
# any children. There must be none, and the test asserts that below.
# Invoke perl on the script directly. The daemon's #!/usr/bin/env
# shebang would put env in the trace. env pledges "stdio exec"
# itself, and that would poison the promise assertions below.
my $pid = fork // die "fork: $!";
if ($pid == 0) {
exec 'ktrace', '-i', '-f', $trace, $^X, $daemon, '-f', '-c',
$config_file;
die "exec ktrace: $!";
}
ok($env->wait_for_hap_port, 'traced daemon serves HAP')
or diag 'daemon did not open the HAP port under ktrace';
# No child processes while it runs. This is phase 2's contract. It
# keeps proc/exec out of the promise set.
chomp(my $children = `pgrep -P $pid 2>/dev/null`);
( run in 1.064 second using v1.01-cache-2.11-cpan-14f38c9f855 )