Open asubiotto opened 4 months ago
cc @golang/runtime
Something that has come up, to prevent people from using this and shooting themselves in the foot, a good place for this instead of an environment variable could be a flag that is only available on the go test
command, so it cannot be used outside of the testing use case (people could of course still use go test -c
with a single test effectively being their main
but then they'd go through so much lengths that they know they're doing something terrible that they shouldn't).
Proposal Details
Proposal
Add a
GORANDSEED
environment variable or an equivalent option to seed runtime randomness. This environment variable will be observed inrandinit
roughly like so: https://github.com/polarsignals/go/blob/ea083ca4892a62eb229c1886517e1cdb575ee19a/src/runtime/rand.go#L44-L51. This effectively replaces seeding via e.g. reading/dev/urandom
on unix systems andrandom_get
in WASM.Use case
The use case for a user-specified seed it to provide a certain level of determinism and reproducibility when testing Go programs. Throughout Go's history, accidental determinism has been avoided as much as possible by randomizing select case selection, map iteration, and even goroutine scheduling (on the local run queue only AFAICT) when running with the race detector. However, purposeful determinism is a useful property to have when testing Go programs. A
GORANDSEED
environment variable would be a step towards letting users control and reproduce runtime randomness.I recently wrote a blog post that achieves purposeful determinism (or close to it) for testing. Having a way to seed the runtime's randomness was a key ingredient.
Shortcomings
GORANDSEED
by itself is not enough for purposeful determinism. One also needs to control the number of OS threads, among other things, so that random number generation order is stable across test runs. However, it is a key ingredient that the developer cannot currently control. Time, for example, can be controlled via-tags=faketime
, and the number of OS threads by e.g. running the test on WASM.Alternatives
An alternative to providing a seed via an environment variable is to intercept the os-specific
readRandom
implementations. One could, for example, use hermit to control/dev/urandom
reads on unix systems. On WASM, some runtimes also seem to allow users to interceptrandom_get
calls. However, these solutions are per-arch while something likeGORANDSEED
would work across architectures.