Repository navigation
ci: print live test results to the job log #242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
026c9d0
ci: print live test results to the job log
goanpeca d2c4ace
ci: harden the live test log output
goanpeca 8388b64
test: make the long-output case fill the pipe
goanpeca 8c51636
ci: show timeout and panic output in the live test log
goanpeca a946c0c
ci: keep both ends of long failed-test output
goanpeca 1e1279f
ci: budget live test failure output per test
goanpeca File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| #!/usr/bin/env bash | ||
| # Tests scripts/live-test-report.sh against a small `go test -json` fixture. | ||
| set -euo pipefail | ||
|
|
||
| here=$(cd "$(dirname "$0")" && pwd) | ||
| root=$(cd "$here/.." && pwd) | ||
| tmp=$(mktemp -d) | ||
| trap 'rm -rf "$tmp"' EXIT | ||
| cd "$root" | ||
|
|
||
| # Every top-level test of the live files, all passing. | ||
| live=$(for f in b2/integration_test.go b2/lock_test.go base/integration_test.go; do | ||
| grep -oE '^func Test[A-Za-z0-9_]*\(t \*testing\.T\)' "$f" | | ||
| sed -E "s#^func (Test[A-Za-z0-9_]*).*#$(dirname "$f") \1#" | ||
| done) | ||
| ev() { printf '{"Action":"%s","Package":"github.com/Backblaze/blazer/%s","Test":"%s","Elapsed":0.5}\n' "$1" "$2" "$3"; } | ||
| while read -r dir name; do ev pass "$dir" "$name"; done <<<"$live" >"$tmp/pass.json" | ||
| echo '{"Action":"pass","Package":"github.com/Backblaze/blazer/b2","Elapsed":12.5}' >>"$tmp/pass.json" | ||
|
|
||
| fail=0 | ||
| check() { # name, expected exit, expected log text, json file | ||
| : >"$tmp/summary.md" | ||
| set +e | ||
| out=$(GITHUB_STEP_SUMMARY="$tmp/summary.md" "$here/live-test-report.sh" "$4" 2>&1) | ||
| code=$? | ||
| set -e | ||
| if [ "$code" = "$2" ] && grep -qF -- "$3" <<<"$out"; then | ||
| echo "ok $1" | ||
| else | ||
| echo "FAIL $1: exit $code, want $2 with '$3'"; sed 's/^/ /' <<<"$out"; fail=1 | ||
| fi | ||
| } | ||
|
|
||
| check "prints the summary to the log" 0 "Live integration tests" "$tmp/pass.json" | ||
| if grep -qF "Live integration tests" "$tmp/summary.md"; then echo "ok writes the summary file too"; else echo "FAIL summary file is empty"; fail=1; fi | ||
| check "prints the per-package result" 0 "PASS b2 (12.5s)" "$tmp/pass.json" | ||
|
|
||
| cp "$tmp/pass.json" "$tmp/fail.json" | ||
| { | ||
| printf '%s\n' '{"Action":"output","Package":"github.com/Backblaze/blazer/b2","Test":"TestAttrs","Output":" attrs_test.go:9: boom\n"}' | ||
| ev fail b2 TestAttrs | ||
| } >>"$tmp/fail.json" | ||
| check "prints the output of a failed test" 1 "attrs_test.go:9: boom" "$tmp/fail.json" | ||
|
|
||
| # A passing test whose name is a prefix of a failing one must not have its output printed. | ||
| cp "$tmp/pass.json" "$tmp/prefix.json" | ||
| { | ||
| printf '%s\n' '{"Action":"output","Package":"github.com/Backblaze/blazer/b2","Test":"TestAttrs","Output":"PASSING-OUTPUT\n"}' | ||
| printf '%s\n' '{"Action":"output","Package":"github.com/Backblaze/blazer/b2","Test":"TestAttrsLong","Output":"FAILING-OUTPUT\n"}' | ||
| ev fail b2 TestAttrsLong | ||
| } >>"$tmp/prefix.json" | ||
| set +e | ||
| out=$(GITHUB_STEP_SUMMARY="$tmp/summary.md" "$here/live-test-report.sh" "$tmp/prefix.json" 2>&1) | ||
| set -e | ||
| if grep -qF FAILING-OUTPUT <<<"$out" && ! grep -qF PASSING-OUTPUT <<<"$out"; then | ||
| echo "ok prints only failed tests' output" | ||
| else | ||
| echo "FAIL exact test-name matching"; sed 's/^/ /' <<<"$out"; fail=1 | ||
| fi | ||
|
|
||
| # A timeout: Go attributes the stack trace to the running test and emits only a package failure. | ||
| cp "$tmp/pass.json" "$tmp/timeout.json" | ||
| { | ||
| printf '%s\n' '{"Action":"run","Package":"github.com/Backblaze/blazer/b2","Test":"TestHangs"}' | ||
| printf '%s\n' '{"Action":"output","Package":"github.com/Backblaze/blazer/b2","Test":"TestHangs","Output":"panic: test timed out after 30m0s\n"}' | ||
| printf '%s\n' '{"Action":"output","Package":"github.com/Backblaze/blazer/b2","Test":"TestAttrs","Output":"UNRELATED-OUTPUT\n"}' | ||
| printf '%s\n' '{"Action":"fail","Package":"github.com/Backblaze/blazer/b2","Elapsed":1800}' | ||
| } >>"$tmp/timeout.json" | ||
| check "prints the timeout reason of a cut-off test" 1 "panic: test timed out after 30m0s" "$tmp/timeout.json" | ||
| set +e | ||
| out=$(GITHUB_STEP_SUMMARY="$tmp/summary.md" "$here/live-test-report.sh" "$tmp/timeout.json" 2>&1) | ||
| set -e | ||
| if grep -qF UNRELATED-OUTPUT <<<"$out"; then echo "FAIL prints output of a passing test in a failed package"; fail=1; else echo "ok skips finished tests in a failed package"; fi | ||
|
|
||
| # More than 300 lines of output must still reach the closing group and the error line. | ||
| cp "$tmp/pass.json" "$tmp/long.json" | ||
| # Enough output to fill the pipe, so a `head` that exits early would SIGPIPE the writer. | ||
| awk 'BEGIN { pad = sprintf("%80s", ""); for (i = 1; i <= 5000; i++) printf "{\"Action\":\"output\",\"Package\":\"github.com/Backblaze/blazer/b2\",\"Test\":\"TestAttrs\",\"Output\":\"line %d%s\\n\"}\n", i, pad }' >>"$tmp/long.json" | ||
| ev fail b2 TestAttrs >>"$tmp/long.json" | ||
| check "keeps the error line after long failure output" 1 "::error::Tests failed in the live run." "$tmp/long.json" | ||
|
|
||
|
|
||
| # The failure message comes last, after the noise (David's case): 400 log lines, then the t.Fatal line. | ||
| cp "$tmp/pass.json" "$tmp/fatal.json" | ||
| awk 'BEGIN { for (i = 1; i <= 400; i++) printf "{\"Action\":\"output\",\"Package\":\"github.com/Backblaze/blazer/b2\",\"Test\":\"TestAttrs\",\"Output\":\" noise %d\\n\"}\n", i }' >>"$tmp/fatal.json" | ||
| printf '%s\n' '{"Action":"output","Package":"github.com/Backblaze/blazer/b2","Test":"TestAttrs","Output":" attrs_test.go:99: FATAL-MESSAGE\n"}' >>"$tmp/fatal.json" | ||
| ev fail b2 TestAttrs >>"$tmp/fatal.json" | ||
| check "keeps the last lines of long failure output" 1 "FATAL-MESSAGE" "$tmp/fatal.json" | ||
| check "says how many lines were omitted" 1 "lines omitted" "$tmp/fatal.json" | ||
|
|
||
| # A timeout keeps its reason (first lines) even when the stack trace is long. | ||
| cp "$tmp/pass.json" "$tmp/longtimeout.json" | ||
| printf '%s\n' '{"Action":"run","Package":"github.com/Backblaze/blazer/b2","Test":"TestHangs"}' '{"Action":"output","Package":"github.com/Backblaze/blazer/b2","Test":"TestHangs","Output":"panic: test timed out after 30m0s\n"}' >>"$tmp/longtimeout.json" | ||
| awk 'BEGIN { for (i = 1; i <= 600; i++) printf "{\"Action\":\"output\",\"Package\":\"github.com/Backblaze/blazer/b2\",\"Test\":\"TestHangs\",\"Output\":\"goroutine %d [running]\\n\"}\n", i }' >>"$tmp/longtimeout.json" | ||
| printf '%s\n' '{"Action":"fail","Package":"github.com/Backblaze/blazer/b2","Elapsed":1800}' >>"$tmp/longtimeout.json" | ||
| check "keeps the timeout reason above a long stack trace" 1 "panic: test timed out after 30m0s" "$tmp/longtimeout.json" | ||
|
|
||
|
|
||
| # The timeout reason sits after 150 lines of progress output and before a 600-line stack trace. | ||
| cp "$tmp/pass.json" "$tmp/latepanic.json" | ||
| printf '%s\n' '{"Action":"run","Package":"github.com/Backblaze/blazer/b2","Test":"TestHangs"}' >>"$tmp/latepanic.json" | ||
| awk 'BEGIN { for (i = 1; i <= 150; i++) printf "{\"Action\":\"output\",\"Package\":\"github.com/Backblaze/blazer/b2\",\"Test\":\"TestHangs\",\"Output\":\"progress %d\\n\"}\n", i }' >>"$tmp/latepanic.json" | ||
| printf '%s\n' '{"Action":"output","Package":"github.com/Backblaze/blazer/b2","Test":"TestHangs","Output":"panic: test timed out after 30m0s\n"}' >>"$tmp/latepanic.json" | ||
| awk 'BEGIN { for (i = 1; i <= 600; i++) printf "{\"Action\":\"output\",\"Package\":\"github.com/Backblaze/blazer/b2\",\"Test\":\"TestHangs\",\"Output\":\"goroutine %d [running]\\n\"}\n", i }' >>"$tmp/latepanic.json" | ||
| printf '%s\n' '{"Action":"fail","Package":"github.com/Backblaze/blazer/b2","Elapsed":1800}' >>"$tmp/latepanic.json" | ||
| check "keeps a timeout reason that follows 150 progress lines" 1 "panic: test timed out after 30m0s" "$tmp/latepanic.json" | ||
|
|
||
| # Three failing tests: the quiet one sits between two noisy ones and must not lose its message. | ||
| cp "$tmp/pass.json" "$tmp/two.json" | ||
| noisy() { # test, count: that many noise lines, then the failure message and the fail event | ||
| awk -v t="$1" -v n="$2" 'BEGIN { for (i = 1; i <= n; i++) printf "{\"Action\":\"output\",\"Package\":\"github.com/Backblaze/blazer/b2\",\"Test\":\"%s\",\"Output\":\"noise %d\\n\"}\n", t, i }' | ||
| printf '{"Action":"output","Package":"github.com/Backblaze/blazer/b2","Test":"%s","Output":" x_test.go:1: FATAL-%s\\n"}\n' "$1" "$1" | ||
| ev fail b2 "$1" | ||
| } | ||
| { noisy TestA 400; noisy TestB 0; noisy TestC 500; } >>"$tmp/two.json" | ||
| check "keeps the failure of the first of three failing tests" 1 "FATAL-TestA" "$tmp/two.json" | ||
| check "keeps the failure of the quiet test between two noisy ones" 1 "FATAL-TestB" "$tmp/two.json" | ||
| check "keeps the failure of the last of three failing tests" 1 "FATAL-TestC" "$tmp/two.json" | ||
|
|
||
| exit "$fail" |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.