1 package io
2
3 import (
4 "bytes"
5 "io"
6 "io/ioutil"
7 "strconv"
8 "strings"
9 "testing"
10 )
11
12 func TestRingBuffer_Write(t *testing.T) {
13 cases := map[string]struct {
14 sliceCapacity int
15 input []byte
16 expectedStart int
17 expectedEnd int
18 expectedSize int
19 expectedWrittenBuffer []byte
20 }{
21 "RingBuffer capacity matches Bytes written": {
22 sliceCapacity: 11,
23 input: []byte("hello world"),
24 expectedStart: 0,
25 expectedEnd: 11,
26 expectedSize: 11,
27 expectedWrittenBuffer: []byte("hello world"),
28 },
29 "RingBuffer capacity is lower than Bytes written": {
30 sliceCapacity: 10,
31 input: []byte("hello world"),
32 expectedStart: 1,
33 expectedEnd: 1,
34 expectedSize: 10,
35 expectedWrittenBuffer: []byte("dello worl"),
36 },
37 "RingBuffer capacity is more than Bytes written": {
38 sliceCapacity: 12,
39 input: []byte("hello world"),
40 expectedStart: 0,
41 expectedEnd: 11,
42 expectedSize: 11,
43 expectedWrittenBuffer: []byte("hello world"),
44 },
45 "No Bytes written": {
46 sliceCapacity: 10,
47 input: []byte(""),
48 expectedStart: 0,
49 expectedEnd: 0,
50 expectedSize: 0,
51 expectedWrittenBuffer: []byte(""),
52 },
53 }
54 for name, c := range cases {
55 t.Run(name, func(t *testing.T) {
56 byteSlice := make([]byte, c.sliceCapacity)
57 ringBuffer := NewRingBuffer(byteSlice)
58 ringBuffer.Write(c.input)
59 if e, a := c.expectedSize, ringBuffer.size; e != a {
60 t.Errorf("expect default size to be %v , got %v", e, a)
61 }
62 if e, a := c.expectedStart, ringBuffer.start; e != a {
63 t.Errorf("expect deafult start to point to %v , got %v", e, a)
64 }
65 if e, a := c.expectedEnd, ringBuffer.end; e != a {
66 t.Errorf("expect default end to point to %v , got %v", e, a)
67 }
68 if e, a := c.expectedWrittenBuffer, ringBuffer.slice; !bytes.Contains(a, e) {
69 t.Errorf("expect written bytes to be %v , got %v", string(e), string(a))
70 }
71 })
72 }
73
74 }
75
76 func TestRingBuffer_Read(t *testing.T) {
77 cases := map[string]struct {
78 input []byte
79 numberOfBytesToRead int
80 expectedStartAfterRead int
81 expectedEndAfterRead int
82 expectedSizeOfBufferAfterRead int
83 expectedReadSlice []byte
84 expectedErrorAfterRead error
85 }{
86 "Read capacity matches Bytes written": {
87 input: []byte("Hello world"),
88 numberOfBytesToRead: 11,
89 expectedStartAfterRead: 11,
90 expectedEndAfterRead: 11,
91 expectedSizeOfBufferAfterRead: 0,
92 expectedReadSlice: []byte("Hello world"),
93 expectedErrorAfterRead: nil,
94 },
95 "Read capacity is lower than Bytes written": {
96 input: []byte("hello world"),
97 numberOfBytesToRead: 5,
98 expectedStartAfterRead: 5,
99 expectedEndAfterRead: 11,
100 expectedSizeOfBufferAfterRead: 6,
101 expectedReadSlice: []byte("hello"),
102 expectedErrorAfterRead: nil,
103 },
104 "Read capacity is more than Bytes written": {
105 input: []byte("hello world"),
106 numberOfBytesToRead: 15,
107 expectedStartAfterRead: 11,
108 expectedEndAfterRead: 11,
109 expectedSizeOfBufferAfterRead: 0,
110 expectedReadSlice: []byte("hello world"),
111 expectedErrorAfterRead: io.EOF,
112 },
113 "No Bytes are read": {
114 input: []byte("hello world"),
115 numberOfBytesToRead: 0,
116 expectedStartAfterRead: 0,
117 expectedEndAfterRead: 11,
118 expectedSizeOfBufferAfterRead: 11,
119 expectedReadSlice: []byte(""),
120 expectedErrorAfterRead: nil,
121 },
122 "No Bytes written": {
123 input: []byte(""),
124 numberOfBytesToRead: 11,
125 expectedStartAfterRead: 0,
126 expectedEndAfterRead: 0,
127 expectedSizeOfBufferAfterRead: 0,
128 expectedReadSlice: []byte(""),
129 expectedErrorAfterRead: io.EOF,
130 },
131 "RingBuffer capacity is more than Bytes Written": {
132 input: []byte("h"),
133 numberOfBytesToRead: 11,
134 expectedStartAfterRead: 1,
135 expectedEndAfterRead: 1,
136 expectedSizeOfBufferAfterRead: 0,
137 expectedReadSlice: []byte("h"),
138 expectedErrorAfterRead: io.EOF,
139 },
140 }
141 for name, c := range cases {
142 byteSlice := make([]byte, 11)
143 t.Run(name, func(t *testing.T) {
144 ringBuffer := NewRingBuffer(byteSlice)
145 readSlice := make([]byte, c.numberOfBytesToRead)
146
147 ringBuffer.Write(c.input)
148 _, err := ringBuffer.Read(readSlice)
149
150 if e, a := c.expectedErrorAfterRead, err; e != a {
151 t.Errorf("Expected %v, got %v", e, a)
152 }
153 if e, a := c.expectedReadSlice, readSlice; !bytes.Contains(a, e) {
154 t.Errorf("expect read buffer to be %v, got %v", string(e), string(a))
155 }
156 if e, a := c.expectedSizeOfBufferAfterRead, ringBuffer.size; e != a {
157 t.Errorf("expect default size to be %v , got %v", e, a)
158 }
159 if e, a := c.expectedStartAfterRead, ringBuffer.start; e != a {
160 t.Errorf("expect default start to point to %v , got %v", e, a)
161 }
162 if e, a := c.expectedEndAfterRead, ringBuffer.end; e != a {
163 t.Errorf("expect default end to point to %v , got %v", e, a)
164 }
165 })
166 }
167 }
168
169 func TestRingBuffer_forConsecutiveReadWrites(t *testing.T) {
170 cases := map[string]struct {
171 input []string
172 sliceCapacity int
173 numberOfBytesToRead []int
174 expectedStartAfterRead []int
175 expectedEnd []int
176 expectedSizeOfBufferAfterRead []int
177 expectedReadSlice []string
178 expectedWrittenBuffer []string
179 expectedErrorAfterRead []error
180 }{
181 "RingBuffer capacity matches Bytes written": {
182 input: []string{"Hello World", "Hello Earth", "Mars,/"},
183 sliceCapacity: 11,
184 numberOfBytesToRead: []int{5, 11},
185 expectedStartAfterRead: []int{5, 6},
186 expectedEnd: []int{11, 6},
187 expectedSizeOfBufferAfterRead: []int{6, 0},
188 expectedReadSlice: []string{"Hello", "EarthMars,/"},
189 expectedWrittenBuffer: []string{"Hello World", "Hello Earth", "Mars,/Earth"},
190 expectedErrorAfterRead: []error{nil, nil},
191 },
192 "RingBuffer capacity is lower than Bytes written": {
193 input: []string{"Hello World", "Hello Earth", "Mars,/"},
194 sliceCapacity: 5,
195 numberOfBytesToRead: []int{5, 5},
196 expectedStartAfterRead: []int{1, 3},
197 expectedEnd: []int{1, 3},
198 expectedSizeOfBufferAfterRead: []int{0, 0},
199 expectedReadSlice: []string{"World", "ars,/"},
200 expectedWrittenBuffer: []string{"dWorl", "thEar", "s,/ar"},
201 expectedErrorAfterRead: []error{nil, nil},
202 },
203 "RingBuffer capacity is more than Bytes written": {
204 input: []string{"Hello World", "Hello Earth", "Mars,/"},
205 sliceCapacity: 15,
206 numberOfBytesToRead: []int{5, 8},
207 expectedStartAfterRead: []int{5, 6},
208 expectedEnd: []int{11, 13},
209 expectedSizeOfBufferAfterRead: []int{6, 7},
210 expectedReadSlice: []string{"Hello", "llo Eart"},
211 expectedWrittenBuffer: []string{"Hello World", "o EarthorldHell", "o EarthMars,/ll"},
212 expectedErrorAfterRead: []error{nil, nil},
213 },
214 "No Bytes written": {
215 input: []string{"", "", ""},
216 sliceCapacity: 11,
217 numberOfBytesToRead: []int{5, 8},
218 expectedStartAfterRead: []int{0, 0},
219 expectedEnd: []int{0, 0},
220 expectedSizeOfBufferAfterRead: []int{0, 0},
221 expectedReadSlice: []string{"", ""},
222 expectedWrittenBuffer: []string{"", "", ""},
223 expectedErrorAfterRead: []error{io.EOF, io.EOF},
224 },
225 }
226 for name, c := range cases {
227 writeSlice := make([]byte, c.sliceCapacity)
228 ringBuffer := NewRingBuffer(writeSlice)
229
230 t.Run(name, func(t *testing.T) {
231 ringBuffer.Write([]byte(c.input[0]))
232 if e, a := c.expectedWrittenBuffer[0], string(ringBuffer.slice); !strings.Contains(a, e) {
233 t.Errorf("Expected %v, got %v", e, a)
234 }
235
236 readSlice := make([]byte, c.numberOfBytesToRead[0])
237 readCount, err := ringBuffer.Read(readSlice)
238
239 if e, a := c.expectedErrorAfterRead[0], err; e != a {
240 t.Errorf("Expected %v, got %v", e, a)
241 }
242 if e, a := len(c.expectedReadSlice[0]), readCount; e != a {
243 t.Errorf("Expected to read %v bytes, read only %v", e, a)
244 }
245 if e, a := c.expectedReadSlice[0], string(readSlice); !strings.Contains(a, e) {
246 t.Errorf("expect read buffer to be %v, got %v", e, a)
247 }
248 if e, a := c.expectedSizeOfBufferAfterRead[0], ringBuffer.size; e != a {
249 t.Errorf("expect buffer size to be %v , got %v", e, a)
250 }
251 if e, a := c.expectedStartAfterRead[0], ringBuffer.start; e != a {
252 t.Errorf("expect default start to point to %v , got %v", e, a)
253 }
254 if e, a := c.expectedEnd[0], ringBuffer.end; e != a {
255 t.Errorf("expect default end tp point to %v , got %v", e, a)
256 }
257
258
261 ringBuffer.Write([]byte(c.input[1]))
262 if e, a := c.expectedWrittenBuffer[1], string(ringBuffer.slice); !strings.Contains(a, e) {
263 t.Errorf("Expected %v, got %v", e, a)
264 }
265
266 ringBuffer.Write([]byte(c.input[2]))
267 if e, a := c.expectedWrittenBuffer[2], string(ringBuffer.slice); !strings.Contains(a, e) {
268 t.Errorf("Expected %v, got %v", e, a)
269 }
270
271 readSlice = make([]byte, c.numberOfBytesToRead[1])
272 readCount, err = ringBuffer.Read(readSlice)
273 if e, a := c.expectedErrorAfterRead[1], err; e != a {
274 t.Errorf("Expected %v, got %v", e, a)
275 }
276 if e, a := len(c.expectedReadSlice[1]), readCount; e != a {
277 t.Errorf("Expected to read %v bytes, read only %v", e, a)
278 }
279 if e, a := c.expectedReadSlice[1], string(readSlice); !strings.Contains(a, e) {
280 t.Errorf("expect read buffer to be %v, got %v", e, a)
281 }
282 if e, a := c.expectedSizeOfBufferAfterRead[1], ringBuffer.size; e != a {
283 t.Errorf("expect buffer size to be %v , got %v", e, a)
284 }
285 if e, a := c.expectedStartAfterRead[1], ringBuffer.start; e != a {
286 t.Errorf("expect default start to point to %v , got %v", e, a)
287 }
288 if e, a := c.expectedEnd[1], ringBuffer.end; e != a {
289 t.Errorf("expect default end to point to %v , got %v", e, a)
290 }
291 })
292 }
293 }
294
295 func TestRingBuffer_ExhaustiveRead(t *testing.T) {
296 slice := make([]byte, 5)
297 buf := NewRingBuffer(slice)
298 buf.Write([]byte("Hello"))
299
300 readSlice := make([]byte, 5)
301 readCount, err := buf.Read(readSlice)
302 if e, a := error(nil), err; e != a {
303 t.Errorf("Expected %v, got %v", e, a)
304 }
305 if e, a := 5, readCount; e != a {
306 t.Errorf("Expected to read %v bytes, read only %v", e, a)
307 }
308 if e, a := "Hello", string(readSlice); e != a {
309 t.Errorf("Expected %v to be read, got %v", e, a)
310 }
311
312 readCount, err = buf.Read(readSlice)
313 if e, a := io.EOF, err; e != a {
314 t.Errorf("Expected %v, got %v", e, a)
315 }
316 if e, a := 0, readCount; e != a {
317 t.Errorf("Expected to read %v bytes, read only %v", e, a)
318 }
319 if e, a := 0, buf.size; e != a {
320 t.Errorf("Expected ring buffer size to be %v, got %v", e, a)
321 }
322 }
323
324 func TestRingBuffer_Reset(t *testing.T) {
325 byteSlice := make([]byte, 10)
326 ringBuffer := NewRingBuffer(byteSlice)
327
328 ringBuffer.Write([]byte("Hello-world"))
329 if ringBuffer.size == 0 {
330 t.Errorf("expected ringBuffer to not be empty")
331 }
332
333 readBuffer := make([]byte, 5)
334 ringBuffer.Read(readBuffer)
335 if ringBuffer.size == 0 {
336 t.Errorf("expected ringBuffer to not be empty")
337 }
338 if e, a := "ello-", string(readBuffer); !strings.EqualFold(e, a) {
339 t.Errorf("expected read string to be %s, got %s", e, a)
340 }
341
342
343 ringBuffer.Reset()
344 if e, a := 0, ringBuffer.size; e != a {
345 t.Errorf("expect default size to be %v , got %v", e, a)
346 }
347 if e, a := 0, ringBuffer.start; e != a {
348 t.Errorf("expect deafult start to point to %v , got %v", e, a)
349 }
350 if e, a := 0, ringBuffer.end; e != a {
351 t.Errorf("expect default end to point to %v , got %v", e, a)
352 }
353 if e, a := 10, len(ringBuffer.slice); e != a {
354 t.Errorf("expect ringBuffer capacity to be %v, got %v", e, a)
355 }
356
357 ringBuffer.Write([]byte("someThing new"))
358 if ringBuffer.size == 0 {
359 t.Errorf("expected ringBuffer to not be empty")
360 }
361
362 ringBuffer.Read(readBuffer)
363 if ringBuffer.size == 0 {
364 t.Errorf("expected ringBuffer to not be empty")
365 }
366
367
368
369
370
371 if e, a := "eThin", string(readBuffer); !strings.EqualFold(e, a) {
372 t.Errorf("expected read string to be %s, got %s", e, a)
373 }
374
375
376 ringBuffer.Reset()
377 if e, a := 0, ringBuffer.size; e != a {
378 t.Errorf("expect default size to be %v , got %v", e, a)
379 }
380 if e, a := 0, ringBuffer.start; e != a {
381 t.Errorf("expect deafult start to point to %v , got %v", e, a)
382 }
383 if e, a := 0, ringBuffer.end; e != a {
384 t.Errorf("expect default end to point to %v , got %v", e, a)
385 }
386 if e, a := 10, len(ringBuffer.slice); e != a {
387 t.Errorf("expect ringBuffer capacity to be %v, got %v", e, a)
388 }
389
390
391 readCount, _ := ringBuffer.Read(readBuffer)
392 if ringBuffer.size != 0 {
393 t.Errorf("expected ringBuffer to be empty")
394 }
395 if e, a := 0, readCount; e != a {
396 t.Errorf("expected read string to be of length %v, got %v", e, a)
397 }
398 }
399
400 func TestRingBufferWriteRead(t *testing.T) {
401 cases := []struct {
402 Input []byte
403 BufferSize int
404 Expected []byte
405 }{
406 {
407 Input: func() []byte {
408 return []byte(`hello world!`)
409 }(),
410 BufferSize: 6,
411 Expected: []byte(`world!`),
412 },
413 {
414 Input: func() []byte {
415 return []byte(`hello world!`)
416 }(),
417 BufferSize: 12,
418 Expected: []byte(`hello world!`),
419 },
420 {
421 Input: func() []byte {
422 return []byte(`hello`)
423 }(),
424 BufferSize: 6,
425 Expected: []byte(`hello`),
426 },
427 {
428 Input: func() []byte {
429 return []byte(`hello!!`)
430 }(),
431 BufferSize: 6,
432 Expected: []byte(`ello!!`),
433 },
434 }
435
436 for i, tt := range cases {
437 t.Run(strconv.Itoa(i), func(t *testing.T) {
438 dataReader := bytes.NewReader(tt.Input)
439
440 ringBuffer := NewRingBuffer(make([]byte, tt.BufferSize))
441
442 n, err := io.Copy(ringBuffer, dataReader)
443 if err != nil {
444 t.Errorf("unexpected error, %v", err)
445 return
446 }
447
448 if e, a := int64(len(tt.Input)), n; e != a {
449 t.Errorf("expect %v, got %v", e, a)
450 }
451
452 actual, err := ioutil.ReadAll(ringBuffer)
453 if err != nil {
454 t.Errorf("unexpected error, %v", err)
455 return
456 }
457
458 if string(tt.Expected) != string(actual) {
459 t.Errorf("%v != %v", string(tt.Expected), string(actual))
460 return
461 }
462 })
463 }
464 }
465
View as plain text