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.

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