github.com/evdatsion/aphelion-dpos-bft@v0.32.1/libs/common/random_test.go (about)

     1  package common
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	mrand "math/rand"
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestRandStr(t *testing.T) {
    16  	l := 243
    17  	s := RandStr(l)
    18  	assert.Equal(t, l, len(s))
    19  }
    20  
    21  func TestRandBytes(t *testing.T) {
    22  	l := 243
    23  	b := RandBytes(l)
    24  	assert.Equal(t, l, len(b))
    25  }
    26  
    27  func TestRandIntn(t *testing.T) {
    28  	n := 243
    29  	for i := 0; i < 100; i++ {
    30  		x := RandIntn(n)
    31  		assert.True(t, x < n)
    32  	}
    33  }
    34  
    35  // Test to make sure that we never call math.rand().
    36  // We do this by ensuring that outputs are deterministic.
    37  func TestDeterminism(t *testing.T) {
    38  	var firstOutput string
    39  
    40  	// Set math/rand's seed for the sake of debugging this test.
    41  	// (It isn't strictly necessary).
    42  	mrand.Seed(1)
    43  
    44  	for i := 0; i < 100; i++ {
    45  		output := testThemAll()
    46  		if i == 0 {
    47  			firstOutput = output
    48  		} else {
    49  			if firstOutput != output {
    50  				t.Errorf("Run #%d's output was different from first run.\nfirst: %v\nlast: %v",
    51  					i, firstOutput, output)
    52  			}
    53  		}
    54  	}
    55  }
    56  
    57  func testThemAll() string {
    58  
    59  	// Such determinism.
    60  	grand.reset(1)
    61  
    62  	// Use it.
    63  	out := new(bytes.Buffer)
    64  	perm := RandPerm(10)
    65  	blob, _ := json.Marshal(perm)
    66  	fmt.Fprintf(out, "perm: %s\n", blob)
    67  	fmt.Fprintf(out, "randInt: %d\n", RandInt())
    68  	fmt.Fprintf(out, "randUint: %d\n", RandUint())
    69  	fmt.Fprintf(out, "randIntn: %d\n", RandIntn(97))
    70  	fmt.Fprintf(out, "randInt31: %d\n", RandInt31())
    71  	fmt.Fprintf(out, "randInt32: %d\n", RandInt32())
    72  	fmt.Fprintf(out, "randInt63: %d\n", RandInt63())
    73  	fmt.Fprintf(out, "randInt64: %d\n", RandInt64())
    74  	fmt.Fprintf(out, "randUint32: %d\n", RandUint32())
    75  	fmt.Fprintf(out, "randUint64: %d\n", RandUint64())
    76  	return out.String()
    77  }
    78  
    79  func TestRngConcurrencySafety(t *testing.T) {
    80  	var wg sync.WaitGroup
    81  	for i := 0; i < 100; i++ {
    82  		wg.Add(1)
    83  		go func() {
    84  			defer wg.Done()
    85  
    86  			_ = RandUint64()
    87  			<-time.After(time.Millisecond * time.Duration(RandIntn(100)))
    88  			_ = RandPerm(3)
    89  		}()
    90  	}
    91  	wg.Wait()
    92  }
    93  
    94  func BenchmarkRandBytes10B(b *testing.B) {
    95  	benchmarkRandBytes(b, 10)
    96  }
    97  func BenchmarkRandBytes100B(b *testing.B) {
    98  	benchmarkRandBytes(b, 100)
    99  }
   100  func BenchmarkRandBytes1KiB(b *testing.B) {
   101  	benchmarkRandBytes(b, 1024)
   102  }
   103  func BenchmarkRandBytes10KiB(b *testing.B) {
   104  	benchmarkRandBytes(b, 10*1024)
   105  }
   106  func BenchmarkRandBytes100KiB(b *testing.B) {
   107  	benchmarkRandBytes(b, 100*1024)
   108  }
   109  func BenchmarkRandBytes1MiB(b *testing.B) {
   110  	benchmarkRandBytes(b, 1024*1024)
   111  }
   112  
   113  func benchmarkRandBytes(b *testing.B, n int) {
   114  	for i := 0; i < b.N; i++ {
   115  		_ = RandBytes(n)
   116  	}
   117  	b.ReportAllocs()
   118  }