Merge remote-tracking branch 'origin' into wal-snapshot-store-v3
commit
1a24557c19
@ -0,0 +1,50 @@
|
|||||||
|
package random
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var r *rand.Rand
|
||||||
|
var mu sync.Mutex
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
r = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// RandomString returns a random string of 20 characters
|
||||||
|
func String() string {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
var output strings.Builder
|
||||||
|
chars := "abcdedfghijklmnopqrstABCDEFGHIJKLMNOP"
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
random := r.Intn(len(chars))
|
||||||
|
randomChar := chars[random]
|
||||||
|
output.WriteString(string(randomChar))
|
||||||
|
}
|
||||||
|
return output.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float64 returns a random float64
|
||||||
|
func Float64() float64 {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
return r.Float64()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intn returns a random int
|
||||||
|
func Intn(n int) int {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
return r.Intn(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jitter adds a little bit of randomness to a given duration. This is
|
||||||
|
// useful to prevent nodes across the cluster performing certain operations
|
||||||
|
// all at the same time.
|
||||||
|
func Jitter(d time.Duration) time.Duration {
|
||||||
|
return d + time.Duration(Float64()*float64(d))
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package random
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_StringLength(t *testing.T) {
|
||||||
|
str := String()
|
||||||
|
if len(str) != 20 {
|
||||||
|
t.Errorf("String() returned a string of length %d; want 20", len(str))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_StringUniqueness(t *testing.T) {
|
||||||
|
const numStrings = 10
|
||||||
|
strs := make(map[string]bool, numStrings)
|
||||||
|
|
||||||
|
for i := 0; i < numStrings; i++ {
|
||||||
|
str := String()
|
||||||
|
if strs[str] {
|
||||||
|
t.Errorf("String() returned a non-unique string: %s", str)
|
||||||
|
}
|
||||||
|
strs[str] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Float64Uniqueness(t *testing.T) {
|
||||||
|
const numFloat64s = 10
|
||||||
|
floats := make(map[float64]bool, numFloat64s)
|
||||||
|
|
||||||
|
for i := 0; i < numFloat64s; i++ {
|
||||||
|
f := Float64()
|
||||||
|
if floats[f] {
|
||||||
|
t.Errorf("Float64() returned a non-unique float64: %f", f)
|
||||||
|
}
|
||||||
|
floats[f] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_IntnUniqueness(t *testing.T) {
|
||||||
|
const numIntns = 10
|
||||||
|
intns := make(map[int]bool, numIntns)
|
||||||
|
|
||||||
|
for i := 0; i < numIntns; i++ {
|
||||||
|
n := Intn(1000000000)
|
||||||
|
if intns[n] {
|
||||||
|
t.Errorf("Intn() returned a non-unique int: %d", n)
|
||||||
|
}
|
||||||
|
intns[n] = true
|
||||||
|
}
|
||||||
|
}
|
@ -1,29 +0,0 @@
|
|||||||
package random
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/rand"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var r *rand.Rand
|
|
||||||
var mu sync.Mutex
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
r = rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// RandomString returns a random string of 20 characters
|
|
||||||
func RandomString() string {
|
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
var output strings.Builder
|
|
||||||
chars := "abcdedfghijklmnopqrstABCDEFGHIJKLMNOP"
|
|
||||||
for i := 0; i < 20; i++ {
|
|
||||||
random := r.Intn(len(chars))
|
|
||||||
randomChar := chars[random]
|
|
||||||
output.WriteString(string(randomChar))
|
|
||||||
}
|
|
||||||
return output.String()
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
package random
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_RandomStringLength(t *testing.T) {
|
|
||||||
str := RandomString()
|
|
||||||
if len(str) != 20 {
|
|
||||||
t.Errorf("RandomString() returned a string of length %d; want 20", len(str))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RandomStringUniqueness(t *testing.T) {
|
|
||||||
const numStrings = 100
|
|
||||||
strs := make(map[string]bool, numStrings)
|
|
||||||
|
|
||||||
for i := 0; i < numStrings; i++ {
|
|
||||||
str := RandomString()
|
|
||||||
if strs[str] {
|
|
||||||
t.Errorf("RandomString() returned a non-unique string: %s", str)
|
|
||||||
}
|
|
||||||
strs[str] = true
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue