112 lines
2.4 KiB
Go
112 lines
2.4 KiB
Go
package randstream_test
|
|
|
|
import (
|
|
"io"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"sneak.berlin/go/x/internal/randstream"
|
|
)
|
|
|
|
const (
|
|
sampleSize = 1 << 20
|
|
helloSeed = "hello"
|
|
)
|
|
|
|
func TestSeededStreamIsDeterministic(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
first := readSample(t, randstream.Params{Seed: helloSeed}, sampleSize)
|
|
second := readSample(t, randstream.Params{Seed: helloSeed}, sampleSize)
|
|
|
|
assert.Equal(t, first, second)
|
|
}
|
|
|
|
func TestDifferentSeedsDiffer(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
hello := readSample(t, randstream.Params{Seed: helloSeed}, sampleSize)
|
|
world := readSample(t, randstream.Params{Seed: "world"}, sampleSize)
|
|
|
|
assert.NotEqual(t, hello, world)
|
|
}
|
|
|
|
func TestUnseededStreamsDiffer(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
first := readSample(t, randstream.Params{Seed: ""}, sampleSize)
|
|
second := readSample(t, randstream.Params{Seed: ""}, sampleSize)
|
|
|
|
assert.NotEqual(t, first, second)
|
|
}
|
|
|
|
func TestReadAlwaysFillsBuffer(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
stream, err := randstream.New(randstream.Params{Seed: "fill"})
|
|
require.NoError(t, err)
|
|
|
|
for _, size := range []int{0, 1, 7, 64, 65, 4096, sampleSize} {
|
|
buffer := make([]byte, size)
|
|
|
|
n, err := stream.Read(buffer)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, size, n)
|
|
}
|
|
}
|
|
|
|
func TestStreamIsContinuousAcrossReads(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const headSize, tailSize = 300, 700
|
|
|
|
whole := readSample(t, randstream.Params{Seed: "continuous"}, headSize+tailSize)
|
|
|
|
stream, err := randstream.New(randstream.Params{Seed: "continuous"})
|
|
require.NoError(t, err)
|
|
|
|
head := make([]byte, headSize)
|
|
tail := make([]byte, tailSize)
|
|
|
|
_, err = io.ReadFull(stream, head)
|
|
require.NoError(t, err)
|
|
|
|
_, err = io.ReadFull(stream, tail)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, whole[:headSize], head)
|
|
assert.Equal(t, whole[headSize:], tail)
|
|
}
|
|
|
|
func TestOutputIsNotTriviallyPatterned(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
sample := readSample(t, randstream.Params{Seed: "entropy"}, sampleSize)
|
|
|
|
var seen [256]bool
|
|
for _, b := range sample {
|
|
seen[b] = true
|
|
}
|
|
|
|
for value, wasSeen := range seen {
|
|
assert.True(t, wasSeen, "byte value %d never appeared", value)
|
|
}
|
|
}
|
|
|
|
// readSample reads size bytes from a new Reader configured by p.
|
|
func readSample(t *testing.T, p randstream.Params, size int) []byte {
|
|
t.Helper()
|
|
|
|
stream, err := randstream.New(p)
|
|
require.NoError(t, err)
|
|
|
|
sample := make([]byte, size)
|
|
|
|
_, err = io.ReadFull(stream, sample)
|
|
require.NoError(t, err)
|
|
|
|
return sample
|
|
}
|