github.com/MetalBlockchain/metalgo@v1.11.9/utils/wrappers/packing_test.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package wrappers
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  const (
    13  	ByteSentinel  = 0
    14  	ShortSentinel = 0
    15  	IntSentinel   = 0
    16  	LongSentinel  = 0
    17  	BoolSentinel  = false
    18  )
    19  
    20  func TestPackerCheckSpace(t *testing.T) {
    21  	require := require.New(t)
    22  
    23  	p := Packer{Offset: -1}
    24  	p.checkSpace(1)
    25  	require.True(p.Errored())
    26  	require.ErrorIs(p.Err, errNegativeOffset)
    27  
    28  	p = Packer{}
    29  	p.checkSpace(-1)
    30  	require.True(p.Errored())
    31  	require.ErrorIs(p.Err, errInvalidInput)
    32  
    33  	p = Packer{Bytes: []byte{0x01}, Offset: 1}
    34  	p.checkSpace(1)
    35  	require.True(p.Errored())
    36  	require.ErrorIs(p.Err, ErrInsufficientLength)
    37  
    38  	p = Packer{Bytes: []byte{0x01}, Offset: 2}
    39  	p.checkSpace(0)
    40  	require.True(p.Errored())
    41  	require.ErrorIs(p.Err, ErrInsufficientLength)
    42  }
    43  
    44  func TestPackerExpand(t *testing.T) {
    45  	require := require.New(t)
    46  
    47  	p := Packer{Bytes: []byte{0x01}, Offset: 2}
    48  	p.expand(1)
    49  	require.True(p.Errored())
    50  	require.ErrorIs(p.Err, ErrInsufficientLength)
    51  
    52  	p = Packer{Bytes: []byte{0x01, 0x02, 0x03}, Offset: 0}
    53  	p.expand(1)
    54  	require.False(p.Errored())
    55  	require.NoError(p.Err)
    56  	require.Equal([]byte{0x01, 0x02, 0x03}, p.Bytes)
    57  }
    58  
    59  func TestPackerPackByte(t *testing.T) {
    60  	require := require.New(t)
    61  
    62  	p := Packer{MaxSize: 1}
    63  	p.PackByte(0x01)
    64  	require.False(p.Errored())
    65  	require.NoError(p.Err)
    66  	require.Equal([]byte{0x01}, p.Bytes)
    67  
    68  	p.PackByte(0x02)
    69  	require.True(p.Errored())
    70  	require.ErrorIs(p.Err, ErrInsufficientLength)
    71  }
    72  
    73  func TestPackerUnpackByte(t *testing.T) {
    74  	require := require.New(t)
    75  
    76  	p := Packer{Bytes: []byte{0x01}, Offset: 0}
    77  	require.Equal(uint8(1), p.UnpackByte())
    78  	require.False(p.Errored())
    79  	require.NoError(p.Err)
    80  	require.Equal(ByteLen, p.Offset)
    81  
    82  	require.Equal(uint8(ByteSentinel), p.UnpackByte())
    83  	require.True(p.Errored())
    84  	require.ErrorIs(p.Err, ErrInsufficientLength)
    85  }
    86  
    87  func TestPackerPackShort(t *testing.T) {
    88  	require := require.New(t)
    89  
    90  	p := Packer{MaxSize: 2}
    91  	p.PackShort(0x0102)
    92  	require.False(p.Errored())
    93  	require.NoError(p.Err)
    94  	require.Equal([]byte{0x01, 0x02}, p.Bytes)
    95  }
    96  
    97  func TestPackerUnpackShort(t *testing.T) {
    98  	require := require.New(t)
    99  
   100  	p := Packer{Bytes: []byte{0x01, 0x02}, Offset: 0}
   101  	require.Equal(uint16(0x0102), p.UnpackShort())
   102  	require.False(p.Errored())
   103  	require.NoError(p.Err)
   104  	require.Equal(ShortLen, p.Offset)
   105  
   106  	require.Equal(uint16(ShortSentinel), p.UnpackShort())
   107  	require.True(p.Errored())
   108  	require.ErrorIs(p.Err, ErrInsufficientLength)
   109  }
   110  
   111  func TestPackerPackInt(t *testing.T) {
   112  	require := require.New(t)
   113  
   114  	p := Packer{MaxSize: 4}
   115  	p.PackInt(0x01020304)
   116  	require.False(p.Errored())
   117  	require.NoError(p.Err)
   118  	require.Equal([]byte{0x01, 0x02, 0x03, 0x04}, p.Bytes)
   119  
   120  	p.PackInt(0x05060708)
   121  	require.True(p.Errored())
   122  	require.ErrorIs(p.Err, ErrInsufficientLength)
   123  }
   124  
   125  func TestPackerUnpackInt(t *testing.T) {
   126  	require := require.New(t)
   127  
   128  	p := Packer{Bytes: []byte{0x01, 0x02, 0x03, 0x04}, Offset: 0}
   129  	require.Equal(uint32(0x01020304), p.UnpackInt())
   130  	require.False(p.Errored())
   131  	require.NoError(p.Err)
   132  	require.Equal(IntLen, p.Offset)
   133  
   134  	require.Equal(uint32(IntSentinel), p.UnpackInt())
   135  	require.True(p.Errored())
   136  	require.ErrorIs(p.Err, ErrInsufficientLength)
   137  }
   138  
   139  func TestPackerPackLong(t *testing.T) {
   140  	require := require.New(t)
   141  
   142  	p := Packer{MaxSize: 8}
   143  	p.PackLong(0x0102030405060708)
   144  	require.False(p.Errored())
   145  	require.NoError(p.Err)
   146  	require.Equal([]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, p.Bytes)
   147  
   148  	p.PackLong(0x090a0b0c0d0e0f00)
   149  	require.True(p.Errored())
   150  	require.ErrorIs(p.Err, ErrInsufficientLength)
   151  }
   152  
   153  func TestPackerUnpackLong(t *testing.T) {
   154  	require := require.New(t)
   155  
   156  	p := Packer{Bytes: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, Offset: 0}
   157  	require.Equal(uint64(0x0102030405060708), p.UnpackLong())
   158  	require.False(p.Errored())
   159  	require.NoError(p.Err)
   160  	require.Equal(LongLen, p.Offset)
   161  
   162  	require.Equal(uint64(LongSentinel), p.UnpackLong())
   163  	require.True(p.Errored())
   164  	require.ErrorIs(p.Err, ErrInsufficientLength)
   165  }
   166  
   167  func TestPackerPackFixedBytes(t *testing.T) {
   168  	require := require.New(t)
   169  
   170  	p := Packer{MaxSize: 4}
   171  	p.PackFixedBytes([]byte("Avax"))
   172  	require.False(p.Errored())
   173  	require.NoError(p.Err)
   174  	require.Equal([]byte("Avax"), p.Bytes)
   175  
   176  	p.PackFixedBytes([]byte("Avax"))
   177  	require.True(p.Errored())
   178  	require.ErrorIs(p.Err, ErrInsufficientLength)
   179  }
   180  
   181  func TestPackerUnpackFixedBytes(t *testing.T) {
   182  	require := require.New(t)
   183  
   184  	p := Packer{Bytes: []byte("Avax")}
   185  	require.Equal([]byte("Avax"), p.UnpackFixedBytes(4))
   186  	require.False(p.Errored())
   187  	require.NoError(p.Err)
   188  	require.Equal(4, p.Offset)
   189  
   190  	require.Nil(p.UnpackFixedBytes(4))
   191  	require.True(p.Errored())
   192  	require.ErrorIs(p.Err, ErrInsufficientLength)
   193  }
   194  
   195  func TestPackerPackBytes(t *testing.T) {
   196  	require := require.New(t)
   197  
   198  	p := Packer{MaxSize: 8}
   199  	p.PackBytes([]byte("Avax"))
   200  	require.False(p.Errored())
   201  	require.NoError(p.Err)
   202  	require.Equal([]byte("\x00\x00\x00\x04Avax"), p.Bytes)
   203  
   204  	p.PackBytes([]byte("Avax"))
   205  	require.True(p.Errored())
   206  	require.ErrorIs(p.Err, ErrInsufficientLength)
   207  }
   208  
   209  func TestPackerUnpackBytes(t *testing.T) {
   210  	require := require.New(t)
   211  
   212  	p := Packer{Bytes: []byte("\x00\x00\x00\x04Avax")}
   213  	require.Equal([]byte("Avax"), p.UnpackBytes())
   214  	require.False(p.Errored())
   215  	require.NoError(p.Err)
   216  	require.Equal(8, p.Offset)
   217  
   218  	require.Nil(p.UnpackBytes())
   219  	require.True(p.Errored())
   220  	require.ErrorIs(p.Err, ErrInsufficientLength)
   221  }
   222  
   223  func TestPackerUnpackLimitedBytes(t *testing.T) {
   224  	require := require.New(t)
   225  
   226  	p := Packer{Bytes: []byte("\x00\x00\x00\x04Avax")}
   227  	require.Equal([]byte("Avax"), p.UnpackLimitedBytes(10))
   228  	require.False(p.Errored())
   229  	require.NoError(p.Err)
   230  	require.Equal(8, p.Offset)
   231  
   232  	require.Nil(p.UnpackLimitedBytes(10))
   233  	require.True(p.Errored())
   234  	require.ErrorIs(p.Err, ErrInsufficientLength)
   235  
   236  	// Reset and don't allow enough bytes
   237  	p = Packer{Bytes: p.Bytes}
   238  	require.Nil(p.UnpackLimitedBytes(2))
   239  	require.True(p.Errored())
   240  	require.ErrorIs(p.Err, errOversized)
   241  }
   242  
   243  func TestPackerString(t *testing.T) {
   244  	require := require.New(t)
   245  
   246  	p := Packer{MaxSize: 6}
   247  
   248  	p.PackStr("Avax")
   249  	require.False(p.Errored())
   250  	require.NoError(p.Err)
   251  	require.Equal([]byte{0x00, 0x04, 0x41, 0x76, 0x61, 0x78}, p.Bytes)
   252  }
   253  
   254  func TestPackerUnpackString(t *testing.T) {
   255  	require := require.New(t)
   256  
   257  	p := Packer{Bytes: []byte("\x00\x04Avax")}
   258  
   259  	require.Equal("Avax", p.UnpackStr())
   260  	require.False(p.Errored())
   261  	require.NoError(p.Err)
   262  	require.Equal(6, p.Offset)
   263  
   264  	require.Equal("", p.UnpackStr())
   265  	require.True(p.Errored())
   266  	require.ErrorIs(p.Err, ErrInsufficientLength)
   267  }
   268  
   269  func TestPackerUnpackLimitedString(t *testing.T) {
   270  	require := require.New(t)
   271  
   272  	p := Packer{Bytes: []byte("\x00\x04Avax")}
   273  	require.Equal("Avax", p.UnpackLimitedStr(10))
   274  	require.False(p.Errored())
   275  	require.NoError(p.Err)
   276  	require.Equal(6, p.Offset)
   277  
   278  	require.Equal("", p.UnpackLimitedStr(10))
   279  	require.True(p.Errored())
   280  	require.ErrorIs(p.Err, ErrInsufficientLength)
   281  
   282  	// Reset and don't allow enough bytes
   283  	p = Packer{Bytes: p.Bytes}
   284  	require.Equal("", p.UnpackLimitedStr(2))
   285  	require.True(p.Errored())
   286  	require.ErrorIs(p.Err, errOversized)
   287  }
   288  
   289  func TestPacker(t *testing.T) {
   290  	require := require.New(t)
   291  
   292  	p := Packer{MaxSize: 3}
   293  
   294  	require.False(p.Errored())
   295  	require.NoError(p.Err)
   296  
   297  	p.PackShort(17)
   298  	require.False(p.Errored())
   299  	require.NoError(p.Err)
   300  	require.Equal([]byte{0x0, 0x11}, p.Bytes)
   301  
   302  	p.PackShort(1)
   303  	require.True(p.Errored())
   304  	require.ErrorIs(p.Err, ErrInsufficientLength)
   305  
   306  	p = Packer{Bytes: p.Bytes}
   307  	require.Equal(uint16(17), p.UnpackShort())
   308  	require.False(p.Errored())
   309  	require.NoError(p.Err)
   310  }
   311  
   312  func TestPackBool(t *testing.T) {
   313  	require := require.New(t)
   314  
   315  	p := Packer{MaxSize: 3}
   316  	p.PackBool(false)
   317  	p.PackBool(true)
   318  	p.PackBool(false)
   319  	require.False(p.Errored())
   320  	require.NoError(p.Err)
   321  
   322  	p = Packer{Bytes: p.Bytes}
   323  	bool1, bool2, bool3 := p.UnpackBool(), p.UnpackBool(), p.UnpackBool()
   324  	require.False(p.Errored())
   325  	require.NoError(p.Err)
   326  	require.False(bool1)
   327  	require.True(bool2)
   328  	require.False(bool3)
   329  }
   330  
   331  func TestPackerPackBool(t *testing.T) {
   332  	require := require.New(t)
   333  
   334  	p := Packer{MaxSize: 1}
   335  
   336  	p.PackBool(true)
   337  	require.False(p.Errored())
   338  	require.NoError(p.Err)
   339  	require.Equal([]byte{0x01}, p.Bytes)
   340  
   341  	p.PackBool(false)
   342  	require.True(p.Errored())
   343  	require.ErrorIs(p.Err, ErrInsufficientLength)
   344  }
   345  
   346  func TestPackerUnpackBool(t *testing.T) {
   347  	require := require.New(t)
   348  
   349  	p := Packer{Bytes: []byte{0x01}, Offset: 0}
   350  
   351  	require.True(p.UnpackBool())
   352  	require.False(p.Errored())
   353  	require.NoError(p.Err)
   354  	require.Equal(BoolLen, p.Offset)
   355  
   356  	require.Equal(BoolSentinel, p.UnpackBool())
   357  	require.True(p.Errored())
   358  	require.ErrorIs(p.Err, ErrInsufficientLength)
   359  
   360  	p = Packer{Bytes: []byte{0x42}, Offset: 0}
   361  	require.False(p.UnpackBool())
   362  	require.True(p.Errored())
   363  	require.ErrorIs(p.Err, errBadBool)
   364  }