#!/usr/bin/env bash # `boot` is downloaded before the repository exists. It may hand off only # after both the downloaded script and the requested Git commit have been # verified. This fixture stubs Git and install inside a throwaway PANAMA_PATH; # it never contacts the network or mutates the real checkout. set -uo pipefail repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" boot="$repo_dir/boot" findings=() note() { findings+=("$1"); } [[ -x "$boot" ]] || { printf 'boot contract: %s is not executable\n' "$boot" >&2; exit 1; } work="$(mktemp -d)" trap 'rm -rf "$work"' EXIT calls="$work/calls" state="$work/state" stub_dir="$work/bin" clone_dir="$work/Panama" revision='0123456789abcdef0123456789abcdef01234567' ancestor_revision='1111111111111111111111111111111111111111' mismatched_revision='fedcba9876543210fedcba9876543210fedcba98' boot_sha="$(sha256sum "$boot" | cut -d' ' -f1)" mkdir -p "$stub_dir" "$state" cat >"$work/fake-install" <>"$calls" STUB chmod +x "$work/fake-install" cat >"$stub_dir/git" <>"$calls" mode="\$(<"$state/mode")" case "\${1:-}" in init) [[ "\$#" -eq 2 && "\$2" == "$clone_dir" ]] || exit 97 mkdir -p "$clone_dir/.git" ;; -C) [[ "\${2:-}" == "$clone_dir" ]] || exit 97 case "\${3:-}" in remote) [[ "\$#" -eq 6 && "\$4" == add && "\$5" == origin \ && "\$6" == https://git.gbrown.org/gib/Panama.git ]] || exit 97 ;; fetch) if [[ "\${4:-}" == --depth=1 ]]; then [[ "\$#" -eq 6 && "\$5" == origin && "\$6" == "$revision" ]] || exit 97 else [[ "\$#" -eq 5 && "\$4" == origin && "\$5" == "$revision" ]] || exit 97 fi [[ "\$mode" != fetch-failure && "\$mode" != fresh-fetch-failure ]] || exit 42 ;; checkout) if [[ "\${4:-}" == --detach ]]; then [[ "\$#" -eq 5 && "\$5" == "$revision" ]] || exit 97 cp "$work/fake-install" "$clone_dir/install" chmod +x "$clone_dir/install" elif [[ "\${4:-}" == -b ]]; then [[ "\$#" -eq 5 && "\$5" == main ]] || exit 97 else exit 97 fi ;; config) case "\${4:-}:\${5:-}:\${6:-}" in branch.main.remote:origin:|branch.main.merge:refs/heads/main:) ;; *) exit 97 ;; esac ;; status) [[ "\$#" -eq 4 && "\$4" == --porcelain ]] || exit 97 cat "$state/status" ;; merge-base) [[ "\$#" -eq 6 && "\$4" == --is-ancestor && "\$5" == HEAD \ && "\$6" == "$revision" ]] || exit 97 [[ "\$mode" != divergent ]] || exit 1 ;; merge) [[ "\$#" -eq 5 && "\$4" == --ff-only && "\$5" == "$revision" ]] || exit 97 if [[ "\$mode" == existing-head-mismatch ]]; then printf '%s\n' '$mismatched_revision' >"$state/head-revision" else printf '%s\n' '$revision' >"$state/head-revision" fi cp "$work/fake-install" "$clone_dir/install" chmod +x "$clone_dir/install" ;; rev-parse) [[ "\$#" -eq 4 && "\$4" == 'HEAD^{commit}' ]] || exit 97 cat "$state/head-revision" ;; *) exit 97 ;; esac ;; *) exit 97 ;; esac STUB chmod +x "$stub_dir/git" configure_case() { local mode="$1" head_revision="${2:-$revision}" status="${3:-}" rm -rf "$clone_dir" : >"$calls" printf '%s\n' "$mode" >"$state/mode" printf '%s\n' "$head_revision" >"$state/head-revision" printf '%s' "$status" >"$state/status" } configure_existing_case() { configure_case "$@" mkdir -p "$clone_dir/.git" cp "$work/fake-install" "$clone_dir/install" chmod +x "$clone_dir/install" } run_boot() { local supplied_revision="$1" supplied_sha="$2" local -a env_args=( "PATH=$stub_dir:$PATH" "PANAMA_PATH=$clone_dir" ) [[ "$supplied_revision" == UNSET ]] \ && env_args+=(-u PANAMA_BOOT_REVISION) \ || env_args+=("PANAMA_BOOT_REVISION=$supplied_revision") [[ "$supplied_sha" == UNSET ]] \ && env_args+=(-u PANAMA_BOOT_SHA256) \ || env_args+=("PANAMA_BOOT_SHA256=$supplied_sha") env "${env_args[@]}" bash "$boot" /dev/null 2>&1 run_status=$? } assert_no_git_or_install() { local case_name="$1" if grep -qE '^(git|install) ' "$calls"; then note "$case_name reached Git or install" fi } assert_no_install_or_rewrite() { local case_name="$1" grep -q '^install ' "$calls" && note "$case_name reached install" grep -qE '^git .* (reset|checkout -B|checkout -f)($| )' "$calls" \ && note "$case_name rewrote the checkout" } # Missing, malformed, or mismatched bootstrap inputs fail before Git. input_cases=( 'missing revision|UNSET|BOOT_SHA' 'short revision|01234567|BOOT_SHA' 'uppercase revision|0123456789ABCDEF0123456789ABCDEF01234567|BOOT_SHA' 'missing digest|REVISION|UNSET' 'short digest|REVISION|01234567' 'uppercase digest|REVISION|AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' 'mismatched digest|REVISION|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' ) for input_case in "${input_cases[@]}"; do IFS='|' read -r name supplied_revision supplied_sha <<<"$input_case" [[ "$supplied_revision" == REVISION ]] && supplied_revision="$revision" [[ "$supplied_sha" == BOOT_SHA ]] && supplied_sha="$boot_sha" configure_case validation-only run_boot "$supplied_revision" "$supplied_sha" (( run_status != 0 )) || note "$name was accepted" assert_no_git_or_install "$name" done # A fresh install fetches only the requested commit, verifies checked-out HEAD, # creates the tracked local main branch, and hands off. configure_case fresh run_boot "$revision" "$boot_sha" (( run_status == 0 )) || note 'verified fresh bootstrap failed' grep -qF "git init $clone_dir" "$calls" \ || note 'fresh bootstrap did not initialize PANAMA_PATH' grep -qF "git -C $clone_dir fetch --depth=1 origin $revision" "$calls" \ || note 'fresh bootstrap did not fetch the exact revision' grep -qF "git -C $clone_dir rev-parse HEAD^{commit}" "$calls" \ || note 'fresh bootstrap did not resolve the checked-out commit' grep -qF "git -C $clone_dir checkout -b main" "$calls" \ || note 'fresh bootstrap did not create local main after verification' grep -qF "git -C $clone_dir config branch.main.remote origin" "$calls" \ || note 'fresh bootstrap did not configure main remote tracking' grep -qF "git -C $clone_dir config branch.main.merge refs/heads/main" "$calls" \ || note 'fresh bootstrap did not configure main merge tracking' grep -qF "install PANAMA_PATH=$clone_dir" "$calls" \ || note 'verified fresh bootstrap did not hand off with PANAMA_PATH' grep -qE '^git (clone|.* pull)' "$calls" \ && note 'fresh bootstrap used mutable clone or pull behavior' # A fetched checkout whose HEAD does not equal the requested commit never # creates the trusted branch or reaches install. configure_case head-mismatch "$mismatched_revision" run_boot "$revision" "$boot_sha" (( run_status != 0 )) || note 'fresh HEAD mismatch returned success' assert_no_install_or_rewrite 'fresh HEAD mismatch' grep -qF "git -C $clone_dir checkout -b main" "$calls" \ && note 'fresh HEAD mismatch created local main before equality passed' # A clean existing ancestor is fetched and advanced with fast-forward only. configure_existing_case existing "$ancestor_revision" run_boot "$revision" "$boot_sha" (( run_status == 0 )) || note 'clean ancestor bootstrap failed' grep -qF "git -C $clone_dir status --porcelain" "$calls" \ || note 'existing checkout cleanliness was not checked' grep -qF "git -C $clone_dir fetch origin $revision" "$calls" \ || note 'existing checkout did not fetch the exact revision' grep -qF "git -C $clone_dir merge-base --is-ancestor HEAD $revision" "$calls" \ || note 'existing checkout ancestry was not checked' grep -qF "git -C $clone_dir merge --ff-only $revision" "$calls" \ || note 'existing checkout was not advanced fast-forward-only' grep -qF "install PANAMA_PATH=$clone_dir" "$calls" \ || note 'verified existing checkout did not reach install' grep -qE '^git .* (reset|pull)($| )' "$calls" \ && note 'existing checkout used reset or pull instead of the exact revision' # Dirty and divergent checkouts fail closed without rewriting or installing. configure_existing_case dirty "$ancestor_revision" $' M boot\n' run_boot "$revision" "$boot_sha" (( run_status != 0 )) || note 'dirty checkout returned success' grep -qF "git -C $clone_dir fetch origin $revision" "$calls" \ && note 'dirty checkout fetched before refusing local work' assert_no_install_or_rewrite 'dirty checkout' configure_existing_case divergent "$ancestor_revision" run_boot "$revision" "$boot_sha" (( run_status != 0 )) || note 'divergent checkout returned success' grep -qF "git -C $clone_dir merge --ff-only $revision" "$calls" \ && note 'divergent checkout attempted a merge' assert_no_install_or_rewrite 'divergent checkout' # Fetch and post-fast-forward equality failures also stop before handoff. configure_existing_case fetch-failure "$ancestor_revision" run_boot "$revision" "$boot_sha" (( run_status != 0 )) || note 'fetch failure returned success' assert_no_install_or_rewrite 'fetch failure' configure_existing_case existing-head-mismatch "$ancestor_revision" run_boot "$revision" "$boot_sha" (( run_status != 0 )) || note 'existing HEAD mismatch returned success' assert_no_install_or_rewrite 'existing HEAD mismatch' if (( ${#findings[@]} > 0 )); then printf 'boot contract: %d finding(s)\n' "${#findings[@]}" >&2 printf ' - %s\n' "${findings[@]}" >&2 exit 1 fi printf 'boot contract: PASS\n'