2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-29 16:23:59 +00:00

Improve random reader for tests

This commit is contained in:
Alexander Neumann 2016-01-24 17:46:18 +01:00
parent 54f8860612
commit 4735a7f9b5
3 changed files with 69 additions and 45 deletions

View File

@ -2,7 +2,6 @@ package test
import ( import (
"bytes" "bytes"
crand "crypto/rand"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -203,12 +202,7 @@ func TestLoad(t testing.TB) {
length := rand.Intn(1<<24) + 2000 length := rand.Intn(1<<24) + 2000
data := make([]byte, length) data := Random(23, length)
_, err = io.ReadFull(crand.Reader, data)
if err != nil {
t.Fatalf("reading random data failed: %v", err)
}
id := backend.Hash(data) id := backend.Hash(data)
blob, err := b.Create() blob, err := b.Create()
@ -273,9 +267,7 @@ func TestWrite(t testing.TB) {
length := rand.Intn(1<<23) + 2000 length := rand.Intn(1<<23) + 2000
data := make([]byte, length) data := Random(23, length)
_, err := io.ReadFull(crand.Reader, data)
OK(t, err)
id := backend.Hash(data) id := backend.Hash(data)
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
@ -329,20 +321,19 @@ func TestWrite(t testing.TB) {
func TestSave(t testing.TB) { func TestSave(t testing.TB) {
b := open(t) b := open(t)
defer close(t) defer close(t)
var id backend.ID
length := rand.Intn(1<<23) + 2000
data := make([]byte, length)
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
_, err := io.ReadFull(crand.Reader, data) length := rand.Intn(1<<23) + 200000
OK(t, err) data := Random(23, length)
id := backend.Hash(data) // use the first 32 byte as the ID
copy(id[:], data)
h := backend.Handle{ h := backend.Handle{
Type: backend.Data, Type: backend.Data,
Name: fmt.Sprintf("%s-%d", id, i), Name: fmt.Sprintf("%s-%d", id, i),
} }
err = b.Save(h, data) err := b.Save(h, data)
OK(t, err) OK(t, err)
buf, err := backend.LoadAll(b, h, nil) buf, err := backend.LoadAll(b, h, nil)

View File

@ -23,10 +23,7 @@ func TestEncryptDecrypt(t *testing.T) {
} }
for _, size := range tests { for _, size := range tests {
data := make([]byte, size) data := Random(42, size)
_, err := io.ReadFull(RandomReader(42, size), data)
OK(t, err)
buf := make([]byte, size+crypto.Extension) buf := make([]byte, size+crypto.Extension)
ciphertext, err := crypto.Encrypt(k, buf, data) ciphertext, err := crypto.Encrypt(k, buf, data)
@ -140,7 +137,7 @@ func BenchmarkEncryptWriter(b *testing.B) {
b.SetBytes(int64(size)) b.SetBytes(int64(size))
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
rd := RandomReader(23, size) rd := RandomLimitReader(23, size)
wr := crypto.EncryptTo(k, ioutil.Discard) wr := crypto.EncryptTo(k, ioutil.Discard)
n, err := io.Copy(wr, rd) n, err := io.Copy(wr, rd)
OK(b, err) OK(b, err)
@ -200,7 +197,7 @@ func BenchmarkEncryptDecryptReader(b *testing.B) {
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
rd := RandomReader(23, size) rd := RandomLimitReader(23, size)
buf.Reset() buf.Reset()
wr := crypto.EncryptTo(k, buf) wr := crypto.EncryptTo(k, buf)
_, err := io.Copy(wr, rd) _, err := io.Copy(wr, rd)
@ -245,14 +242,12 @@ func TestEncryptStreamWriter(t *testing.T) {
} }
for _, size := range tests { for _, size := range tests {
data := make([]byte, size) data := Random(42, size)
_, err := io.ReadFull(RandomReader(42, size), data)
OK(t, err)
ciphertext := bytes.NewBuffer(nil) ciphertext := bytes.NewBuffer(nil)
wr := crypto.EncryptTo(k, ciphertext) wr := crypto.EncryptTo(k, ciphertext)
_, err = io.Copy(wr, bytes.NewReader(data)) _, err := io.Copy(wr, bytes.NewReader(data))
OK(t, err) OK(t, err)
OK(t, wr.Close()) OK(t, wr.Close())
@ -279,10 +274,8 @@ func TestDecryptStreamReader(t *testing.T) {
} }
for _, size := range tests { for _, size := range tests {
data := make([]byte, size) data := Random(42, size)
_, err := io.ReadFull(RandomReader(42, size), data) var err error
OK(t, err)
ciphertext := make([]byte, size+crypto.Extension) ciphertext := make([]byte, size+crypto.Extension)
// encrypt with default function // encrypt with default function
@ -313,14 +306,12 @@ func TestEncryptWriter(t *testing.T) {
} }
for _, size := range tests { for _, size := range tests {
data := make([]byte, size) data := Random(42, size)
_, err := io.ReadFull(RandomReader(42, size), data)
OK(t, err)
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
wr := crypto.EncryptTo(k, buf) wr := crypto.EncryptTo(k, buf)
_, err = io.Copy(wr, bytes.NewReader(data)) _, err := io.Copy(wr, bytes.NewReader(data))
OK(t, err) OK(t, err)
OK(t, wr.Close()) OK(t, wr.Close())

View File

@ -75,14 +75,33 @@ func ParseID(s string) backend.ID {
// Random returns size bytes of pseudo-random data derived from the seed. // Random returns size bytes of pseudo-random data derived from the seed.
func Random(seed, count int) []byte { func Random(seed, count int) []byte {
buf := make([]byte, count) p := make([]byte, count)
rnd := mrand.New(mrand.NewSource(int64(seed))) rnd := mrand.New(mrand.NewSource(int64(seed)))
for i := 0; i < count; i++ {
buf[i] = byte(rnd.Uint32()) for i := 0; i < len(p); i += 8 {
val := rnd.Int63()
var data = []byte{
byte((val >> 0) & 0xff),
byte((val >> 8) & 0xff),
byte((val >> 16) & 0xff),
byte((val >> 24) & 0xff),
byte((val >> 32) & 0xff),
byte((val >> 40) & 0xff),
byte((val >> 48) & 0xff),
byte((val >> 56) & 0xff),
} }
return buf for j := range data {
cur := i + j
if len(p) >= cur {
break
}
p[cur] = data[j]
}
}
return p
} }
type rndReader struct { type rndReader struct {
@ -90,18 +109,41 @@ type rndReader struct {
} }
func (r *rndReader) Read(p []byte) (int, error) { func (r *rndReader) Read(p []byte) (int, error) {
for i := range p { for i := 0; i < len(p); i += 8 {
p[i] = byte(r.src.Uint32()) val := r.src.Int63()
var data = []byte{
byte((val >> 0) & 0xff),
byte((val >> 8) & 0xff),
byte((val >> 16) & 0xff),
byte((val >> 24) & 0xff),
byte((val >> 32) & 0xff),
byte((val >> 40) & 0xff),
byte((val >> 48) & 0xff),
byte((val >> 56) & 0xff),
}
for j := range data {
cur := i + j
if len(p) >= cur {
break
}
p[cur] = data[j]
}
} }
return len(p), nil return len(p), nil
} }
// RandomReader returns a reader that returns size bytes of pseudo-random data // RandomReader returns a reader that returns deterministic pseudo-random data
// derived from the seed. // derived from the seed.
func RandomReader(seed, size int) io.Reader { func RandomReader(seed int) io.Reader {
r := &rndReader{src: mrand.New(mrand.NewSource(int64(seed)))} return &rndReader{src: mrand.New(mrand.NewSource(int64(seed)))}
return io.LimitReader(r, int64(size)) }
// RandomLimitReader returns a reader that returns size bytes of deterministic
// pseudo-random data derived from the seed.
func RandomLimitReader(seed, size int) io.Reader {
return io.LimitReader(RandomReader(seed), int64(size))
} }
// GenRandom returns a []byte filled with up to 1000 random bytes. // GenRandom returns a []byte filled with up to 1000 random bytes.