1
2
3
4
5 package gensupport
6
7 import (
8 "bytes"
9 "io"
10 "reflect"
11 "testing"
12 "testing/iotest"
13
14 "google.golang.org/api/googleapi"
15 )
16
17
18 func getChunkAsString(t *testing.T, mb *MediaBuffer) (string, error) {
19 chunk, _, size, err := mb.Chunk()
20
21 buf, e := io.ReadAll(chunk)
22 if e != nil {
23 t.Fatalf("Failed reading chunk: %v", e)
24 }
25 if size != len(buf) {
26 t.Fatalf("reported chunk size doesn't match actual chunk size: got: %v; want: %v", size, len(buf))
27 }
28 return string(buf), err
29 }
30
31 func TestChunking(t *testing.T) {
32 type testCase struct {
33 data string
34 finalErr error
35 chunkSize int
36 wantChunks []string
37 }
38
39 for _, singleByteReads := range []bool{true, false} {
40 for _, tc := range []testCase{
41 {
42 data: "abcdefg",
43 finalErr: nil,
44 chunkSize: 3,
45 wantChunks: []string{"abc", "def", "g"},
46 },
47 {
48 data: "abcdefg",
49 finalErr: nil,
50 chunkSize: 1,
51 wantChunks: []string{"a", "b", "c", "d", "e", "f", "g"},
52 },
53 {
54 data: "abcdefg",
55 finalErr: nil,
56 chunkSize: 7,
57 wantChunks: []string{"abcdefg"},
58 },
59 {
60 data: "abcdefg",
61 finalErr: nil,
62 chunkSize: 8,
63 wantChunks: []string{"abcdefg"},
64 },
65 {
66 data: "abcdefg",
67 finalErr: io.ErrUnexpectedEOF,
68 chunkSize: 3,
69 wantChunks: []string{"abc", "def", "g"},
70 },
71 {
72 data: "abcdefg",
73 finalErr: io.ErrUnexpectedEOF,
74 chunkSize: 8,
75 wantChunks: []string{"abcdefg"},
76 },
77 } {
78 var r io.Reader = &errReader{buf: []byte(tc.data), err: tc.finalErr}
79
80 if singleByteReads {
81 r = iotest.OneByteReader(r)
82 }
83
84 mb := NewMediaBuffer(r, tc.chunkSize)
85 var gotErr error
86 got := []string{}
87 for {
88 chunk, err := getChunkAsString(t, mb)
89 if len(chunk) != 0 {
90 got = append(got, string(chunk))
91 }
92 if err != nil {
93 gotErr = err
94 break
95 }
96 mb.Next()
97 }
98
99 if !reflect.DeepEqual(got, tc.wantChunks) {
100 t.Errorf("Failed reading buffer: got: %v; want:%v", got, tc.wantChunks)
101 }
102
103 expectedErr := tc.finalErr
104 if expectedErr == nil {
105 expectedErr = io.EOF
106 }
107 if gotErr != expectedErr {
108 t.Errorf("Reading buffer error: got: %v; want: %v", gotErr, expectedErr)
109 }
110 }
111 }
112 }
113
114 func TestChunkCanBeReused(t *testing.T) {
115 er := &errReader{buf: []byte("abcdefg")}
116 mb := NewMediaBuffer(er, 3)
117
118
119 expectChunk := func(want string, wantErr error) {
120 got, err := getChunkAsString(t, mb)
121 if err != wantErr {
122 t.Errorf("error reading buffer: got: %v; want: %v", err, wantErr)
123 }
124 if !reflect.DeepEqual(got, want) {
125 t.Errorf("Failed reading buffer: got: %q; want:%q", got, want)
126 }
127 }
128 expectChunk("abc", nil)
129
130 expectChunk("abc", nil)
131 mb.Next()
132 expectChunk("def", nil)
133 expectChunk("def", nil)
134 mb.Next()
135 expectChunk("g", io.EOF)
136 expectChunk("g", io.EOF)
137 mb.Next()
138 expectChunk("", io.EOF)
139 }
140
141 func TestPos(t *testing.T) {
142 er := &errReader{buf: []byte("abcdefg")}
143 mb := NewMediaBuffer(er, 3)
144
145 expectChunkAtOffset := func(want int64, wantErr error) {
146 _, off, _, err := mb.Chunk()
147 if err != wantErr {
148 t.Errorf("error reading buffer: got: %v; want: %v", err, wantErr)
149 }
150 if got := off; got != want {
151 t.Errorf("resumable buffer Pos: got: %v; want: %v", got, want)
152 }
153 }
154
155
156 expectChunkAtOffset(0, nil)
157
158 expectChunkAtOffset(0, nil)
159
160
161
162 mb.Next()
163 mb.Next()
164 expectChunkAtOffset(3, nil)
165
166 mb.Next()
167
168
169 expectChunkAtOffset(6, io.EOF)
170
171
172 mb.Next()
173 expectChunkAtOffset(7, io.EOF)
174 mb.Next()
175 expectChunkAtOffset(7, io.EOF)
176 }
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191 type reader struct {
192 r *bytes.Reader
193 }
194
195 func (r *reader) ReadAt(b []byte, off int64) (n int, err error) {
196 return r.r.ReadAt(b, off)
197 }
198
199 func (r *reader) Read(b []byte) (n int, err error) {
200 return r.r.Read(b)
201 }
202
203
204 type typerReader struct {
205 r *bytes.Reader
206 }
207
208 func (tr *typerReader) ReadAt(b []byte, off int64) (n int, err error) {
209 return tr.r.ReadAt(b, off)
210 }
211
212 func (tr *typerReader) Read(b []byte) (n int, err error) {
213 return tr.r.Read(b)
214 }
215
216 func (tr *typerReader) ContentType() string {
217 return "ctype"
218 }
219
220
221 type readerAt struct {
222 r *bytes.Reader
223 }
224
225 func (ra *readerAt) ReadAt(b []byte, off int64) (n int, err error) {
226 return ra.r.ReadAt(b, off)
227 }
228
229
230 type typerReaderAt struct {
231 r *bytes.Reader
232 }
233
234 func (tra *typerReaderAt) ReadAt(b []byte, off int64) (n int, err error) {
235 return tra.r.ReadAt(b, off)
236 }
237
238 func (tra *typerReaderAt) ContentType() string {
239 return "ctype"
240 }
241
242 func TestAdapter(t *testing.T) {
243 data := "abc"
244
245 checkConversion := func(to io.Reader, wantTyper bool) {
246 if _, ok := to.(googleapi.ContentTyper); ok != wantTyper {
247 t.Errorf("reader implements typer? got: %v; want: %v", ok, wantTyper)
248 }
249 if typer, ok := to.(googleapi.ContentTyper); ok && typer.ContentType() != "ctype" {
250 t.Errorf("content type: got: %s; want: ctype", typer.ContentType())
251 }
252 buf, err := io.ReadAll(to)
253 if err != nil {
254 t.Errorf("error reading data: %v", err)
255 return
256 }
257 if !bytes.Equal(buf, []byte(data)) {
258 t.Errorf("failed reading data: got: %s; want: %s", buf, data)
259 }
260 }
261
262 type testCase struct {
263 from io.ReaderAt
264 wantTyper bool
265 }
266 for _, tc := range []testCase{
267 {
268 from: &reader{bytes.NewReader([]byte(data))},
269 wantTyper: false,
270 },
271 {
272
273 from: &typerReader{bytes.NewReader([]byte(data))},
274 wantTyper: true,
275 },
276 {
277
278 from: &readerAt{bytes.NewReader([]byte(data))},
279 wantTyper: false,
280 },
281 {
282
283 from: &typerReaderAt{bytes.NewReader([]byte(data))},
284 wantTyper: true,
285 },
286 } {
287 to := ReaderAtToReader(tc.from, int64(len(data)))
288 checkConversion(to, tc.wantTyper)
289
290
291
292 to = ReaderAtToReader(tc.from, int64(len(data)))
293 checkConversion(to, tc.wantTyper)
294 }
295 }
296
View as plain text