<feed xmlns='http://www.w3.org/2005/Atom'>
<title>archsetup/scripts/testing/run-test.sh, branch main</title>
<subtitle>Builds a full dev workstation from a bare Arch Linux install.
</subtitle>
<id>https://git.cjennings.net/archsetup/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/archsetup/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/'/>
<updated>2026-05-22T20:52:24+00:00</updated>
<entry>
<title>refactor(testing): clone the dotfiles repo into the VM test</title>
<updated>2026-05-22T20:52:24+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-22T20:52:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=68172c8b4c33b4b2cc44d235a9c71685cd4ac3d5'/>
<id>urn:sha1:68172c8b4c33b4b2cc44d235a9c71685cd4ac3d5</id>
<content type='text'>
The dotfiles live in a separate repo now, so the VM test clones that source, bundles it, and clones from the bundle into /tmp/dotfiles-test on the VM. archsetup's in-VM clone of DOTFILES_REPO then resolves against the local path with no network. DOTFILES_SOURCE overrides the source for testing a local checkout instead of the published repo. The cleanup trap tracks the host-side bundle and clone, so a mid-run abort leaves nothing behind.
</content>
</entry>
<entry>
<title>fix: correct a POSIX-sh bashism in init and document two SC2034 cases</title>
<updated>2026-05-20T17:02:47+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-20T17:02:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=618e6cce0b1662f50c6e766bba7e11b6d6952532'/>
<id>urn:sha1:618e6cce0b1662f50c6e766bba7e11b6d6952532</id>
<content type='text'>
init runs under #!/bin/sh but used $(&lt;file) to read /etc/hostname, a bashism that breaks on a strict POSIX sh. I switched it to $(cat) and quoted $interface_up in the same script.

The two VM_IP assignments in the test scripts are read by the sourced validation.sh, which shellcheck can't follow, so they now carry a documented disable=SC2034 instead of a bare suppression. The rest of the shellcheck findings across the scripts are intentional (word-splitting on $SSH_OPTS, integer tests in [ ]) or already accepted, so I left them alone.
</content>
</entry>
<entry>
<title>fix(testing): cleanup traps, arg validation, and two real bugs</title>
<updated>2026-05-17T19:38:40+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-17T19:38:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=663cec6520a72680609c0d803494fb0bde4ce765'/>
<id>urn:sha1:663cec6520a72680609c0d803494fb0bde4ce765</id>
<content type='text'>
Two real bugs and a sweep of hygiene across the harness. `make test`
passed cleanly on this branch with the same 52/0/5 profile as the
2026-05-11 run, so the wiring is verified end-to-end.

Real bugs:

- `lib/vm-utils.sh` `snapshot_exists` was running
  `qemu-img snapshot -l | grep -q "$snapshot_name"`, which matches the
  name as a substring anywhere in the output — including inside dates
  or filenames in other fields. Replaced with an awk field extraction
  on the TAG column plus `grep -Fxq` for a whole-line literal match.
- `run-test-baremetal.sh` was setting `VALIDATION_PASSED=true|false`
  after validation, but `validation.sh` already uses
  `VALIDATION_PASSED` as a pass counter. The test report then
  referenced `$VALIDATION_PASSED_COUNT`, which is defined nowhere.
  Renamed the boolean to `TEST_PASSED` (matching run-test.sh's
  pattern) and report the actual counter.

Cleanup traps and arg validation:

- `run-test.sh` now installs a top-level EXIT trap that, on abort,
  kills QEMU and restores the clean-install snapshot. A
  `CLEANUP_DONE=1` sentinel keeps the existing normal-path cleanup
  from double-firing. This is the recurring pain from 2026-05-11
  where two failed runs left orphaned QEMU processes and dirty base
  disks behind.
- `create-base-vm.sh` and `debug-vm.sh` got the same kind of trap, plus
  `debug-vm.sh` now rejects non-`.qcow2` paths up front instead of
  letting QEMU fail later.
- `run-test.sh`, `run-test-baremetal.sh`, and `cleanup-tests.sh` now
  validate that options with required values actually receive one
  (`${var:?msg}` for `--script`/`--snapshot`/`--host`/`--password`,
  numeric check for `--keep`).
- `run-test-baremetal.sh` traps the temp git bundle for cleanup if the
  script aborts before its explicit `rm`. The ZFS rollback loop now
  uses `while IFS= read -r ds` and quotes `$ds` inside the ssh_cmd so
  dataset names with whitespace wouldn't break it.

Smaller hygiene:

- `vm-utils.sh` `check_ovmf` also checks `OVMF_VARS_TEMPLATE`; `start_qemu`
  validates disk and ISO paths before building the QEMU command;
  numeric tests quoted.
- `cleanup-tests.sh` find expression for temp disks wrapped in
  `\( ... -o ... \)`, all `while read` loops use `IFS= read -r`,
  orphaned QEMU cleanup tries SIGTERM with a 2s sleep before SIGKILL.
- `create-base-vm.sh` moved the "Copy an archangel-*.iso" info line
  before its `fatal` instead of after (unreachable), and added the
  serial-log path to the final summary.
- `lib/logging.sh` `stop_timer` no longer produces `$((end - ))` when
  the named timer was never started.
- `lib/network-diagnostics.sh` `read` → `IFS= read -r`.
- `setup-testing-env.sh` now installs all missing pacman packages in
  one transaction instead of one-at-a-time (avoids half-installed
  state if package N fails). KVM check also verifies the user has
  read+write on `/dev/kvm` and prints the `gpasswd -a $(id -un) kvm`
  fix if not.

A few items from the review I deliberately skipped: replacing the
codebase-wide unquoted `$SSH_OPTS` string with an array (cosmetic, would
need to be done everywhere at once), `set -e` adds where the existing
fall-through-on-failure is intentional, and a `--force` gate on
`create-base-vm.sh` (would break the expected workflow).
</content>
</entry>
<entry>
<title>fix(testing): drop stale plugin checks, count failed validations</title>
<updated>2026-05-11T22:19:56+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-11T22:19:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=14eecb5b8e76cf1b1de20643d496dc94cfdce0ab'/>
<id>urn:sha1:14eecb5b8e76cf1b1de20643d496dc94cfdce0ab</id>
<content type='text'>
validate_hyprland_plugins and validate_hyprpm_hook checked for the hyprland-plugins-setup script and the hyprpm pacman hook, both removed in 4a3056a (Hyprland 0.54 brings the layouts into core). I deleted the two functions and their calls in validate_window_manager.

I also disabled errexit in run-test.sh from the validation phase onward, so one failed check is counted in VALIDATION_FAILED instead of aborting the run before the report or VM cleanup. About 16 validations across the file do a bare `return 1` after `validation_fail`; any of them firing under the previous behavior would have killed the harness mid-run.
</content>
</entry>
<entry>
<title>fix(test): use PROJECT_ROOT for git bundle creation</title>
<updated>2026-01-29T14:15:14+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-01-29T14:15:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=79ecbc3b2139898e6a5d2e8ff3a2917182dc3656'/>
<id>urn:sha1:79ecbc3b2139898e6a5d2e8ff3a2917182dc3656</id>
<content type='text'>
The git bundle command was running from current directory
instead of PROJECT_ROOT, causing it to bundle from wrong repo.

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(testing): add make test target and display report on completion</title>
<updated>2026-01-28T04:22:34+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-01-28T04:22:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=d227e69ce273c08bf495d2f700b0f067011c0126'/>
<id>urn:sha1:d227e69ce273c08bf495d2f700b0f067011c0126</id>
<content type='text'>
Add 'make test' Makefile target to run full VM integration test suite.
Print test report to terminal after generation for immediate visibility.
</content>
</entry>
<entry>
<title>feat(testing): rewrite test infrastructure from libvirt to direct QEMU</title>
<updated>2026-01-27T23:22:55+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-01-27T23:22:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=8a0c06745814dc2fdadaaad3e2394d766bb71d9e'/>
<id>urn:sha1:8a0c06745814dc2fdadaaad3e2394d766bb71d9e</id>
<content type='text'>
Replace the never-fully-operational libvirt-based VM test infrastructure
with direct QEMU management and archangel ISO for fully automated,
unattended base VM creation.

Key changes:
- vm-utils.sh: complete rewrite — QEMU process mgmt via PID file,
  monitor socket for graceful shutdown, qemu-img snapshots, SSH
  port forwarding (localhost:2222)
- create-base-vm.sh: boots archangel ISO, SSHs in, runs unattended
  install via config file, verifies, creates clean-install snapshot
- run-test.sh: snapshot revert, git bundle transfer, detached archsetup
  execution with setsid, polling, validation, and report generation
- debug-vm.sh: CoW overlay disk, GTK display, auto-cleanup on close
- setup-testing-env.sh: reduced deps to qemu-full/sshpass/edk2-ovmf/socat
- cleanup-tests.sh: PID-based process management, orphan detection
- validation.sh: port-based SSH (backward compatible), fuzzel/foot for
  Hyprland, corrected package list paths
- network-diagnostics.sh: getent/curl instead of nslookup/ping (SLIRP)

New files:
- archsetup-test.conf: archangel config for base VM (btrfs, no encrypt)
- archsetup-vm.conf: archsetup config for unattended test execution
- assets/archangel.conf.example: reference archangel config

Deleted:
- finalize-base-vm.sh: merged into create-base-vm.sh
- archinstall-config.json: replaced by archangel .conf format

Tested: full end-to-end run — 51 validations passed, 0 failures.

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(testing): remove obsolete --skip-slow-packages option</title>
<updated>2026-01-25T00:52:34+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-01-25T00:52:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=7d0f90da66985b402c6a25eb3eca8cc9e6060ced'/>
<id>urn:sha1:7d0f90da66985b402c6a25eb3eca8cc9e6060ced</id>
<content type='text'>
This flag was removed from archsetup but remained in test scripts.
</content>
</entry>
</feed>
