test(cubemaster): add race and docker-backed test gates, de-flake unit tests - #1491
Conversation
| @command -v docker >/dev/null 2>&1 || { echo "error: docker is not installed"; exit 1; } | ||
| @docker info >/dev/null 2>&1 || { echo "error: docker daemon is not reachable"; exit 1; } | ||
| $(Q)CI=true CUBEMASTER_REQUIRE_DOCKER_TESTS=1 go test -v -count=1 \ | ||
| -gcflags=all=-l -timeout=20m -run '$(DOCKER_TEST_PATTERN)' \ |
There was a problem hiding this comment.
The Docker gate can silently pass with zero tests executed. go test -run exits 0 with "no tests to run" when the regex matches nothing, so if any of the six hardcoded test names is renamed/split or this regex drifts, the gate goes green without exercising anything — defeating the purpose of a hard docker-backed gate. Consider asserting the expected tests actually ran (e.g. fail when a package reports zero matching tests, or parse go test -v/-json output for each expected test name).
| $(call msg,Run race-enabled unit tests) | ||
| $(Q)go clean -testcache | ||
| @( for pkg in ${COVERAGE_PACKAGES}; do \ | ||
| CI=true CGO_ENABLED=1 go test -short -v -race -count=1 \ |
There was a problem hiding this comment.
This race sweep covers ./pkg/templatecenter, whose gomonkey-based tests the existing test target already documents as needing -gcflags=all=-l because "a stub intermittently fails to take effect." gomonkey patches a function's entry instructions; the race detector instruments function prologues with tsan calls, changing the instruction layout gomonkey rewrites. This combination is a known source of intermittent "stub did not take effect" failures — worth validating this gate is stable across several CI runs before relying on it. If it flakes, scoping -race to packages that don't use gomonkey would reduce noise.
OverallSolid, well-scoped test-infra PR. The channel-based synchronization rewrites are correct and are genuine de-flakes — the old code also contained non-atomic shared writes ( Findings
What's good
|
…t tests - CI: expand CubeMaster test matrix with Race and Docker jobs, introducing root_make / cubemaster_builder / cubemaster_host run modes - Makefile: add test-race and test-docker targets; test-docker fails fast when no Docker daemon is reachable - queueworker, recov: replace time.Sleep polling with channel-based synchronization in tests to remove flakes - tests/unittest: gate the new race sweep and docker-backed db tests Signed-off-by: jinlong <jinlong@tencent.com>
ad5bb8a to
0f784bf
Compare
| -gcflags=all=-l -timeout=20m $$pkg || exit 1 ;\ | ||
| done ) | ||
|
|
||
| DOCKER_TEST_PATTERN=^(TestAliasStoreMySQL|TestAliasStorePostgreSQL|TestUpsertReplicaPostgreSQLUpdatePath|TestTrySessionLockPostgreSQL|TestArtifactGCSessionLockMySQL|TestInitReturnsDaoDefaultOnPostgreSQL)$$ |
There was a problem hiding this comment.
The test-docker gate can silently pass with zero tests executed. If any of these six test names is renamed, moved to another package, or deleted, go test -run '^(...)$' exits 0 with [no tests to run] (both packages still compile), so CI stays green while the Docker coverage the gate exists to enforce quietly disappears.
Since the whole point of this gate is to force the Docker-backed tests to run in CI (they're skipped under -short), I'd suggest a self-check that the filter actually matched something — e.g. run go test -list '^...$' ./pkg/base/db ./pkg/templatecenter first and fail unless the expected 6 top-level tests are all present, or invert the selection (drop -run and run the two packages without -short, letting the CUBEMASTER_REQUIRE_DOCKER_TESTS/testing.Short() helpers in mysql_testutil_test.go/postgres_testutil_test.go decide). A hardcoded name list also means any future Docker test added to these packages following the same env-helper pattern won't join the gate until someone edits this line.
| display_name: "CubeMaster Docker", | ||
| make_target: "test-docker", | ||
| requires_builder: false, | ||
| run_mode: "cubemaster_host" |
There was a problem hiding this comment.
The special CubeMaster entries are generated before the amd64/arm64 fan-out, so every CubeMaster-touching PR now runs 6 CubeMaster jobs: base + Race + Docker, each on both amd64 and arm64. The Docker variant spins up mysql:8.0/postgres:16-alpine via dockertest on the host runner — doing that on the arm64 runner too means pulling multi-arch DB images and running containers to re-validate arch-independent SQL logic. If the arm64 DB coverage isn't specifically needed, consider restricting the Docker variant to amd64 (and confirming whether the full -race sweep needs to run on both arches, since it is the longest job).
Summary
Add race and Docker-backed test gates for CubeMaster unit tests, and replace
time.Sleeppolling with channel-based synchronization to remove flakiness.root_make,cubemaster_builder, andcubemaster_hosttest-raceandtest-dockertargets;test-dockerfails fast when the Docker daemon is unreachable instead of skippingtime.Sleeppolling with channel-based synchronization to avoid intermittent failuresTesting
-race -count=1)-shortsuite is unaffected