-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stress tests #54
Stress tests #54
Changes from 9 commits
0819d89
79a534a
803075a
8525fba
57effe9
c5683a7
4da5cb4
22d7236
398371c
91a5725
95650ab
04cf99a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package crypto | ||
|
||
import ( | ||
"bytes" | ||
"crypto/rand" | ||
"errors" | ||
"testing" | ||
) | ||
|
||
func TestDigest(t *testing.T) { | ||
msg := []byte("test message") | ||
d := Digest(msg) | ||
if len(d) != HashSizeByte { | ||
t.Fatal("Computation of Hash failed.") | ||
} | ||
if bytes.Equal(d, make([]byte, HashSizeByte)) { | ||
t.Fatal("Hash is all zeros.") | ||
} | ||
} | ||
|
||
type testErrorRandReader struct{} | ||
|
||
func (er testErrorRandReader) Read([]byte) (int, error) { | ||
return 0, errors.New("Not enough entropy!") | ||
} | ||
|
||
func TestMakeRand(t *testing.T) { | ||
r, err := MakeRand() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
// check if hashed the random output: | ||
if len(r) != HashSizeByte { | ||
t.Fatal("Looks like Digest wasn't called correctly.") | ||
} | ||
orig := rand.Reader | ||
rand.Reader = testErrorRandReader{} | ||
r, err = MakeRand() | ||
if err == nil { | ||
t.Fatal("No error returned") | ||
} | ||
rand.Reader = orig | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,11 @@ import ( | |
"bytes" | ||
"testing" | ||
|
||
"crypto/rand" | ||
"errors" | ||
"fmt" | ||
"github.com/coniks-sys/coniks-go/crypto/sign" | ||
"io" | ||
) | ||
|
||
var signKey sign.PrivateKey | ||
|
@@ -235,3 +239,190 @@ func TestPoliciesChange(t *testing.T) { | |
t.Error(key3, "value mismatch") | ||
} | ||
} | ||
|
||
func TestTB(t *testing.T) { | ||
key1 := "key" | ||
val1 := []byte("value") | ||
|
||
pad, err := NewPAD(NewPolicies(3, vrfPrivKey1), signKey, 3) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
tb, err := pad.TB(key1, val1) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
pk, ok := pad.signKey.Public() | ||
if !ok { | ||
t.Fatal("Couldn't retrieve public-key.") | ||
} | ||
tbb := tb.Serialize(pad.latestSTR.Signature) | ||
if !pk.Verify(tbb, tb.Signature) { | ||
t.Fatal("Couldn't validate signature") | ||
} | ||
// create next epoch and see if the TB is inserted as promised: | ||
pad.Update(nil) | ||
|
||
ap, err := pad.Lookup(key1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we also verify the proof of inclusion here, just to make this test as a sample for complete TB verification? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like in 91a5725? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, I suggest to make some small changes, though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for your feedback :-) 95650ab |
||
if !bytes.Equal(ap.LookupIndex, tb.Index) || !bytes.Equal(ap.Leaf.Value(), tb.Value) { | ||
t.Error("Value wasn't inserted as promised") | ||
} | ||
} | ||
|
||
func TestNewPADMissingPolicies(t *testing.T) { | ||
defer func() { | ||
if r := recover(); r == nil { | ||
t.Fatal("Expected NewPAD to panic if policies are missing.") | ||
} | ||
}() | ||
if _, err := NewPAD(nil, signKey, 10); err != nil { | ||
t.Fatal("Expected NewPAD to panic but got error.") | ||
} | ||
} | ||
|
||
// TODO move the following to some (internal?) testutils package | ||
type testErrorRandReader struct{} | ||
|
||
func (er testErrorRandReader) Read([]byte) (int, error) { | ||
return 0, errors.New("Not enough entropy!") | ||
} | ||
|
||
func mockRandReadWithErroringReader() (orig io.Reader) { | ||
orig = rand.Reader | ||
rand.Reader = testErrorRandReader{} | ||
return | ||
} | ||
|
||
func unMockRandReader(orig io.Reader) { | ||
rand.Reader = orig | ||
} | ||
|
||
func TestNewPADErrorWhileCreatingTree(t *testing.T) { | ||
origRand := mockRandReadWithErroringReader() | ||
defer unMockRandReader(origRand) | ||
|
||
pad, err := NewPAD(NewPolicies(3, vrfPrivKey1), signKey, 3) | ||
if err == nil || pad != nil { | ||
t.Fatal("NewPad should return an error in case the tree creation failed") | ||
} | ||
} | ||
|
||
func BenchmarkCreateLargePAD(b *testing.B) { | ||
snapLen := uint64(10) | ||
keyPrefix := "key" | ||
valuePrefix := []byte("value") | ||
|
||
// total number of entries in tree: | ||
NumEntries := uint64(1000000) | ||
// tree.Clone and update STR every: | ||
noUpdate := uint64(NumEntries + 1) | ||
|
||
b.ResetTimer() | ||
// benchmark creating a large tree (don't Update tree) | ||
for n := 0; n < b.N; n++ { | ||
_, err := createPad(NumEntries, keyPrefix, valuePrefix, snapLen, | ||
noUpdate) | ||
if err != nil { | ||
b.Fatal(err) | ||
} | ||
} | ||
} | ||
|
||
// | ||
// Benchmarks which can be used produce data similar to Figure 7. in Section 5. | ||
// | ||
func BenchmarkPADUpdate100K(b *testing.B) { benchPADUpdate(b, 100000) } | ||
func BenchmarkPADUpdate500K(b *testing.B) { benchPADUpdate(b, 500000) } | ||
|
||
// make sure you have enough memory/cpu power if you want to run the benchmarks | ||
// below; also give the benchmarks enough time to finish using the -timeout flag | ||
func BenchmarkPADUpdate1M(b *testing.B) { benchPADUpdate(b, 1000000) } | ||
func BenchmarkPADUpdate2_5M(b *testing.B) { benchPADUpdate(b, 2500000) } | ||
func BenchmarkPADUpdate5M(b *testing.B) { benchPADUpdate(b, 5000000) } | ||
func BenchmarkPADUpdate7_5M(b *testing.B) { benchPADUpdate(b, 7500000) } | ||
func BenchmarkPADUpdate10M(b *testing.B) { benchPADUpdate(b, 10000000) } | ||
|
||
func benchPADUpdate(b *testing.B, entries uint64) { | ||
keyPrefix := "key" | ||
valuePrefix := []byte("value") | ||
snapLen := uint64(10) | ||
noUpdate := uint64(entries + 1) | ||
pad, err := createPad(uint64(entries), keyPrefix, valuePrefix, snapLen, noUpdate) | ||
if err != nil { | ||
b.Fatal(err) | ||
} | ||
b.ResetTimer() | ||
for i := 0; i < b.N; i++ { | ||
pad.Update(nil) | ||
} | ||
} | ||
|
||
// | ||
// END Benchmarks for Figure 7. in Section 5 | ||
// | ||
|
||
func BenchmarkPADLookUpFrom10K(b *testing.B) { benchPADLookup(b, 10000) } | ||
func BenchmarkPADLookUpFrom50K(b *testing.B) { benchPADLookup(b, 50000) } | ||
func BenchmarkPADLookUpFrom100K(b *testing.B) { benchPADLookup(b, 100000) } | ||
func BenchmarkPADLookUpFrom500K(b *testing.B) { benchPADLookup(b, 500000) } | ||
func BenchmarkPADLookUpFrom1M(b *testing.B) { benchPADLookup(b, 1000000) } | ||
func BenchmarkPADLookUpFrom5M(b *testing.B) { benchPADLookup(b, 5000000) } | ||
func BenchmarkPADLookUpFrom10M(b *testing.B) { benchPADLookup(b, 10000000) } | ||
|
||
func benchPADLookup(b *testing.B, entries uint64) { | ||
snapLen := uint64(10) | ||
keyPrefix := "key" | ||
valuePrefix := []byte("value") | ||
updateOnce := uint64(entries - 1) | ||
pad, err := createPad(entries, keyPrefix, valuePrefix, snapLen, | ||
updateOnce) | ||
if err != nil { | ||
b.Fatal(err) | ||
} | ||
// ignore the tree creation: | ||
b.ResetTimer() | ||
//fmt.Println("Done creating large pad/tree.") | ||
|
||
// measure LookUps in large tree (with NumEntries leafs) | ||
for n := 0; n < b.N; n++ { | ||
b.StopTimer() | ||
var key string | ||
if n < int(entries) { | ||
key = keyPrefix + string(n) | ||
} else { | ||
key = keyPrefix + string(n%int(entries)) | ||
} | ||
b.StartTimer() | ||
_, err := pad.Lookup(key) | ||
if err != nil { | ||
b.Fatalf("Coudldn't lookup key=%s", key) | ||
} | ||
} | ||
} | ||
|
||
// creates a PAD containing a tree with N entries (+ potential emptyLeafNodes) | ||
// each key value pair has the form (keyPrefix+string(i), valuePrefix+string(i)) | ||
// for i = 0,...,N | ||
// The STR will get updated every epoch defined by every multiple of | ||
// `updateEvery`. If `updateEvery > N` createPAD won't update the STR. | ||
func createPad(N uint64, keyPrefix string, valuePrefix []byte, snapLen uint64, | ||
updateEvery uint64) (*PAD, error) { | ||
pad, err := NewPAD(NewPolicies(3, vrfPrivKey1), signKey, snapLen) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
for i := uint64(0); i < N; i++ { | ||
key := keyPrefix + string(i) | ||
value := append(valuePrefix, byte(i)) | ||
if err := pad.Set(key, value); err != nil { | ||
return nil, fmt.Errorf("Couldn't set key=%s and value=%s. Error: %v", | ||
key, value, err) | ||
} | ||
if i != 0 && (i%updateEvery == 0) { | ||
pad.Update(nil) | ||
} | ||
} | ||
return pad, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
package util | ||
|
||
import ( | ||
"encoding/binary" | ||
"math/rand" | ||
"testing" | ||
"time" | ||
|
@@ -27,3 +28,37 @@ func TestBitsBytesConvert(t *testing.T) { | |
} | ||
} | ||
} | ||
|
||
func TestIntToBytes(t *testing.T) { | ||
numInt := 42 | ||
b := IntToBytes(numInt) | ||
if int(binary.LittleEndian.Uint32(b)) != numInt { | ||
t.Fatal("Conversion to bytes looks wrong!") | ||
} | ||
numInt = -42 | ||
b = IntToBytes(numInt) | ||
if int32(binary.LittleEndian.Uint32(b)) != int32(numInt) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can it be simplified to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, pushed a second ago. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wait, I changed another line; but here it's needed or not? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right. Sorry for the noise. |
||
t.Fatal("Conversion to bytes looks wrong!") | ||
} | ||
} | ||
|
||
func TestULongToBytes(t *testing.T) { | ||
numInt := uint64(42) | ||
b := ULongToBytes(numInt) | ||
if binary.LittleEndian.Uint64(b) != numInt { | ||
t.Fatal("Conversion to bytes looks wrong!") | ||
} | ||
} | ||
|
||
func TestLongToBytes(t *testing.T) { | ||
numInt := int64(42) | ||
b := LongToBytes(numInt) | ||
if int64(binary.LittleEndian.Uint64(b)) != numInt { | ||
t.Fatal("Conversion to bytes looks wrong!") | ||
} | ||
numInt = int64(-42) | ||
b = LongToBytes(numInt) | ||
if int64(binary.LittleEndian.Uint64(b)) != numInt { | ||
t.Fatal("Conversion to bytes looks wrong!") | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should
TestTB()
be moved totb_test.go
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, why not. It makes sense (04cf99a)