github.com/DFWallet/tendermint-cosmos@v0.0.2/types/part_set_test.go (about) 1 package types 2 3 import ( 4 "io/ioutil" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 "github.com/stretchr/testify/require" 9 10 "github.com/DFWallet/tendermint-cosmos/crypto/merkle" 11 tmrand "github.com/DFWallet/tendermint-cosmos/libs/rand" 12 ) 13 14 const ( 15 testPartSize = 65536 // 64KB ... 4096 // 4KB 16 ) 17 18 func TestBasicPartSet(t *testing.T) { 19 // Construct random data of size partSize * 100 20 nParts := 100 21 data := tmrand.Bytes(testPartSize * nParts) 22 partSet := NewPartSetFromData(data, testPartSize) 23 24 assert.NotEmpty(t, partSet.Hash()) 25 assert.EqualValues(t, nParts, partSet.Total()) 26 assert.Equal(t, nParts, partSet.BitArray().Size()) 27 assert.True(t, partSet.HashesTo(partSet.Hash())) 28 assert.True(t, partSet.IsComplete()) 29 assert.EqualValues(t, nParts, partSet.Count()) 30 assert.EqualValues(t, testPartSize*nParts, partSet.ByteSize()) 31 32 // Test adding parts to a new partSet. 33 partSet2 := NewPartSetFromHeader(partSet.Header()) 34 35 assert.True(t, partSet2.HasHeader(partSet.Header())) 36 for i := 0; i < int(partSet.Total()); i++ { 37 part := partSet.GetPart(i) 38 // t.Logf("\n%v", part) 39 added, err := partSet2.AddPart(part) 40 if !added || err != nil { 41 t.Errorf("failed to add part %v, error: %v", i, err) 42 } 43 } 44 // adding part with invalid index 45 added, err := partSet2.AddPart(&Part{Index: 10000}) 46 assert.False(t, added) 47 assert.Error(t, err) 48 // adding existing part 49 added, err = partSet2.AddPart(partSet2.GetPart(0)) 50 assert.False(t, added) 51 assert.Nil(t, err) 52 53 assert.Equal(t, partSet.Hash(), partSet2.Hash()) 54 assert.EqualValues(t, nParts, partSet2.Total()) 55 assert.EqualValues(t, nParts*testPartSize, partSet.ByteSize()) 56 assert.True(t, partSet2.IsComplete()) 57 58 // Reconstruct data, assert that they are equal. 59 data2Reader := partSet2.GetReader() 60 data2, err := ioutil.ReadAll(data2Reader) 61 require.NoError(t, err) 62 63 assert.Equal(t, data, data2) 64 } 65 66 func TestWrongProof(t *testing.T) { 67 // Construct random data of size partSize * 100 68 data := tmrand.Bytes(testPartSize * 100) 69 partSet := NewPartSetFromData(data, testPartSize) 70 71 // Test adding a part with wrong data. 72 partSet2 := NewPartSetFromHeader(partSet.Header()) 73 74 // Test adding a part with wrong trail. 75 part := partSet.GetPart(0) 76 part.Proof.Aunts[0][0] += byte(0x01) 77 added, err := partSet2.AddPart(part) 78 if added || err == nil { 79 t.Errorf("expected to fail adding a part with bad trail.") 80 } 81 82 // Test adding a part with wrong bytes. 83 part = partSet.GetPart(1) 84 part.Bytes[0] += byte(0x01) 85 added, err = partSet2.AddPart(part) 86 if added || err == nil { 87 t.Errorf("expected to fail adding a part with bad bytes.") 88 } 89 } 90 91 func TestPartSetHeaderValidateBasic(t *testing.T) { 92 testCases := []struct { 93 testName string 94 malleatePartSetHeader func(*PartSetHeader) 95 expectErr bool 96 }{ 97 {"Good PartSet", func(psHeader *PartSetHeader) {}, false}, 98 {"Invalid Hash", func(psHeader *PartSetHeader) { psHeader.Hash = make([]byte, 1) }, true}, 99 } 100 for _, tc := range testCases { 101 tc := tc 102 t.Run(tc.testName, func(t *testing.T) { 103 data := tmrand.Bytes(testPartSize * 100) 104 ps := NewPartSetFromData(data, testPartSize) 105 psHeader := ps.Header() 106 tc.malleatePartSetHeader(&psHeader) 107 assert.Equal(t, tc.expectErr, psHeader.ValidateBasic() != nil, "Validate Basic had an unexpected result") 108 }) 109 } 110 } 111 112 func TestPartValidateBasic(t *testing.T) { 113 testCases := []struct { 114 testName string 115 malleatePart func(*Part) 116 expectErr bool 117 }{ 118 {"Good Part", func(pt *Part) {}, false}, 119 {"Too big part", func(pt *Part) { pt.Bytes = make([]byte, BlockPartSizeBytes+1) }, true}, 120 {"Too big proof", func(pt *Part) { 121 pt.Proof = merkle.Proof{ 122 Total: 1, 123 Index: 1, 124 LeafHash: make([]byte, 1024*1024), 125 } 126 }, true}, 127 } 128 129 for _, tc := range testCases { 130 tc := tc 131 t.Run(tc.testName, func(t *testing.T) { 132 data := tmrand.Bytes(testPartSize * 100) 133 ps := NewPartSetFromData(data, testPartSize) 134 part := ps.GetPart(0) 135 tc.malleatePart(part) 136 assert.Equal(t, tc.expectErr, part.ValidateBasic() != nil, "Validate Basic had an unexpected result") 137 }) 138 } 139 } 140 141 func TestParSetHeaderProtoBuf(t *testing.T) { 142 testCases := []struct { 143 msg string 144 ps1 *PartSetHeader 145 expPass bool 146 }{ 147 {"success empty", &PartSetHeader{}, true}, 148 {"success", 149 &PartSetHeader{Total: 1, Hash: []byte("hash")}, true}, 150 } 151 152 for _, tc := range testCases { 153 protoBlockID := tc.ps1.ToProto() 154 155 psh, err := PartSetHeaderFromProto(&protoBlockID) 156 if tc.expPass { 157 require.Equal(t, tc.ps1, psh, tc.msg) 158 } else { 159 require.Error(t, err, tc.msg) 160 } 161 } 162 } 163 164 func TestPartProtoBuf(t *testing.T) { 165 166 proof := merkle.Proof{ 167 Total: 1, 168 Index: 1, 169 LeafHash: tmrand.Bytes(32), 170 } 171 testCases := []struct { 172 msg string 173 ps1 *Part 174 expPass bool 175 }{ 176 {"failure empty", &Part{}, false}, 177 {"failure nil", nil, false}, 178 {"success", 179 &Part{Index: 1, Bytes: tmrand.Bytes(32), Proof: proof}, true}, 180 } 181 182 for _, tc := range testCases { 183 proto, err := tc.ps1.ToProto() 184 if tc.expPass { 185 require.NoError(t, err, tc.msg) 186 } 187 188 p, err := PartFromProto(proto) 189 if tc.expPass { 190 require.NoError(t, err) 191 require.Equal(t, tc.ps1, p, tc.msg) 192 } 193 } 194 }