init
This commit is contained in:
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
if {$argc != 1} {
|
||||
puts stderr "usage: boot.exp RUNNER"
|
||||
exit 2
|
||||
}
|
||||
|
||||
set runner [file normalize [lindex $argv 0]]
|
||||
set timeout 30
|
||||
set acceptance_name "boot"
|
||||
source [file join [file dirname [info script]] harness.exp]
|
||||
|
||||
proc boot_mouse {runner} {
|
||||
global spawn_id
|
||||
spawn -noecho $runner
|
||||
await_exact "Cheesed to meet you! v0.1.0" "the cheesed startup banner"
|
||||
await_exact "cheesed: base bootstrap complete; cheesed is PID 1" "PID 1 confirmation"
|
||||
await_exact "MOUSE 0.1.0 (x86_64)" "the MOUSE login banner"
|
||||
await_exact "mouse:~# " "the root shell prompt"
|
||||
}
|
||||
|
||||
boot_mouse $runner
|
||||
|
||||
send -- "hostname\r"
|
||||
await_exact "mouse\r" "the configured hostname"
|
||||
await_exact "mouse:~# " "the prompt after hostname"
|
||||
|
||||
send -- "cat /proc/1/comm\r"
|
||||
await_exact "cheesed\r" "cheesed in /proc/1"
|
||||
await_exact "mouse:~# " "the prompt after the PID 1 check"
|
||||
|
||||
send -- "sh -c 'test -c /dev/null'; echo DEV_STATUS_\$?\r"
|
||||
await_exact "DEV_STATUS_0\r" "a mounted devtmpfs"
|
||||
await_exact "mouse:~# " "the prompt after the devtmpfs check"
|
||||
|
||||
send -- "clear; echo CLEAR_STATUS_\$?\r"
|
||||
await_exact "CLEAR_STATUS_0\r" "a successful clear command"
|
||||
await_exact "mouse:~# " "the prompt after clear"
|
||||
|
||||
send -- {sh -c 'i=0; while [ "$i" -lt 8 ]; do (sleep 1) & i=$((i + 1)); done'}
|
||||
send -- "\r"
|
||||
await_exact "mouse:~# " "the prompt after starting orphan probes"
|
||||
await_exact "cheesed: reaped orphan PID " "PID 1 orphan reaping"
|
||||
|
||||
send -- "sleep 2\r"
|
||||
await_exact "mouse:~# " "all orphan probes to exit"
|
||||
send -- {sh -c 'if grep -l ") Z " /proc/[0-9]*/stat >/dev/null; then hostname; else cat /proc/1/comm; fi'}
|
||||
send -- "\r"
|
||||
await_exact "cheesed\r" "a zombie-free process table"
|
||||
await_exact "mouse:~# " "the prompt after the zombie check"
|
||||
|
||||
send -- "kill -TERM 1\r"
|
||||
await_exact "cheesed: received poweroff request" "the poweroff request"
|
||||
await_clean_exit "poweroff"
|
||||
|
||||
boot_mouse $runner
|
||||
send -- "kill -INT 1\r"
|
||||
await_exact "cheesed: received reboot request" "the reboot request"
|
||||
await_clean_exit "reboot"
|
||||
|
||||
puts "boot acceptance tests passed"
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$acceptance_dir/harness.sh"
|
||||
acceptance_init
|
||||
acceptance_require_commands "the boot acceptance test" expect
|
||||
acceptance_copy_disk boot
|
||||
|
||||
MOUSE_KERNEL_ARGS="console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1 quiet loglevel=3"
|
||||
MOUSE_BOOT_MODE=disk
|
||||
MOUSE_DISK_IMAGE="$test_disk"
|
||||
MOUSE_NETWORK=0
|
||||
export MOUSE_KERNEL_ARGS
|
||||
export MOUSE_BOOT_MODE
|
||||
export MOUSE_DISK_IMAGE
|
||||
export MOUSE_NETWORK
|
||||
|
||||
exec expect "$acceptance_dir/boot.exp" "$runner"
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
if {$argc != 3} {
|
||||
puts stderr "usage: btrfs.exp RUNNER DISK MODE"
|
||||
exit 2
|
||||
}
|
||||
|
||||
set runner [file normalize [lindex $argv 0]]
|
||||
set disk [file normalize [lindex $argv 1]]
|
||||
set mode [lindex $argv 2]
|
||||
if {$mode ni {first alternate rollback powerloss-stage powerloss-verify}} {
|
||||
puts stderr "invalid btrfs mode: $mode"
|
||||
exit 2
|
||||
}
|
||||
set timeout 180
|
||||
set acceptance_name "btrfs"
|
||||
source [file join [file dirname [info script]] harness.exp]
|
||||
|
||||
acceptance_log
|
||||
set env(MOUSE_DISK_IMAGE) $disk
|
||||
set env(MOUSE_MEMORY) 1G
|
||||
|
||||
set env(MOUSE_BOOT_MODE) disk
|
||||
set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1"
|
||||
spawn -noecho $runner
|
||||
|
||||
await_exact "cheesed: base bootstrap complete; cheesed is PID 1" "PID 1 confirmation"
|
||||
await_exact "mouse login: root (automatic login)" "the serial login"
|
||||
await_prompt
|
||||
sendline {sh -c "grep -Eq '^[^ ]+ / btrfs ' /proc/mounts && grep -Eq '^[^ ]+ /usr/local btrfs ' /proc/mounts && grep -Eq '^[^ ]+ /var btrfs ' /proc/mounts && grep -Eq '^[^ ]+ /home btrfs ' /proc/mounts && grep -Eq '^[^ ]+ /srv btrfs ' /proc/mounts"; echo MOUNTS_$?}
|
||||
await_exact "MOUNTS_0\r" "the btrfs root and persistent subvolume mounts"
|
||||
await_exact "mouse:~# " "the prompt after mount verification"
|
||||
sendline {btrfs version; echo VERSION_$?}
|
||||
await_exact "btrfs-progs v7.0\r" "the pinned btrfs userspace version"
|
||||
await_exact "VERSION_0\r" "the btrfs version status"
|
||||
await_exact "mouse:~# " "the prompt after version"
|
||||
|
||||
if {$mode in {first powerloss-stage}} {
|
||||
sendline {sh -c 'test "$(cat /etc/mouse-boot-environment)" = default && mkdir -p /var/lib/mouse /home/mouse-state /usr/local/share/mouse /srv/mouse && echo base-default >/etc/bootenv-state && echo var-shared >/var/lib/mouse/state && echo home-shared >/home/mouse-state/value && echo local-shared >/usr/local/share/mouse/state && echo srv-shared >/srv/mouse/state'; echo WRITE_$?}
|
||||
await_exact "WRITE_0\r" "boot-environment and persistent state creation"
|
||||
await_exact "mouse:~# " "the prompt after state creation"
|
||||
sendline {mouse-bootenv prepare; echo PREPARE_$?}
|
||||
await_exact "alternate is ready for an update\r" "the inactive snapshot preparation"
|
||||
await_exact "PREPARE_0\r" "the preparation status"
|
||||
await_exact "mouse:~# " "the prompt after preparation"
|
||||
sendline {sh -c 'echo alternate-updated >/run/mouse-root/ROOT/alternate/etc/bootenv-state'; mouse-bootenv activate alternate; echo ACTIVATE_$?}
|
||||
await_exact "alternate will boot next\r" "the alternate activation"
|
||||
await_exact "ACTIVATE_0\r" "the activation status"
|
||||
if {$mode eq "powerloss-stage"} {
|
||||
exec kill -KILL [exp_pid]
|
||||
expect eof
|
||||
catch wait
|
||||
puts "power-loss interruption staged"
|
||||
exit 0
|
||||
}
|
||||
} elseif {$mode in {alternate powerloss-verify}} {
|
||||
sendline {sh -c 'test "$(cat /etc/mouse-boot-environment)" = alternate && test "$(cat /etc/bootenv-state)" = alternate-updated && test "$(cat /var/lib/mouse/state)" = var-shared && test "$(cat /home/mouse-state/value)" = home-shared && test "$(cat /usr/local/share/mouse/state)" = local-shared && test "$(cat /srv/mouse/state)" = srv-shared'; echo ALTERNATE_$?}
|
||||
await_exact "ALTERNATE_0\r" "the alternate root and shared persistent state"
|
||||
if {$mode eq "alternate"} {
|
||||
await_exact "mouse:~# " "the prompt after alternate verification"
|
||||
sendline {mouse-bootenv rollback; echo ROLLBACK_$?}
|
||||
await_exact "default will boot next\r" "the default rollback activation"
|
||||
await_exact "ROLLBACK_0\r" "the rollback status"
|
||||
}
|
||||
} else {
|
||||
sendline {sh -c 'test "$(cat /etc/mouse-boot-environment)" = default && test "$(cat /etc/bootenv-state)" = base-default && test "$(cat /var/lib/mouse/state)" = var-shared && test "$(cat /home/mouse-state/value)" = home-shared && test "$(cat /usr/local/share/mouse/state)" = local-shared && test "$(cat /srv/mouse/state)" = srv-shared'; echo DEFAULT_$?}
|
||||
await_exact "DEFAULT_0\r" "the rolled-back root and shared persistent state"
|
||||
}
|
||||
await_exact "mouse:~# " "the prompt before poweroff"
|
||||
poweroff
|
||||
puts "$mode btrfs acceptance passed"
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$acceptance_dir/harness.sh"
|
||||
acceptance_init
|
||||
acceptance_require_commands "the btrfs acceptance test" expect
|
||||
acceptance_copy_disk btrfs
|
||||
|
||||
"$acceptance_dir/btrfs.exp" "$runner" "$test_disk" first
|
||||
"$acceptance_dir/btrfs.exp" "$runner" "$test_disk" alternate
|
||||
"$acceptance_dir/btrfs.exp" "$runner" "$test_disk" rollback
|
||||
|
||||
powerloss_disk="$temporary/mouse-disk-powerloss.img"
|
||||
acceptance_clone_disk "$build_dir/mouse-disk.img" "$powerloss_disk"
|
||||
"$acceptance_dir/btrfs.exp" "$runner" "$powerloss_disk" powerloss-stage
|
||||
"$acceptance_dir/btrfs.exp" "$runner" "$powerloss_disk" powerloss-verify
|
||||
|
||||
printf '%s\n' \
|
||||
"btrfs root, boot-environment, and power-loss acceptance tests passed"
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
if {$argc != 3} {
|
||||
puts stderr "usage: firmware.exp RUNNER LABEL CHECK"
|
||||
exit 2
|
||||
}
|
||||
|
||||
set runner [file normalize [lindex $argv 0]]
|
||||
set label [lindex $argv 1]
|
||||
set check [lindex $argv 2]
|
||||
set timeout 90
|
||||
set acceptance_name "firmware-$check"
|
||||
source [file join [file dirname [info script]] harness.exp]
|
||||
|
||||
acceptance_log
|
||||
spawn -noecho $runner
|
||||
await_exact "Cheesed to meet you! v0.1.0" "MOUSE through the Limine firmware path"
|
||||
await_exact "mouse login: " "the authenticated firmware-boot login"
|
||||
sendline {root}
|
||||
await_exact "Password: " "the root password prompt"
|
||||
sendline {cheddar}
|
||||
await_exact "mouse:~# " "the root shell"
|
||||
switch -- $check {
|
||||
raw-virtio {
|
||||
set check_command {[ -e /sys/block/vda ]}
|
||||
}
|
||||
raw-sata {
|
||||
set check_command {[ -e /sys/block/sda ]}
|
||||
}
|
||||
raw-uefi-sata {
|
||||
set check_command {[ -d /sys/firmware/efi ] && [ -e /sys/block/sda ]}
|
||||
}
|
||||
raw-uefi-nvme {
|
||||
set check_command {[ -d /sys/firmware/efi ] && [ -e /sys/block/nvme0n1 ]}
|
||||
}
|
||||
default {
|
||||
puts stderr "unknown firmware check: $check"
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
sendline "sh -c 'grep -q \"root=PARTUUID=4d4f5553-4500-4000-8000-000000000002\" /proc/cmdline && grep -Eq \"^\[^ \]+ / btrfs \" /proc/mounts && $check_command'; echo FIRMWARE_\$?"
|
||||
await_exact "FIRMWARE_0\r" "the GPT, Limine, PARTUUID, and Btrfs boot contract"
|
||||
await_exact "mouse:~# " "the prompt after firmware verification"
|
||||
poweroff
|
||||
|
||||
puts "$label acceptance passed"
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$acceptance_dir/harness.sh"
|
||||
acceptance_init
|
||||
acceptance_require_commands "the firmware acceptance test" expect
|
||||
acceptance_require_file \
|
||||
"$build_dir/mouse-disk.img" \
|
||||
"run 'make check' before checking BIOS firmware"
|
||||
acceptance_require_file \
|
||||
"$build_dir/ovmf-code.fd" \
|
||||
"run 'make check' before checking UEFI firmware"
|
||||
acceptance_make_temporary firmware
|
||||
|
||||
raw_disk="$temporary/mouse-disk.img"
|
||||
acceptance_clone_disk "$build_dir/mouse-disk.img" "$raw_disk"
|
||||
|
||||
run_firmware()
|
||||
{
|
||||
label=$1
|
||||
check=$2
|
||||
disk=$3
|
||||
bus=$4
|
||||
firmware=$5
|
||||
|
||||
MOUSE_BOOT_MODE=firmware \
|
||||
MOUSE_DISK_IMAGE="$disk" \
|
||||
MOUSE_DISK_BUS="$bus" \
|
||||
MOUSE_FIRMWARE="$firmware" \
|
||||
MOUSE_UEFI_CODE="$build_dir/ovmf-code.fd" \
|
||||
MOUSE_MEMORY="${MOUSE_MEMORY:-1G}" \
|
||||
expect "$acceptance_dir/firmware.exp" "$runner" "$label" "$check"
|
||||
}
|
||||
|
||||
run_firmware "BIOS raw VirtIO" raw-virtio \
|
||||
"$raw_disk" virtio bios
|
||||
run_firmware "BIOS raw AHCI" raw-sata \
|
||||
"$raw_disk" sata bios
|
||||
run_firmware "UEFI raw AHCI" raw-uefi-sata \
|
||||
"$raw_disk" sata uefi
|
||||
run_firmware "UEFI raw NVMe" raw-uefi-nvme \
|
||||
"$raw_disk" nvme uefi
|
||||
|
||||
printf '%s\n' "BIOS and UEFI firmware acceptance passed"
|
||||
@@ -0,0 +1,73 @@
|
||||
if {![info exists acceptance_name]} {
|
||||
puts stderr "acceptance harness requires acceptance_name"
|
||||
exit 2
|
||||
}
|
||||
|
||||
proc fail {message} {
|
||||
global acceptance_name
|
||||
puts stderr "$acceptance_name acceptance failed: $message"
|
||||
exit 1
|
||||
}
|
||||
|
||||
proc await_exact {value description} {
|
||||
expect {
|
||||
-exact $value { return }
|
||||
timeout { fail "timed out waiting for $description" }
|
||||
eof { fail "QEMU exited while waiting for $description" }
|
||||
}
|
||||
}
|
||||
|
||||
proc await {value description} {
|
||||
await_exact $value $description
|
||||
}
|
||||
|
||||
proc await_regexp {value description} {
|
||||
expect {
|
||||
-re $value { return }
|
||||
timeout { fail "timed out waiting for $description" }
|
||||
eof { fail "QEMU exited while waiting for $description" }
|
||||
}
|
||||
}
|
||||
|
||||
proc sendline {line} {
|
||||
send -- $line
|
||||
send -- "\r"
|
||||
}
|
||||
|
||||
proc prompt {} {
|
||||
await_exact "mouse:~# " "the root prompt"
|
||||
}
|
||||
|
||||
proc await_prompt {} {
|
||||
send -- "\r"
|
||||
await_exact "mouse:~# " "the root prompt"
|
||||
}
|
||||
|
||||
proc await_clean_exit {action} {
|
||||
expect {
|
||||
eof {
|
||||
set result [wait]
|
||||
set status [lindex $result 3]
|
||||
if {$status != 0} {
|
||||
fail "QEMU exited with status $status after $action"
|
||||
}
|
||||
}
|
||||
timeout { fail "QEMU did not exit after $action" }
|
||||
}
|
||||
}
|
||||
|
||||
proc poweroff {} {
|
||||
sendline {poweroff}
|
||||
await_exact "cheesed: received poweroff request" "the poweroff request"
|
||||
await_exact "cheesed: root filesystem remounted read-only" "the read-only root remount"
|
||||
await_clean_exit "poweroff"
|
||||
}
|
||||
|
||||
proc acceptance_log {} {
|
||||
global env
|
||||
if {[info exists env(MOUSE_EXPECT_LOG)]} {
|
||||
log_user 1
|
||||
} else {
|
||||
log_user 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
|
||||
acceptance_init() {
|
||||
acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
repo_dir=$(CDPATH= cd -- "$acceptance_dir/../.." && pwd)
|
||||
runner="$repo_dir/scripts/run-qemu.sh"
|
||||
build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build"}
|
||||
temporary=
|
||||
}
|
||||
|
||||
acceptance_require_commands() {
|
||||
description=$1
|
||||
shift
|
||||
for command in "$@"; do
|
||||
if ! command -v "$command" >/dev/null 2>&1; then
|
||||
printf '%s\n' "$command is required for $description" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
acceptance_require_file() {
|
||||
path=$1
|
||||
instruction=$2
|
||||
if [ ! -f "$path" ]; then
|
||||
printf '%s\n' "$instruction" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
acceptance_cleanup_extra() {
|
||||
:
|
||||
}
|
||||
|
||||
acceptance_cleanup() {
|
||||
acceptance_cleanup_extra
|
||||
if [ -n "$temporary" ] && [ -d "$temporary" ]; then
|
||||
rm -rf "$temporary"
|
||||
fi
|
||||
}
|
||||
|
||||
acceptance_make_temporary() {
|
||||
name=$1
|
||||
temporary=$(mktemp -d "${TMPDIR:-/tmp}/mouse-$name.XXXXXX")
|
||||
trap acceptance_cleanup EXIT HUP INT TERM
|
||||
}
|
||||
|
||||
acceptance_copy_disk() {
|
||||
name=$1
|
||||
description=${2:-$1}
|
||||
base_disk="$build_dir/mouse-disk.img"
|
||||
acceptance_require_file \
|
||||
"$base_disk" \
|
||||
"run 'make check' before checking $description"
|
||||
acceptance_make_temporary "$name"
|
||||
test_disk="$temporary/mouse-disk.img"
|
||||
acceptance_clone_disk "$base_disk" "$test_disk"
|
||||
}
|
||||
|
||||
acceptance_clone_disk() {
|
||||
source=$1
|
||||
destination=$2
|
||||
if [ "$(uname -s)" = Darwin ] && cp -c "$source" "$destination" 2>/dev/null; then
|
||||
return
|
||||
fi
|
||||
cp "$source" "$destination"
|
||||
}
|
||||
Executable
+99
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
if {$argc != 3} {
|
||||
puts stderr "usage: multi-user.exp RUNNER DISK MODE"
|
||||
exit 2
|
||||
}
|
||||
set runner [file normalize [lindex $argv 0]]
|
||||
set disk [file normalize [lindex $argv 1]]
|
||||
set mode [lindex $argv 2]
|
||||
if {$mode ni {provision login verify}} {
|
||||
puts stderr "invalid multi-user mode: $mode"
|
||||
exit 2
|
||||
}
|
||||
set timeout 75
|
||||
set acceptance_name "multi-user"
|
||||
source [file join [file dirname [info script]] harness.exp]
|
||||
|
||||
acceptance_log
|
||||
set env(MOUSE_BOOT_MODE) disk
|
||||
set env(MOUSE_DISK_IMAGE) $disk
|
||||
set env(MOUSE_NETWORK) 0
|
||||
if {$mode eq "provision"} {
|
||||
set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1 quiet loglevel=3"
|
||||
} else {
|
||||
set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed panic=-1 quiet loglevel=3"
|
||||
}
|
||||
spawn -noecho $runner
|
||||
|
||||
if {$mode eq "provision"} {
|
||||
await "mouse login: root (automatic login)" "the provisioning login"
|
||||
await "mouse:~# " "the provisioning shell"
|
||||
sendline {groupadd -R /run/mouse-root/ROOT/default operators; useradd -R /run/mouse-root/ROOT/default -M -g operators -s /bin/tcsh alice; mkdir /run/mouse-root/home/alice; chown 1000:1000 /run/mouse-root/home/alice; echo CREATE_$status}
|
||||
await "CREATE_0\r" "account creation"
|
||||
await "mouse:~# " "the provisioning prompt"
|
||||
sendline {sh -c 'grep -q "^root:x:0:0:root:/root:/bin/sh$" /run/mouse-root/ROOT/default/etc/passwd && grep -q "^toor:x:0:0:BSD-style root account:/root:/bin/tcsh$" /run/mouse-root/ROOT/default/etc/passwd'; echo ADMIN_$status}
|
||||
await "ADMIN_0\r" "the BSD-style administrator accounts"
|
||||
await "mouse:~# " "the provisioning prompt"
|
||||
sendline {sh -c 'usermod -R /run/mouse-root/ROOT/default -p "$(head -n 1 /run/mouse-root/ROOT/default/etc/shadow | cut -d: -f2)" alice'; echo PASSWORD_$status}
|
||||
await "PASSWORD_0\r" "the alternate-root password setup"
|
||||
await "mouse:~# " "the provisioning prompt"
|
||||
sendline {sh -c 'test "$(grep "^alice:" /run/mouse-root/ROOT/default/etc/shadow | cut -d: -f2)" = "$(head -n 1 /run/mouse-root/ROOT/default/etc/shadow | cut -d: -f2)" && grep -q "^alice:x:1000:1000::/home/alice:/bin/tcsh$" /run/mouse-root/ROOT/default/etc/passwd'; echo ACCOUNT_$status}
|
||||
await "ACCOUNT_0\r" "the on-disk login account"
|
||||
await "mouse:~# " "the provisioning prompt"
|
||||
sendline {echo enable_mouse_echo=YES >/run/mouse-root/ROOT/default/etc/rc.conf; echo enable_network=NO >>/run/mouse-root/ROOT/default/etc/rc.conf; echo POLICY_$status}
|
||||
await "POLICY_0\r" "the offline test policy"
|
||||
await "mouse:~# " "the provisioning prompt"
|
||||
poweroff
|
||||
puts "account provisioning acceptance passed"
|
||||
exit 0
|
||||
}
|
||||
|
||||
await "mouse login: " "the authenticated login prompt"
|
||||
set timeout 2
|
||||
expect {
|
||||
-exact "root (automatic login)" { fail "normal disk enabled root autologin" }
|
||||
timeout {}
|
||||
}
|
||||
set timeout 75
|
||||
sendline {alice}
|
||||
await "Password: " "the password prompt"
|
||||
if {$mode eq "login"} {
|
||||
sendline {wrong-password}
|
||||
await "Login incorrect" "failed authentication rejection"
|
||||
await "mouse login: " "the retry login prompt"
|
||||
sendline {alice}
|
||||
await "Password: " "the second password prompt"
|
||||
}
|
||||
sendline {cheddar}
|
||||
await "mouse:~> " "the ordinary user shell"
|
||||
sendline {id}
|
||||
await "uid=1000(alice) gid=1000(operators) groups=1000(operators)\r" "the ordinary identity"
|
||||
await "mouse:~> " "the user prompt"
|
||||
sendline {sh -c 'test "$HOME" = /home/alice && test "$SHELL" = /bin/tcsh && test -O /home/alice && ! touch /usr/alice-must-not-write'; echo USER_$status}
|
||||
await "USER_0\r" "home ownership and base protection"
|
||||
await "mouse:~> " "the user prompt"
|
||||
sendline {su - root}
|
||||
await "Password: " "the explicit elevation password"
|
||||
sendline {cheddar}
|
||||
await "mouse:~# " "the elevated root shell"
|
||||
sendline {id}
|
||||
await "uid=0(root) gid=0(root) groups=0(root)\r" "authorised root elevation"
|
||||
await "mouse:~# " "the root prompt"
|
||||
sendline {sh -c 'test -d /bin && test -d /sbin && test -d /usr/bin && test -d /usr/sbin && test -x /bin/ln && test -x /sbin/cheesed && test -x /usr/bin/passwd && test -x /usr/sbin/useradd'; echo FHS_$?}
|
||||
await "FHS_0\r" "the FHS command-directory split"
|
||||
await "mouse:~# " "the root prompt"
|
||||
sendline {sh -c 'rm -f /tmp/ln-source /tmp/ln-target; echo mouse >/tmp/ln-source; ln /tmp/ln-source /tmp/ln-target; test "$(cat /tmp/ln-target)" = mouse'; echo LN_$?}
|
||||
await "LN_0\r" "the statically linked ln command"
|
||||
await "mouse:~# " "the root prompt"
|
||||
sendline {exit}
|
||||
await "mouse:~> " "the ordinary user shell after leaving root"
|
||||
sendline {su - toor}
|
||||
await "Password: " "the toor password prompt"
|
||||
sendline {cheddar}
|
||||
await "mouse:~# " "the toor shell"
|
||||
sendline {echo $LOGNAME $SHELL}
|
||||
await "toor /bin/tcsh\r" "the toor login and friendly shell"
|
||||
await "mouse:~# " "the toor prompt"
|
||||
poweroff
|
||||
puts "$mode authenticated multi-user acceptance passed"
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$acceptance_dir/harness.sh"
|
||||
acceptance_init
|
||||
acceptance_require_commands "the multi-user acceptance test" expect
|
||||
acceptance_copy_disk multi-user "multi-user operation"
|
||||
|
||||
"$acceptance_dir/multi-user.exp" "$runner" "$test_disk" provision
|
||||
"$acceptance_dir/multi-user.exp" "$runner" "$test_disk" login
|
||||
"$acceptance_dir/multi-user.exp" "$runner" "$test_disk" verify
|
||||
printf '%s\n' "multi-user acceptance tests passed"
|
||||
Executable
+77
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
if {$argc != 3} {
|
||||
puts stderr "usage: network.exp RUNNER DISK MODE"
|
||||
exit 2
|
||||
}
|
||||
set runner [file normalize [lindex $argv 0]]
|
||||
set disk [file normalize [lindex $argv 1]]
|
||||
set mode [lindex $argv 2]
|
||||
if {$mode ni {first verify}} {
|
||||
puts stderr "invalid network mode: $mode"
|
||||
exit 2
|
||||
}
|
||||
set timeout 90
|
||||
set acceptance_name "network"
|
||||
source [file join [file dirname [info script]] harness.exp]
|
||||
proc poweroff {} {
|
||||
sendline {kill -TERM 1}
|
||||
await "cheesed: received poweroff request" "the poweroff request"
|
||||
await "Stopping network" "the network shutdown"
|
||||
await "cheesed: root filesystem remounted read-only" "the read-only remount"
|
||||
expect {
|
||||
eof {
|
||||
set result [wait]
|
||||
if {[lindex $result 3] != 0} {
|
||||
fail "QEMU exited unsuccessfully"
|
||||
}
|
||||
}
|
||||
timeout { fail "QEMU did not power off" }
|
||||
}
|
||||
}
|
||||
|
||||
acceptance_log
|
||||
set env(MOUSE_BOOT_MODE) disk
|
||||
set env(MOUSE_DISK_IMAGE) $disk
|
||||
set env(MOUSE_NETWORK) 1
|
||||
set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1"
|
||||
spawn -noecho $runner
|
||||
|
||||
await "Starting network" "the network service"
|
||||
await "mouse login: root (automatic login)" "the test login"
|
||||
await "cheesed: service graph started; cgroup supervision active" "the completed service graph"
|
||||
send -- "\r"
|
||||
prompt
|
||||
|
||||
sendline {sh -c 'test -s /run/mouse-network.ready && grep -q eth0 /proc/net/route && grep -q 00000000 /proc/net/route && grep -q "^nameserver " /etc/resolv.conf'; echo LEASE_$?}
|
||||
await "LEASE_0\r" "the DHCP route and resolver state"
|
||||
prompt
|
||||
sendline {nc -z -w 5 1.1.1.1 80; echo IP_$?}
|
||||
await "IP_0\r" "the IP endpoint"
|
||||
prompt
|
||||
sendline {nc -z -w 5 example.com 80; echo DNS_$?}
|
||||
await "DNS_0\r" "the DNS endpoint"
|
||||
prompt
|
||||
sendline {service network status; echo STATUS_$?}
|
||||
await "network running" "accurate service status"
|
||||
await "STATUS_0\r" "the service status exit code"
|
||||
prompt
|
||||
sendline {service network restart}
|
||||
await "Stopping network" "runtime network stop"
|
||||
await "Starting network" "runtime network restart"
|
||||
prompt
|
||||
sendline {sh -c 'test -s /run/mouse-network.ready'; echo RESTART_$?}
|
||||
await "RESTART_0\r" "the renewed lease"
|
||||
prompt
|
||||
|
||||
if {$mode eq "first"} {
|
||||
sendline {sed 's/metric 100/metric 200/' /etc/dhcpcd.conf >/run/dhcpcd.conf.new && mv /run/dhcpcd.conf.new /etc/dhcpcd.conf; echo POLICY_$?}
|
||||
await "POLICY_0\r" "the persistent policy update"
|
||||
prompt
|
||||
} else {
|
||||
sendline {sh -c 'grep -q "^metric 200$" /etc/dhcpcd.conf && grep -q "eth0.*200" /proc/net/route'; echo PERSIST_$?}
|
||||
await "PERSIST_0\r" "the persisted route metric"
|
||||
prompt
|
||||
}
|
||||
poweroff
|
||||
puts "$mode network acceptance passed"
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$acceptance_dir/harness.sh"
|
||||
acceptance_init
|
||||
acceptance_require_commands "the network acceptance test" expect
|
||||
acceptance_copy_disk network networking
|
||||
|
||||
"$acceptance_dir/network.exp" "$runner" "$test_disk" first
|
||||
"$acceptance_dir/network.exp" "$runner" "$test_disk" verify
|
||||
printf '%s\n' "network acceptance tests passed"
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
if {$argc != 3} {
|
||||
puts stderr "usage: pkgsrc.exp RUNNER DISK MODE"
|
||||
exit 2
|
||||
}
|
||||
set runner [file normalize [lindex $argv 0]]
|
||||
set disk [file normalize [lindex $argv 1]]
|
||||
set mode [lindex $argv 2]
|
||||
if {$mode ni {install verify}} {
|
||||
puts stderr "invalid pkgsrc mode: $mode"
|
||||
exit 2
|
||||
}
|
||||
set timeout 1800
|
||||
set acceptance_name "pkgsrc"
|
||||
source [file join [file dirname [info script]] harness.exp]
|
||||
|
||||
acceptance_log
|
||||
set env(MOUSE_BOOT_MODE) disk
|
||||
set env(MOUSE_DISK_IMAGE) $disk
|
||||
set env(MOUSE_NETWORK) 1
|
||||
set env(MOUSE_MEMORY) 2G
|
||||
set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1"
|
||||
spawn -noecho $runner
|
||||
|
||||
await_exact "mouse login: root (automatic login)" "the serial login"
|
||||
await_prompt
|
||||
|
||||
if {$mode eq "install"} {
|
||||
sendline {sh -c 'test "$(cat /usr/share/mouse/pkgsrc.version)" = 2026Q2 && test ! -e /usr/share/mouse/pkgsrc-2026Q2.tar.gz'; echo SOURCE_$?}
|
||||
await_exact "SOURCE_0\r" "the pkgsrc release marker without a duplicate archive"
|
||||
await_exact "mouse:~# " "the prompt after source verification"
|
||||
|
||||
sendline {sh -c "test \"$(command -v make)\" = /usr/bin/make && make --version | grep -q '^GNU Make 4.4.1$' && test \"$(command -v bmake)\" = /usr/local/bin/bmake && test ! -e /usr/share/mk && test \"$(command -v pkg_add)\" = /usr/local/sbin/pkg_add && test \"$(command -v pkg_info)\" = /usr/local/sbin/pkg_info && test \"$(command -v less)\" = /usr/bin/less && test -f /usr/local/share/mk/bsd.own.mk && test -d /var/db/pkg && test -d /usr/local/src/pkgsrc && pkg_info -e 'bootstrap-mk-files-[0-9]*' >/dev/null && pkg_info -e 'bmake-[0-9]*' >/dev/null && pkg_info -e 'pkg_install-[0-9]*' >/dev/null"; echo SEED_$?}
|
||||
await_exact "SEED_0\r" "the release-built pkgsrc seed"
|
||||
await_exact "mouse:~# " "the prompt after seed verification"
|
||||
|
||||
sendline {sh -c "grep -Eq '^TOOLS_PLATFORM\.awk\?=[[:space:]]*/usr/bin/awk$' /usr/local/etc/mk.conf && grep -Eq '^LOCALBASE=[[:space:]]*/usr/local$' /usr/local/etc/mk.conf && grep -Eq '^PKG_DBDIR=[[:space:]]*/var/db/pkg$' /usr/local/etc/mk.conf && grep -Eq '^INIT_SYSTEM=[[:space:]]*rc\.d$' /usr/local/etc/mk.conf && grep -Eq '^RCD_SCRIPTS_DIR=[[:space:]]*/usr/local/etc/rc\.d$' /usr/local/etc/mk.conf && grep -Eq '^PKG_RCD_SCRIPTS=[[:space:]]*YES$' /usr/local/etc/mk.conf && test -L /usr/local/etc/rc.subr"; echo POLICY_$?}
|
||||
await_exact "POLICY_0\r" "the pkgsrc prefix, database, service, and MOUSE ABI policy"
|
||||
await_exact "mouse:~# " "the prompt after policy verification"
|
||||
|
||||
sendline {cp -R /usr/share/mouse/pkgsrc-fixture/local /usr/local/src/pkgsrc/; bmake -C /usr/local/src/pkgsrc/local/mouse-hello install; echo INSTALL_$?}
|
||||
await_exact "INSTALL_0\r" "the pkgsrc package installation"
|
||||
await_exact "mouse:~# " "the prompt after package installation"
|
||||
sendline {/usr/local/bin/mouse-hello; sh -c "test -x /usr/local/etc/rc.d/mouse_hello && /usr/local/sbin/pkg_info -L mouse-hello | grep -qx /usr/local/share/examples/rc.d/mouse_hello && readelf -l /usr/local/bin/mouse-hello | grep -q INTERP && readelf -d /usr/local/bin/mouse-hello | grep -q NEEDED"; /usr/local/sbin/pkg_info -e 'mouse-hello-[0-9]*'; echo PACKAGE_$?}
|
||||
await_exact "Hello from pkgsrc on MOUSE\r" "the installed pkgsrc command"
|
||||
await_regexp {mouse-hello-1\.0\r} "the pkgsrc package record"
|
||||
await_exact "PACKAGE_0\r" "the installed package status"
|
||||
await_exact "mouse:~# " "the prompt before starting the newly installed service"
|
||||
sendline {service mouse_hello start; sh -c 'test -f /run/mouse-hello-service.ready'; service mouse_hello status; echo RUNTIME_$?}
|
||||
await_exact "mouse_hello running\r" "the newly discovered pkgsrc service start"
|
||||
await_exact "mouse_hello running\r" "the newly discovered pkgsrc service status"
|
||||
await_exact "RUNTIME_0\r" "the newly installed service runtime control"
|
||||
await_exact "mouse:~# " "the prompt before enabling the pkgsrc service"
|
||||
sendline {printf '%s\n' 'enable_mouse_hello=YES' >>/etc/rc.conf; echo ENABLE_$?}
|
||||
await_exact "ENABLE_0\r" "the persistent pkgsrc service policy"
|
||||
} else {
|
||||
sendline {sh -c 'test -x /usr/local/bin/mouse-hello && test -d /var/db/pkg && test -f /run/mouse-hello-service.ready && service mouse_hello status >/dev/null && grep -Eq "^LOCALBASE=[[:space:]]*/usr/local$" /usr/local/etc/mk.conf'; /usr/local/bin/mouse-hello; /usr/local/sbin/pkg_info -e 'mouse-hello-[0-9]*'; echo PERSIST_$?}
|
||||
await_exact "Hello from pkgsrc on MOUSE\r" "the persistent pkgsrc command"
|
||||
await_regexp {mouse-hello-1\.0\r} "the persistent package record"
|
||||
await_exact "PERSIST_0\r" "the persistent pkgsrc state"
|
||||
}
|
||||
|
||||
await_exact "mouse:~# " "the prompt before poweroff"
|
||||
poweroff
|
||||
puts "$mode pkgsrc acceptance passed"
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$acceptance_dir/harness.sh"
|
||||
acceptance_init
|
||||
server_pid=
|
||||
|
||||
acceptance_cleanup_extra() {
|
||||
if [ -n "$server_pid" ]; then
|
||||
kill "$server_pid" 2>/dev/null || :
|
||||
wait "$server_pid" 2>/dev/null || :
|
||||
fi
|
||||
}
|
||||
|
||||
acceptance_require_commands "the pkgsrc acceptance test" expect python3
|
||||
acceptance_copy_disk pkgsrc
|
||||
|
||||
python3 -m http.server 18080 \
|
||||
--bind 127.0.0.1 \
|
||||
--directory "$repo_dir/tests/fixtures/pkgsrc/distfiles" \
|
||||
>"$temporary/http.log" 2>&1 &
|
||||
server_pid=$!
|
||||
sleep 1
|
||||
if ! kill -0 "$server_pid" 2>/dev/null; then
|
||||
printf '%s\n' "pkgsrc source server failed to start" >&2
|
||||
cat "$temporary/http.log" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"$acceptance_dir/pkgsrc.exp" "$runner" "$test_disk" install
|
||||
"$acceptance_dir/pkgsrc.exp" "$runner" "$test_disk" verify
|
||||
printf '%s\n' "pkgsrc seed, rc.d installation, and persistence tests passed"
|
||||
Executable
+110
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
if {$argc != 3} {
|
||||
puts stderr "usage: service-integration.exp RUNNER DISK MODE"
|
||||
exit 2
|
||||
}
|
||||
|
||||
set runner [file normalize [lindex $argv 0]]
|
||||
set disk [file normalize [lindex $argv 1]]
|
||||
set mode [lindex $argv 2]
|
||||
if {$mode ni {enabled disabled failure}} {
|
||||
puts stderr "invalid service-integration mode: $mode"
|
||||
exit 2
|
||||
}
|
||||
set timeout 180
|
||||
set acceptance_name "service-integration"
|
||||
source [file join [file dirname [info script]] harness.exp]
|
||||
|
||||
acceptance_log
|
||||
set env(MOUSE_BOOT_MODE) disk
|
||||
set env(MOUSE_DISK_IMAGE) $disk
|
||||
set env(MOUSE_NETWORK) 0
|
||||
set env(MOUSE_MEMORY) 1G
|
||||
set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1"
|
||||
spawn -noecho $runner
|
||||
|
||||
if {$mode eq "failure"} {
|
||||
await_regexp {required service console_login failed: start command exited with status [0-9]+; entering emergency console} "the required-service failure"
|
||||
await_regexp {cheesed: started emergency shell as PID [0-9]+} "the emergency shell"
|
||||
await_exact "mouse:~# " "the emergency prompt"
|
||||
sendline {sh -c 'set -- `cat /proc/$PPID/stat`; cat /proc/$4/comm'}
|
||||
await_exact "cheesed\r" "the emergency shell parent"
|
||||
await_exact "mouse:~# " "the prompt after the emergency parent check"
|
||||
sendline {mv /etc/rc.d/console_login.good /etc/rc.d/console_login; chmod 0755 /etc/rc.d/console_login}
|
||||
await_exact "mouse:~# " "the prompt after restoring console login"
|
||||
poweroff
|
||||
puts "required-service failure acceptance passed"
|
||||
exit 0
|
||||
}
|
||||
|
||||
await_exact "cheesed: base bootstrap complete; cheesed is PID 1" "PID 1 confirmation"
|
||||
if {$mode eq "disabled"} {
|
||||
await_exact "cheesed: enabled optional services: (none)" "disabled service policy"
|
||||
} else {
|
||||
await_exact "cheesed: enabled optional services: mouse_echo" "enabled service policy"
|
||||
}
|
||||
await_exact "cheesed: service graph started; cgroup supervision active" "the supervised service graph"
|
||||
await_prompt
|
||||
|
||||
sendline {sh -c 'test "$(cat /proc/1/comm)" = cheesed && test -S /run/cheesed.sock && test -f /sys/fs/cgroup/mouse.services/console_login/cgroup.events; echo BASE_$?'}
|
||||
await_exact "BASE_0\r" "the cheesed and cgroup service contract"
|
||||
await_exact "mouse:~# " "the prompt after the base contract check"
|
||||
sendline {service console_login status}
|
||||
await_exact "console_login running\r" "the required console service status"
|
||||
await_exact "mouse:~# " "the prompt after the console status"
|
||||
|
||||
if {$mode eq "disabled"} {
|
||||
sendline {sh -c 'service mouse_echo status >/dev/null 2>&1; test $? -ne 0 && test ! -e /sys/fs/cgroup/mouse.services/mouse_echo; echo DISABLED_$?'}
|
||||
await_exact "DISABLED_0\r" "the disabled service state"
|
||||
await_exact "mouse:~# " "the prompt after the disabled check"
|
||||
sendline {sh -c 'cksum /etc/rc.conf > /run/rc.conf.cksum'; service mouse_echo start}
|
||||
await_exact "mouse_echo running\r" "the runtime-only service start"
|
||||
await_exact "mouse:~# " "the prompt after the runtime start"
|
||||
sendline {sh -c 'test "$(cksum /etc/rc.conf)" = "$(cat /run/rc.conf.cksum)" && test -f /sys/fs/cgroup/mouse.services/mouse_echo/cgroup.events; echo POLICY_$?'}
|
||||
await_exact "POLICY_0\r" "unchanged persistent policy and live cgroup"
|
||||
await_exact "mouse:~# " "the prompt after the persistent-policy check"
|
||||
sendline {service mouse_echo stop}
|
||||
await_exact "mouse_echo stopped\r" "the runtime-only service stop"
|
||||
await_exact "mouse:~# " "the prompt after the runtime stop"
|
||||
sendline {sh -c 'cp /etc/rc.d/console_login /etc/rc.d/console_login.good && printf "#!/bin/sh\nexit 42\n" >/etc/rc.d/console_login && chmod 0755 /etc/rc.d/console_login'; echo FAILURE_$?}
|
||||
await_exact "FAILURE_0\r" "the required-service failure setup"
|
||||
await_exact "mouse:~# " "the prompt after failure setup"
|
||||
poweroff
|
||||
puts "disabled service acceptance passed"
|
||||
exit 0
|
||||
}
|
||||
|
||||
sendline {sh -c 'test -f /run/mouse-echo.ready && grep -qx "populated 1" /sys/fs/cgroup/mouse.services/mouse_echo/cgroup.events; echo ENABLED_$?'}
|
||||
await_exact "ENABLED_0\r" "the enabled service cgroup"
|
||||
await_exact "mouse:~# " "the prompt after the enabled check"
|
||||
sendline {sh -c 'i=0; while [ "$i" -lt 4 ]; do set -- $(cat /sys/fs/cgroup/mouse.services/mouse_echo/cgroup.procs); kill -KILL "$1"; i=$((i + 1)); sleep 2; done; echo EXHAUST_$?'}
|
||||
await_exact "EXHAUST_0\r" "four supervised service crashes"
|
||||
await_exact "mouse:~# " "the prompt after exhausting restarts"
|
||||
sendline {sh -c 'service mouse_echo status >/dev/null 2>&1; echo FAILED_STATUS_$?'}
|
||||
await_exact "FAILED_STATUS_1\r" "the failed service status"
|
||||
await_exact "mouse:~# " "the prompt after failed status"
|
||||
sendline {service mouse_echo restart}
|
||||
await_exact "mouse_echo running\r" "administrative service restart"
|
||||
await_exact "mouse:~# " "the prompt after the administrative restart"
|
||||
sendline {service mouse_echo stop}
|
||||
await_exact "mouse_echo stopped\r" "the bounded service stop"
|
||||
await_exact "mouse:~# " "the prompt after the stop"
|
||||
sendline {sh -c 'test -f /run/mouse-echo.term && grep -qx "populated 0" /sys/fs/cgroup/mouse.services/mouse_echo/cgroup.events; echo STOPPED_$?'}
|
||||
await_exact "STOPPED_0\r" "SIGTERM delivery and cgroup cleanup"
|
||||
await_exact "mouse:~# " "the prompt after cgroup cleanup"
|
||||
sendline {service mouse_echo start}
|
||||
await_exact "mouse_echo running\r" "the final service start"
|
||||
await_exact "mouse:~# " "the prompt after the final start"
|
||||
sendline {sh -c 'sed "s/enable_mouse_echo=YES/enable_mouse_echo=NO/" /etc/rc.conf >/run/rc.conf.next && mv /run/rc.conf.next /etc/rc.conf'; echo NEXT_$?}
|
||||
await_exact "NEXT_0\r" "the disabled policy for the next boot"
|
||||
await_exact "mouse:~# " "the prompt after the next-boot policy update"
|
||||
|
||||
sendline {kill -TERM 1}
|
||||
await_exact "cheesed: received poweroff request" "the poweroff request"
|
||||
await_exact "cheesed: stopping service mouse_echo" "the dependent service stopping first"
|
||||
await_exact "cheesed: stopping service console_login" "the console service stopping"
|
||||
await_exact "cheesed: root filesystem remounted read-only" "the read-only root remount"
|
||||
await_clean_exit "poweroff"
|
||||
|
||||
puts "enabled service-integration acceptance passed"
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$acceptance_dir/harness.sh"
|
||||
acceptance_init
|
||||
acceptance_require_commands "the service-integration acceptance test" expect
|
||||
acceptance_copy_disk service-integration
|
||||
|
||||
requested_modes=" ${MOUSE_SERVICE_INTEGRATION_MODES:-enabled disabled failure} "
|
||||
for mode in enabled disabled failure; do
|
||||
case "$requested_modes" in
|
||||
*" $mode "*) "$acceptance_dir/service-integration.exp" "$runner" "$test_disk" "$mode" ;;
|
||||
esac
|
||||
done
|
||||
Executable
+64
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
if {$argc != 3} {
|
||||
puts stderr "usage: storage.exp RUNNER DISK MODE"
|
||||
exit 2
|
||||
}
|
||||
|
||||
set runner [file normalize [lindex $argv 0]]
|
||||
set disk [file normalize [lindex $argv 1]]
|
||||
set mode [lindex $argv 2]
|
||||
if {$mode ni {first verify failure}} {
|
||||
puts stderr "invalid storage mode: $mode"
|
||||
exit 2
|
||||
}
|
||||
set timeout 60
|
||||
set acceptance_name "storage"
|
||||
source [file join [file dirname [info script]] harness.exp]
|
||||
|
||||
acceptance_log
|
||||
set env(MOUSE_BOOT_MODE) disk
|
||||
set env(MOUSE_DISK_IMAGE) $disk
|
||||
set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1"
|
||||
|
||||
spawn -noecho $runner
|
||||
|
||||
if {$mode eq "failure"} {
|
||||
await_regexp {VFS: Unable to mount root fs} "the failed-root diagnostic"
|
||||
expect {
|
||||
eof {
|
||||
set result [wait]
|
||||
if {[lindex $result 3] != 0} {
|
||||
fail "QEMU exited unsuccessfully after the expected kernel panic"
|
||||
}
|
||||
}
|
||||
timeout {
|
||||
fail "QEMU did not exit after the failed-root diagnostic"
|
||||
}
|
||||
}
|
||||
puts "failed-root diagnostic acceptance passed"
|
||||
exit 0
|
||||
}
|
||||
|
||||
await_exact "cheesed: base bootstrap complete; cheesed is PID 1" "PID 1 confirmation"
|
||||
if {$mode eq "verify"} {
|
||||
await_exact "cheesed: enabled optional services: (none)" "persisted service policy"
|
||||
}
|
||||
await_exact "mouse login: root (automatic login)" "the serial login"
|
||||
await_prompt
|
||||
|
||||
if {$mode eq "first"} {
|
||||
sendline {sh -c 'test -s /etc/machine-id && mkdir -p /var/lib/mouse /home/mouse-state && echo etc-state > /etc/mouse-state && echo var-state > /var/lib/mouse/state && echo home-state > /home/mouse-state/value && cp /etc/machine-id /var/lib/mouse/machine-id.first'; echo STATE_$?}
|
||||
await_exact "STATE_0\r" "persistent state creation"
|
||||
await_exact "mouse:~# " "the prompt after state creation"
|
||||
sendline {sh -c 'printf "%s\n" "# Persistent MOUSE service policy belongs in this file." "enable_network=NO" > /etc/rc.conf'; echo POLICY_$?}
|
||||
await_exact "POLICY_0\r" "persistent policy update"
|
||||
await_exact "mouse:~# " "the prompt after the policy update"
|
||||
} else {
|
||||
sendline {sh -c 'test "$(cat /etc/mouse-state)" = etc-state && test "$(cat /var/lib/mouse/state)" = var-state && test "$(cat /home/mouse-state/value)" = home-state && test "$(cat /etc/machine-id)" = "$(cat /var/lib/mouse/machine-id.first)" && test "$(cat /etc/rc.conf | tail -1)" = enable_network=NO'; echo PERSIST_$?}
|
||||
await_exact "PERSIST_0\r" "persistent state after reboot"
|
||||
await_exact "mouse:~# " "the prompt after persistence verification"
|
||||
}
|
||||
|
||||
poweroff
|
||||
puts "$mode persistent-root acceptance passed"
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$acceptance_dir/harness.sh"
|
||||
acceptance_init
|
||||
acceptance_require_commands "the storage acceptance test" expect dd
|
||||
acceptance_copy_disk storage
|
||||
|
||||
"$acceptance_dir/storage.exp" "$runner" "$test_disk" first
|
||||
"$acceptance_dir/storage.exp" "$runner" "$test_disk" verify
|
||||
"$acceptance_dir/storage.exp" "$runner" "$test_disk" verify
|
||||
|
||||
failed_disk="$test_disk"
|
||||
root_start=264192
|
||||
dd if=/dev/zero of="$failed_disk" bs=512 seek="$root_start" \
|
||||
count=262144 conv=notrunc 2>/dev/null
|
||||
"$acceptance_dir/storage.exp" "$runner" "$failed_disk" failure
|
||||
|
||||
printf '%s\n' "storage acceptance tests passed"
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
if {$argc != 2} {
|
||||
puts stderr "usage: toolchain.exp RUNNER DISK"
|
||||
exit 2
|
||||
}
|
||||
set runner [file normalize [lindex $argv 0]]
|
||||
set disk [file normalize [lindex $argv 1]]
|
||||
set timeout 300
|
||||
set acceptance_name "toolchain"
|
||||
source [file join [file dirname [info script]] harness.exp]
|
||||
|
||||
acceptance_log
|
||||
set env(MOUSE_BOOT_MODE) disk
|
||||
set env(MOUSE_DISK_IMAGE) $disk
|
||||
set env(MOUSE_NETWORK) 0
|
||||
set env(MOUSE_MEMORY) 1G
|
||||
set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1"
|
||||
spawn -noecho $runner
|
||||
|
||||
await "mouse:~# " "the root shell"
|
||||
sendline {cc --version; cc -dumpmachine; make --version; sh -c 'test "$(command -v make)" = /usr/bin/make && test "$(command -v gmake)" = /usr/bin/gmake && test "$(readlink /usr/bin/gmake)" = make && test ! -e /usr/share/mk'; echo MAKE_ID_$status}
|
||||
await "clang version 22.1.3" "the native Clang version"
|
||||
await "x86_64-unknown-linux-musl\r" "the MOUSE compiler target"
|
||||
await "GNU Make 4.4.1" "the base GNU make version"
|
||||
await "MAKE_ID_0\r" "the base make ownership"
|
||||
await "mouse:~# " "the prompt after compiler identification"
|
||||
|
||||
sendline {echo 'int answer(void) { return 42; }' >/tmp/answer.c; echo 'int answer(void);' >/tmp/main.c; echo 'int main(void) { return answer() != 42; }' >>/tmp/main.c; cc -c /tmp/answer.c -o /tmp/answer.o; ar rcs /tmp/libanswer.a /tmp/answer.o; cc /tmp/main.c /tmp/libanswer.a -o /tmp/hello-c; cc -static /tmp/main.c /tmp/libanswer.a -o /tmp/hello-c-static; /tmp/hello-c; /tmp/hello-c-static; echo C_$status}
|
||||
await "C_0\r" "the native C build"
|
||||
await "mouse:~# " "the prompt after the C build"
|
||||
|
||||
sendline {cd /tmp; echo '#include <stdio.h>' >make-main.c; echo 'int main(void) { puts("made"); return 0; }' >>make-main.c; sh -c 'printf "CC=cc\nall: made\nmade: make-main.c\n\t\$(CC) make-main.c -o made\n" >Makefile'; make && ./made && pkgconf --exists libcrypt; echo BUILD_$status}
|
||||
await "made\r" "the make-built program output"
|
||||
await "BUILD_0\r" "make and pkgconf"
|
||||
await "mouse:/tmp# " "the prompt after the make build"
|
||||
|
||||
sendline {echo '#include <filesystem>' >/tmp/hello.cpp; echo '#include <stdexcept>' >>/tmp/hello.cpp; echo '#include <string>' >>/tmp/hello.cpp; echo 'int main() { try { if (std::filesystem::path("/tmp").filename() != "tmp") throw std::runtime_error("filesystem"); } catch (...) { return 1; } return 0; }' >>/tmp/hello.cpp; c++ /tmp/hello.cpp -o /tmp/hello-cxx; c++ -static /tmp/hello.cpp -o /tmp/hello-cxx-static; /tmp/hello-cxx; /tmp/hello-cxx-static; echo CXX_$status}
|
||||
await "CXX_0\r" "the native C++ build"
|
||||
await "mouse:/tmp# " "the prompt after the C++ build"
|
||||
|
||||
sendline {sh -c 'for f in /tmp/hello-c /tmp/hello-cxx; do readelf -l "$f" | grep -q INTERP || { echo "missing INTERP: $f"; exit 1; }; readelf -d "$f" | grep -q NEEDED || { echo "missing NEEDED: $f"; exit 1; }; done; for f in /tmp/hello-c-static /tmp/hello-cxx-static; do if readelf -l "$f" | grep -q INTERP; then echo "unexpected INTERP: $f"; exit 1; fi; if readelf -d "$f" 2>/dev/null | grep -q NEEDED; then echo "unexpected NEEDED: $f"; exit 1; fi; done; exit 0'; echo LINKAGE_$status}
|
||||
await "LINKAGE_0\r" "dynamic defaults and explicit static builds"
|
||||
await "mouse:/tmp# " "the prompt after the linkage audit"
|
||||
|
||||
sendline {echo 'int mouse_shared(void) { return 7; }' >/tmp/shared.c; echo 'int mouse_shared(void); int main(void) { return mouse_shared() != 7; }' >/tmp/shared-user.c; cc -fPIC -shared /tmp/shared.c -o /tmp/libmouse.so; cc /tmp/shared-user.c -L/tmp -Wl,-rpath,/tmp -lmouse -o /tmp/shared-user; /tmp/shared-user; sh -c 'test -f /usr/lib/crtbeginS.o && test -f /usr/lib/crtendS.o && file /tmp/libmouse.so | grep -q "shared object"'; echo SHARED_$status}
|
||||
await "SHARED_0\r" "building and consuming a shared library"
|
||||
await "mouse:/tmp# " "the prompt after the shared-library build"
|
||||
|
||||
sendline {sh -c 'mkdir -p /tmp/tar-source /tmp/tar-output; echo archived >/tmp/tar-source/value; tar -czf /tmp/value.tar.gz -C /tmp/tar-source value; tar -xf /tmp/value.tar.gz -C /tmp/tar-output; test "$(cat /tmp/tar-output/value)" = archived'; echo TAR_$status}
|
||||
await "TAR_0\r" "the gzip-compressed archive round trip"
|
||||
await "mouse:/tmp# " "the prompt after the archive round trip"
|
||||
|
||||
poweroff
|
||||
|
||||
puts "native toolchain guest acceptance passed"
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$acceptance_dir/harness.sh"
|
||||
acceptance_init
|
||||
acceptance_require_commands "the toolchain acceptance test" expect
|
||||
acceptance_copy_disk toolchain "the toolchain"
|
||||
|
||||
"$acceptance_dir/toolchain.exp" "$runner" "$test_disk"
|
||||
printf '%s\n' "toolchain acceptance tests passed"
|
||||
Executable
+77
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
if {$argc != 1} {
|
||||
puts stderr "usage: world.exp RUNNER"
|
||||
exit 2
|
||||
}
|
||||
|
||||
set runner [file normalize [lindex $argv 0]]
|
||||
set timeout 90
|
||||
set acceptance_name "world"
|
||||
source [file join [file dirname [info script]] harness.exp]
|
||||
|
||||
acceptance_log
|
||||
spawn -noecho $runner
|
||||
await_exact "cheesed: base bootstrap complete; cheesed is PID 1" "the World boot"
|
||||
await_exact "mouse login: root (automatic login)" "the automatic test login"
|
||||
await_prompt
|
||||
|
||||
sendline {sh -c 'man -w ls | grep -q /usr/share/man && man ls | grep -q "list directory contents" && apropos "list directory contents" | grep -q "ls(1)"'; echo MANUAL_$?}
|
||||
await_exact "MANUAL_0\r" "the installed World manuals and apropos database"
|
||||
await_exact "mouse:~# " "the prompt after the manual check"
|
||||
|
||||
sendline {sh -c 'printf mouse-world >/tmp/plain && gzip -c /tmp/plain | gzip -dc | cmp - /tmp/plain && bzip2 -c /tmp/plain | bzip2 -dc | cmp - /tmp/plain && xz -c /tmp/plain | xz -dc | cmp - /tmp/plain && zstd -q -c /tmp/plain | zstd -q -dc | cmp - /tmp/plain && tar -a -cf /tmp/plain.zip -C /tmp plain && mkdir /tmp/unzip && unzip -q /tmp/plain.zip -d /tmp/unzip && cmp /tmp/plain /tmp/unzip/plain && file /tmp/plain | grep -q text'; echo ARCHIVE_$?}
|
||||
await_exact "ARCHIVE_0\r" "the World compression, archive, and file-identification tools"
|
||||
await_exact "mouse:~# " "the prompt after the archive check"
|
||||
|
||||
sendline {sh -c 'openssl version | grep -q OpenSSL && free >/dev/null && uptime >/dev/null && vmstat 1 2 >/dev/null && watch --version >/dev/null && sysctl kernel.hostname | grep -q mouse && lsblk >/dev/null && findmnt / >/dev/null && flock /tmp/world.lock true'; echo RUNTIME_$?}
|
||||
await_exact "RUNTIME_0\r" "the crypto, process, sysctl, and storage administration tools"
|
||||
await_exact "mouse:~# " "the prompt after the runtime administration check"
|
||||
|
||||
sendline {sh -c 'ip link show lo >/dev/null && ip -6 address show dev lo | grep -q ::1 && ss -l >/dev/null && tc qdisc show dev lo >/dev/null && bridge link >/dev/null && nft add table inet mouse_acceptance && nft list table inet mouse_acceptance >/dev/null && nft delete table inet mouse_acceptance'; echo NETWORK_TOOLS_$?}
|
||||
await_exact "NETWORK_TOOLS_0\r" "the IPv6, socket, route, traffic-control, and nftables tools"
|
||||
await_exact "mouse:~# " "the prompt after the network-tool check"
|
||||
|
||||
sendline {sh -c 'ip link add mouse-dummy type dummy && ip link add mouse-bridge type bridge && ip link set mouse-dummy master mouse-bridge && ip link add link mouse-dummy name mouse-vlan type vlan id 42 && ip link delete mouse-bridge && ip link delete mouse-vlan && ip link delete mouse-dummy'; echo VIRTUAL_LINKS_$?}
|
||||
await_exact "VIRTUAL_LINKS_0\r" "the dummy, bridge, and VLAN kernel interfaces"
|
||||
await_exact "mouse:~# " "the prompt after the virtual-link check"
|
||||
|
||||
sendline {sh -c 'service loopback status >/dev/null && service mdevd status >/dev/null && service syslogd status >/dev/null && service cron status >/dev/null && service ntpd status >/dev/null'; echo SERVICES_$?}
|
||||
await_exact "SERVICES_0\r" "the device, logging, job, and time services"
|
||||
await_exact "mouse:~# " "the prompt after the World service check"
|
||||
|
||||
sendline {sh -c 'sleep 8 && service ntpd status >/dev/null && test -S /run/ntpd.sock && ntpctl -s status >/dev/null'; echo NTPD_$?}
|
||||
await_exact "NTPD_0\r" "the supervised time service after the restart window"
|
||||
await_exact "mouse:~# " "the prompt after the time-service stability check"
|
||||
|
||||
sendline {sh -c 'sleep 30 & probe=$!; ps -p 1 | grep -q cheesed && pgrep cheesed >/dev/null && pkill -P $$ sleep && wait "$probe" 2>/dev/null; killed=$?; test "$killed" -ne 0 && dmesg | grep -q "Linux version" && ping -c 1 127.0.0.1 >/dev/null'; echo ADMIN_$?}
|
||||
await_exact "ADMIN_0\r" "process, kernel-log, and network diagnosis"
|
||||
await_exact "mouse:~# " "the prompt after administration checks"
|
||||
|
||||
sendline {sh -c 'mkdir -p /tmp/mouse-mount; mount -t tmpfs tmpfs /tmp/mouse-mount && echo mounted >/tmp/mouse-mount/state && umount /tmp/mouse-mount && test ! -e /tmp/mouse-mount/state'; echo MOUNT_$?}
|
||||
await_exact "MOUNT_0\r" "manual mount and unmount"
|
||||
await_exact "mouse:~# " "the prompt after mount checks"
|
||||
|
||||
sendline {sh -c 'printf "a\nworld-editor\n.\nwq\n" | vi -e /tmp/mouse-vi && grep -qx world-editor /tmp/mouse-vi'; echo VI_$?}
|
||||
await_exact "VI_0\r" "the base editor"
|
||||
await_exact "mouse:~# " "the prompt after editor verification"
|
||||
|
||||
sendline {logger -p user.notice mouse-world-syslog; sleep 1; grep -q mouse-world-syslog /var/log/messages; echo SYSLOG_$?}
|
||||
await_exact "SYSLOG_0\r" "durable base logging"
|
||||
await_exact "mouse:~# " "the prompt after logging verification"
|
||||
|
||||
sendline {sh -c 'kill -USR2 "$(cat /run/syslogd.pid)" && sleep 1 && logger -p user.notice mouse-world-after-rotation && sleep 1 && test -f /var/log/messages.0 && grep -q mouse-world-syslog /var/log/messages.0 && grep -q mouse-world-after-rotation /var/log/messages'; echo ROTATE_$?}
|
||||
await_exact "ROTATE_0\r" "base log rotation and descriptor reopening"
|
||||
await_exact "mouse:~# " "the prompt after log rotation"
|
||||
|
||||
sendline {sh -c 'printf "* * * * * /bin/true\n" | crontab - && crontab -l | grep -q "/bin/true"'; echo CRON_$?}
|
||||
await_exact "CRON_0\r" "the base crontab interface"
|
||||
await_exact "mouse:~# " "the prompt after crontab verification"
|
||||
|
||||
sendline {depmod -a; modinfo mouse_test >/dev/null && modprobe mouse_test && grep -q '^mouse_test ' /proc/modules && rmmod mouse_test; echo MODULE_$?}
|
||||
await_exact "MODULE_0\r" "loadable external kernel modules"
|
||||
await_exact "mouse:~# " "the prompt after module verification"
|
||||
|
||||
poweroff
|
||||
|
||||
puts "World facilities acceptance passed"
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$acceptance_dir/harness.sh"
|
||||
acceptance_init
|
||||
acceptance_require_commands "the World acceptance test" expect
|
||||
acceptance_copy_disk world
|
||||
|
||||
MOUSE_BOOT_MODE=disk \
|
||||
MOUSE_DISK_IMAGE="$test_disk" \
|
||||
MOUSE_KERNEL_ARGS="console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" \
|
||||
MOUSE_MEMORY="${MOUSE_MEMORY:-1G}" \
|
||||
exec expect "$acceptance_dir/world.exp" "$runner"
|
||||
Reference in New Issue
Block a user