You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

194 lines
5.0 KiB

package types
import (
"io"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/merkle"
tmrand "github.com/tendermint/tendermint/libs/rand"
)
const (
testPartSize = 65536 // 64KB ... 4096 // 4KB
)
func TestBasicPartSet(t *testing.T) {
// Construct random data of size partSize * 100
nParts := 100
data := tmrand.Bytes(testPartSize * nParts)
partSet := NewPartSetFromData(data, testPartSize)
assert.NotEmpty(t, partSet.Hash())
assert.EqualValues(t, nParts, partSet.Total())
assert.Equal(t, nParts, partSet.BitArray().Size())
assert.True(t, partSet.HashesTo(partSet.Hash()))
assert.True(t, partSet.IsComplete())
assert.EqualValues(t, nParts, partSet.Count())
assert.EqualValues(t, testPartSize*nParts, partSet.ByteSize())
// Test adding parts to a new partSet.
partSet2 := NewPartSetFromHeader(partSet.Header())
assert.True(t, partSet2.HasHeader(partSet.Header()))
for i := 0; i < int(partSet.Total()); i++ {
part := partSet.GetPart(i)
// t.Logf("\n%v", part)
added, err := partSet2.AddPart(part)
if !added || err != nil {
t.Errorf("failed to add part %v, error: %v", i, err)
}
}
// adding part with invalid index
added, err := partSet2.AddPart(&Part{Index: 10000})
assert.False(t, added)
assert.Error(t, err)
// adding existing part
added, err = partSet2.AddPart(partSet2.GetPart(0))
assert.False(t, added)
assert.NoError(t, err)
assert.Equal(t, partSet.Hash(), partSet2.Hash())
assert.EqualValues(t, nParts, partSet2.Total())
assert.EqualValues(t, nParts*testPartSize, partSet.ByteSize())
assert.True(t, partSet2.IsComplete())
// Reconstruct data, assert that they are equal.
data2Reader := partSet2.GetReader()
data2, err := io.ReadAll(data2Reader)
require.NoError(t, err)
assert.Equal(t, data, data2)
}
func TestWrongProof(t *testing.T) {
// Construct random data of size partSize * 100
data := tmrand.Bytes(testPartSize * 100)
partSet := NewPartSetFromData(data, testPartSize)
// Test adding a part with wrong data.
partSet2 := NewPartSetFromHeader(partSet.Header())
// Test adding a part with wrong trail.
part := partSet.GetPart(0)
part.Proof.Aunts[0][0] += byte(0x01)
added, err := partSet2.AddPart(part)
if added || err == nil {
t.Errorf("expected to fail adding a part with bad trail.")
}
// Test adding a part with wrong bytes.
part = partSet.GetPart(1)
part.Bytes[0] += byte(0x01)
added, err = partSet2.AddPart(part)
if added || err == nil {
t.Errorf("expected to fail adding a part with bad bytes.")
}
}
func TestPartSetHeaderValidateBasic(t *testing.T) {
testCases := []struct {
testName string
malleatePartSetHeader func(*PartSetHeader)
expectErr bool
}{
{"Good PartSet", func(psHeader *PartSetHeader) {}, false},
{"Invalid Hash", func(psHeader *PartSetHeader) { psHeader.Hash = make([]byte, 1) }, true},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
data := tmrand.Bytes(testPartSize * 100)
ps := NewPartSetFromData(data, testPartSize)
psHeader := ps.Header()
tc.malleatePartSetHeader(&psHeader)
assert.Equal(t, tc.expectErr, psHeader.ValidateBasic() != nil, "Validate Basic had an unexpected result")
})
}
}
func TestPartValidateBasic(t *testing.T) {
testCases := []struct {
testName string
malleatePart func(*Part)
expectErr bool
}{
{"Good Part", func(pt *Part) {}, false},
{"Too big part", func(pt *Part) { pt.Bytes = make([]byte, BlockPartSizeBytes+1) }, true},
{"Too big proof", func(pt *Part) {
pt.Proof = merkle.Proof{
Total: 1,
Index: 1,
LeafHash: make([]byte, 1024*1024),
}
}, true},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
data := tmrand.Bytes(testPartSize * 100)
ps := NewPartSetFromData(data, testPartSize)
part := ps.GetPart(0)
tc.malleatePart(part)
assert.Equal(t, tc.expectErr, part.ValidateBasic() != nil, "Validate Basic had an unexpected result")
})
}
}
func TestParSetHeaderProtoBuf(t *testing.T) {
testCases := []struct {
msg string
ps1 *PartSetHeader
expPass bool
}{
{"success empty", &PartSetHeader{}, true},
{"success",
&PartSetHeader{Total: 1, Hash: []byte("hash")}, true},
}
for _, tc := range testCases {
protoBlockID := tc.ps1.ToProto()
psh, err := PartSetHeaderFromProto(&protoBlockID)
if tc.expPass {
require.Equal(t, tc.ps1, psh, tc.msg)
} else {
require.Error(t, err, tc.msg)
}
}
}
func TestPartProtoBuf(t *testing.T) {
proof := merkle.Proof{
Total: 1,
Index: 1,
LeafHash: tmrand.Bytes(32),
}
testCases := []struct {
msg string
ps1 *Part
expPass bool
}{
{"failure empty", &Part{}, false},
{"failure nil", nil, false},
{"success",
&Part{Index: 1, Bytes: tmrand.Bytes(32), Proof: proof}, true},
}
for _, tc := range testCases {
proto, err := tc.ps1.ToProto()
if tc.expPass {
require.NoError(t, err, tc.msg)
}
p, err := PartFromProto(proto)
if tc.expPass {
require.NoError(t, err)
require.Equal(t, tc.ps1, p, tc.msg)
}
}
}