From 8db72edd3c69a47c597c3b31540d8baba9d6686c Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 17 Oct 2026 21:32:53 +0200 Subject: [PATCH] merge-check.sh runs and vets the integration level with the integration tag and times each level; the unit bound is not enforced yet (issue 895) --- Makefile | 8 +++- merge-check.sh | 99 ++++++++++++++++++++++++++++++++++++++++---- testdata/store-tests | 1 + 3 files changed, 97 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 4522ff06..fce59ecf 100644 --- a/Makefile +++ b/Makefile @@ -110,14 +110,18 @@ proxy-image: # after formatting never ran through it. The script is the one list of steps; this target only gives it # a database (MESH_TEST_POSTGRES, exported above). # +# **Two levels** (issue 895): the unit level, `go test ./...` untagged, timed and held to a bound; and the integration +# level, `-tags integration`, the tests that start a bus, a store or another process. Each is said with its time. +# # **Packages in parallel, under the race detector, each test on a bus of its own** (internal/testbus), # as the script runs them: a bus per test, of the release the mesh runs, makes the suite the same in any # order, and the timeout bounds a hang to a failure with a stack, never a stalled gate. check: postgres @sh merge-check.sh ; status=$$? ; docker rm -f $(PG_CONTAINER) >/dev/null 2>&1 || true ; exit $$status -# Without a database the store's tests skip rather than fail, so this is the honest subset and not -# the gate. +# The unit level alone (untagged: no bus, no store, no other process), which a developer runs continuously. The tests +# that need a bus or the store carry `//go:build integration` and run in `check`, not here; without a database the +# store's tests would skip rather than fail anyway. test: go test -timeout 15m ./... diff --git a/merge-check.sh b/merge-check.sh index 239bf8ac..9eb92ba4 100755 --- a/merge-check.sh +++ b/merge-check.sh @@ -9,15 +9,31 @@ # seat's first layer (`mesh/merge-gate`), run because the mesh's module graph builds `mesh-controller` # from this repository; it is not repeated here. This is the code's own quality and its suite: # -# 1. formatted and vetted; -# 2. the whole suite, packages in parallel, against the throwaway store the build seat raised at the -# release the mesh runs; every live test on a bus of its own (internal/testbus), so nothing is -# serialised. Under the race detector when the toolchain has a C compiler, and said when it has not. +# 1. formatted and vetted, with and without the build tag `integration`; +# 2. the unit level: `go test ./...` untagged and without the race detector, timed and held to a bound +# (unit_bound below): a test with no database, bus, running service or other process (novox/hq ADR 0391, +# how-we-build section 5). With a bound set, over it the check fails and names the slowest tests (issue 895); +# 3. the integration level: the whole suite with `-tags integration`, packages in parallel, against the +# throwaway store the build seat raised at the release the mesh runs; every live test on a bus of its own +# (internal/testbus), so nothing is serialised. Under the race detector when the toolchain has a C +# compiler, and said when it has not. +# +# **A test that starts a bus, a store or another process, or composes the whole mesh, carries +# `//go:build integration`** as the first line of its file; a file that held both kinds is two files +# (`_integration_test.go` beside `_test.go`). Each level says its test count and its time. # # Exit 0 is a pass; anything else fails `mesh/repo-check` with the last line printed. set -eu export GOFLAGS=-mod=vendor GOPROXY=off +# **The unit level's bound, in seconds** (issue 895): the slowest package's own test time of the untagged run, the +# compile not counted. It is NOT enforced yet: while this script is main's it judges the pull requests that put the +# `integration` tag on the tests, and on main the untagged run still holds them (about a minute), so the level's time +# is said and not judged. The release that tags the tests sets this to a number of seconds (and then to 1, how-we-build +# section 5: the whole unit suite under a second); with a number set, a run over it fails the check and names the +# slowest tests. +unit_bound= + # judge_store_tests says each listed test of one package as `go test -v` reported it, and counts in $missing each # that did not pass: $1 the package, $2 go test's exit status, $3 the file holding its output, then the names. # A result is found anywhere in a line, not only at its start: when a test's last output leaves a line open, @@ -36,6 +52,44 @@ judge_store_tests() { missing=$((missing + 1)) fi } +# judge_unit_run says the unit level as `go test -v` reported it and fails when it was over the bound: $1 the file +# holding the output of the untagged `go test -v` of every package (packages one after another, each ending in its +# `ok