aboutsummaryrefslogtreecommitdiff
path: root/tests/unit/test_common.bats
Commit message (Collapse)AuthorAgeFilesLines
* refactor: collapse sshd_config seds into enable_sshd_root_loginCraig Jennings2026-04-261-0/+73
| | | | | | | | | | | | The two sed -i invocations in configure_ssh worked on stock Arch sshd_config but had a real silent-failure mode. If neither the commented (#PermitRootLogin) nor the uncommented form was present, both seds did nothing and the install shipped without root SSH. The user discovered it at first ssh attempt, not at install time. The second sed was also redundant. By the time it ran, the first sed had produced a line matching the second sed's pattern. The new enable_sshd_root_login helper in lib/common.sh combines both substitutions into one sed -i -e ..., then verifies PermitRootLogin yes is present in the file. If the verification fails, it calls error rather than silently appending. Silent appending would mask a corrupted starting file, which is exactly the failure mode worth flagging loudly. The helper takes the config path as an argument so the bats tests in commit 7486abb can run unprivileged against tempfiles. configure_ssh passes /mnt/etc/ssh/sshd_config and is now a single call instead of two seds. Verified: bats 135 → 140 (+5 covering normal/boundary/error). Lint clean. Helper smoke-tested against current Arch sshd_config. The loud-error path can't be exercised against the live default but is covered by the bats error case. Filed as a follow-up :techdebt: item: ~10 other sed -i sites in installer/archangel and lib/btrfs.sh follow the same silent-replace pattern. The FILES= site for LUKS is the worst (silent failure means LUKS prompts on every boot). Triage each per this same recipe in a future session.
* refactor: extract EFI_DIR constant for the install-time EFI mount pointCraig Jennings2026-04-261-0/+8
| | | | | | | | | | The literal /mnt/efi appeared at 17 sites across installer/archangel and installer/lib/btrfs.sh. Renaming it (or pointing tests at a different mount) meant touching every site and risking incomplete sweeps. One canonical name in installer/lib/common.sh now backs every reference. EFI_DIR has no trailing slash so the three expansion patterns in the codebase compose cleanly. Bare ($EFI_DIR), sub-path ($EFI_DIR/EFI/ZBM), and the index-suffix used by install_grub_all_efi for secondary EFI mounts (${EFI_DIR}${i}). The sync_efi_partitions staging path also moves from the literal /mnt/efi_sync to ${EFI_DIR}_sync, so it follows EFI_DIR if anyone ever changes the base. Two follow-ups filed as separate :techdebt: items. MNTPOINT=/mnt extraction across the 50+ /mnt/... sites (pacstrap, arch-chroot, fstab writes), and the related /mnt${chroot_efi_dir} composition pattern at btrfs.sh:681-682. Both ship together when MNTPOINT lands. Verified: bats 134 → 135 (+1 pinning EFI_DIR=/mnt/efi). Lint clean. All four expansion patterns smoke-tested at runtime and produce the original literal byte-for-byte. VM run skipped, pure constant substitution with zero behavior change.
* fix: fail fast on missing ZFSBootMenu efibootmgr entryCraig Jennings2026-04-261-0/+78
| | | | | | | | | | 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.
* feat: PrivateTmp=yes drop-in for systemd-tmpfiles on ZFS-rootCraig Jennings2026-04-211-0/+68
| | | | | | | | | | | | | | | | | | | | | | On ZFS-on-root, statx() across sibling services' /var/tmp/systemd-private-*/tmp mounts returns errno 132 (ENOTNAM). This produces 10-30 journal errors per boot and causes systemd-tmpfiles-clean.service to fail every periodic run (exit 73 / CANTCREAT). Running tmpfiles inside its own mount namespace avoids traversing sibling private-tmp paths. install_zfs() now calls configure_tmpfiles_private_tmp() between configure_zfs_tools and sync_efi_partitions, so the genesis snapshot captures the drop-ins. Btrfs path is untouched — errno 132 is ZFS-specific. The drop-in file-writing is factored into install_dropin() in lib/common.sh (service, name, root; body from stdin). Six bats tests exercise path, content, directory permissions, idempotent overwrite, empty content, and special-character preservation. Full root-cause write-up and verification steps in docs/zfs-tmpfiles-private-tmp-fix.md.
* refactor: merge install_base and install_base_btrfsCraig Jennings2026-04-131-0/+63
| | | | | | | | | | | | | | | | Extract the pacstrap package list into pacstrap_packages(filesystem) in lib/common.sh (common + filesystem-specific). install_base() now dispatches on FILESYSTEM for both the archzfs-repo-append and the package list. install_base_btrfs() deleted; install_btrfs() call site updated to invoke install_base. Old: 49 + 38 lines of ~95% copy-paste. New: 32 lines + a 20-line pure helper. 7 bats tests cover: zfs has zfs-dkms/zfs-utils, btrfs has btrfs-progs + grub + grub-btrfs + snapper + snap-pac, each flavor excludes the other's specifics, common packages are in both, unknown filesystem returns status 1, output is one-per-line. make test: 65/65.
* refactor: unify get_{luks,zfs}_passphrase and get_root_passwordCraig Jennings2026-04-131-0/+29
| | | | | | | | | | | | | | | Extract the prompt/confirm/min-length loop into prompt_password() in lib/common.sh using a nameref for the output variable, so UI output stays on the terminal (no command-substitution capture) and the three callers collapse from ~30 lines each to a single helper call. - get_luks_passphrase() — min 8 chars - get_zfs_passphrase() — min 8 chars - get_root_password() — no min (was unchecked before; preserved) 5 bats tests added: match+min-ok path, length-retry loop, mismatch-retry loop, min_len=0 disables check, empty passphrase when min_len=0. make test: 58/58.
* test: add bats unit tests for common.sh and config.shCraig Jennings2026-04-121-0/+88
23 bats tests covering the pure logic in installer/lib/common.sh (command_exists, require_command, info/warn/error, enable_color, require_root, log) and installer/lib/config.sh (parse_args, load_config, validate_config, check_config). Makefile adds a 'bats' target; 'test' now runs lint + bats (VM integration tests remain under test-install).