GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — mcpproxy-go/scripts/go-test-retry-runtime-fault.test.sh at main · DocSpring/mcpproxy-go Expand file tree/ Copy pathgo-test-retry-runtime-fault.test.shMore file actions executable file ·242 lines (216 loc) · 12.5 KB / Copy pathgo-test-retry-runtime-fault.test.shFile metadata and controlsexecutable file ·242 lines (216 loc) · 12.5 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 #!/usr/bin/env bash # go-test-retry-runtime-fault.test.sh — red/green self-test for # go-test-retry-runtime-fault.sh (issue #1794). Hermetic: a fake `go` on PATH # replays canned output, counts its invocations and records the package list # it was given, so the test proves the retry fires only when every failed # package died of a runtime fault, re-runs only those packages, keeps the # coverage profile, and never retries when any package shows a genuine # failure (assertion, timeout, data race, build failure) — including a # genuine failure sitting next to a fault, in the same package or another. # Run directly: ./scripts/go-test-retry-runtime-fault.test.sh (bash 3.2 ok) set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SUT="$SCRIPT_DIR/go-test-retry-runtime-fault.sh" pass=0 fail=0 check() { # desc, then the condition command (exit 0 = pass) local desc="$1" shift if "$@"; then echo "ok - $desc" pass=$((pass + 1)) else echo "FAIL - $desc" fail=$((fail + 1)) fi } work="$(mktemp -d)" trap 'rm -rf "$work"' EXIT mkdir -p "$work/bin" cat > "$work/bin/go" <<'FAKE' #!/usr/bin/env bash # Fake `go`: CASE_DIR holds run1.out/run1.exit and run2.out/run2.exit; the # invocation count lives in CASE_DIR/count and every argv is appended to # CASE_DIR/argv. n=$(( $(cat "$CASE_DIR/count" 2>/dev/null || echo 0) + 1 )) echo "$n" > "$CASE_DIR/count" printf '%s\n' "$*" >> "$CASE_DIR/argv" for a in "$@"; do case "$a" in -coverprofile=*) printf 'mode: atomic\nrun%d.go:1.1,2.2 1 1\n' "$n" > "${a#-coverprofile=}" ;; esac done cat "$CASE_DIR/run$n.out" exit "$(cat "$CASE_DIR/run$n.exit")" FAKE chmod +x "$work/bin/go" export PATH="$work/bin:$PATH" new_case() { # name -> sets CASE_DIR (exported for the fake go) and d d="$work/$1" mkdir -p "$d" export CASE_DIR="$d" } count() { cat "$d/count" 2>/dev/null || echo 0; } argv_line() { sed -n "${1}p" "$d/argv"; } FAULT_OUT=$'=== RUN TestSolR2\nunexpected fault address 0xffffffffffffffff\nfatal error: fault\n[signal 0xc0000005 code=0x0 addr=0xffffffffffffffff pc=0x7ff7]\nFAIL\tgithub.com/x/y/internal/security/scanner\t12.345s\nok \tgithub.com/x/y/internal/other\t0.100s\nFAIL' ASSERT_OUT=$'=== RUN TestThing\n thing_test.go:12: expected 1, got 2\n--- FAIL: TestThing (0.00s)\nFAIL\tgithub.com/x/y/internal/thing\t0.200s\nFAIL' TIMEOUT_OUT=$'panic: test timed out after 20m0s\nFAIL\tgithub.com/x/y/cmd/mcpproxy\t1200.360s\nFAIL' BUILD_OUT=$'# github.com/x/y/internal/broken\nbroken.go:3:1: syntax error\nFAIL\tgithub.com/x/y/internal/broken [build failed]\nFAIL' OK_OUT=$'ok \tgithub.com/x/y/internal/security/scanner\t11.000s' # A fault in one package and a genuine failure in another, in one run. FAULT_PLUS_ASSERT_OUT="$ASSERT_OUT"$'\n'"$FAULT_OUT" FAULT_PLUS_TIMEOUT_OUT="$FAULT_OUT"$'\n'"$TIMEOUT_OUT" FAULT_PLUS_BUILD_OUT="$FAULT_OUT"$'\n'"$BUILD_OUT" # A fault AND an assertion failure inside the same package block. FAULT_SAME_PKG_ASSERT_OUT=$'=== RUN TestA\n a_test.go:9: boom\n--- FAIL: TestA (0.00s)\n=== RUN TestB\nunexpected fault address 0xffffffffffffffff\nfatal error: fault\nFAIL\tgithub.com/x/y/internal/mixed\t3.000s\nFAIL' # A data race report next to a fault in the same package. FAULT_PLUS_RACE_OUT=$'=== RUN TestR\nWARNING: DATA RACE\nRead at 0x00c0 by goroutine 7:\nunexpected fault address 0xffffffffffffffff\nfatal error: fault\nFAIL\tgithub.com/x/y/internal/racy\t2.000s\nFAIL' # Test diagnostics that merely CONTAIN the fault words (indented by testing). DIAG_TEXT_OUT=$'=== RUN TestResponse\n thing_test.go:12: expected no "fatal error: fault" in response, got unexpected fault address 0xdead\n--- FAIL: TestResponse (0.00s)\nFAIL\tgithub.com/x/y/internal/diag\t0.100s\nFAIL' # 1. Runtime fault, retry passes: exit 0, exactly two invocations, the second # narrowed to the failed package, flags preserved, warning annotation out. new_case fault_then_pass printf '%s\n' "$FAULT_OUT" > "$d/run1.out"; echo 2 > "$d/run1.exit" printf '%s\n' "$OK_OUT" > "$d/run2.out"; echo 0 > "$d/run2.exit" out=$("$SUT" -v -race -timeout 40m -- ./... 2>&1); st=$? check "fault then pass: exit 0" [ "$st" -eq 0 ] check "fault then pass: two go invocations" [ "$(count)" = 2 ] check "fault then pass: retry narrowed to the failed package with the same flags" \ [ "$(argv_line 2)" = "test -v -race -timeout 40m github.com/x/y/internal/security/scanner" ] check "fault then pass: ::warning:: annotation names the package" \ grep -q '::warning.*github.com/x/y/internal/security/scanner' <<<"$out" # 2. Runtime fault, retry fails too: non-zero exit, two invocations. new_case fault_then_fail printf '%s\n' "$FAULT_OUT" > "$d/run1.out"; echo 2 > "$d/run1.exit" printf '%s\n' "$ASSERT_OUT" > "$d/run2.out"; echo 1 > "$d/run2.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "fault then fail: exit non-zero" [ "$st" -ne 0 ] check "fault then fail: two go invocations" [ "$(count)" = 2 ] # 3. Ordinary assertion failure: never retried, original exit kept. new_case assertion printf '%s\n' "$ASSERT_OUT" > "$d/run1.out"; echo 1 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "assertion failure: exit 1 unchanged" [ "$st" -eq 1 ] check "assertion failure: one go invocation" [ "$(count)" = 1 ] # 4. Test timeout: not a fault, never retried. new_case timeout printf '%s\n' "$TIMEOUT_OUT" > "$d/run1.out"; echo 1 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "timeout: exit 1 unchanged" [ "$st" -eq 1 ] check "timeout: one go invocation" [ "$(count)" = 1 ] # 5. Build failure: not a fault, never retried. new_case build printf '%s\n' "$BUILD_OUT" > "$d/run1.out"; echo 1 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "build failure: exit 1 unchanged" [ "$st" -eq 1 ] check "build failure: one go invocation" [ "$(count)" = 1 ] # 6. Green run: one invocation, exit 0. new_case green printf '%s\n' "$OK_OUT" > "$d/run1.out"; echo 0 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "green: exit 0" [ "$st" -eq 0 ] check "green: one go invocation" [ "$(count)" = 1 ] # 7. Coverage profile: the retry writes FILE.retry and it is folded into FILE # with a single mode line. new_case coverage printf '%s\n' "$FAULT_OUT" > "$d/run1.out"; echo 2 > "$d/run1.exit" printf '%s\n' "$OK_OUT" > "$d/run2.out"; echo 0 > "$d/run2.exit" cov="$d/coverage.out" "$SUT" -v "-coverprofile=$cov" -- ./... >/dev/null 2>&1; st=$? check "coverage: exit 0" [ "$st" -eq 0 ] check "coverage: retry wrote to FILE.retry" grep -q -- "-coverprofile=$cov.retry" <<<"$(argv_line 2)" check "coverage: one mode line" [ "$(grep -c '^mode:' "$cov")" = 1 ] check "coverage: first run rows kept" grep -q 'run1.go' "$cov" check "coverage: retry rows appended" grep -q 'run2.go' "$cov" check "coverage: FILE.retry removed" [ ! -f "$cov.retry" ] # 9. Fault in one package, assertion failure in another: never retried, the # first run's exit is kept (a retry could let an order-dependent failure # pass). new_case fault_plus_assert printf '%s\n' "$FAULT_PLUS_ASSERT_OUT" > "$d/run1.out"; echo 1 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "fault + assertion elsewhere: exit 1 unchanged" [ "$st" -eq 1 ] check "fault + assertion elsewhere: one go invocation" [ "$(count)" = 1 ] # 10. Fault in one package, timeout in another: never retried. new_case fault_plus_timeout printf '%s\n' "$FAULT_PLUS_TIMEOUT_OUT" > "$d/run1.out"; echo 1 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "fault + timeout elsewhere: exit 1 unchanged" [ "$st" -eq 1 ] check "fault + timeout elsewhere: one go invocation" [ "$(count)" = 1 ] # 11. Fault in one package, build failure in another: never retried. new_case fault_plus_build printf '%s\n' "$FAULT_PLUS_BUILD_OUT" > "$d/run1.out"; echo 1 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "fault + build failure elsewhere: exit 1 unchanged" [ "$st" -eq 1 ] check "fault + build failure elsewhere: one go invocation" [ "$(count)" = 1 ] # 12. Fault and an assertion failure in the SAME package: never retried. new_case fault_same_pkg_assert printf '%s\n' "$FAULT_SAME_PKG_ASSERT_OUT" > "$d/run1.out"; echo 1 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "fault + assertion in the same package: exit 1 unchanged" [ "$st" -eq 1 ] check "fault + assertion in the same package: one go invocation" [ "$(count)" = 1 ] # 13. Fault next to a data race report: never retried. new_case fault_plus_race printf '%s\n' "$FAULT_PLUS_RACE_OUT" > "$d/run1.out"; echo 1 > "$d/run1.exit" "$SUT" -v -race -- ./... >/dev/null 2>&1; st=$? check "fault + data race: exit 1 unchanged" [ "$st" -eq 1 ] check "fault + data race: one go invocation" [ "$(count)" = 1 ] # 14. Test diagnostics that only mention the fault words (indented) are not # a runtime fault: never retried. new_case diag_text printf '%s\n' "$DIAG_TEXT_OUT" > "$d/run1.out"; echo 1 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "diagnostic text only: exit 1 unchanged" [ "$st" -eq 1 ] check "diagnostic text only: one go invocation" [ "$(count)" = 1 ] # 15. Two faulted packages, nothing else: both retried, nothing more. new_case two_faults printf '%s\n' "$FAULT_OUT" $'unexpected fault address 0xffffffffffffffff\nfatal error: fault\nFAIL\tgithub.com/x/y/internal/second\t1.000s\nFAIL' > "$d/run1.out"; echo 2 > "$d/run1.exit" printf '%s\n' "$OK_OUT" $'ok \tgithub.com/x/y/internal/second\t0.100s' > "$d/run2.out"; echo 0 > "$d/run2.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "two faults: exit 0" [ "$st" -eq 0 ] check "two faults: retry lists exactly the two packages" \ [ "$(argv_line 2)" = "test -v github.com/x/y/internal/security/scanner github.com/x/y/internal/second" ] # 16. No flags at all (`-- ./...`) must work under set -u on bash 3.2. new_case no_flags printf '%s\n' "$OK_OUT" > "$d/run1.out"; echo 0 > "$d/run1.exit" "$SUT" -- ./... >/dev/null 2>&1; st=$? check "no flags: exit 0" [ "$st" -eq 0 ] check "no flags: go ran with the packages only" [ "$(argv_line 1)" = "test ./..." ] # 17. A PASSING package whose output carries unindented fault-looking text # (a println in a test), followed by a package that fails silently (no # `--- FAIL:`, e.g. os.Exit(1) in TestMain): the `ok \t` summary line # must reset the block, so the silent failure is not retried. new_case ok_block_leak printf '%s\n' $'=== RUN TestLog\nfatal error: fault\n--- PASS: TestLog (0.00s)\nok \tgithub.com/x/y/internal/noisy\t0.100s\n=== RUN TestMainExit\nFAIL\tgithub.com/x/y/internal/silent\t0.200s\nFAIL' > "$d/run1.out"; echo 1 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "ok block leak: exit 1 unchanged" [ "$st" -eq 1 ] check "ok block leak: one go invocation" [ "$(count)" = 1 ] # 18. A `? \t<pkg>\t[no test files]` line also closes a block. new_case question_block printf '%s\n' $'fatal error: fault\n? \tgithub.com/x/y/internal/notests\t[no test files]\nFAIL\tgithub.com/x/y/internal/silent\t0.200s\nFAIL' > "$d/run1.out"; echo 1 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "question-mark block: exit 1 unchanged" [ "$st" -eq 1 ] check "question-mark block: one go invocation" [ "$(count)" = 1 ] # 19. An INDENTED subtest `--- FAIL:` (the parent crashed before reporting) # next to a fault in the same package: a genuine failure, never retried. new_case subtest_fail_then_fault printf '%s\n' $'=== RUN TestParent\n=== RUN TestParent/sub\n p_test.go:9: boom\n --- FAIL: TestParent/sub (0.00s)\n=== RUN TestParent/next\nunexpected fault address 0xffffffffffffffff\nfatal error: fault\nFAIL\tgithub.com/x/y/internal/parent\t1.000s\nFAIL' > "$d/run1.out"; echo 2 > "$d/run1.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "indented subtest FAIL + fault: exit 2 unchanged" [ "$st" -eq 2 ] check "indented subtest FAIL + fault: one go invocation" [ "$(count)" = 1 ] # 20. CRLF log lines (a Windows pipe that converted line endings) still # count as a fault, and the summary line still closes the block. new_case crlf printf '%s\r\n' '=== RUN TestSolR2' 'unexpected fault address 0xffffffffffffffff' 'fatal error: fault' $'FAIL\tgithub.com/x/y/internal/security/scanner\t12.345s' 'FAIL' > "$d/run1.out"; echo 2 > "$d/run1.exit" printf '%s\n' "$OK_OUT" > "$d/run2.out"; echo 0 > "$d/run2.exit" "$SUT" -v -- ./... >/dev/null 2>&1; st=$? check "crlf: exit 0" [ "$st" -eq 0 ] check "crlf: two go invocations" [ "$(count)" = 2 ] # 8. Usage: no `--` separator is a usage error, go never runs. new_case usage "$SUT" -v ./... >/dev/null 2>&1; st=$? check "usage: missing -- exits 64" [ "$st" -eq 64 ] check "usage: go never ran" [ ! -f "$d/count" ] echo echo "$pass passed, $fail failed" [ "$fail" -eq 0 ] |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |