plan9 SQL seal tests: read the whole goroutine dump, not its first MiB
waitPlan9SealQueued and the handle-registration wait looked for the queued goroutine in runtime.Stack(buf, true) with a fixed 1 MiB buffer. runtime.Stack stops at the buffer's end, and a full run of the console package has thousands of goroutines. A goroutine past that point was never seen, and the wait timed out after 10 s. CI on Go 1.26.10 hit it twice. The diagnostic run (54f217fe) showed the dump at exactly 1048576 of 1048576 bytes with 3344 goroutines. Both waits now use plan9GoroutineStacks, which doubles the buffer until the dump fits. This replaces the diagnostic, which the revert in this commit removes.
Human
Prompt
Can we make sure we're on the latest version of go to deal with https://emudhra.we-have-a-problem.com ?
From this commit's own message. The prompt ledger has no entries for it — which is what a squashed, rebased or amended commit looks like, and what every commit looks like in a repo without a ledger.
Summary
Adds plan9GoroutineStacks (a growing buffer) and uses it in both stack-scanning waits in plan9_sql_seal_test.go. Test-only.
Agent notes
Reproduced locally with 4000 parked goroutines and the target started last: the 1 MiB buffer filled and missed it, and the helper found it. Why 1.26.10 tips it over and 1.26.5 doesn't is not established: the dump sits right at the limit, and goroutine order and stack depth vary between toolchains. internal/host/startup_largebox_linux_test.go:1709 has the same pattern with 8 MiB; not touched here.
1 file changed,
+18
−8
internal/console/plan9_sql_seal_test.go+18 −8
CI passed — run details
CI log
=== gate ===
cd launchctx && go vet ./... && go test ./... -count=1
ok amadan.net/carlos/platform.git/launchctx 0.014s
? amadan.net/carlos/platform.git/launchctx/controlname [no test files]
? amadan.net/carlos/platform.git/launchctx/wireid [no test files]
go vet ./...
gofmt -l .: clean
go test ./... -count=1 -timeout 30m
ok github.com/carlosframework/platform 336.797s
? github.com/carlosframework/platform/cmd/changelog [no test files]
ok github.com/carlosframework/platform/cmd/console 3.135s
ok github.com/carlosframework/platform/cmd/moveprobe 92.548s
ok github.com/carlosframework/platform/cmd/zddprobe 0.738s
ok github.com/carlosframework/platform/internal/activator 250.356s
ok github.com/carlosframework/platform/internal/agentsock 0.018s
ok github.com/carlosframework/platform/internal/alerting 0.004s
ok github.com/carlosframework/platform/internal/analytics 0.036s
ok github.com/carlosframework/platform/internal/appconfig 2.677s
ok github.com/carlosframework/platform/internal/apperr 0.099s
ok github.com/carlosframework/platform/internal/applog 0.169s
ok github.com/carlosframework/platform/internal/awsinv 0.011s
ok github.com/carlosframework/platform/internal/boxchoice 0.007s
ok github.com/carlosframework/platform/internal/boxid 0.736s
? github.com/carlosframework/platform/internal/boxid/boxidtest [no test files]
? github.com/carlosframework/platform/internal/boxid/internal/signtest [no test files]
ok github.com/carlosframework/platform/internal/boxvolumes 0.009s
ok github.com/carlosframework/platform/internal/caps 0.014s
ok github.com/carlosframework/platform/internal/certwarm 0.003s
ok github.com/carlosframework/platform/internal/cgroup 0.741s
ok github.com/carlosframework/platform/internal/changelog 0.456s
ok github.com/carlosframework/platform/internal/claimactivation 1.020s
ok github.com/carlosframework/platform/internal/clamd 0.059s
? github.com/carlosframework/platform/internal/cliflag [no test files]
ok github.com/carlosframework/platform/internal/console 419.306s
? github.com/carlosframework/platform/internal/controlname [no test files]
? github.com/carlosframework/platform/internal/controlsock [no test files]
ok github.com/carlosframework/platform/internal/dbdoor 6.630s
ok github.com/carlosframework/platform/internal/dbdoor/dbdoortest 0.017s
ok github.com/carlosframework/platform/internal/dbverify 0.006s
ok github.com/carlosframework/platform/internal/dnsrec 0.006s
ok github.com/carlosframework/platform/internal/docsite 0.011s
ok github.com/carlosframework/platform/internal/domains 3.181s
ok github.com/carlosframework/platform/internal/doorkey 0.019s
ok github.com/carlosframework/platform/internal/economics 0.014s
ok github.com/carlosframework/platform/internal/edge 46.199s
? github.com/carlosframework/platform/internal/edgeproof [no test files]
ok github.com/carlosframework/platform/internal/edgesfile 0.012s
ok github.com/carlosframework/platform/internal/fleetapi 0.246s
ok github.com/carlosframework/platform/internal/gate 2.282s
ok github.com/carlosframework/platform/internal/genselect 0.048s
ok github.com/carlosframework/platform/internal/geo 0.022s
ok github.com/carlosframework/platform/internal/geoip 0.056s
ok github.com/carlosframework/platform/internal/historyreadback 0.669s
ok github.com/carlosframework/platform/internal/host 194.891s
ok github.com/carlosframework/platform/internal/hostactors 6.698s
ok github.com/carlosframework/platform/internal/hostactors/awsmembership 0.013s
ok github.com/carlosframework/platform/internal/hostbox 3.606s
ok github.com/carlosframework/platform/internal/hostclaim 0.984s
ok github.com/carlosframework/platform/internal/hostenv 0.016s
ok github.com/carlosframework/platform/internal/hostevidence 0.007s
ok github.com/carlosframework/platform/internal/hostexec 7.239s
ok github.com/carlosframework/platform/internal/hostfence 0.088s
ok github.com/carlosframework/platform/internal/hostfiles 10.738s
ok github.com/carlosframework/platform/internal/hostfloor 0.039s
ok github.com/carlosframework/platform/internal/hostguard 1.161s
ok github.com/carlosframework/platform/internal/hostops 2.589s
? github.com/carlosframework/platform/internal/hostops/fencerelease [no test files]
ok github.com/carlosframework/platform/internal/hostops/internal/fencerelease 0.004s
ok github.com/carlosframework/platform/internal/hostquarantine 0.003s
ok github.com/carlosframework/platform/internal/hostrelocate 0.756s
ok github.com/carlosframework/platform/internal/hostresolve 0.282s
ok github.com/carlosframework/platform/internal/hostwrite 0.009s
ok github.com/carlosframework/platform/internal/infraview 0.009s
ok github.com/carlosframework/platform/internal/instancectl 5.325s
ok github.com/carlosframework/platform/internal/instanceexec 2.782s
ok github.com/carlosframework/platform/internal/instancefs 0.008s
ok github.com/carlosframework/platform/internal/instancekey 0.013s
ok github.com/carlosframework/platform/internal/instanceupdates 0.012s
ok github.com/carlosframework/platform/internal/layout 2.290s
ok github.com/carlosframework/platform/internal/lbhealth 0.003s
ok github.com/carlosframework/platform/internal/lease 10.069s
ok github.com/carlosframework/platform/internal/lease/leasetest 0.645s
ok github.com/carlosframework/platform/internal/ledger 0.330s
ok github.com/carlosframework/platform/internal/mail 0.305s
ok github.com/carlosframework/platform/internal/maintenance 0.113s
ok github.com/carlosframework/platform/internal/maintenanceexec 5.804s
ok github.com/carlosframework/platform/internal/maintenanceguard 0.122s
ok github.com/carlosframework/platform/internal/metrics 0.006s
ok github.com/carlosframework/platform/internal/moves 22.474s
ok github.com/carlosframework/platform/internal/moves/archive 1.579s
ok github.com/carlosframework/platform/internal/objstore 0.227s
ok github.com/carlosframework/platform/internal/ops 0.239s
ok github.com/carlosframework/platform/internal/park 0.393s
ok github.com/carlosframework/platform/internal/privatefile 0.004s
ok github.com/carlosframework/platform/internal/provision 22.597s
ok github.com/carlosframework/platform/internal/publicrelease 0.009s
? github.com/carlosframework/platform/internal/regionname [no test files]
ok github.com/carlosframework/platform/internal/registry 6.288s
ok github.com/carlosframework/platform/internal/relay 7.231s
ok github.com/carlosframework/platform/internal/release 26.796s
ok github.com/carlosframework/platform/internal/rollout 4.423s
ok github.com/carlosframework/platform/internal/rolloutwords 0.005s
ok github.com/carlosframework/platform/internal/rootaws 0.009s
ok github.com/carlosframework/platform/internal/rootparticipation 0.066s
ok github.com/carlosframework/platform/internal/rootstate 0.031s
ok github.com/carlosframework/platform/internal/runs 0.557s
ok github.com/carlosframework/platform/internal/s3compat 0.005s
ok github.com/carlosframework/platform/internal/safefile 0.006s
ok github.com/carlosframework/platform/internal/schedule 2.914s
ok github.com/carlosframework/platform/internal/seeds 0.012s
ok github.com/carlosframework/platform/internal/sim/hostlife 17.127s
ok github.com/carlosframework/platform/internal/sim/litestreamfacts 4.070s
ok github.com/carlosframework/platform/internal/status 0.099s
ok github.com/carlosframework/platform/internal/steering 0.011s
ok github.com/carlosframework/platform/internal/stopevidence 0.258s
ok github.com/carlosframework/platform/internal/svcrole 0.002s
ok github.com/carlosframework/platform/internal/telemetry 0.005s
ok github.com/carlosframework/platform/internal/termfence 0.006s
ok github.com/carlosframework/platform/internal/tunnelclient 0.004s
ok github.com/carlosframework/platform/internal/unixdial 0.005s
ok github.com/carlosframework/platform/internal/updatewords 0.008s
ok github.com/carlosframework/platform/internal/usage 0.006s
ok github.com/carlosframework/platform/internal/version 0.002s
ok github.com/carlosframework/platform/internal/vet 1.849s
=== cross ===
--- shard 0 of 5 ---
cross-compiling darwin/arm64
--- shard 1 of 5 ---
cross-compiling darwin/amd64
--- shard 2 of 5 ---
cross-compiling linux/arm64
linux/arm64 carlos binary: 49938594 bytes (ceiling 52000000)
--- shard 3 of 5 ---
cross-compiling windows/amd64
--- shard 4 of 5 ---
cross-compiling windows/arm64
=== minio-contract ===
minio contract: arm64, minio RELEASE.2025-09-07T16-13-09Z, mc RELEASE.2025-08-13T08-35-41Z
minio: downloading https://github.com/minio/minio/releases/download/RELEASE.2025-09-07T16-13-09Z/minio.linux-arm64.RELEASE.2025-09-07T16-13-09Z
minio: downloaded, digest verified
mc: downloading https://github.com/minio/mc/releases/download/RELEASE.2025-08-13T08-35-41Z/mc.linux-arm64.RELEASE.2025-08-13T08-35-41Z
mc: downloaded, digest verified
minio healthy on 127.0.0.1:20999
Added `local` successfully.
Bucket created successfully `local/contract-bucket`.
Bucket created successfully `local/denied-bucket`.
Created policy `contract-only` successfully.
Added user `scopeduser` successfully.
Attached Policies: [contract-only]
To User: scopeduser
buckets and scoped user ready
=== RUN TestDeliveredContractMinio
=== RUN TestDeliveredContractMinio/put
=== RUN TestDeliveredContractMinio/get_round-trips_the_body
=== RUN TestDeliveredContractMinio/list_shows_the_key
=== RUN TestDeliveredContractMinio/head_and_list_agree_on_the_version
=== RUN TestDeliveredContractMinio/the_app_cannot_tag_its_own_object
=== RUN TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/not_by_PutObjectTagging
=== RUN TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/and_not_by_x-amz-tagging_on_upload
=== RUN TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route
=== RUN TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CreateMultipartUpload
=== RUN TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CopyObject_with_a_REPLACE_tagging_directive
=== RUN TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/but_multipart_itself_is_allowed
=== RUN TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_copy_itself_is_allowed
=== RUN TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/a_POST-policy_forged_tag_with_a_matching_version_is_still_not_a_verdict
=== RUN TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_an_ordinary_tagged-with-something-else_upload_is_allowed
=== RUN TestDeliveredContractMinio/delete_removes_it
=== RUN TestDeliveredContractMinio/cross-bucket_denial
--- PASS: TestDeliveredContractMinio (0.02s)
--- PASS: TestDeliveredContractMinio/put (0.00s)
--- PASS: TestDeliveredContractMinio/get_round-trips_the_body (0.00s)
--- PASS: TestDeliveredContractMinio/list_shows_the_key (0.00s)
--- PASS: TestDeliveredContractMinio/head_and_list_agree_on_the_version (0.00s)
--- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object (0.00s)
--- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/not_by_PutObjectTagging (0.00s)
--- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/and_not_by_x-amz-tagging_on_upload (0.00s)
--- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route (0.01s)
--- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CreateMultipartUpload (0.00s)
--- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CopyObject_with_a_REPLACE_tagging_directive (0.00s)
--- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/but_multipart_itself_is_allowed (0.00s)
--- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_copy_itself_is_allowed (0.00s)
--- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/a_POST-policy_forged_tag_with_a_matching_version_is_still_not_a_verdict (0.00s)
--- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_an_ordinary_tagged-with-something-else_upload_is_allowed (0.00s)
--- PASS: TestDeliveredContractMinio/delete_removes_it (0.00s)
--- PASS: TestDeliveredContractMinio/cross-bucket_denial (0.00s)
PASS
ok github.com/carlosframework/platform/internal/objstore 0.025s
=== RUN TestT4StorageProbeMinio
2026/10/20 17:15:48 moves: T4: STORE: list: operation error S3: ListObjectsV2, https response error StatusCode: 403, RequestID: 18E04C4DB415233D, HostID: 7c420053e0fbcd7f41653fdd92ffa2802c903d05303b1aa15adc2e8bb65d183f, api error SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method.
--- PASS: TestT4StorageProbeMinio (0.01s)
PASS
ok github.com/carlosframework/platform/internal/host 0.023s
minio contract: PASS
diff --git a/internal/console/plan9_sql_seal_test.go b/internal/console/plan9_sql_seal_test.go| index 86b3604c5..86c910f45 100644 |
| --- a/internal/console/plan9_sql_seal_test.go |
| +++ b/internal/console/plan9_sql_seal_test.go |
| @@ -46,20 +46,32 @@ func plan9SealQueuedStmtQuery(st *sql.Stmt, out chan<- error) { |
| out <- err |
| } |
| +// plan9GoroutineStacks returns every goroutine's stack. runtime.Stack stops |
| +// at the end of the buffer it is given, and a full run of this package has |
| +// thousands of goroutines, so the buffer grows until the whole dump fits: |
| +// a goroutine past a fixed buffer's end would never be seen. |
| +func plan9GoroutineStacks() []string { |
| + buf := make([]byte, 1<<20) |
| + for { |
| + n := runtime.Stack(buf, true) |
| + if n < len(buf) { |
| + return strings.Split(string(buf[:n]), "\n\n") |
| + } |
| + buf = make([]byte, 2*len(buf)) |
| + } |
| +} |
| + |
| // waitPlan9SealQueued returns once the goroutine running fn has finished |
| // (done has a value) or is parked on the database/sql driver-connection lock, |
| // which the batch commit holds. |
| func waitPlan9SealQueued(t *testing.T, fn string, done chan error) { |
| t.Helper() |
| deadline := time.Now().Add(10 * time.Second) |
| - buf := make([]byte, 1<<20) |
| - n := 0 |
| for time.Now().Before(deadline) { |
| if len(done) > 0 { |
| return |
| } |
| - n = runtime.Stack(buf, true) |
| - for _, g := range strings.Split(string(buf[:n]), "\n\n") { |
| + for _, g := range plan9GoroutineStacks() { |
| onDriver := strings.Contains(g, "database/sql.withLock(") || strings.Contains(g, "database/sql.resultFromStatement(") || strings.Contains(g, "database/sql.rowsiFromStatement(") |
| if strings.Contains(g, "console."+fn+"(") && onDriver && strings.Contains(g, "sync.(*Mutex).lockSlow(") { |
| return |
| @@ -67,7 +79,7 @@ func waitPlan9SealQueued(t *testing.T, fn string, done chan error) { |
| } |
| runtime.Gosched() |
| } |
| - t.Fatalf("%s neither finished nor queued on the driver connection (DIAGNOSTIC: last dump %d of %d bytes, %d goroutines)", fn, n, len(buf), runtime.NumGoroutine()) |
| + t.Fatalf("%s neither finished nor queued on the driver connection", fn) |
| } |
| // TestPlan9SQLBatchSealsRetainedWriteQueuedAcrossCommit checks the view fast |
| @@ -249,11 +261,9 @@ func TestPlan9SQLSealDuringHandleRegistration(t *testing.T) { |
| } |
| }() |
| deadline := time.Now().Add(10 * time.Second) |
| - buf := make([]byte, 1<<20) |
| waiting := false |
| for time.Now().Before(deadline) && !waiting { |
| - n := runtime.Stack(buf, true) |
| - for _, g := range strings.Split(string(buf[:n]), "\n\n") { |
| + for _, g := range plan9GoroutineStacks() { |
| if strings.Contains(g, "console.(*claimBoundDB)."+method+"(") && strings.Contains(g, "sync.(*Mutex).lockSlow(") { |
| waiting = true |
| break |