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