github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/protokit/protokit_test.go (about)

     1  // Copyright 2020 Insolar Network Ltd.
     2  // All rights reserved.
     3  // This material is licensed under the Insolar License version 1.0,
     4  // available at https://github.com/insolar/assured-ledger/blob/master/LICENSE.md.
     5  
     6  package protokit
     7  
     8  import (
     9  	"bytes"
    10  	"math"
    11  	"testing"
    12  
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  type testCase struct {
    17  	Name     string
    18  	WireType WireType
    19  	FieldId  float64
    20  	TypeByte byte
    21  	Data     []byte
    22  	Result   uint64
    23  	Size     uint64
    24  }
    25  
    26  func (tc *testCase) getTypeByte() byte {
    27  	return byte(math.Pow(2, WireTypeBits) + tc.FieldId)
    28  }
    29  
    30  // TODO this cases cause panics - WireStartGroup, WireEndGroup
    31  var testCases = []testCase{
    32  	{
    33  		Name:     "WireVarint",
    34  		WireType: WireVarint,
    35  		FieldId:  0,
    36  		Data:     []byte{123},
    37  		Result:   uint64(123),
    38  		Size:     2,
    39  	},
    40  	{
    41  		Name:     "WireFixed64",
    42  		WireType: WireFixed64,
    43  		FieldId:  1,
    44  		Data:     []byte{1, 1, 1, 1, 1, 1, 1, 1, 1},
    45  		Result:   uint64(0x101010101010101),
    46  		Size:     9,
    47  	},
    48  	{
    49  		Name:     "WireBytes",
    50  		WireType: WireBytes,
    51  		FieldId:  2,
    52  		Data:     []byte{123},
    53  		Result:   uint64(123),
    54  		Size:     2,
    55  	},
    56  	{
    57  		Name:     "WireFixed32",
    58  		WireType: WireFixed32,
    59  		FieldId:  5,
    60  		Data:     []byte{1, 1, 1, 1, 1},
    61  		Result:   uint64(0x1010101),
    62  		Size:     5,
    63  	},
    64  }
    65  
    66  func TestSafeWireTag(t *testing.T) {
    67  	var test uint64
    68  	test = math.MaxUint32 + 1
    69  	wireTag, err := SafeWireTag(test)
    70  	require.Error(t, err)
    71  	require.Equal(t, WireTag(0), wireTag)
    72  
    73  	test = uint64(math.Pow(2, WireTypeBits-1))
    74  	wireTag, err = SafeWireTag(test)
    75  	require.Error(t, err)
    76  	require.Equal(t, WireTag(0), wireTag)
    77  
    78  	test = uint64(math.Pow(2, WireTypeBits))
    79  	wireTag, err = SafeWireTag(test)
    80  	require.NoError(t, err)
    81  	require.Equal(t, WireTag(test), wireTag)
    82  	require.Equal(t, WireVarint, wireTag.Type())
    83  }
    84  
    85  func TestWireTypeDecodeFromAnotherType(t *testing.T) {
    86  	buf := bytes.Buffer{}
    87  	buf.Write([]byte{byte(math.Pow(2, WireTypeBits)), 123})
    88  
    89  	// try to decode WireVariant to WireBytes
    90  	_, _, err := WireBytes.ReadTagValue(&buf)
    91  	require.Error(t, err)
    92  
    93  	// try to decode WireVariant to WireFixed64
    94  	_, _, err = WireFixed64.ReadTagValue(&buf)
    95  	require.Error(t, err)
    96  
    97  	// try to decode WireVariant to WireFixed32
    98  	_, _, err = WireFixed32.ReadTagValue(&buf)
    99  	require.Error(t, err)
   100  }
   101  
   102  func TestWireTypeDecodeFrom(t *testing.T) {
   103  	buf := bytes.Buffer{}
   104  
   105  	for _, test := range testCases {
   106  		t.Run(test.Name, func(t *testing.T) {
   107  			buf.Reset()
   108  			buf.Write(append([]byte{test.getTypeByte()}, test.Data...))
   109  
   110  			wireTag, data, err := test.WireType.ReadTagValue(&buf)
   111  			require.NoError(t, err)
   112  			require.Equal(t, test.Result, data)
   113  			require.Equal(t, test.WireType, wireTag.Type())
   114  		})
   115  	}
   116  }
   117  
   118  func TestWireTagDecodeFromAnotherType(t *testing.T) {
   119  	buf := bytes.Buffer{}
   120  	buf.Write([]byte{byte(math.Pow(2, WireTypeBits)), 123})
   121  
   122  	// try to decode WireVariant to WireBytes
   123  	_, err := WireBytes.Tag(1).ReadTagValue(&buf)
   124  	require.Error(t, err)
   125  
   126  	// try to decode WireVariant to WireFixed64
   127  	_, err = WireFixed64.Tag(1).ReadTagValue(&buf)
   128  	require.Error(t, err)
   129  
   130  	// try to decode WireVariant to WireFixed32
   131  	_, err = WireFixed32.Tag(1).ReadTagValue(&buf)
   132  	require.Error(t, err)
   133  }
   134  
   135  func TestWireTagDecodeFrom(t *testing.T) {
   136  	buf := bytes.Buffer{}
   137  
   138  	for _, test := range testCases {
   139  		t.Run(test.Name, func(t *testing.T) {
   140  			buf.Reset()
   141  			buf.Write(append([]byte{test.getTypeByte()}, test.Data...))
   142  
   143  			tag := test.WireType.Tag(1)
   144  			data, err := tag.ReadTagValue(&buf)
   145  			require.NoError(t, err)
   146  			require.Equal(t, test.Result, data)
   147  		})
   148  	}
   149  }
   150  
   151  func TestEnsureFixedFieldSize(t *testing.T) {
   152  	tag := WireFixed64.Tag(1)
   153  	newTag := tag.EnsureFixedFieldSize(9)
   154  	require.Equal(t, tag, newTag)
   155  
   156  	tag = WireFixed32.Tag(1)
   157  	newTag = tag.EnsureFixedFieldSize(5)
   158  	require.Equal(t, tag, newTag)
   159  }
   160  
   161  func TestEnsureFixedFieldSizeFailed(t *testing.T) {
   162  	tag := WireVarint.Tag(1)
   163  	require.PanicsWithValue(t, "illegal state - not fixed size", func() { tag.EnsureFixedFieldSize(12) })
   164  
   165  	tag = WireBytes.Tag(1)
   166  	require.PanicsWithValue(t, "illegal state - not fixed size", func() { tag.EnsureFixedFieldSize(12) })
   167  }
   168  
   169  func TestWireTagMustEncodeTo(t *testing.T) {
   170  	buf := bytes.Buffer{}
   171  
   172  	for _, test := range testCases {
   173  		t.Run(test.Name, func(t *testing.T) {
   174  			buf.Reset()
   175  			buf.Write(append([]byte{test.getTypeByte()}, test.Data...))
   176  
   177  			tag := test.WireType.Tag(1)
   178  			tag.MustWrite(&buf, 1234)
   179  		})
   180  	}
   181  }
   182  
   183  func TestWireTagFieldSize(t *testing.T) {
   184  	buf := bytes.Buffer{}
   185  
   186  	for _, test := range testCases {
   187  		t.Run(test.Name, func(t *testing.T) {
   188  			buf.Reset()
   189  			buf.Write(append([]byte{test.getTypeByte()}, test.Data...))
   190  
   191  			tag := test.WireType.Tag(1)
   192  			size := tag.FieldSize(0)
   193  			require.Equal(t, test.Size, size)
   194  		})
   195  	}
   196  }
   197  
   198  func TestSizeTag(t *testing.T) {
   199  	require.Equal(t, 1, SizeTag(1))
   200  	require.Panics(t, func() { SizeTag(0) })
   201  	require.Panics(t, func() { SizeTag(MaxFieldID + 1) })
   202  }
   203  
   204  func TestEncodeBytes(t *testing.T) {
   205  	for i := uint64(1); i != 0; i <<= 1 {
   206  		var b [MaxVarintSize]byte
   207  		n := EncodeVarintToBytes(b[:], i)
   208  		require.Equal(t, n, SizeVarint64(i))
   209  		x, n2 := DecodeVarintFromBytes(b[:])
   210  		if n != n2 {
   211  			DecodeVarintFromBytes(b[:])
   212  		}
   213  		require.Equal(t, n, n2)
   214  		require.Equal(t, i, x)
   215  	}
   216  }
   217  
   218  func TestSizeVarint(t *testing.T) {
   219  	sz := 1
   220  	for i := uint32(1); i != 0; i <<= 1 {
   221  		n := SizeVarint32(i)
   222  		require.GreaterOrEqual(t, n, sz)
   223  		require.Equal(t, n, SizeVarint64(uint64(i)))
   224  		if n == sz {
   225  			continue
   226  		}
   227  		require.Equal(t, sz+1, n)
   228  		require.Equal(t, sz, SizeVarint32(i-1), i)
   229  		sz = n
   230  	}
   231  
   232  	for i := uint64(1 << 32); i != 0; i <<= 1 {
   233  		n := SizeVarint64(i)
   234  		require.GreaterOrEqual(t, n, sz)
   235  		if n == sz {
   236  			continue
   237  		}
   238  		require.Equal(t, sz+1, n)
   239  		require.Equal(t, sz, SizeVarint64(i-1), i)
   240  		sz = n
   241  	}
   242  	require.Equal(t, MaxVarintSize, sz)
   243  }