Both packages had zero tests before this change. The helpers in them
are pure (imagemgr) or scripted-runner-friendly (dmsnap), so they're
cheap to pin and worth catching regressions on.
imagemgr/paths_test.go:
* DebianBasePackages returns a defensive copy (mutating the result
can't poison subsequent calls — important because hashPackages
digests this list).
* BuildMetadataPackages stays in lockstep with DebianBasePackages.
* hashPackages is order-sensitive and includes a trailing newline
in its canonical join (regression guard for any future "sort the
list before hashing" temptation that would invalidate every
on-disk hash).
* StageOptionalArtifactPath returns "" for empty/whitespace input
and joins by name otherwise.
* WritePackagesMetadata writes <rootfs>.packages.sha256 with the
expected hash, no-ops on empty rootfs path or empty package list.
* DebianBasePackages contains the small critical-package floor
(ca-certificates, curl, git) so a future apt-list trim can't
silently drop them.
dmsnap/dmsnap_test.go:
* Create runs losetup base, losetup cow, blockdev getsz, dmsetup
create in that order, with a snapshot table referencing the loops
in (base, cow) order — a swap would corrupt every VM.
* Create's failure path unwinds with losetup -d on cow then base.
* Cleanup tears down dmsetup before losetup (otherwise dmsetup sees
EBUSY against vanished backing devices).
* Cleanup falls back to DMDev when DMName is empty.
* Cleanup tolerates "No such device" on losetup -d (idempotent
re-run after a partial cleanup).
* Cleanup surfaces non-missing losetup errors (the tolerance is
narrow on purpose).
* Remove returns nil on a missing target and surfaces non-retryable
errors immediately.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>