github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/dbnode/encoding/istream_test.go (about)

     1  // Copyright (c) 2016 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package encoding
    22  
    23  import (
    24  	"io"
    25  	"testing"
    26  
    27  	"github.com/stretchr/testify/require"
    28  
    29  	"github.com/m3db/m3/src/dbnode/x/xio"
    30  )
    31  
    32  func TestIStreamReadBits(t *testing.T) {
    33  	byteStream := []byte{
    34  		0xca, 0xfe, 0xfd, 0x89, 0x1a, 0x2b, 0x3c, 0x48, 0x55, 0xe6, 0xf7,
    35  		0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80,
    36  	}
    37  
    38  	is := NewIStream(xio.NewBytesReader64(byteStream))
    39  	numBits := []byte{1, 3, 4, 8, 7, 2, 64, 64}
    40  	var res []uint64
    41  	for _, v := range numBits {
    42  		read, err := is.ReadBits(v)
    43  		require.NoError(t, err)
    44  		res = append(res, read)
    45  	}
    46  	expected := []uint64{0x1, 0x4, 0xa, 0xfe, 0x7e, 0x3, 0x1234567890abcdef, 0x1}
    47  	require.Equal(t, expected, res)
    48  
    49  	_, err := is.ReadBits(8)
    50  	require.EqualError(t, err, io.EOF.Error())
    51  }
    52  
    53  func TestIStreamReadByte(t *testing.T) {
    54  	var (
    55  		byteStream = []uint8{
    56  			0xca, 0xfe, 0xfd, 0x89, 0x1a, 0x2b, 0x3c, 0x48, 0x55, 0xe6, 0xf7,
    57  			0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80,
    58  		}
    59  		is  = NewIStream(xio.NewBytesReader64(byteStream))
    60  		res = make([]byte, 0, len(byteStream))
    61  	)
    62  
    63  	for range byteStream {
    64  		read, err := is.ReadByte()
    65  		require.NoError(t, err)
    66  		res = append(res, read)
    67  	}
    68  	require.Equal(t, byteStream, res)
    69  
    70  	_, err := is.ReadByte()
    71  	require.EqualError(t, err, io.EOF.Error())
    72  }
    73  
    74  func TestIStreamPeekBitsSuccess(t *testing.T) {
    75  	byteStream := []byte{0xa9, 0xfe, 0xfe, 0xdf, 0x9b, 0x57, 0x21, 0xf1}
    76  	is := NewIStream(xio.NewBytesReader64(byteStream))
    77  	inputs := []struct {
    78  		numBits  uint8
    79  		expected uint64
    80  	}{
    81  		{0, 0},
    82  		{1, 0x1},
    83  		{8, 0xa9},
    84  		{10, 0x2a7},
    85  		{13, 0x153f},
    86  		{16, 0xa9fe},
    87  		{32, 0xa9fefedf},
    88  		{64, 0xa9fefedf9b5721f1},
    89  	}
    90  	for _, input := range inputs {
    91  		res, err := is.PeekBits(input.numBits)
    92  		require.NoError(t, err)
    93  		require.Equal(t, input.expected, res)
    94  	}
    95  	require.Equal(t, uint64(0), is.current)
    96  	require.Equal(t, 0, int(is.remaining))
    97  }
    98  
    99  func TestIStreamPeekBitsError(t *testing.T) {
   100  	byteStream := []byte{0x1, 0x2}
   101  	is := NewIStream(xio.NewBytesReader64(byteStream))
   102  	res, err := is.PeekBits(20)
   103  	require.EqualError(t, err, io.EOF.Error())
   104  	require.Equal(t, uint64(0), res)
   105  }
   106  
   107  func TestIStreamReadAfterPeekBits(t *testing.T) {
   108  	byteStream := []byte{0xab, 0xcd}
   109  	is := NewIStream(xio.NewBytesReader64(byteStream))
   110  	res, err := is.PeekBits(10)
   111  	require.NoError(t, err)
   112  	require.Equal(t, uint64(0x2af), res)
   113  	_, err = is.PeekBits(20)
   114  	require.EqualError(t, err, io.EOF.Error())
   115  
   116  	inputs := []struct {
   117  		numBits  uint8
   118  		expected uint64
   119  	}{
   120  		{2, 0x2},
   121  		{9, 0x15e},
   122  	}
   123  	for _, input := range inputs {
   124  		res, err := is.ReadBits(input.numBits)
   125  		require.NoError(t, err)
   126  		require.Equal(t, input.expected, res)
   127  	}
   128  	_, err = is.ReadBits(8)
   129  	require.EqualError(t, err, io.EOF.Error())
   130  }
   131  
   132  func TestIStreamPeekAfterReadBits(t *testing.T) {
   133  	byteStream := []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA}
   134  	is := NewIStream(xio.NewBytesReader64(byteStream))
   135  
   136  	res, err := is.ReadBits(16)
   137  	require.NoError(t, err)
   138  	require.Equal(t, uint64(0x102), res)
   139  
   140  	res, err = is.PeekBits(63)
   141  	require.NoError(t, err)
   142  	require.Equal(t, uint64(0x30405060708090A)>>1, res)
   143  
   144  	res, err = is.PeekBits(64)
   145  	require.NoError(t, err)
   146  	require.Equal(t, uint64(0x30405060708090A), res)
   147  
   148  	res, err = is.ReadBits(1)
   149  	require.NoError(t, err)
   150  	require.Equal(t, uint64(0), res)
   151  
   152  	res, err = is.PeekBits(63)
   153  	require.NoError(t, err)
   154  	require.Equal(t, uint64(0x30405060708090A), res)
   155  
   156  	_, err = is.PeekBits(64)
   157  	require.EqualError(t, err, io.EOF.Error())
   158  }
   159  
   160  func TestIStreamRemainingBitsInCurrentByte(t *testing.T) {
   161  	byteStream := []byte{0xff, 0, 0x42}
   162  	is := NewIStream(xio.NewBytesReader64(byteStream))
   163  	for _, b := range byteStream {
   164  		for i := 0; i < 8; i++ {
   165  			var expected uint
   166  			if i > 0 {
   167  				expected = uint(8 - i)
   168  			}
   169  			require.Equal(t, expected, is.RemainingBitsInCurrentByte())
   170  			bit, err := is.ReadBit()
   171  			require.NoError(t, err)
   172  			expectedBit := Bit(b>>i) & 1
   173  			require.Equal(t, expectedBit, bit)
   174  		}
   175  	}
   176  }
   177  
   178  func TestIStreamReset(t *testing.T) {
   179  	is := NewIStream(xio.NewBytesReader64([]byte{0xff}))
   180  	_, _ = is.ReadBits(8)
   181  	_, _ = is.ReadBits(1)
   182  	is.Reset(xio.NewBytesReader64(nil))
   183  	require.Equal(t, uint64(0), is.current)
   184  	require.Equal(t, uint8(0), is.remaining)
   185  	require.Equal(t, 0, is.index)
   186  }