package common import ( "bytes" "encoding/json" "fmt" mrand "math/rand" "sync" "testing" "time" "github.com/stretchr/testify/assert" ) func TestRandStr(t *testing.T) { l := 243 s := RandStr(l) assert.Equal(t, l, len(s)) } func TestRandBytes(t *testing.T) { l := 243 b := RandBytes(l) assert.Equal(t, l, len(b)) } func TestRandIntn(t *testing.T) { n := 243 for i := 0; i < 100; i++ { x := RandIntn(n) assert.True(t, x < n) } } // Test to make sure that we never call math.rand(). // We do this by ensuring that outputs are deterministic. func TestDeterminism(t *testing.T) { var firstOutput string // Set math/rand's seed for the sake of debugging this test. // (It isn't strictly necessary). mrand.Seed(1) for i := 0; i < 100; i++ { output := testThemAll() if i == 0 { firstOutput = output } else { if firstOutput != output { t.Errorf("Run #%d's output was different from first run.\nfirst: %v\nlast: %v", i, firstOutput, output) } } } } func testThemAll() string { // Such determinism. grand.reset(1) // Use it. out := new(bytes.Buffer) perm := RandPerm(10) blob, _ := json.Marshal(perm) fmt.Fprintf(out, "perm: %s\n", blob) fmt.Fprintf(out, "randInt: %d\n", RandInt()) fmt.Fprintf(out, "randUint: %d\n", RandUint()) fmt.Fprintf(out, "randIntn: %d\n", RandIntn(97)) fmt.Fprintf(out, "randInt31: %d\n", RandInt31()) fmt.Fprintf(out, "randInt32: %d\n", RandInt32()) fmt.Fprintf(out, "randInt63: %d\n", RandInt63()) fmt.Fprintf(out, "randInt64: %d\n", RandInt64()) fmt.Fprintf(out, "randUint32: %d\n", RandUint32()) fmt.Fprintf(out, "randUint64: %d\n", RandUint64()) fmt.Fprintf(out, "randUint16Exp: %d\n", RandUint16Exp()) fmt.Fprintf(out, "randUint32Exp: %d\n", RandUint32Exp()) fmt.Fprintf(out, "randUint64Exp: %d\n", RandUint64Exp()) return out.String() } func TestRngConcurrencySafety(t *testing.T) { var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(1) go func() { defer wg.Done() _ = RandUint64() <-time.After(time.Millisecond * time.Duration(RandIntn(100))) _ = RandPerm(3) }() } wg.Wait() } func BenchmarkRandBytes10B(b *testing.B) { benchmarkRandBytes(b, 10) } func BenchmarkRandBytes100B(b *testing.B) { benchmarkRandBytes(b, 100) } func BenchmarkRandBytes1KiB(b *testing.B) { benchmarkRandBytes(b, 1024) } func BenchmarkRandBytes10KiB(b *testing.B) { benchmarkRandBytes(b, 10*1024) } func BenchmarkRandBytes100KiB(b *testing.B) { benchmarkRandBytes(b, 100*1024) } func BenchmarkRandBytes1MiB(b *testing.B) { benchmarkRandBytes(b, 1024*1024) } func benchmarkRandBytes(b *testing.B, n int) { for i := 0; i < b.N; i++ { _ = RandBytes(n) } b.ReportAllocs() }