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

Side by Side Diff: common/recordio/reader_test.go

Issue 1253353008: logdog: Add frame read/write library. (Closed) Base URL: https://github.com/luci/luci-go@logdog-review-output
Patch Set: Refresh? Created 5 years, 1 month 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/recordio/reader.go ('k') | common/recordio/writer.go » ('j') | 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 recordio
6
7 import (
8 "bytes"
9 "encoding/binary"
10 "errors"
11 "io"
12 "io/ioutil"
13 "testing"
14
15 . "github.com/smartystreets/goconvey/convey"
16 )
17
18 // plainReader implements the io.Reader interface on top of a bytes.Buffer;
19 // however, it does not also implement io.ByteReader.
20 type plainReader struct {
21 buf bytes.Buffer
22 err error
23 }
24
25 func (r *plainReader) loadFrames(chunks ...[]byte) {
26 for _, chunk := range chunks {
27 _, err := WriteFrame(&r.buf, chunk)
28 if err != nil {
29 panic(err)
30 }
31 }
32 }
33
34 func (r *plainReader) Read(data []byte) (int, error) {
35 if r.err != nil {
36 return 0, r.err
37 }
38 return r.buf.Read(data)
39 }
40
41 type testByteReader struct {
42 plainReader
43
44 readByteErr error
45 readBytes int
46 byteBuf [1]byte
47 }
48
49 func (r *testByteReader) ReadByte() (b byte, err error) {
50 if r.readByteErr != nil {
51 return 0, r.readByteErr
52 }
53
54 b, err = r.buf.ReadByte()
55 if err == nil {
56 r.readBytes++
57 }
58 return
59 }
60
61 // TestReader tests the default Reader implementation, "reader".
62 func TestReader(t *testing.T) {
63 t.Parallel()
64
65 Convey(`A frame reader with max size 1MB using a plain io.Reader`, t, fu nc() {
66 maxSize := int64(1024 * 1024)
67 tr := plainReader{}
68 r := NewReader(&tr, maxSize)
69
70 Convey(`Will return io.EOF with an empty reader.`, func() {
71 _, err := r.ReadFrameAll()
72 So(err, ShouldEqual, io.EOF)
73 })
74
75 Convey(`Can successfully read a frame.`, func() {
76 data := []byte{0x13, 0x37, 0xd0, 0x65}
77 tr.loadFrames(data)
78
79 f, err := r.ReadFrameAll()
80 So(err, ShouldBeNil)
81 So(f, ShouldResemble, data)
82 })
83
84 Convey(`Can successfully read two frames.`, func() {
85 data := [][]byte{
86 {0x13, 0x37, 0xd0, 0x65},
87 {0xd0, 0x06, 0xea, 0x15, 0xf0, 0x0d},
88 }
89 tr.loadFrames(data...)
90
91 c, fr, err := r.ReadFrame()
92 So(err, ShouldBeNil)
93 So(c, ShouldEqual, 4)
94
95 d, err := ioutil.ReadAll(fr)
96 So(err, ShouldBeNil)
97 So(d, ShouldResemble, data[0])
98
99 c, fr, err = r.ReadFrame()
100 So(err, ShouldBeNil)
101 So(c, ShouldEqual, 6)
102
103 d, err = ioutil.ReadAll(fr)
104 So(err, ShouldBeNil)
105 So(d, ShouldResemble, data[1])
106 })
107
108 Convey(`When reading a frame, will return EOF if the frame is ex ceeded.`, func() {
109 data := []byte{0x13, 0x37, 0xd0, 0x65}
110 tr.loadFrames(data)
111
112 count, fr, err := r.ReadFrame()
113 So(err, ShouldBeNil)
114 So(count, ShouldEqual, 4)
115
116 buf := make([]byte, 5)
117 c, err := fr.Read(make([]byte, 5))
118 So(c, ShouldEqual, 4)
119 So(err, ShouldBeNil)
120
121 buf = buf[count:]
122 _, err = fr.Read(buf)
123 So(err, ShouldEqual, io.EOF)
124 })
125
126 Convey(`Will fail if the underlying frame exceeds the maximum si ze.`, func() {
127 var sizeBuf [binary.MaxVarintLen64]byte
128 tr.buf.Write(sizeBuf[:binary.PutUvarint(sizeBuf[:], uint 64(maxSize+1))])
129
130 _, err := r.ReadFrameAll()
131 So(err, ShouldEqual, ErrFrameTooLarge)
132 })
133
134 Convey(`Will fail if the frame contains an invalid size header.` , func() {
135 tr.buf.Write([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
136 _, err := r.ReadFrameAll()
137 So(err, ShouldNotBeNil)
138 })
139
140 Convey(`Can read conscutive frames, then io.EOF.`, func() {
141 data := [][]byte{}
142 for _, size := range []int{
143 0,
144 14,
145 1024 * 1024,
146 0,
147 511,
148 } {
149 data = append(data, bytes.Repeat([]byte{0x5A}, s ize))
150 tr.loadFrames(data[len(data)-1])
151 }
152
153 for _, expected := range data {
154 f, err := r.ReadFrameAll()
155 So(err, ShouldBeNil)
156
157 if len(expected) == 0 {
158 expected = nil
159 }
160 So(f, ShouldResemble, expected)
161 }
162
163 _, err := r.ReadFrameAll()
164 So(err, ShouldEqual, io.EOF)
165 })
166 })
167
168 Convey(`A frame reader with max size 1MB using an io.Reader+io.ByteReade r`, t, func() {
169 tr := testByteReader{}
170 r := NewReader(&tr, 1024*1024)
171
172 Convey(`Will return io.EOF with an empty reader.`, func() {
173 _, err := r.ReadFrameAll()
174 So(err, ShouldEqual, io.EOF)
175 })
176
177 Convey(`Will use io.ByteReader to read the frame header.`, func( ) {
178 data := []byte{0x13, 0x37, 0xd0, 0x65}
179 tr.loadFrames(data)
180
181 f, err := r.ReadFrameAll()
182 So(err, ShouldBeNil)
183 So(f, ShouldResemble, data)
184 So(tr.readBytes, ShouldEqual, 1)
185 })
186
187 Convey(`Will fail if the underlying io.Reader returns an error.` , func() {
188 tr.loadFrames([]byte{})
189 tr.err = errors.New("test: test-induced error")
190 tr.readByteErr = tr.err
191 _, err := r.ReadFrameAll()
192 So(err, ShouldEqual, tr.err)
193 })
194
195 Convey(`Will fail if an error is returned while reading frame's data.`, func() {
196 data := []byte{0x13, 0x37, 0xd0, 0x65}
197 tr.loadFrames(data)
198
199 // Have "ReadByte()" calls ignore the configured error. This will cause
200 // the frame size to be read without incident, but the f rame data to still
201 // return an error.
202 tr.err = errors.New("test: test-induced error")
203 data, err := r.ReadFrameAll()
204 So(err, ShouldEqual, tr.err)
205 })
206 })
207 }
OLDNEW
« no previous file with comments | « common/recordio/reader.go ('k') | common/recordio/writer.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698