Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion .github/scripts/observe-go-cache.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ set -euo pipefail
export LC_ALL=C
prefix='[Test] Validate Go Project - Isolated PostgreSQL / '
fail() { printf 'native-go-cache: %s\n' "$*" >&2; exit 2; }
diagnose_jobs() {
local summary
summary="$(jq -cse --argjson run "$run" --argjson attempt "$attempt" --arg head "$head" --arg prefix "$prefix" '
def positive: type == "number" and . > 0 and floor == .;
(if length == 1 then .[0] else error("expected one job inventory") end) |
if type == "array" and length > 0 and
all(.[]; type == "object" and (.total_count | positive) and (.jobs | type == "array"))
then [.[].jobs[]] as $all |
[$all[] | select(.name | type == "string") | select(.name | startswith($prefix))] as $fixture |
{pages:length, reported_totals:([.[].total_count] | unique | .[0:8]),
total_count_variants:([.[].total_count] | unique | length),
fetched_jobs:($all | length), duplicate_ids:(($all | length) - ($all | map(.id) | unique | length)),
fixture_jobs:($fixture | length), fixture_invalid:([$fixture[] | select(
((.id | positive) and .run_id == $run and .run_attempt == $attempt and .head_sha == $head and
.status == "completed" and .conclusion == "success" and (.steps | type == "array") and
([.steps[].name] | length == (unique | length))) | not)] | length)}
else {state:"invalid_shape"} end
' "$jobs" 2>/dev/null)" || summary='{"state":"unreadable"}'
printf 'native-go-cache: job-evidence-summary=%s\n' "$summary" >&2
}
validate_jobs() {
jq -e --argjson run "$run" --argjson attempt "$attempt" --arg head "$head" --arg prefix "$prefix" '
def positive: type == "number" and . > 0 and floor == .;
Expand All @@ -19,7 +39,10 @@ validate_jobs() {
all($fixture[]; (.id | positive) and .run_id == $run and .run_attempt == $attempt and .head_sha == $head and
.status == "completed" and .conclusion == "success" and (.steps | type == "array") and
([.steps[].name] | length == (unique | length))))
' "$jobs" >/dev/null 2>&1 || fail 'incomplete, stale or unsuccessful current-attempt jobs'
' "$jobs" >/dev/null 2>&1 || {
diagnose_jobs
fail 'incomplete, stale or unsuccessful current-attempt jobs'
}
}
normalize_log() {
sed -E 's/^[0-9]{4}-[0-9T:.+-]+Z //; s/^Cache saved with the key: /Cache saved with key: /' "$1"
Expand Down
41 changes: 41 additions & 0 deletions .github/tests/test-go-cache-native-observer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,47 @@ reject_jobs '.[1].jobs[0].head_sha = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"'
reject_jobs '.[1].jobs[0].status = "in_progress"'
reject_jobs '.[1].jobs[0].name += " unexpected"'
reject_jobs '.[1].jobs[1].steps |= map(select(.name != "Save Go module cache"))'
reject_jobs_with_summary() {
reject_jobs "$1"
local summary
summary="$(sed -n 's/^native-go-cache: job-evidence-summary=//p' "$scratch/error")"
[[ -n "$summary" ]] || fail 'rejected jobs have no sanitized diagnostic'
jq -e '
if keys == ["state"] then .state | IN("invalid_shape", "unreadable")
else keys == ["duplicate_ids", "fetched_jobs", "fixture_invalid", "fixture_jobs", "pages", "reported_totals", "total_count_variants"] and
(.reported_totals | length <= 8 and all(.[]; type == "number" and . > 0 and floor == .)) and
(del(.reported_totals) | all(.[]; type == "number" and . >= 0 and floor == .)) end
' <<<"$summary" >/dev/null || fail 'diagnostic exposed unapproved fields or unbounded values'
jq -e "$2" <<<"$summary" >/dev/null || fail 'diagnostic does not identify the rejected invariant'
}
reject_jobs_with_summary '.[0].total_count = 10' \
'.pages == 2 and .reported_totals == [9,10] and .fetched_jobs == 9 and .duplicate_ids == 0 and .fixture_jobs == 9'
reject_jobs_with_summary '.[1].jobs |= .[1:]' \
'.reported_totals == [9] and .fetched_jobs == 8 and .duplicate_ids == 0 and .fixture_jobs == 8'
reject_jobs_with_summary '.[1].jobs[0] = .[1].jobs[1]' \
'.fetched_jobs == 9 and .duplicate_ids == 1 and .fixture_jobs == 9'
reject_jobs_with_summary '.[1].jobs[0].run_attempt = 1' \
'.fixture_invalid == 1 and .fixture_jobs == 9 and .duplicate_ids == 0'
reject_jobs_with_summary '.[1].jobs[0].status = "in_progress"' \
'.fixture_invalid == 1 and .fixture_jobs == 9'
reject_jobs_with_summary '. + [range(10;22) | {total_count:.,jobs:[]}]' \
'.pages == 14 and .total_count_variants == 13 and (.reported_totals | length == 8)'
# Only scalar counts may leave rejected evidence; never echo native names,
# identifiers, arbitrary response text or parser diagnostics.
reject_jobs_with_summary '.[0].total_count = "private-response-sentinel"' \
'. == {state:"invalid_shape"}'
if grep -q 'private-response-sentinel' "$scratch/error"; then fail 'diagnostic disclosed raw evidence'; fi
printf 'not-json private-response-sentinel\n' >"$scratch/jobs.json"
if check pr >"$scratch/out" 2>"$scratch/error"; then fail 'malformed evidence passed'; fi
[[ ! -s "$scratch/out" ]] || fail 'malformed evidence published success'
grep -qx 'native-go-cache: job-evidence-summary={"state":"unreadable"}' "$scratch/error" || fail 'malformed evidence lacks a safe diagnostic'
if grep -q 'private-response-sentinel' "$scratch/error"; then fail 'parser disclosed raw evidence'; fi
for evidence in '' ' ' '{} {}'; do
printf '%s\n' "$evidence" >"$scratch/jobs.json"
if check pr >"$scratch/out" 2>"$scratch/error"; then fail 'empty or multiple-root evidence passed'; fi
[[ ! -s "$scratch/out" ]] || fail 'invalid JSON stream published success'
grep -qx 'native-go-cache: job-evidence-summary={"state":"unreadable"}' "$scratch/error" || fail 'invalid JSON stream lacks one safe diagnostic'
done
cp "$scratch/good-jobs.json" "$scratch/jobs.json"
cp "$scratch/logs/108.log" "$scratch/good-scan.log"
printf 'Cache saved with the key: setup-go-unsafe\n' >>"$scratch/logs/108.log"
Expand Down
Loading