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