diff --git a/test/cli.sh b/test/cli.sh index fe94771..073d749 100644 --- a/test/cli.sh +++ b/test/cli.sh @@ -3349,12 +3349,25 @@ check "forgejo-runner: --version refuses a path, not a release number" 2 "releas "$FR" --instance https://f.example.com --version ../../etc/passwd check "forgejo-runner: --version refuses a non-numeric pin" 2 "release number like" \ "$FR" --instance https://f.example.com --version latest -# Reaching the root check is the proof a good pin got THROUGH validation: this -# runs as a normal user in CI, so "must run as root" is the next gate down. -check "forgejo-runner: a plain release number passes validation" 1 "must run as root" \ - "$FR" --instance https://f.example.com --version 12.13.2 -check "forgejo-runner: a leading v is stripped before that check" 1 "must run as root" \ - "$FR" --instance https://f.example.com --version v12.13.2 +# Reaching the gate BELOW validation is the proof a good pin got THROUGH it. +# Which gate that is depends on who runs the suite, and both readings are +# equally good evidence: a normal user hits "must run as root", while root +# itself gets further, to the token prompt. Asserting only the first made these +# two checks depend on the account the suite happened to run under — #136's +# class again, surfaced by the Forgejo runner, which runs job containers as +# uid 0 where GitHub's runner is the unprivileged `runner` user. Either way the +# exit is 1 and validation is behind us, which is the whole claim (#144). +past_version_validation() { + local out rc + out="$("$FR" --instance https://f.example.com --version "$1" 2>&1)"; rc=$? + [ "$rc" -eq 1 ] || { printf 'exit %s, wanted 1\n' "$rc"; return 1; } + printf '%s' "$out" | grep -qE 'must run as root|FORGEJO_RUNNER_TOKEN is unset' \ + || { printf 'neither gate below validation was reached:\n%s\n' "$out"; return 1; } +} +check "forgejo-runner: a plain release number passes validation" 0 "" \ + past_version_validation 12.13.2 +check "forgejo-runner: a leading v is stripped before that check" 0 "" \ + past_version_validation v12.13.2 # A schemeless host and a repo URL are the two ways an operator mis-states the # instance, and only one of them would fail loudly on its own — a repo URL # registers somewhere subtly wrong instead. Both refuse by name.