test: container lab for the two-tier apply

A disposable ubuntu container, a fake private tier and a fake bootstrap
endpoint, so the whole documented path — chezmoi init --apply, dotup pick,
dotup private, cmp apply, dotsecrets — can run end to end without touching a
real machine or a real credential. The fake tier mirrors the real one's
structure (seven secrets and one alias) because dotsecrets is copied verbatim
and the "8 exports, not 7" assertion depends on that cardinality; its ids are
sequential and obviously synthetic.

check-verbatim.sh keeps the fake tier's copies of shipped files honest, and
snapshot.sh records file modes so a 644 where a 600 belongs is a diff.
This commit is contained in:
bcherb2
2026-08-21 22:34:53 -04:00
parent d1e3f8bce2
commit a001406a33
22 changed files with 2809 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
#!/bin/bash
# chezmoi is how dotup ARRIVES, so "it must already be here" is the natural
# assumption -- and it is wrong often enough to have broken a real install.
#
# get.chezmoi.io installs to ./bin RELATIVE TO THE CWD when -b is not given,
# which is exactly what the README's one-liner does. Run it from $HOME and the
# binary lands in ~/bin; run it from /workspace, as anyone in a container does,
# and it lands in /workspace/bin. Neither is on PATH, and the private tier then
# failed with `chezmoi: not found` AFTER writing the bws token -- half
# configured, at the very last step, having already spent the password.
#
# So this scenario puts the machine in exactly that state -- chezmoi nowhere
# find_tool looks -- and asks two questions:
#
# does dotup install one, before asking for anything?
# and if it CANNOT, does it say so before the password rather than after?
#
# It cannot be a unit test on a developer box: find_tool probes
# /home/linuxbrew/.linuxbrew/bin by absolute path, and any box with linuxbrew
# satisfies the lookup no matter what PATH says. A container has no such
# directory, so absence here is real.
set -u
fail() { echo "FAIL: $*"; exit 1; }
ok() { echo " ok $*"; }
# ---- public tier first, unaided, exactly as the README says ------------------
sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply "$PUB_URL" >/tmp/init.log 2>&1 \
|| { tail -20 /tmp/init.log; fail "public tier init"; }
D=$HOME/.local/bin/dotup
[ -x "$D" ] || fail "no dotup after the public apply"
ok "public tier applied"
# ---- now take chezmoi away, everywhere find_tool looks ----------------------
for c in "$HOME/.local/bin/chezmoi" "$HOME/bin/chezmoi" "$HOME/.npm-global/bin/chezmoi" \
/usr/local/bin/chezmoi /usr/local/go/bin/chezmoi \
/home/linuxbrew/.linuxbrew/bin/chezmoi /opt/homebrew/bin/chezmoi; do
[ -e "$c" ] && { sudo rm -f "$c" || rm -f "$c"; }
done
command -v chezmoi >/dev/null 2>&1 && fail "chezmoi is still on PATH; the state under test never happened"
for c in "$HOME/.local/bin/chezmoi" "$HOME/bin/chezmoi" "$HOME/.npm-global/bin/chezmoi" \
/usr/local/bin/chezmoi /usr/local/go/bin/chezmoi \
/home/linuxbrew/.linuxbrew/bin/chezmoi /opt/homebrew/bin/chezmoi; do
[ -e "$c" ] && fail "chezmoi is still at $c -- find_tool would find it"
done
ok "chezmoi is absent from every place find_tool looks"
# ---- tick the row that needs it, and answer q at the first prompt ------------
# `q` is enough: ensure_chezmoi runs BEFORE the prompt on purpose, so whatever
# it did has already happened by the time the first question is asked.
S=${XDG_CONFIG_HOME:-$HOME/.config}/dotfiles
mkdir -p "$S"; printf 'private/private-repo\n' > "$S/selected"
printf 'q\n' | timeout 180 script -q -c "$D private" /dev/null >/tmp/priv.log 2>&1
rc=$?
out=$(tr -d '\r' </tmp/priv.log | sed 's/\x1b\[[0-9;]*m//g')
printf '%s\n' "$out" | sed 's/^/ | /'
# ---- what must be true ------------------------------------------------------
case $out in
*"chezmoi is not on PATH or in the usual places"*) ok "it noticed chezmoi was missing" ;;
*) fail "dotup never noticed chezmoi was missing (rc=$rc)" ;;
esac
case $out in
*"the chezmoi installer failed"*|*"chezmoi still not found"*)
fail "the installer call did not install anything -- the private repo
cannot be cloned, and this is the failure that used to happen AFTER
the password had already been typed and the bws token written" ;;
esac
case $out in
*"the private repo cannot be cloned without chezmoi"*)
fail "dotup gave up on the private repo instead of installing chezmoi" ;;
esac
case $out in
*"chezmoi installed to ~/.local/bin"*) ok "it installed one, and said where" ;;
*) fail "no chezmoi was installed" ;;
esac
[ -x "$HOME/.local/bin/chezmoi" ] || fail "nothing executable at ~/.local/bin/chezmoi"
"$HOME/.local/bin/chezmoi" --version >/dev/null 2>&1 || fail "the installed chezmoi does not run"
ok "the installed chezmoi is a working binary"
# The ordering that makes the failure survivable: chezmoi is resolved BEFORE
# anything is asked for. If it can only be discovered missing afterwards, the
# password has been spent and the token is already on disk.
a=$(printf '%s\n' "$out" | grep -n 'installing it' | head -1 | cut -d: -f1)
b=$(printf '%s\n' "$out" | grep -n 'Bootstrap URL' | head -1 | cut -d: -f1)
[ -n "$a" ] && [ -n "$b" ] && [ "$a" -lt "$b" ] \
|| fail "chezmoi was not resolved before the first prompt (installing=$a prompt=$b)"
ok "chezmoi was resolved before the first question was asked"
case $out in
*"public-only machine"*) ok "q at the prompt left a public-only machine" ;;
*) fail "q was not accepted at the URL prompt" ;;
esac
echo "CHEZMOI-ABSENT PASS"