github.com/m3db/m3@v1.5.0/src/dbnode/persist/fs/msgpack/stream_with_digest_test.go (about)

     1  // Copyright (c) 2020 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 msgpack
    22  
    23  import (
    24  	"bufio"
    25  	"bytes"
    26  	"hash/adler32"
    27  	"testing"
    28  
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  const srcString = "foo bar baz qux quux corge grault"
    33  
    34  func TestDecoderStreamWithDigestRead(t *testing.T) {
    35  	stream := newTestDecoderStream()
    36  
    37  	// Read srcString in chunkLen size chunks
    38  	chunkLen := 3
    39  	buf := make([]byte, len(srcString))
    40  	for start := 0; start < len(srcString); start = start + chunkLen {
    41  		end := start + chunkLen
    42  		if end > len(srcString) {
    43  			end = len(srcString)
    44  		}
    45  
    46  		n, err := stream.Read(buf[start:end])
    47  		require.NoError(t, err)
    48  		require.Equal(t, chunkLen, n)
    49  		require.Equal(t, adler32.Checksum(buf[:end]), stream.digest().Sum32())
    50  	}
    51  }
    52  
    53  func TestDecoderStreamWithDigestReadByte(t *testing.T) {
    54  	stream := newTestDecoderStream()
    55  
    56  	buf := make([]byte, len(srcString))
    57  	for i := 1; i < len(srcString); i++ {
    58  		n, err := stream.Read(buf[i-1 : i])
    59  		require.NoError(t, err)
    60  		require.Equal(t, 1, n)
    61  		require.Equal(t, adler32.Checksum(buf[:i]), stream.digest().Sum32())
    62  	}
    63  }
    64  
    65  func TestDecoderStreamWithDigestUnreadByte(t *testing.T) {
    66  	stream := decoderStreamWithDigest{
    67  		reader:       bufio.NewReader(bytes.NewReader([]byte(srcString))),
    68  		readerDigest: adler32.New(),
    69  	}
    70  
    71  	b, err := stream.ReadByte()
    72  	require.NoError(t, err)
    73  	require.Equal(t, srcString[0], b)
    74  	require.False(t, stream.unreadByte)
    75  
    76  	err = stream.UnreadByte()
    77  	require.NoError(t, err)
    78  	require.True(t, stream.unreadByte)
    79  }
    80  
    81  func TestDecoderStreamWithDigestReset(t *testing.T) {
    82  	stream := newTestDecoderStream()
    83  
    84  	b, err := stream.ReadByte()
    85  	require.NoError(t, err)
    86  	require.Equal(t, srcString[0], b)
    87  
    88  	b, err = stream.ReadByte()
    89  	require.NoError(t, err)
    90  	require.Equal(t, srcString[1], b)
    91  
    92  	stream.reset(bufio.NewReader(bytes.NewReader([]byte(srcString))))
    93  
    94  	b, err = stream.ReadByte()
    95  	require.NoError(t, err)
    96  	require.Equal(t, srcString[0], b)
    97  }
    98  
    99  func TestDecoderStreamWithDigestValidate(t *testing.T) {
   100  	stream := newTestDecoderStream()
   101  	buf := make([]byte, 5)
   102  
   103  	n, err := stream.Read(buf)
   104  	require.NoError(t, err)
   105  	require.Equal(t, 5, n)
   106  
   107  	require.NoError(t, stream.validate(adler32.Checksum(buf)))
   108  	require.Error(t, stream.validate(adler32.Checksum([]byte("asdf"))))
   109  }
   110  
   111  func TestDecoderStreamWithDigestCapture(t *testing.T) {
   112  	stream := newTestDecoderStream()
   113  
   114  	require.NoError(t, stream.validate(1))
   115  
   116  	bytes := []byte("manual capture")
   117  	require.NoError(t, stream.capture(bytes))
   118  
   119  	require.Equal(t, adler32.Checksum(bytes), stream.digest().Sum32())
   120  }
   121  
   122  func TestDecoderStreamWithDigestReadUnreadRead(t *testing.T) {
   123  	stream := newTestDecoderStream()
   124  
   125  	buf := make([]byte, len(srcString))
   126  	end := 0
   127  
   128  	b1, err := stream.ReadByte()
   129  	require.NoError(t, err)
   130  	buf[0] = b1
   131  	end++
   132  	require.Equal(t, adler32.Checksum(buf[:end]), stream.digest().Sum32())
   133  
   134  	err = stream.UnreadByte()
   135  	end--
   136  	require.NoError(t, err)
   137  
   138  	b2, err := stream.ReadByte()
   139  	require.NoError(t, err)
   140  	end++
   141  	require.Equal(t, b1, b2)
   142  	require.Equal(t, adler32.Checksum(buf[:end]), stream.digest().Sum32())
   143  
   144  	n, err := stream.Read(buf[end : end+4])
   145  	require.NoError(t, err)
   146  	require.Equal(t, 4, n)
   147  	end += n
   148  	require.Equal(t, adler32.Checksum(buf[:end]), stream.digest().Sum32())
   149  
   150  	err = stream.UnreadByte()
   151  	end--
   152  	require.NoError(t, err)
   153  
   154  	n, err = stream.Read(buf[end : end+4])
   155  	require.NoError(t, err)
   156  	require.Equal(t, 4, n)
   157  	end += n
   158  	require.Equal(t, adler32.Checksum(buf[:end]), stream.digest().Sum32())
   159  }
   160  
   161  func TestDecoderStreamWithDigestSetEnabled(t *testing.T) {
   162  	stream := newTestDecoderStream()
   163  
   164  	// Disable digest calculation
   165  	stream.setDigestReaderEnabled(false)
   166  
   167  	buf := make([]byte, 5)
   168  	_, err := stream.Read(buf)
   169  	require.NoError(t, err)
   170  	require.Equal(t, stream.digest().Sum32(), uint32(1))
   171  
   172  	_, err = stream.ReadByte()
   173  	require.NoError(t, err)
   174  	require.Equal(t, stream.digest().Sum32(), uint32(1))
   175  
   176  	// Enable digest calculation
   177  	stream.setDigestReaderEnabled(true)
   178  
   179  	_, err = stream.Read(buf)
   180  	require.NoError(t, err)
   181  	require.Equal(t, stream.digest().Sum32(), adler32.Checksum([]byte(srcString[6:11])))
   182  
   183  	_, err = stream.ReadByte()
   184  	require.NoError(t, err)
   185  	require.Equal(t, stream.digest().Sum32(), adler32.Checksum([]byte(srcString[6:12])))
   186  }
   187  
   188  func newTestDecoderStream() *decoderStreamWithDigest {
   189  	d := newDecoderStreamWithDigest(bufio.NewReader(bytes.NewReader([]byte(srcString))))
   190  	d.setDigestReaderEnabled(true)
   191  	return d
   192  }