github.com/vipernet-xyz/tm@v0.34.24/libs/protoio/io_test.go (about)

     1  // Protocol Buffers for Go with Gadgets
     2  //
     3  // Copyright (c) 2013, The GoGo Authors. All rights reserved.
     4  // http://github.com/gogo/protobuf
     5  //
     6  // Redistribution and use in source and binary forms, with or without
     7  // modification, are permitted provided that the following conditions are
     8  // met:
     9  //
    10  //     * Redistributions of source code must retain the above copyright
    11  // notice, this list of conditions and the following disclaimer.
    12  //     * Redistributions in binary form must reproduce the above
    13  // copyright notice, this list of conditions and the following disclaimer
    14  // in the documentation and/or other materials provided with the
    15  // distribution.
    16  //
    17  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    18  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    19  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    20  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    21  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    22  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    23  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    24  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    25  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    26  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    27  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    28  
    29  package protoio_test
    30  
    31  import (
    32  	"bytes"
    33  	"encoding/binary"
    34  	"fmt"
    35  	"io"
    36  	"math/rand"
    37  	"testing"
    38  	"time"
    39  
    40  	"github.com/gogo/protobuf/proto"
    41  	"github.com/gogo/protobuf/test"
    42  	"github.com/stretchr/testify/require"
    43  
    44  	"github.com/vipernet-xyz/tm/libs/protoio"
    45  )
    46  
    47  func iotest(writer protoio.WriteCloser, reader protoio.ReadCloser) error {
    48  	varint := make([]byte, binary.MaxVarintLen64)
    49  	size := 1000
    50  	msgs := make([]*test.NinOptNative, size)
    51  	lens := make([]int, size)
    52  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
    53  	for i := range msgs {
    54  		msgs[i] = test.NewPopulatedNinOptNative(r, true)
    55  		// issue 31
    56  		if i == 5 {
    57  			msgs[i] = &test.NinOptNative{}
    58  		}
    59  		// issue 31
    60  		if i == 999 {
    61  			msgs[i] = &test.NinOptNative{}
    62  		}
    63  		// FIXME Check size
    64  		bz, err := proto.Marshal(msgs[i])
    65  		if err != nil {
    66  			return err
    67  		}
    68  		visize := binary.PutUvarint(varint, uint64(len(bz)))
    69  		n, err := writer.WriteMsg(msgs[i])
    70  		if err != nil {
    71  			return err
    72  		}
    73  		if n != len(bz)+visize {
    74  			return fmt.Errorf("WriteMsg() wrote %v bytes, expected %v", n, len(bz)+visize)
    75  		}
    76  		lens[i] = n
    77  	}
    78  	if err := writer.Close(); err != nil {
    79  		return err
    80  	}
    81  	i := 0
    82  	for {
    83  		msg := &test.NinOptNative{}
    84  		if n, err := reader.ReadMsg(msg); err != nil {
    85  			if err == io.EOF {
    86  				break
    87  			}
    88  			return err
    89  		} else if n != lens[i] {
    90  			return fmt.Errorf("read %v bytes, expected %v", n, lens[i])
    91  		}
    92  		if err := msg.VerboseEqual(msgs[i]); err != nil {
    93  			return err
    94  		}
    95  		i++
    96  	}
    97  	if i != size {
    98  		panic("not enough messages read")
    99  	}
   100  	if err := reader.Close(); err != nil {
   101  		return err
   102  	}
   103  	return nil
   104  }
   105  
   106  type buffer struct {
   107  	*bytes.Buffer
   108  	closed bool
   109  }
   110  
   111  func (b *buffer) Close() error {
   112  	b.closed = true
   113  	return nil
   114  }
   115  
   116  func newBuffer() *buffer {
   117  	return &buffer{bytes.NewBuffer(nil), false}
   118  }
   119  
   120  func TestVarintNormal(t *testing.T) {
   121  	buf := newBuffer()
   122  	writer := protoio.NewDelimitedWriter(buf)
   123  	reader := protoio.NewDelimitedReader(buf, 1024*1024)
   124  	err := iotest(writer, reader)
   125  	require.NoError(t, err)
   126  	require.True(t, buf.closed, "did not close buffer")
   127  }
   128  
   129  func TestVarintNoClose(t *testing.T) {
   130  	buf := bytes.NewBuffer(nil)
   131  	writer := protoio.NewDelimitedWriter(buf)
   132  	reader := protoio.NewDelimitedReader(buf, 1024*1024)
   133  	err := iotest(writer, reader)
   134  	require.NoError(t, err)
   135  }
   136  
   137  // issue 32
   138  func TestVarintMaxSize(t *testing.T) {
   139  	buf := newBuffer()
   140  	writer := protoio.NewDelimitedWriter(buf)
   141  	reader := protoio.NewDelimitedReader(buf, 20)
   142  	err := iotest(writer, reader)
   143  	require.Error(t, err)
   144  }
   145  
   146  func TestVarintError(t *testing.T) {
   147  	buf := newBuffer()
   148  	buf.Write([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f})
   149  	reader := protoio.NewDelimitedReader(buf, 1024*1024)
   150  	msg := &test.NinOptNative{}
   151  	n, err := reader.ReadMsg(msg)
   152  	require.Error(t, err)
   153  	require.Equal(t, 10, n)
   154  }
   155  
   156  func TestVarintTruncated(t *testing.T) {
   157  	buf := newBuffer()
   158  	buf.Write([]byte{0xff, 0xff})
   159  	reader := protoio.NewDelimitedReader(buf, 1024*1024)
   160  	msg := &test.NinOptNative{}
   161  	n, err := reader.ReadMsg(msg)
   162  	require.Error(t, err)
   163  	require.Equal(t, 2, n)
   164  }
   165  
   166  func TestShort(t *testing.T) {
   167  	buf := newBuffer()
   168  
   169  	varintBuf := make([]byte, binary.MaxVarintLen64)
   170  	varintLen := binary.PutUvarint(varintBuf, 100)
   171  	_, err := buf.Write(varintBuf[:varintLen])
   172  	require.NoError(t, err)
   173  
   174  	bz, err := proto.Marshal(&test.NinOptNative{Field15: []byte{0x01, 0x02, 0x03}})
   175  	require.NoError(t, err)
   176  	buf.Write(bz)
   177  
   178  	reader := protoio.NewDelimitedReader(buf, 1024*1024)
   179  	require.NoError(t, err)
   180  	msg := &test.NinOptNative{}
   181  	n, err := reader.ReadMsg(msg)
   182  	require.Error(t, err)
   183  	require.Equal(t, varintLen+len(bz), n)
   184  }