aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-04-26 01:08:37 -0500
committerCraig Jennings <c@cjennings.net>2026-04-26 01:08:37 -0500
commitbdda6b17c83e0e298c76bbaf146f082218389cd8 (patch)
tree8bfa18cdd39e6b1969f6bc8a13d64a1e5482fd52 /tests
parent5d677360721ec3ea0f3624ca2a2f20e7241bfba8 (diff)
downloadarchangel-bdda6b17c83e0e298c76bbaf146f082218389cd8.tar.gz
archangel-bdda6b17c83e0e298c76bbaf146f082218389cd8.zip
fix: fail fast on missing ZFSBootMenu efibootmgr entry
The post-bootloader boot-order step in `configure_zfsbootmenu` parsed `efibootmgr` output through a `grep | head | grep -oP` chain with no null guards. If any link returned empty (the entry wasn't created, the label was different, or efibootmgr itself failed), the surrounding `if [[ -n "$bootnum" ]]` silently skipped, the install reported success, and the user rebooted into a machine that wouldn't boot ZFSBootMenu by default. I replaced the chain with two pure helpers in `lib/common.sh`, `parse_efibootmgr_entry` and `parse_efibootmgr_bootorder`. The caller in `archangel` invokes them with explicit `|| error` guards on each parse stage. The helpers capture `efibootmgr` output once and reuse it (it was called twice before). The same hardening covers the BootOrder lookup at the adjacent line. It used to rely on the now-removed `bootnum` guard for safety. The helpers are stdin-driven and use bash regex, so they're easy to test in bats without exercising the real efibootmgr binary. Added 9 unit tests across normal cases, hex-character boot numbers, multi-match selection, missing label, missing BootOrder line, empty input, and an empty label argument. The empty-label case would otherwise falsely match `BootCurrent` via the hex regex, capturing "C". The helper now guards it explicitly. Verified manually against real efibootmgr output (GRUB entry at Boot0001, BootOrder 0006,0001,2001,2002,2003). Both helpers parsed correctly. VM integration not re-run for this small post-bootloader change. The next scheduled `make test-install` exercises the green path.
Diffstat (limited to 'tests')
-rw-r--r--tests/unit/test_common.bats78
1 files changed, 78 insertions, 0 deletions
diff --git a/tests/unit/test_common.bats b/tests/unit/test_common.bats
index c81d2e3..0bb76a1 100644
--- a/tests/unit/test_common.bats
+++ b/tests/unit/test_common.bats
@@ -246,3 +246,81 @@ Environment="FOO=bar baz"'
[[ "$output" == *'"FOO=bar baz"'* ]]
teardown_dropin_tmp
}
+
+#############################
+# parse_efibootmgr_entry
+#############################
+
+@test "parse_efibootmgr_entry returns boot number for matching label" {
+ local sample="BootCurrent: 0001
+Boot0000* Windows Boot Manager
+Boot0001* ZFSBootMenu
+Boot0002* PXE Boot"
+ run parse_efibootmgr_entry "ZFSBootMenu" <<< "$sample"
+ [ "$status" -eq 0 ]
+ [ "$output" = "0001" ]
+}
+
+@test "parse_efibootmgr_entry returns first match when multiple labels match" {
+ local sample="Boot0001* ZFSBootMenu
+Boot0002* ZFSBootMenu-disk2"
+ run parse_efibootmgr_entry "ZFSBootMenu" <<< "$sample"
+ [ "$status" -eq 0 ]
+ [ "$output" = "0001" ]
+}
+
+@test "parse_efibootmgr_entry handles hex characters in boot number" {
+ local sample="Boot00FE* ZFSBootMenu"
+ run parse_efibootmgr_entry "ZFSBootMenu" <<< "$sample"
+ [ "$status" -eq 0 ]
+ [ "$output" = "00FE" ]
+}
+
+@test "parse_efibootmgr_entry returns 1 with empty output when label absent" {
+ local sample="Boot0001* Windows Boot Manager"
+ run parse_efibootmgr_entry "ZFSBootMenu" <<< "$sample"
+ [ "$status" -eq 1 ]
+ [ -z "$output" ]
+}
+
+@test "parse_efibootmgr_entry returns 1 with empty output for empty input" {
+ run parse_efibootmgr_entry "ZFSBootMenu" < /dev/null
+ [ "$status" -eq 1 ]
+ [ -z "$output" ]
+}
+
+@test "parse_efibootmgr_entry returns 1 for empty label without false-matching BootCurrent" {
+ local sample="BootCurrent: 0001
+Boot0001* ZFSBootMenu"
+ run parse_efibootmgr_entry "" <<< "$sample"
+ [ "$status" -eq 1 ]
+ [ -z "$output" ]
+}
+
+#############################
+# parse_efibootmgr_bootorder
+#############################
+
+@test "parse_efibootmgr_bootorder extracts comma-separated boot numbers" {
+ local sample="BootCurrent: 0001
+BootOrder: 0001,0002,0003
+Boot0001* ZFSBootMenu"
+ run parse_efibootmgr_bootorder <<< "$sample"
+ [ "$status" -eq 0 ]
+ [ "$output" = "0001,0002,0003" ]
+}
+
+@test "parse_efibootmgr_bootorder strips whitespace from boot order" {
+ local sample="BootOrder: 0001, 0002 , 0003"
+ run parse_efibootmgr_bootorder <<< "$sample"
+ [ "$status" -eq 0 ]
+ [ "$output" = "0001,0002,0003" ]
+}
+
+@test "parse_efibootmgr_bootorder returns 1 when BootOrder line absent" {
+ local sample="BootCurrent: 0001
+Boot0001* ZFSBootMenu"
+ run parse_efibootmgr_bootorder <<< "$sample"
+ [ "$status" -eq 1 ]
+ [ -z "$output" ]
+}