TestBuild/EmulatedRISCV/finalizerinvariants.go fails at random, it needs as much time as its timeout
TestBuild/EmulatedRISCV/finalizerinvariants.go needs about the same time as the timeout that stops it, thus it fails when the runner is slow.
What happens
--- FAIL: TestBuild (451.35s)
--- FAIL: TestBuild/EmulatedRISCV (0.00s)
--- FAIL: TestBuild/EmulatedRISCV/finalizerinvariants.go (123.35s)
main_test.go:450: failed to run compiled binary /tmp/tinygo.../main: context deadline exceeded
main_test.go:450: output:
--- timeout of 2m0s exceeded, terminating...main_test.go line 584 gives buildAndRun a fixed limit of 2*time.Minute for the compiled binary. Under the riscv-qemu emulator this test needs about 120s, thus the result depends on the speed of the runner.
Measurements
Two runs of make ASSERT=1 test on the same commit, 02021b58:
| run | time of the test | time of the whole package | result |
|---|---|---|---|
| 34474260782 attempt 1 | 122.86s | 831.8s | fail |
| 34474260782 attempt 2 | 123.35s | 901.9s | fail |
The same step passed the same day on the same commit in run 34446941721 and run 34466667108, where the package took about 750s. Thus the two failing runners were 11% to 20% slower than the passing ones, which is enough to pass the limit of 120s.
Only EmulatedRISCV fails. EmulatedCortexM3 and the other emulated targets pass with the same test.
Why it matters
A test that needs 120s against a limit of 120s fails at random on dev for everybody. It gives failures that look like a fault of the pull request under test, which costs time to examine.
Possible corrections
- Give the emulated targets more time than the hosted targets. The fixed
2*time.Minuteatmain_test.goline 584 is used for every target, and a QEMU target is much slower than the host. - Make the test do less work on the emulated targets.
- Do not run this test on riscv-qemu, in the same way as the exception for simavr and math.go at
main_test.goline 446.
Correction 1 looks best, because the test is not wrong, it is only slow under emulation.
Note
The test came in with 31fff2c9 (#5545) on 2026-08-26. Several changes to the garbage collector and to finalizers have gone into dev since then, which may have made the test slower and brought it to the limit:
02021b58 runtime: preserve malloc allocations until free
59fb1040 runtime: precisely scan globals on all platforms
160372b9 runtime: eagerly mark Boehm global roots
829fe514 runtime: precisely scan Wasm globals
a7360d5a runtime: require explicit GC layoutsIf one of those made the test slower, that is worth a look on its own, because the limit only shows the problem, it does not cause it.
Source: tinygo-org/tinygo