Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Side by Side Diff: common/funnybase/funnybase_test.go

Issue 1219323002: Rename funnybase and add more serializations. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@master
Patch Set: fixes Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « common/funnybase/funnybase.goconvey ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package funnybase
6
7 import (
8 "bytes"
9 "flag"
10 "fmt"
11 "io"
12 "math"
13 "math/rand"
14 "sort"
15 "testing"
16 "time"
17
18 . "github.com/smartystreets/goconvey/convey"
19 )
20
21 type testCase struct {
22 expect []byte
23 val int64
24 }
25
26 type testCaseSlice []testCase
27
28 func (t testCaseSlice) Len() int { return len(t) }
29 func (t testCaseSlice) Less(i, j int) bool { return t[i].val < t[j].val }
30 func (t testCaseSlice) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
31
32 var cases = testCaseSlice{
33 {[]byte{b01000000, b01111111, b11111111, b11111111, b11111111, 0xff, 0xf f, 0xff, b11111111}, -math.MaxInt64 - 1},
34 {[]byte{b01000001, b00000000, b00000000, b00000000, b00000000, 0, 0, 0, b00000001}, -math.MaxInt64},
35 {[]byte{b01000001, b00000000, b00000000, b00000000, b00000000, 0, 0, 0, b00000011}, -math.MaxInt64 + 1},
36 {[]byte{b01100000, b01111111, b11111111, b11111111, b11111111}, -math.Ma xInt32 - 1},
37 {[]byte{b01100001, b00000000, b00000000, b00000000, b00000001}, -math.Ma xInt32},
38 {[]byte{b01100001, b00000000, b00000000, b00000000, b00000011}, -math.Ma xInt32 + 1},
39 {[]byte{b01110000, b01111111, b11111111}, -math.MaxInt16 - 1},
40 {[]byte{b01111000, b01111110}, -129},
41 {[]byte{b01111000, b01111111}, -128},
42 {[]byte{b01111001, b00000001}, -127},
43 {[]byte{b01111001, b01111101}, -65},
44 {[]byte{b01111001, b01111111}, -64},
45 {[]byte{b01111010, b00000011}, -63},
46 {[]byte{b01111101, b01011111}, -5},
47 {[]byte{b01111110, b00111111}, -3},
48 {[]byte{b01111111, b01111111}, -1},
49 {[]byte{b10000000, b00000000}, 0},
50 {[]byte{b10000010, b10100000}, 5},
51 {[]byte{b10000100, b10001000}, 17},
52 {[]byte{b10000101, b11111100}, 63},
53 {[]byte{b10000110, b10000000}, 64},
54 {[]byte{b10000110, b10000010}, 65},
55 {[]byte{b10000111, b10000000}, 128},
56 {[]byte{b10011110, b11111111, 0xff, 0xff, b11111110}, math.MaxInt32},
57 {[]byte{b10011111, b10000000, 0, 0, 0}, math.MaxInt32 + 1},
58 {[]byte{b10111110, b11111111, 0xff, 0xff, b11111111, 0xff, 0xff, 0xff, b 11111110}, math.MaxInt64},
59 }
60
61 var seed = flag.Int64("funnybase.seed", 0, "Random seed to use for randomized fu nnybase tests")
62
63 func init() {
64 flag.Parse()
65 if *seed == 0 {
66 *seed = time.Now().UnixNano()
67 }
68 fmt.Println("funnybase.seed =", *seed)
69 }
70
71 func TestPut(t *testing.T) {
72 Convey("Put", t, func() {
73 for _, c := range cases {
74 c := c
75 Convey(fmt.Sprintf("%d -> % x", c.val, c.expect), func() {
76 Convey("Put", func() {
77 buf := make([]byte, MaxFunnyBaseLen64)
78 n := Put(buf, c.val)
79 So(n, ShouldEqual, len(c.expect))
80 So(buf[:n], ShouldResemble, c.expect)
81 })
82 Convey("Write", func() {
83 buf := &bytes.Buffer{}
84 err := Write(buf, c.val)
85 So(err, ShouldBeNil)
86 So(buf.Bytes(), ShouldResemble, c.expect )
87 })
88
89 if c.val >= 0 {
90 Convey("PutUint", func() {
91 buf := make([]byte, MaxFunnyBase Len64)
92 n := PutUint(buf, uint64(c.val))
93 So(n, ShouldEqual, len(c.expect) )
94 So(buf[:n], ShouldResemble, c.ex pect)
95 })
96 Convey("WriteUint", func() {
97 buf := &bytes.Buffer{}
98 err := WriteUint(buf, uint64(c.v al))
99 So(err, ShouldBeNil)
100 So(buf.Bytes(), ShouldResemble, c.expect)
101 })
102 }
103 })
104 }
105 })
106 }
107
108 func TestGet(t *testing.T) {
109 Convey("Get", t, func() {
110 for _, c := range cases {
111 c := c
112 Convey(fmt.Sprintf("% x -> %d", c.expect, c.val), func() {
113 v, n := Get(c.expect)
114 So(n, ShouldEqual, len(c.expect))
115 So(v, ShouldEqual, c.val)
116
117 if c.val >= 0 {
118 v, n := GetUint(c.expect)
119 So(n, ShouldEqual, len(c.expect))
120 So(v, ShouldEqual, c.val)
121 }
122 })
123 }
124 })
125 }
126
127 func TestRead(t *testing.T) {
128 Convey("Read", t, func() {
129 for _, c := range cases {
130 c := c
131 Convey(fmt.Sprintf("% x -> %d", c.expect, c.val), func() {
132 buf := bytes.NewBuffer(c.expect)
133 v, err := Read(buf)
134 So(err, ShouldBeNil)
135 So(v, ShouldEqual, c.val)
136
137 if c.val >= 0 {
138 buf := bytes.NewBuffer(c.expect)
139 v, err := ReadUint(buf)
140 So(err, ShouldBeNil)
141 So(v, ShouldEqual, c.val)
142 }
143 })
144 }
145 })
146 }
147
148 func TestSort(t *testing.T) {
149 // TODO(iannucci): Enable full test with num = 20000000.
150 num := 100000
151 num += len(cases)
152 randomCases := make(testCaseSlice, num)
153
154 rcSub := randomCases[copy(randomCases, cases):]
155 r := rand.New(rand.NewSource(*seed))
156 for i := range rcSub {
157 v := int64(uint64(r.Uint32())<<32 | uint64(r.Uint32()))
158 rcSub[i].val = v
159 buf := make([]byte, MaxFunnyBaseLen64)
160 rcSub[i].expect = buf[:Put(buf, v)]
161 }
162
163 sort.Sort(randomCases)
164
165 shouldBeLessThanOrEqual := func(actual interface{}, expected ...interfac e{}) string {
166 a, b := actual.([]byte), expected[0].([]byte)
167 if bytes.Compare(a, b) <= 0 {
168 return fmt.Sprintf("Expected A <= B (but it wasn't)!\nA: [% x]\nB: [% x]", a, b)
169 }
170 return ""
171 }
172
173 Convey("TestSort", t, func() {
174 prev := randomCases[0]
175 for _, c := range randomCases[1:] {
176 // Actually asserting with the So for every entry in the sorted array will
177 // produce 100000 green checkmarks on a sucessful test, which is a bit
178 // much :).
179 if bytes.Compare(c.expect, prev.expect) < 0 {
180 So(c.expect, shouldBeLessThanOrEqual, prev.expec t)
181 break
182 }
183 prev = c
184 }
185
186 // This silly assertion is done so that this test has a green ch eck next to
187 // it in the event that it passes. Otherwise convey thinks we sk ipped the
188 // test, which isn't correct.
189 So(true, ShouldBeTrue)
190 })
191 }
192
193 type fakeWriter struct{ count int }
194
195 func (f *fakeWriter) WriteByte(byte) error {
196 if f.count == 0 {
197 return fmt.Errorf("nope")
198 }
199 f.count--
200 return nil
201 }
202
203 func TestErrors(t *testing.T) {
204 smallerInt64 := []byte{b01000000, b01111111, b11111111, b11111111, b1111 1111, 0xff, 0xff, 0xff, b11111110}
205
206 prettyBigUint64 := []byte{b10111111, b10000000, 0, 0, 0, 0, 0, 0, 0}
207 prettyBigUint64Val := uint64(math.MaxInt64 + 1)
208
209 reallyBigUint64 := []byte{b10111111, b11111111, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
210 reallyBigUint64Val := uint64(math.MaxUint64)
211 tests := []struct {
212 name string
213 buf []byte
214
215 v int64
216 n int
217 err error
218
219 uv uint64
220 un int
221 uerr error
222 }{
223 {
224 name: "Too big!!",
225 buf: []byte{b11000000}, // 65 bits!?
226 n: -1,
227 un: -1,
228 err: ErrOverflow,
229 uerr: ErrOverflow,
230 }, {
231 name: "Nil buffer",
232 err: io.EOF,
233 uerr: io.EOF,
234 }, {
235 name: "Empty buffer",
236 buf: []byte{},
237 err: io.EOF,
238 uerr: io.EOF,
239 }, {
240 name: "Small buffer",
241 buf: cases[len(cases)-1].expect[:4],
242 err: io.EOF,
243 uerr: io.EOF,
244 }, {
245 name: "Reading a negative number with *Uint",
246 buf: cases[0].expect,
247 v: cases[0].val,
248 n: len(cases[0].expect),
249
250 un: -2,
251 uerr: ErrUnderflow,
252 }, {
253 name: "Reading a number smaller than min int64",
254 buf: smallerInt64,
255 n: -2,
256 err: ErrUnderflow,
257
258 un: -2,
259 uerr: ErrUnderflow,
260 }, {
261 name: "Reading a number bigger than int64",
262 buf: prettyBigUint64,
263 n: -1,
264 err: ErrOverflow,
265
266 uv: prettyBigUint64Val,
267 un: len(prettyBigUint64),
268 }, {
269 name: "Reading MaxUint64",
270 buf: reallyBigUint64,
271 n: -1,
272 err: ErrOverflow,
273
274 uv: reallyBigUint64Val,
275 un: len(reallyBigUint64),
276 },
277 }
278
279 Convey("Error conditions", t, func() {
280 for _, t := range tests {
281 Convey(t.name, func() {
282 Convey("Get", func() {
283 v, n := Get(t.buf)
284 So(v, ShouldEqual, t.v)
285 So(n, ShouldEqual, t.n)
286 })
287 Convey("GetUint", func() {
288 uv, un := GetUint(t.buf)
289 So(uv, ShouldEqual, t.uv)
290 So(un, ShouldEqual, t.un)
291 })
292 Convey("Read", func() {
293 v, err := Read(bytes.NewBuffer(t.buf))
294 So(err, ShouldEqual, t.err)
295 So(v, ShouldEqual, t.v)
296 })
297 Convey("ReadUint", func() {
298 uv, err := ReadUint(bytes.NewBuffer(t.bu f))
299 So(err, ShouldEqual, t.uerr)
300 So(uv, ShouldEqual, t.uv)
301 })
302 })
303 }
304 Convey("Panics", func() {
305 Convey("Put", func() {
306 buf := make([]byte, MaxFunnyBaseLen64)
307 buf = buf[:4] // enough capacity, but not enough length!
308 So(func() { Put(buf, cases[0].val) }, ShouldPani c)
309 })
310 Convey("PutUint", func() {
311 buf := make([]byte, MaxFunnyBaseLen64)
312 buf = buf[:4] // enough capacity, but not enough length!
313 So(func() { PutUint(buf, reallyBigUint64Val) }, ShouldPanic)
314 })
315 })
316 Convey("Write Errors", func() {
317 // Test each error return location in writeSignMag
318 for count := 0; count < 3; count++ {
319 fw := &fakeWriter{count}
320 err := Write(fw, -10000)
321 So(err.Error(), ShouldContainSubstring, "nope")
322 So(fw.count, ShouldEqual, 0)
323 }
324 })
325 })
326 }
OLDNEW
« no previous file with comments | « common/funnybase/funnybase.goconvey ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698