#!/usr/bin/env bash # Exit-asserting RM-03 regression harness for ci-queue-wait.sh. # Every case is a process-level assertion: a classifier-only green cannot satisfy it. set -u SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" WORK_DIR="${MOSAIC_TEST_WORK_DIR:-$PWD/.mosaic-test-work/ci-queue-wait-tristate}" REPO_DIR="$WORK_DIR/repo" STUB_DIR="$WORK_DIR/stubs" AUDIT_LOG="$WORK_DIR/audit/ci-queue-wait.jsonl" FEATURE_BRANCH="fix/rm-03-fixture" rm -rf "$WORK_DIR" mkdir -p "$REPO_DIR" "$STUB_DIR" git -C "$REPO_DIR" init -q git -C "$REPO_DIR" checkout -q -b "$FEATURE_BRANCH" git -C "$REPO_DIR" remote add origin https://git.example.test/acme/widgets.git cat > "$STUB_DIR/curl" <<'SH' #!/usr/bin/env bash set -euo pipefail url="" has_write_out=0 for arg in "$@"; do case "$arg" in -w) has_write_out=1 ;; http://*|https://*) url="$arg" ;; esac done printf '%s\n' "$url" >> "${MOSAIC_STUB_URL_LOG:?}" case "$url" in */branches/*) if [[ "${MOSAIC_STUB_BRANCH_MODE:-ok}" == "unreachable" ]]; then exit 7 fi body='{"commit":{"id":"deadbeefcafef00d0123456789abcdef01234567"}}' if [[ "$has_write_out" -eq 1 ]]; then printf '%s\n200' "$body" else printf '%s' "$body" fi ;; */status) case "${MOSAIC_STUB_STATUS_MODE:?}" in success) printf '%s' '{"state":"success","statuses":[{"status":"success"}]}' ;; pending) printf '%s' '{"state":"pending","statuses":[{"status":"pending","context":"ci/test"}]}' ;; failure) printf '%s' '{"state":"failure","statuses":[{"status":"failure"}]}' ;; no-status) printf '%s' '{"state":"","statuses":[]}' ;; aggregate-success-no-status) printf '%s' '{"state":"success","statuses":[]}' ;; malformed) printf '%s' 'not-json' ;; malformed-statuses-type) printf '%s' '{"state":"success","statuses":"corrupt"}' ;; malformed-status-entry) printf '%s' '{"state":"success","statuses":[null]}' ;; large-success) python3 -c 'import json; print(json.dumps({"state":"success", "statuses":[{"status":"success"}], "padding":"x" * (160 * 1024)}), end="")' ;; unreachable) exit 7 ;; *) echo "unknown status mode" >&2; exit 2 ;; esac ;; *) echo "unexpected curl URL: $url" >&2; exit 2 ;; esac SH chmod +x "$STUB_DIR/curl" run_guard() { local status_mode="$1" local audit_log="${2:-$AUDIT_LOG}" shift 2 || true ( cd "$REPO_DIR" || exit export PATH="$STUB_DIR:$PATH" export MOSAIC_CREDENTIALS_FILE="$WORK_DIR/no-credentials.json" if [[ "$status_mode" == "credential-unresolvable" ]]; then export HOME="$WORK_DIR/empty-home" mkdir -p "$HOME" unset GITEA_TOKEN GITEA_URL MOSAIC_GIT_IDENTITY export MOSAIC_STUB_STATUS_MODE=success else export GITEA_TOKEN=stub-token export GITEA_URL=https://git.example.test export MOSAIC_STUB_STATUS_MODE="$status_mode" fi export MOSAIC_STUB_URL_LOG="$WORK_DIR/urls.log" export MOSAIC_CI_QUEUE_AUDIT_LOG="$audit_log" "$SCRIPT_DIR/ci-queue-wait.sh" --purpose "${MOSAIC_TEST_PURPOSE:-push}" -t 0 -i 0 "$@" ) } failures=0 run_assertion() { local name="$1" expected_rc="$2" status_mode="$3" required_text="$4" local output rc shift 4 set +e output=$(run_guard "$status_mode" "$AUDIT_LOG" "$@" 2>&1) rc=$? set -e case "$expected_rc" in zero) if [[ "$rc" -ne 0 ]]; then echo "FAIL $name: expected rc=0, got rc=$rc" >&2 failures=$((failures + 1)) fi ;; nonzero) if [[ "$rc" -eq 0 ]]; then echo "FAIL $name: expected rc!=0, got rc=0" >&2 failures=$((failures + 1)) fi ;; not126) if [[ "$rc" -eq 126 ]]; then echo "FAIL $name: payload transport hit ARG_MAX (rc=126)" >&2 failures=$((failures + 1)) fi ;; esac if [[ "$output" != *"$required_text"* ]]; then echo "FAIL $name: output missing '$required_text' (rc=$rc)" >&2 printf '%s\n' "$output" >&2 failures=$((failures + 1)) fi } set -e : > "$WORK_DIR/urls.log" run_assertion success zero success 'state=terminal-success' run_assertion pending nonzero pending 'ASSERTED_NOT_READY' run_assertion failure nonzero failure 'ASSERTED_NOT_READY' run_assertion no-status nonzero no-status 'ASSERTED_NOT_READY' run_assertion aggregate-success-no-status nonzero aggregate-success-no-status 'ASSERTED_NOT_READY' run_assertion malformed nonzero malformed 'ASSERTED_NOT_READY' run_assertion malformed-statuses-type nonzero malformed-statuses-type 'ASSERTED_NOT_READY' run_assertion malformed-status-entry nonzero malformed-status-entry 'ASSERTED_NOT_READY' run_assertion large-payload not126 large-success 'state=terminal-success' run_assertion credential-unresolvable zero credential-unresolvable 'CANNOT_ASSERT' run_assertion provider-unreachable zero unreachable 'CANNOT_ASSERT' if [[ ! -s "$AUDIT_LOG" ]] || ! grep -q '"outcome":"CANNOT_ASSERT"' "$AUDIT_LOG"; then echo "FAIL provider-unreachable-audit: expected durable CANNOT_ASSERT JSONL record" >&2 failures=$((failures + 1)) fi # Merge cannot proceed without exact-head evidence. CANNOT_ASSERT is retryable exit 75, # distinct from ASSERTED_NOT_READY (3/124), and still writes its audit record. merge_audit_lines_before=$(wc -l < "$AUDIT_LOG") set +e merge_unreachable_output=$(MOSAIC_TEST_PURPOSE=merge run_guard unreachable "$AUDIT_LOG" 2>&1) merge_unreachable_rc=$? set -e if [[ "$merge_unreachable_rc" -ne 75 ]]; then echo "FAIL merge-provider-unreachable: expected rc=75, got rc=$merge_unreachable_rc" >&2 failures=$((failures + 1)) fi if [[ "$merge_unreachable_output" != *"CANNOT_ASSERT"* ]]; then echo "FAIL merge-provider-unreachable: expected loud CANNOT_ASSERT diagnostic" >&2 failures=$((failures + 1)) fi merge_audit_lines_after=$(wc -l < "$AUDIT_LOG") if [[ "$merge_audit_lines_after" -le "$merge_audit_lines_before" ]]; then echo "FAIL merge-provider-unreachable: expected an additional audit record" >&2 failures=$((failures + 1)) fi # A feature-branch push with no -B must inspect the checked-out feature branch. if ! grep -q "/branches/$FEATURE_BRANCH" "$WORK_DIR/urls.log"; then echo "FAIL implicit-branch: provider was not queried for $FEATURE_BRANCH" >&2 failures=$((failures + 1)) fi # Merge callers can pin both a fork repository and the exact reviewed head SHA. exact_sha=0123456789abcdef0123456789abcdef01234567 : > "$WORK_DIR/urls.log" run_assertion exact-fork-head zero success 'state=terminal-success' \ -B fix/rm-03-fixture -R contributor/widgets-fork --sha "$exact_sha" if ! grep -q "/repos/contributor/widgets-fork/commits/$exact_sha/status" "$WORK_DIR/urls.log"; then echo "FAIL exact-fork-head: status URL did not bind fork repository and exact SHA" >&2 failures=$((failures + 1)) fi if grep -q '/branches/' "$WORK_DIR/urls.log"; then echo "FAIL exact-fork-head: explicit SHA must not be re-resolved through a branch" >&2 failures=$((failures + 1)) fi # Platform/repository discovery failures use the same audited CANNOT_ASSERT path. audit_lines_before=$(wc -l < "$AUDIT_LOG") git -C "$REPO_DIR" remote set-url origin https://gitlab.com/acme/widgets.git set +e unsupported_output=$(run_guard success "$AUDIT_LOG" 2>&1) unsupported_rc=$? set -e git -C "$REPO_DIR" remote set-url origin https://git.example.test/acme/widgets.git if [[ "$unsupported_rc" -ne 0 ]]; then echo "FAIL unsupported-platform: expected degraded rc=0, got rc=$unsupported_rc" >&2 failures=$((failures + 1)) fi if [[ "$unsupported_output" != *"CANNOT_ASSERT"* ]]; then echo "FAIL unsupported-platform: expected loud CANNOT_ASSERT diagnostic" >&2 failures=$((failures + 1)) fi audit_lines_after=$(wc -l < "$AUDIT_LOG") if [[ "$audit_lines_after" -le "$audit_lines_before" ]]; then echo "FAIL unsupported-platform: expected an additional audit record" >&2 failures=$((failures + 1)) fi # A degraded pass is forbidden if the audit receipt cannot be written. mkdir -p "$WORK_DIR/not-a-directory" printf 'file' > "$WORK_DIR/not-a-directory/parent" set +e audit_failure_output=$(run_guard unreachable "$WORK_DIR/not-a-directory/parent/audit.jsonl" 2>&1) audit_failure_rc=$? set -e if [[ "$audit_failure_rc" -eq 0 ]]; then echo "FAIL audit-unavailable: expected rc!=0, got rc=0" >&2 failures=$((failures + 1)) fi if [[ "$audit_failure_output" != *"audit"* ]]; then echo "FAIL audit-unavailable: expected loud audit failure diagnostic" >&2 failures=$((failures + 1)) fi if [[ "$failures" -ne 0 ]]; then echo "ci-queue-wait tri-state regression failed ($failures assertions)" >&2 exit 1 fi echo "ci-queue-wait tri-state regression passed (all outcome classes)"