github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/codec/cbor/decoder_test.go (about)

     1  package cbor_test
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	cborcodec "github.com/onflow/flow-go/model/encoding/cbor"
    11  	"github.com/onflow/flow-go/network/codec"
    12  	"github.com/onflow/flow-go/network/codec/cbor"
    13  	"github.com/onflow/flow-go/utils/unittest"
    14  )
    15  
    16  func TestDecoder_Decode(t *testing.T) {
    17  	c := cbor.NewCodec()
    18  
    19  	blockProposal := unittest.ProposalFixture()
    20  
    21  	t.Run("decodes message successfully", func(t *testing.T) {
    22  		var buf bytes.Buffer
    23  
    24  		err := c.NewEncoder(&buf).Encode(blockProposal)
    25  		require.NoError(t, err)
    26  
    27  		decoded, err := c.NewDecoder(&buf).Decode()
    28  		require.NoError(t, err)
    29  		require.Equal(t, blockProposal, decoded)
    30  	})
    31  
    32  	t.Run("returns error when data is empty", func(t *testing.T) {
    33  		var buf bytes.Buffer
    34  		// empty buffer
    35  
    36  		decoded, err := c.NewDecoder(&buf).Decode()
    37  		assert.Nil(t, decoded)
    38  		assert.True(t, codec.IsErrInvalidEncoding(err))
    39  	})
    40  
    41  	t.Run("returns error when data is empty - nil byte", func(t *testing.T) {
    42  		var buf bytes.Buffer
    43  
    44  		// nil byte
    45  		buf.WriteByte(0x00)
    46  
    47  		decoded, err := c.NewDecoder(&buf).Decode()
    48  		assert.Nil(t, decoded)
    49  		assert.True(t, codec.IsErrInvalidEncoding(err))
    50  	})
    51  
    52  	t.Run("returns error when data is empty - cbor nil", func(t *testing.T) {
    53  		var buf bytes.Buffer
    54  
    55  		// explicit cbor encoding of nil
    56  		err := cborcodec.NewCodec().NewEncoder(&buf).Encode(nil)
    57  		require.NoError(t, err)
    58  
    59  		decoded, err := c.NewDecoder(&buf).Decode()
    60  		assert.Nil(t, decoded)
    61  		assert.True(t, codec.IsErrInvalidEncoding(err))
    62  	})
    63  
    64  	t.Run("returns error when data is empty - cbor empty []byte", func(t *testing.T) {
    65  		var buf bytes.Buffer
    66  
    67  		// explicit cbor encoding of an empty byte slice
    68  		err := cborcodec.NewCodec().NewEncoder(&buf).Encode([]byte{})
    69  		require.NoError(t, err)
    70  
    71  		decoded, err := c.NewDecoder(&buf).Decode()
    72  		assert.Nil(t, decoded)
    73  		assert.True(t, codec.IsErrInvalidEncoding(err))
    74  	})
    75  
    76  	t.Run("returns error when message code is invalid", func(t *testing.T) {
    77  		var buf bytes.Buffer
    78  
    79  		// the first byte is the message code, the remaining bytes are the message
    80  		// in this test, only the first byte is set since there should be an error after reading
    81  		// the invalid code
    82  		datas := [][]byte{
    83  			{codec.CodeMin.Uint8() - 1}, // code < min
    84  			{codec.CodeMin.Uint8()},     // code == min
    85  			{codec.CodeMax.Uint8()},     // code == max
    86  			{codec.CodeMax.Uint8() + 1}, // code > max
    87  		}
    88  
    89  		for i := range datas {
    90  			err := cborcodec.NewCodec().NewEncoder(&buf).Encode(datas[i])
    91  			require.NoError(t, err)
    92  
    93  			decoded, err := c.NewDecoder(&buf).Decode()
    94  			assert.Nil(t, decoded)
    95  			assert.True(t, codec.IsErrUnknownMsgCode(err))
    96  
    97  			buf.Reset()
    98  		}
    99  	})
   100  
   101  	t.Run("returns error when unmarshalling fails - empty", func(t *testing.T) {
   102  		var buf bytes.Buffer
   103  
   104  		err := cborcodec.NewCodec().NewEncoder(&buf).Encode([]byte{codec.CodeBlockProposal.Uint8()})
   105  		require.NoError(t, err)
   106  
   107  		decoded, err := c.NewDecoder(&buf).Decode()
   108  		assert.Nil(t, decoded)
   109  		assert.True(t, codec.IsErrMsgUnmarshal(err))
   110  	})
   111  
   112  	t.Run("returns error when unmarshalling fails - wrong type", func(t *testing.T) {
   113  		// first encode the message to bytes with an incorrect type
   114  		var data bytes.Buffer
   115  		_ = data.WriteByte(codec.CodeCollectionGuarantee.Uint8())
   116  		encoder := cborcodec.EncMode.NewEncoder(&data)
   117  		err := encoder.Encode(blockProposal)
   118  		require.NoError(t, err)
   119  
   120  		// encode the message to bytes
   121  		var buf bytes.Buffer
   122  		encoder = cborcodec.EncMode.NewEncoder(&buf)
   123  		err = encoder.Encode(data.Bytes())
   124  		require.NoError(t, err)
   125  
   126  		decoded, err := c.NewDecoder(&buf).Decode()
   127  		assert.Nil(t, decoded)
   128  		assert.True(t, codec.IsErrMsgUnmarshal(err), "incorrect error type: %v", err)
   129  	})
   130  
   131  	t.Run("returns error when unmarshalling fails - corrupt", func(t *testing.T) {
   132  		// first encode the message to bytes
   133  		var data bytes.Buffer
   134  		_ = data.WriteByte(codec.CodeBlockProposal.Uint8())
   135  		encoder := cborcodec.EncMode.NewEncoder(&data)
   136  		err := encoder.Encode(blockProposal)
   137  		require.NoError(t, err)
   138  
   139  		var buf bytes.Buffer
   140  		encoder = cborcodec.EncMode.NewEncoder(&buf)
   141  		encoded := data.Bytes()
   142  
   143  		// corrupt the encoded message
   144  		encoded[2] = 0x20
   145  
   146  		// encode the message to bytes
   147  		err = encoder.Encode(encoded)
   148  		require.NoError(t, err)
   149  
   150  		decoded, err := c.NewDecoder(&buf).Decode()
   151  		assert.Nil(t, decoded)
   152  		assert.True(t, codec.IsErrMsgUnmarshal(err), "incorrect error type: %v", err)
   153  	})
   154  }