Files
gastownhall__beads/scripts/check_testing_short_test.go
Jim Wordelman 5941096915 Fix: check-testing-short.sh flags comments and misnames the offending function (round 2) (#5809)
* test(feat): red — Fix: check-testing-short.sh flags comments and misnames the offending function (refs be-0v13)

* feat: green — Fix: check-testing-short.sh flags comments and misnames the offending function (refs be-0v13)

Skip comment-only mentions of testing.Short() before the allowlist
check: read the exact matched line and treat a line whose first
non-whitespace characters are // as non-offending. Existing
func-attribution logic already reports "unknown" for a hit above the
first func in a file, so no change was needed there.

Also fixes two test-fixture bugs found while confirming RED: the RED
test file's own source contained the literal substring testing.Short()
(now built via string concatenation into a shortCall const so the
checker doesn't flag this file when it scans the real repo tree), and
single-file temp-dir fixtures omitted the grep filename prefix
(now every fixture dir gets a companion .go file so find+grep always
sees 2+ filenames, matching real repo-root invocations).

* test(scripts): red — check-testing-short.sh must not attribute a hit between two functions to the preceding one (refs be-r56j)

* fix(scripts): green — resolve testing.Short() hits to the containing function, not the nearest preceding one (refs be-r56j)

* chore: release gate PASS for be-053u-check-testing-short-round2

* ci: retrigger — unrelated Ryuk reaper flake in storage/uow/tracker job

The "Test (storage domain + uow)" job failed on an infrastructure flake
unrelated to this PR's diff. That job runs three package trees in one
go test invocation (.github/workflows/pr.yml:676), so Go runs their test
binaries in parallel and each starts its own Dolt testcontainer. The
binaries share a single testcontainers Ryuk reaper; in this run the
internal/tracker binary reused a sibling's reaper and its handshake was
reset:

  23:12:21 Reaper obtained from Docker for this test session 6a74346c
  23:12:21 Reaper handshake failed: read ack: ... connection reset by peer

With no live connection holding the session open, Ryuk reaped the
session's containers. The tracker package's Dolt container went down
mid-suite and every subsequent store-backed test failed with
"connection refused" on 127.0.0.1:32772.

This is be-2on, root-caused on a different PR (#5339) with the identical
signature. The durable fix is PR #5770 (disable Ryuk on the Dolt
testcontainer steps), which is open and awaiting upstream merge.

This PR touches only scripts/check-testing-short.sh, its test, and a
release-gate record — nothing in internal/tracker or the Dolt path.
Empty commit to re-trigger CI.
2026-08-19 21:01:15 -07:00

111 lines
4.3 KiB
Go

package scripts_test
import (
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
)
// Built via concatenation so this file's own source never contains the
// literal substring check-testing-short.sh scans for — otherwise this test
// file would flag itself when TestCheckTestingShortPassesOnCleanRepoTree
// runs the checker against the real repo tree.
const shortCall = "testing" + ".Short()"
func TestCheckTestingShortIgnoresCommentOnlyMention(t *testing.T) {
out, err := runCheckTestingShort(t, map[string]string{
"pkg_test.go": "package pkg\n\nimport \"testing\"\n\nfunc TestFoo(t *testing.T) {\n\t// this comment mentions " + shortCall + " and should not fail the gate\n}\n",
})
if err != nil {
t.Fatalf("comment-only mention of %s should not fail the gate; err=%v output=%s", shortCall, err, out)
}
}
func TestCheckTestingShortStillFlagsRealCallAndNamesFunc(t *testing.T) {
out, err := runCheckTestingShort(t, map[string]string{
"pkg_test.go": "package pkg\n\nimport \"testing\"\n\nfunc TestBar(t *testing.T) {\n\tif " + shortCall + " {\n\t\tt.Skip(\"slow\")\n\t}\n}\n",
})
if err == nil {
t.Fatalf("real %s call should still fail the gate; output=%s", shortCall, out)
}
if !strings.Contains(out, "TestBar") {
t.Errorf("expected offending function TestBar named in output, got: %s", out)
}
}
func TestCheckTestingShortReportsUnknownAboveFirstFunc(t *testing.T) {
out, err := runCheckTestingShort(t, map[string]string{
"pkg_test.go": "package pkg\n\nimport \"testing\"\n\nvar shortMode = " + shortCall + "\n\nfunc TestBaz(t *testing.T) {}\n",
})
if err == nil {
t.Fatalf("real %s call above any func should still fail the gate; output=%s", shortCall, out)
}
if !strings.Contains(out, "unknown") {
t.Errorf("expected 'unknown' function name for a hit above the first func, got: %s", out)
}
if strings.Contains(out, "TestBaz") {
t.Errorf("hit above the first func must not be attributed to a later func TestBaz: %s", out)
}
}
func TestCheckTestingShortReportsUnknownBetweenFunctions(t *testing.T) {
out, err := runCheckTestingShort(t, map[string]string{
"pkg_test.go": "package pkg\n\nimport \"testing\"\n\nfunc TestA(t *testing.T) {\n\tt.Log(\"a\")\n}\n\nvar shortAgain = " + shortCall + "\n\nfunc TestB(t *testing.T) {}\n",
})
if err == nil {
t.Fatalf("real %s call between two functions should still fail the gate; output=%s", shortCall, out)
}
if !strings.Contains(out, "unknown") {
t.Errorf("expected 'unknown' function name for a hit between two functions (not truly inside either body), got: %s", out)
}
if strings.Contains(out, "TestA") {
t.Errorf("hit between two functions must not be attributed to the preceding func TestA: %s", out)
}
}
func TestCheckTestingShortPassesOnCleanRepoTree(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("checker is a Bash boundary")
}
repo := sourceRepoRoot(t)
cmd := exec.Command("bash", filepath.Join(repo, "scripts", "check-testing-short.sh"))
cmd.Dir = repo
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("check-testing-short.sh failed on clean repo tree (all 9 allowlist entries must still be recognized): %v\noutput: %s", err, out)
}
}
func runCheckTestingShort(t *testing.T, files map[string]string) (string, error) {
t.Helper()
if runtime.GOOS == "windows" {
t.Skip("checker is a Bash boundary")
}
dir := t.TempDir()
// A second, innocuous .go file keeps find+grep invoked with 2+ filenames,
// matching real usage (repo root always has many .go files): grep only
// prefixes matches with the filename when given more than one file, so a
// single-fixture temp dir would silently corrupt the file:line parse in
// check-testing-short.sh's read loop.
if err := os.WriteFile(filepath.Join(dir, "companion.go"), []byte("package pkg\n"), 0600); err != nil {
t.Fatalf("write companion.go: %v", err)
}
for rel, content := range files {
full := filepath.Join(dir, rel)
if err := os.MkdirAll(filepath.Dir(full), 0700); err != nil {
t.Fatalf("mkdir %s: %v", filepath.Dir(full), err)
}
if err := os.WriteFile(full, []byte(content), 0600); err != nil {
t.Fatalf("write %s: %v", rel, err)
}
}
script := filepath.Join(sourceRepoRoot(t), "scripts", "check-testing-short.sh")
cmd := exec.Command("bash", script)
cmd.Dir = dir
out, err := cmd.CombinedOutput()
return string(out), err
}