- package common
-
- import (
- "bytes"
- "encoding/json"
- "fmt"
- "io"
- 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)
- }
- }
-
- // It is essential that these tests run and never repeat their outputs
- // lest we've been pwned and the behavior of our randomness is controlled.
- // See Issues:
- // * https://github.com/tendermint/tmlibs/issues/99
- // * https://github.com/tendermint/tendermint/issues/973
- func TestUniqueRng(t *testing.T) {
- buf := new(bytes.Buffer)
- outputs := make(map[string][]int)
- for i := 0; i < 100; i++ {
- testThemAll(buf)
- output := buf.String()
- buf.Reset()
- runs, seen := outputs[output]
- if seen {
- t.Errorf("Run #%d's output was already seen in previous runs: %v", i, runs)
- }
- outputs[output] = append(outputs[output], i)
- }
- }
-
- func testThemAll(out io.Writer) {
- // Reset the internal PRNG
- reset()
-
- // Set math/rand's Seed so that any direct invocations
- // of math/rand will reveal themselves.
- mrand.Seed(1)
- 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())
- }
-
- 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()
- }
|