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