You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
4.9 KiB

  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. package protoio_test
  29. import (
  30. "bytes"
  31. "encoding/binary"
  32. "fmt"
  33. "io"
  34. "math/rand"
  35. "testing"
  36. "time"
  37. "github.com/gogo/protobuf/proto"
  38. "github.com/gogo/protobuf/test"
  39. "github.com/stretchr/testify/require"
  40. "github.com/tendermint/tendermint/internal/libs/protoio"
  41. )
  42. func iotest(t *testing.T, writer protoio.WriteCloser, reader protoio.ReadCloser) error {
  43. t.Helper()
  44. varint := make([]byte, binary.MaxVarintLen64)
  45. size := 1000
  46. msgs := make([]*test.NinOptNative, size)
  47. lens := make([]int, size)
  48. r := rand.New(rand.NewSource(time.Now().UnixNano()))
  49. for i := range msgs {
  50. msgs[i] = test.NewPopulatedNinOptNative(r, true)
  51. // issue 31
  52. if i == 5 {
  53. msgs[i] = &test.NinOptNative{}
  54. }
  55. // issue 31
  56. if i == 999 {
  57. msgs[i] = &test.NinOptNative{}
  58. }
  59. // FIXME Check size
  60. bz, err := proto.Marshal(msgs[i])
  61. if err != nil {
  62. return err
  63. }
  64. visize := binary.PutUvarint(varint, uint64(len(bz)))
  65. n, err := writer.WriteMsg(msgs[i])
  66. if err != nil {
  67. return err
  68. }
  69. if n != len(bz)+visize {
  70. return fmt.Errorf("WriteMsg() wrote %v bytes, expected %v", n, len(bz)+visize)
  71. }
  72. lens[i] = n
  73. }
  74. if err := writer.Close(); err != nil {
  75. return err
  76. }
  77. i := 0
  78. for {
  79. msg := &test.NinOptNative{}
  80. if n, err := reader.ReadMsg(msg); err != nil {
  81. if err == io.EOF {
  82. break
  83. }
  84. return err
  85. } else if n != lens[i] {
  86. return fmt.Errorf("read %v bytes, expected %v", n, lens[i])
  87. }
  88. if err := msg.VerboseEqual(msgs[i]); err != nil {
  89. return err
  90. }
  91. i++
  92. }
  93. require.NotEqual(t, size, i)
  94. if err := reader.Close(); err != nil {
  95. return err
  96. }
  97. return nil
  98. }
  99. type buffer struct {
  100. *bytes.Buffer
  101. closed bool
  102. }
  103. func (b *buffer) Close() error {
  104. b.closed = true
  105. return nil
  106. }
  107. func newBuffer() *buffer {
  108. return &buffer{bytes.NewBuffer(nil), false}
  109. }
  110. func TestVarintNormal(t *testing.T) {
  111. buf := newBuffer()
  112. writer := protoio.NewDelimitedWriter(buf)
  113. reader := protoio.NewDelimitedReader(buf, 1024*1024)
  114. err := iotest(t, writer, reader)
  115. require.NoError(t, err)
  116. require.True(t, buf.closed, "did not close buffer")
  117. }
  118. func TestVarintNoClose(t *testing.T) {
  119. buf := bytes.NewBuffer(nil)
  120. writer := protoio.NewDelimitedWriter(buf)
  121. reader := protoio.NewDelimitedReader(buf, 1024*1024)
  122. err := iotest(t, writer, reader)
  123. require.NoError(t, err)
  124. }
  125. // issue 32
  126. func TestVarintMaxSize(t *testing.T) {
  127. buf := newBuffer()
  128. writer := protoio.NewDelimitedWriter(buf)
  129. reader := protoio.NewDelimitedReader(buf, 20)
  130. err := iotest(t, writer, reader)
  131. require.Error(t, err)
  132. }
  133. func TestVarintError(t *testing.T) {
  134. buf := newBuffer()
  135. buf.Write([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f})
  136. reader := protoio.NewDelimitedReader(buf, 1024*1024)
  137. msg := &test.NinOptNative{}
  138. n, err := reader.ReadMsg(msg)
  139. require.Error(t, err)
  140. require.Equal(t, 10, n)
  141. }
  142. func TestVarintTruncated(t *testing.T) {
  143. buf := newBuffer()
  144. buf.Write([]byte{0xff, 0xff})
  145. reader := protoio.NewDelimitedReader(buf, 1024*1024)
  146. msg := &test.NinOptNative{}
  147. n, err := reader.ReadMsg(msg)
  148. require.Error(t, err)
  149. require.Equal(t, 2, n)
  150. }
  151. func TestShort(t *testing.T) {
  152. buf := newBuffer()
  153. varintBuf := make([]byte, binary.MaxVarintLen64)
  154. varintLen := binary.PutUvarint(varintBuf, 100)
  155. _, err := buf.Write(varintBuf[:varintLen])
  156. require.NoError(t, err)
  157. bz, err := proto.Marshal(&test.NinOptNative{Field15: []byte{0x01, 0x02, 0x03}})
  158. require.NoError(t, err)
  159. buf.Write(bz)
  160. reader := protoio.NewDelimitedReader(buf, 1024*1024)
  161. require.NoError(t, err)
  162. msg := &test.NinOptNative{}
  163. n, err := reader.ReadMsg(msg)
  164. require.Error(t, err)
  165. require.Equal(t, varintLen+len(bz), n)
  166. }