Files
orca/scripts/tests/install_test.bash
Jon Chery 61c97c847c fix(P1): recompute TARBALL after fallback version walk (REQ-132)
The fallback walk (REQ-098) reassigns VERSION from the requested
release to the nearest older release carrying a binary asset, but
never recomputed TARBALL (set once at line 106 from the requested
version). The stale tarball name then flowed into:

  - grep -F "$TARBALL" SHA256SUMS  -> matched nothing (the fallback
    release's SHA256SUMS only lists the fallback tarball)
  - sha256sum -c -                 -> empty stdin -> "no properly
    formatted checksum lines found" -> REQ-132 refusal
  - tar -xzf "${TMPDIR}/${TARBALL}" -> would look for the wrong
    filename (download saved under the stale name too)

User-visible symptom (v0.14.2 latest had no asset, fell back to
v0.12.18):

  install: verifying checksum...
  sha256sum: 'standard input': no properly formatted checksum lines found
  install: error: checksum verification failed (REQ-132); refusing to install

Fix: recompute TARBALL immediately after VERSION is reassigned in the
fallback branch, so download/grep/sha256sum/tar all reference the
fallback version's tarball. ASSET_URL and SHA256SUMS_URL were already
correct (derived from the API/ASSET_URL); TARBALL was the only stale
variable.

Reproduced the exact error before the fix; confirmed end-to-end
install succeeds after (orca-v0.12.18-linux-amd64.tar.gz: OK ->
extracting -> installed). Added a bats regression test pinning
--version v0.14.2 and asserting the dry-run "would install" line
references the fallback version (not the stale pinned one).

---ci---
project: orca
phase: 1
milestone: v0.15
status: execute
decisions:
  - id: D-001
    decision: Recompute TARBALL in the fallback branch immediately
      after VERSION is reassigned, so grep/sha256sum/tar use the
      fallback version's filename instead of the stale requested
      version's.
    rationale: Reproduced the exact user error ("no properly formatted
      checksum lines found") by running grep -F "$TARBALL" SHA256SUMS
      | sha256sum -c with a stale v0.14.2 tarball name against v0.12.18
      SHA256SUMS. TARBALL is the only stale variable: ASSET_URL and
      VERSION are correctly updated from API output, and SHA256SUMS_URL
      derives from ASSET_URL. Single-line fix, minimal blast radius,
      preserves the working non-fallback path.
    confidence: 0.96
    alternatives:
      - lazy TARBALL via a function (over-engineering for one stale
        assignment)
      - move TARBALL= assignment past the fallback block (breaks
        find_asset_url which needs the requested version's name
        pre-walk)
lessons:
  - When a fallback/walk mutates one variable (VERSION), audit every
    variable derived from it (TARBALL) for the same mutation. The
    user-facing info line at 167 constructed the name inline and
    looked correct, masking that the variable itself was stale.
---/ci---
2026-08-10 21:18:24 +00:00

85 lines
3.7 KiB
Bash

#!/usr/bin/env bats
# Tests for scripts/install.sh (REQ-098: fallback walk + --check dry-run).
# Hermetic: tests the argument parsing, arch detection, and --check
# output formatting without hitting the Gitea API. The network-dependent
# fallback walk is tested via a mock curl in a separate test.
load test_helper
@test "install.sh --help exits 0 and shows usage" {
run "$SCRIPTS_DIR/install.sh" --help
assert_status 0 "$status"
assert_contains "$output" "--system"
assert_contains "$output" "--version"
assert_contains "$output" "--check"
assert_contains "$output" "--help"
}
@test "install.sh --check flag is parsed without error" {
# --check with a pinned version that exists (v0.4.5) should succeed
# and print the dry-run block. This is a live integration test against
# the public Gitea API; skip if network is unavailable.
skip_if_no_network
run "$SCRIPTS_DIR/install.sh" --check --version v0.4.5
assert_status 0 "$status"
assert_contains "$output" "dry-run (--check)"
assert_contains "$output" "would install: orca v0.4.5"
assert_contains "$output" "no files will be written"
}
@test "install.sh --check falls back when latest release has no asset" {
# v0.9.0 is a pre-execution release with no binary asset. --check
# should walk back and find v0.4.5 (which has an asset), printing
# a warning. This is a live integration test; skip if no network.
skip_if_no_network
run timeout 60 "$SCRIPTS_DIR/install.sh" --check --version v0.9.0
assert_status 0 "$status"
assert_contains "$output" "WARNING"
assert_contains "$output" "falling back"
assert_contains "$output" "dry-run (--check)"
}
@test "install.sh fallback walk syncs TARBALL to fallback version (REQ-132 regression)" {
# Regression guard: when the fallback walk reassigns VERSION, the
# TARBALL variable must be recomputed too. v0.14.2 is a release with
# no binary asset; the installer must walk back to an earlier release.
# The dry-run "would install" line must reference the SAME fallback
# version as the "falling back to" line — not the stale pinned one.
# Before the fix, TARBALL stayed at the pinned v0.14.2 name while
# VERSION became the fallback, causing grep|sha256sum to see no
# matching checksum line and REQ-132 to refuse install.
skip_if_no_network
run timeout 60 "$SCRIPTS_DIR/install.sh" --check --version v0.14.2
assert_status 0 "$status"
assert_contains "$output" "falling back"
# Capture the fallback version from the "falling back to vX.Y.Z" line.
fb_version="$(printf '%s\n' "$output" | sed -n 's/.*falling back to \(v[0-9][0-9.]*\).*/\1/p' | head -1)"
[ -n "$fb_version" ] || { echo "could not parse fallback version from output: $output" >&2; return 1; }
# The dry-run "would install" line must use the fallback version,
# proving VERSION and TARBALL are in sync (not the stale pinned v0.14.2).
assert_contains "$output" "would install: orca ${fb_version}"
# And it must NOT reference the stale pinned version in the install line.
assert_not_contains "$output" "would install: orca v0.14.2"
}
@test "install.sh rejects unknown arguments" {
run "$SCRIPTS_DIR/install.sh" --bogus-flag
[ "$status" -ne 0 ]
assert_contains "$output" "unknown argument"
}
@test "install.sh --system requires root" {
# Only test the root check if we're NOT root (CI may run as root).
if [ "$(id -u)" -eq 0 ]; then
skip "running as root; --system root check not testable"
fi
run "$SCRIPTS_DIR/install.sh" --system --version v0.4.5 --check
[ "$status" -ne 0 ]
assert_contains "$output" "--system requires root"
}
# Helper: skip if the Gitea instance is unreachable.
skip_if_no_network() {
curl -fsSL --max-time 5 "https://git.cloudinit.dev/api/v1/repos/coreci/orca/releases/tags/v0.4.5" >/dev/null 2>&1 \
|| skip "Gitea API unreachable — network-dependent test skipped"
}