1
2
3
4
5 package binary
6
7 import (
8 "bytes"
9 "io"
10 "math"
11 "testing"
12 )
13
14 func testConstant(t *testing.T, w uint, max int) {
15 buf := make([]byte, MaxVarintLen64)
16 n := PutUvarint(buf, 1<<w-1)
17 if n != max {
18 t.Errorf("MaxVarintLen%d = %d; want %d", w, max, n)
19 }
20 }
21
22 func TestConstants(t *testing.T) {
23 testConstant(t, 16, MaxVarintLen16)
24 testConstant(t, 32, MaxVarintLen32)
25 testConstant(t, 64, MaxVarintLen64)
26 }
27
28 func testVarint(t *testing.T, x int64) {
29 buf := make([]byte, MaxVarintLen64)
30 n := PutVarint(buf, x)
31 y, m := Varint(buf[0:n])
32 if x != y {
33 t.Errorf("Varint(%d): got %d", x, y)
34 }
35 if n != m {
36 t.Errorf("Varint(%d): got n = %d; want %d", x, m, n)
37 }
38
39 buf2 := []byte("prefix")
40 buf2 = AppendVarint(buf2, x)
41 if string(buf2) != "prefix"+string(buf[:n]) {
42 t.Errorf("AppendVarint(%d): got %q, want %q", x, buf2, "prefix"+string(buf[:n]))
43 }
44
45 y, err := ReadVarint(bytes.NewReader(buf))
46 if err != nil {
47 t.Errorf("ReadVarint(%d): %s", x, err)
48 }
49 if x != y {
50 t.Errorf("ReadVarint(%d): got %d", x, y)
51 }
52 }
53
54 func testUvarint(t *testing.T, x uint64) {
55 buf := make([]byte, MaxVarintLen64)
56 n := PutUvarint(buf, x)
57 y, m := Uvarint(buf[0:n])
58 if x != y {
59 t.Errorf("Uvarint(%d): got %d", x, y)
60 }
61 if n != m {
62 t.Errorf("Uvarint(%d): got n = %d; want %d", x, m, n)
63 }
64
65 buf2 := []byte("prefix")
66 buf2 = AppendUvarint(buf2, x)
67 if string(buf2) != "prefix"+string(buf[:n]) {
68 t.Errorf("AppendUvarint(%d): got %q, want %q", x, buf2, "prefix"+string(buf[:n]))
69 }
70
71 y, err := ReadUvarint(bytes.NewReader(buf))
72 if err != nil {
73 t.Errorf("ReadUvarint(%d): %s", x, err)
74 }
75 if x != y {
76 t.Errorf("ReadUvarint(%d): got %d", x, y)
77 }
78 }
79
80 var tests = []int64{
81 -1 << 63,
82 -1<<63 + 1,
83 -1,
84 0,
85 1,
86 2,
87 10,
88 20,
89 63,
90 64,
91 65,
92 127,
93 128,
94 129,
95 255,
96 256,
97 257,
98 1<<63 - 1,
99 }
100
101 func TestVarint(t *testing.T) {
102 for _, x := range tests {
103 testVarint(t, x)
104 testVarint(t, -x)
105 }
106 for x := int64(0x7); x != 0; x <<= 1 {
107 testVarint(t, x)
108 testVarint(t, -x)
109 }
110 }
111
112 func TestUvarint(t *testing.T) {
113 for _, x := range tests {
114 testUvarint(t, uint64(x))
115 }
116 for x := uint64(0x7); x != 0; x <<= 1 {
117 testUvarint(t, x)
118 }
119 }
120
121 func TestBufferTooSmall(t *testing.T) {
122 buf := []byte{0x80, 0x80, 0x80, 0x80}
123 for i := 0; i <= len(buf); i++ {
124 buf := buf[0:i]
125 x, n := Uvarint(buf)
126 if x != 0 || n != 0 {
127 t.Errorf("Uvarint(%v): got x = %d, n = %d", buf, x, n)
128 }
129
130 x, err := ReadUvarint(bytes.NewReader(buf))
131 wantErr := io.EOF
132 if i > 0 {
133 wantErr = io.ErrUnexpectedEOF
134 }
135 if x != 0 || err != wantErr {
136 t.Errorf("ReadUvarint(%v): got x = %d, err = %s", buf, x, err)
137 }
138 }
139 }
140
141
142
143 func TestBufferTooBigWithOverflow(t *testing.T) {
144 tests := []struct {
145 in []byte
146 name string
147 wantN int
148 wantValue uint64
149 }{
150 {
151 name: "invalid: 1000 bytes",
152 in: func() []byte {
153 b := make([]byte, 1000)
154 for i := range b {
155 b[i] = 0xff
156 }
157 b[999] = 0
158 return b
159 }(),
160 wantN: -11,
161 wantValue: 0,
162 },
163 {
164 name: "valid: math.MaxUint64-40",
165 in: []byte{0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
166 wantValue: math.MaxUint64 - 40,
167 wantN: 10,
168 },
169 {
170 name: "invalid: with more than MaxVarintLen64 bytes",
171 in: []byte{0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
172 wantN: -11,
173 wantValue: 0,
174 },
175 {
176 name: "invalid: 10th byte",
177 in: []byte{0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f},
178 wantN: -10,
179 wantValue: 0,
180 },
181 }
182
183 for _, tt := range tests {
184 tt := tt
185 t.Run(tt.name, func(t *testing.T) {
186 value, n := Uvarint(tt.in)
187 if g, w := n, tt.wantN; g != w {
188 t.Errorf("bytes returned=%d, want=%d", g, w)
189 }
190 if g, w := value, tt.wantValue; g != w {
191 t.Errorf("value=%d, want=%d", g, w)
192 }
193 })
194 }
195 }
196
197 func testOverflow(t *testing.T, buf []byte, x0 uint64, n0 int, err0 error) {
198 x, n := Uvarint(buf)
199 if x != 0 || n != n0 {
200 t.Errorf("Uvarint(% X): got x = %d, n = %d; want 0, %d", buf, x, n, n0)
201 }
202
203 r := bytes.NewReader(buf)
204 len := r.Len()
205 x, err := ReadUvarint(r)
206 if x != x0 || err != err0 {
207 t.Errorf("ReadUvarint(%v): got x = %d, err = %s; want %d, %s", buf, x, err, x0, err0)
208 }
209 if read := len - r.Len(); read > MaxVarintLen64 {
210 t.Errorf("ReadUvarint(%v): read more than MaxVarintLen64 bytes, got %d", buf, read)
211 }
212 }
213
214 func TestOverflow(t *testing.T) {
215 testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x2}, 0, -10, errOverflow)
216 testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1, 0, 0}, 0, -11, errOverflow)
217 testOverflow(t, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 1<<64-1, -11, errOverflow)
218 }
219
220 func TestNonCanonicalZero(t *testing.T) {
221 buf := []byte{0x80, 0x80, 0x80, 0}
222 x, n := Uvarint(buf)
223 if x != 0 || n != 4 {
224 t.Errorf("Uvarint(%v): got x = %d, n = %d; want 0, 4", buf, x, n)
225
226 }
227 }
228
229 func BenchmarkPutUvarint32(b *testing.B) {
230 buf := make([]byte, MaxVarintLen32)
231 b.SetBytes(4)
232 for i := 0; i < b.N; i++ {
233 for j := uint(0); j < MaxVarintLen32; j++ {
234 PutUvarint(buf, 1<<(j*7))
235 }
236 }
237 }
238
239 func BenchmarkPutUvarint64(b *testing.B) {
240 buf := make([]byte, MaxVarintLen64)
241 b.SetBytes(8)
242 for i := 0; i < b.N; i++ {
243 for j := uint(0); j < MaxVarintLen64; j++ {
244 PutUvarint(buf, 1<<(j*7))
245 }
246 }
247 }
248
View as plain text