diff options
| author | Craig Jennings <c@cjennings.net> | 2026-04-26 01:09:01 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-04-26 01:09:01 -0500 |
| commit | 1a261b0c220903c8bb628e7f2b94cf75a843f688 (patch) | |
| tree | a4d6d7db9148bb450738818ef59755a5e2eebee3 /tests/unit/test_disk.bats | |
| parent | 6b65665eca8a4b36b0b6eae4d761fccd7b4c1fc4 (diff) | |
| download | archangel-1a261b0c220903c8bb628e7f2b94cf75a843f688.tar.gz archangel-1a261b0c220903c8bb628e7f2b94cf75a843f688.zip | |
test: expand bats coverage across installer modules
Added unit tests for `disk.sh`, `btrfs.sh`, the archangel monolith's `gather_input` unattended branch, and filled gap cases in `config.sh`. The suite grew from 71 to 110 tests.
`installer/lib/disk.sh` was completely uncovered. New `tests/unit/test_disk.bats` covers the four pure partition-path helpers (`get_efi_partition`, `get_root_partition`, `get_efi_partitions`, `get_root_partitions`) across SATA, virtio, and NVMe inputs, mixed arrays, and the empty-input behavior. Side-effecting functions in the same file (sgdisk, mkfs.fat, partprobe, and fzf wrappers) stay deliberately VM-tested.
`installer/lib/btrfs.sh` had no bats coverage. New `tests/unit/test_btrfs.bats` covers `get_luks_devices`, the only pure helper in the file. It pins the asymmetric naming convention where the first device gets the bare `LUKS_MAPPER_NAME` and subsequent devices append the index.
The archangel monolith was un-source-able for tests because its top-level code created a /tmp log file and redirected stdout via `exec > >(tee...)`, plus called `main "$@"` unconditionally at the bottom. I extracted the logging setup into an `init_logging` function called from `main`, and wrapped the main call in a `[[ "${BASH_SOURCE[0]}" == "${0}" ]]` guard. Sourcing the script now loads function definitions silently, with no log file and no banner. Running it directly works exactly as before. Verified both paths.
That refactor unlocks `tests/unit/test_archangel.bats`, which covers `gather_input` in unattended mode. Required-field validation for HOSTNAME, TIMEZONE, ROOT_PASSWORD, and DISKS. Optional-field defaulting (FILESYSTEM to zfs, LOCALE to en_US.UTF-8, KEYMAP to us, ENABLE_SSH to yes). Filesystem-specific encryption checks (ZFS_PASSPHRASE required when not NO_ENCRYPT, same for LUKS_PASSPHRASE on Btrfs). Filesystem validity. RAID_LEVEL defaulting for multi-disk installs. The interactive branch stays out of scope per the testing-strategy policy.
`tests/unit/test_config.bats` got five gap tests: `check_config` when CONFIG_FILE is set, `validate_config` against a non-block-device entry (e.g. /dev/null) and a missing path, and `parse_args` accepting `--color` and `--config-file` together in either order.
`testing-strategy.org` got an expanded "What bats does NOT cover" section. The doc previously named six tools (mkfs, cryptsetup, zpool create, pacstrap, arch-chroot, grub-install). The new list adds sgdisk, partprobe, blkid, mkfs.fat, mkfs.btrfs, snapper, efibootmgr, mount, umount, findmnt, mountpoint, and fzf. It also names the conditions (root needed, real /dev or /sys state) that make a function VM-only. The coverage table at the top now lists the three new test files.
No behavior change in production code. The init_logging extraction preserves the existing log path and banner format byte-for-byte.
Diffstat (limited to 'tests/unit/test_disk.bats')
| -rw-r--r-- | tests/unit/test_disk.bats | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/tests/unit/test_disk.bats b/tests/unit/test_disk.bats new file mode 100644 index 0000000..f4e6929 --- /dev/null +++ b/tests/unit/test_disk.bats @@ -0,0 +1,132 @@ +#!/usr/bin/env bats +# Unit tests for installer/lib/disk.sh +# +# Coverage scope: pure partition-path helpers only. Side-effecting +# functions (partition_disk, partition_disks, format_efi, +# format_efi_partitions, select_disks) wrap sgdisk / mkfs.fat / +# partprobe / fzf and are validated by VM integration per the +# project's testing-strategy.org policy. + +setup() { + # shellcheck disable=SC1091 + source "${BATS_TEST_DIRNAME}/../../installer/lib/common.sh" + # shellcheck disable=SC1091 + source "${BATS_TEST_DIRNAME}/../../installer/lib/disk.sh" +} + +############################# +# get_efi_partition +############################# + +@test "get_efi_partition: SATA disk gets numeric suffix 1" { + run get_efi_partition /dev/sda + [ "$status" -eq 0 ] + [ "$output" = "/dev/sda1" ] +} + +@test "get_efi_partition: virtio disk gets numeric suffix 1" { + run get_efi_partition /dev/vda + [ "$status" -eq 0 ] + [ "$output" = "/dev/vda1" ] +} + +@test "get_efi_partition: NVMe disk gets p1 suffix" { + run get_efi_partition /dev/nvme0n1 + [ "$status" -eq 0 ] + [ "$output" = "/dev/nvme0n1p1" ] +} + +@test "get_efi_partition: NVMe with multi-namespace disk gets p1 suffix" { + run get_efi_partition /dev/nvme1n2 + [ "$status" -eq 0 ] + [ "$output" = "/dev/nvme1n2p1" ] +} + +@test "get_efi_partition: empty input documents current behavior" { + # Empty input misses the nvme regex so the bare-suffix branch fires, + # producing just "1". This pins the existing behavior; the function + # is never called with empty in production but pinning catches a + # change in suffix-rule logic. + run get_efi_partition "" + [ "$status" -eq 0 ] + [ "$output" = "1" ] +} + +############################# +# get_root_partition +############################# + +@test "get_root_partition: SATA disk gets numeric suffix 2" { + run get_root_partition /dev/sda + [ "$status" -eq 0 ] + [ "$output" = "/dev/sda2" ] +} + +@test "get_root_partition: NVMe disk gets p2 suffix" { + run get_root_partition /dev/nvme0n1 + [ "$status" -eq 0 ] + [ "$output" = "/dev/nvme0n1p2" ] +} + +@test "get_root_partition: virtio disk gets numeric suffix 2" { + run get_root_partition /dev/vdb + [ "$status" -eq 0 ] + [ "$output" = "/dev/vdb2" ] +} + +############################# +# get_efi_partitions +############################# + +@test "get_efi_partitions: two SATA disks emit two suffixed partitions" { + run get_efi_partitions /dev/sda /dev/sdb + [ "$status" -eq 0 ] + [ "$output" = "/dev/sda1 +/dev/sdb1" ] +} + +@test "get_efi_partitions: mixed SATA + NVMe gets correct per-disk suffix" { + run get_efi_partitions /dev/sda /dev/nvme0n1 + [ "$status" -eq 0 ] + [ "$output" = "/dev/sda1 +/dev/nvme0n1p1" ] +} + +@test "get_efi_partitions: single NVMe disk emits one p1 partition" { + run get_efi_partitions /dev/nvme0n1 + [ "$status" -eq 0 ] + [ "$output" = "/dev/nvme0n1p1" ] +} + +@test "get_efi_partitions: three disks emit three lines in order" { + run get_efi_partitions /dev/sda /dev/sdb /dev/sdc + [ "$status" -eq 0 ] + local lines + lines=$(echo "$output" | wc -l) + [ "$lines" -eq 3 ] +} + +############################# +# get_root_partitions +############################# + +@test "get_root_partitions: two SATA disks emit two suffix-2 partitions" { + run get_root_partitions /dev/sda /dev/sdb + [ "$status" -eq 0 ] + [ "$output" = "/dev/sda2 +/dev/sdb2" ] +} + +@test "get_root_partitions: mixed SATA + NVMe applies correct suffix per disk" { + run get_root_partitions /dev/sda /dev/nvme0n1 + [ "$status" -eq 0 ] + [ "$output" = "/dev/sda2 +/dev/nvme0n1p2" ] +} + +@test "get_root_partitions: NVMe array gets p2 suffix on each entry" { + run get_root_partitions /dev/nvme0n1 /dev/nvme1n1 + [ "$status" -eq 0 ] + [ "$output" = "/dev/nvme0n1p2 +/dev/nvme1n1p2" ] +} |
