diff --git a/test/integration.d/boot-test.sh b/test/integration.d/boot-test.sh new file mode 100755 index 0000000..a8d1144 --- /dev/null +++ b/test/integration.d/boot-test.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# +# Everyday boot: boots the installed system a second time and records how +# long it takes to answer SSH and what systemd-analyze reports, then asserts +# that systemd finished starting with no failed units. CI reports these next +# to the install time, so a change that slows booting shows up in its PR. + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +base_image_ready || { echo "No base image; run this through ./test/integration" >&2; exit 1; } + +log "Booting the installed system" +boot_started=$(date +%s%N) +start_vm_from_base +wait_for_ssh 300 failure-boot-ssh-timeout || exit 1 +boot_ms=$((($(date +%s%N) - boot_started) / 1000000)) +# Coarse: wait_for_ssh polls every 5 s. systemd-analyze below has the exact +# firmware, loader, kernel and userspace split. +log "SSH answered within ${boot_ms} ms of power-on" + +# --wait returns once startup has finished, so systemd-analyze has final +# numbers and a unit that fails late in boot is still counted. +state=$(ssh_guest "timeout 120 systemctl is-system-running --wait" 2>/dev/null | tr -d '\r') +ssh_guest "systemd-analyze" >"$RUN_DIR/systemd-analyze.txt" 2>/dev/null || true +ssh_guest "systemd-analyze blame --no-pager | head -n 20" >"$RUN_DIR/systemd-analyze-blame.txt" 2>/dev/null || true +ssh_guest "systemctl --failed --no-legend --plain" >"$RUN_DIR/failed-units.txt" 2>/dev/null || true +printf '{"boot_to_ssh_ms": %d, "system_state": "%s"}\n' "$boot_ms" "$state" >"$RUN_DIR/boot-timing.json" + +check "systemd reports the system running (got: ${state:-nothing})" test "$state" = running +check "no failed units" test ! -s "$RUN_DIR/failed-units.txt" +capture_console "success-boot" + +stop_vm +finish