[Go] Add test coverage for the rand package#427
Open
tauptlab wants to merge 1 commit into
Open
Conversation
Closes the TODO that asked for tests of the exported noise-generating functions. Includes deterministic byte-level tests, range invariants, 5-sigma moment checks, and a concurrent stress test. Also adds in-place TODO comments for two pre-existing bugs surfaced while writing the tests (I63n input validation, randSource.Int63 math.MinInt64 overflow), to be fixed in follow-up PRs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the test-coverage TODO at the top of rand.go. The package only had a test for Boolean's bit-shifting before this.
The tests are in three layers. Byte-stream tests swap randBuf for a bytes.NewReader and check exact outputs - this is where the targeted edge cases live: I63n's rejection loop at (MaxInt64/n)*n, the sign-bit mask, Geometric's leading-zero counting, and Uniform's r==0 fallback. The fallback can't be reached from crypto/rand at any realistic call count, but it's reachable by feeding 128 zero bytes (forces Geometric()>=1024 so math.Pow(2,k) overflows to +Inf).
Range tests verify that outputs sit in the documented range, 10k samples each. Moment tests sample 1M times and compare mean and variance against population values, with 5-sigma tolerances derived from each distribution's variance and 4th central moment. The helper skips the variance check on Bernoulli-shaped distributions where mu_4 == sigma^4.
TestNormal_FourthMoment is a separate explicit check because Normal and Laplace at the same variance both pass the regular moment test - they only differ at mu_4 (3 vs 6). The library uses both for the Gaussian and Laplace mechanisms.
TestConcurrent stresses the package locks with 8 goroutines, plus a Boolean mean check so it has signal even without -race. testing.Short() skips the moment tests.
rand.go
Dropped the test-coverage TODO. One-line comment above randBuf saying it must wrap crypto/rand.
Two new TODO comments for bugs I bumped into while writing the tests:
Will send separate PRs.
Testing
go test ./go/... clean. -count=10 clean. -short skips the moments. Couldn't run -race - no gcc on this Windows machine.