| OLD | NEW |
| (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 frame |
| 6 |
| 7 import ( |
| 8 "bytes" |
| 9 "encoding/binary" |
| 10 "errors" |
| 11 "io" |
| 12 "testing" |
| 13 |
| 14 . "github.com/smartystreets/goconvey/convey" |
| 15 ) |
| 16 |
| 17 // plainReader implements the io.Reader interface on top of a bytes.Buffer; |
| 18 // however, it does not also implement io.ByteReader. |
| 19 type plainReader struct { |
| 20 buf bytes.Buffer |
| 21 err error |
| 22 } |
| 23 |
| 24 func (r *plainReader) loadFrame(data []byte) { |
| 25 _, err := WriteFrame(&r.buf, data) |
| 26 if err != nil { |
| 27 panic(err) |
| 28 } |
| 29 } |
| 30 |
| 31 func (r *plainReader) Read(data []byte) (int, error) { |
| 32 if r.err != nil { |
| 33 return 0, r.err |
| 34 } |
| 35 return r.buf.Read(data) |
| 36 } |
| 37 |
| 38 type testByteReader struct { |
| 39 plainReader |
| 40 readBytes int |
| 41 } |
| 42 |
| 43 func (r *testByteReader) ReadByte() (byte, error) { |
| 44 b, err := r.buf.ReadByte() |
| 45 if err == nil { |
| 46 r.readBytes++ |
| 47 } |
| 48 return b, err |
| 49 } |
| 50 |
| 51 // TestReader tests the default Reader implementation, "reader". |
| 52 func TestReader(t *testing.T) { |
| 53 t.Parallel() |
| 54 |
| 55 Convey(`A frame reader with max size 1MB using a plain io.Reader`, t, fu
nc() { |
| 56 maxSize := 1024 * 1024 |
| 57 tr := plainReader{} |
| 58 r := NewReader(&tr, maxSize) |
| 59 |
| 60 Convey(`Will return io.EOF with an empty reader.`, func() { |
| 61 _, err := r.ReadFrame() |
| 62 So(err, ShouldEqual, io.EOF) |
| 63 }) |
| 64 |
| 65 Convey(`Can successfully read a frame.`, func() { |
| 66 data := []byte{0x13, 0x37, 0xd0, 0x65} |
| 67 tr.loadFrame(data) |
| 68 |
| 69 f, err := r.ReadFrame() |
| 70 So(err, ShouldBeNil) |
| 71 So(f, ShouldResemble, data) |
| 72 }) |
| 73 |
| 74 Convey(`Will fail if the underlying frame exceeds the maximum si
ze.`, func() { |
| 75 var sizeBuf [binary.MaxVarintLen64]byte |
| 76 tr.buf.Write(sizeBuf[:binary.PutUvarint(sizeBuf[:], uint
64(maxSize+1))]) |
| 77 |
| 78 _, err := r.ReadFrame() |
| 79 So(err, ShouldEqual, ErrFrameTooLarge) |
| 80 }) |
| 81 |
| 82 Convey(`Will fail if the frame contains an invalid size header.`
, func() { |
| 83 tr.buf.Write([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}) |
| 84 _, err := r.ReadFrame() |
| 85 So(err, ShouldNotBeNil) |
| 86 }) |
| 87 |
| 88 Convey(`Can read conscutive frames, then io.EOF.`, func() { |
| 89 data := [][]byte{} |
| 90 for _, size := range []int{ |
| 91 0, |
| 92 14, |
| 93 1024 * 1024, |
| 94 0, |
| 95 511, |
| 96 } { |
| 97 data = append(data, bytes.Repeat([]byte{0x5A}, s
ize)) |
| 98 tr.loadFrame(data[len(data)-1]) |
| 99 } |
| 100 |
| 101 for _, expected := range data { |
| 102 f, err := r.ReadFrame() |
| 103 So(err, ShouldBeNil) |
| 104 So(f, ShouldResemble, expected) |
| 105 } |
| 106 |
| 107 _, err := r.ReadFrame() |
| 108 So(err, ShouldEqual, io.EOF) |
| 109 }) |
| 110 }) |
| 111 |
| 112 Convey(`A frame reader with max size 1MB using an io.Reader+io.ByteReade
r`, t, func() { |
| 113 tr := testByteReader{} |
| 114 r := NewReader(&tr, 1024*1024) |
| 115 |
| 116 Convey(`Will return io.EOF with an empty reader.`, func() { |
| 117 _, err := r.ReadFrame() |
| 118 So(err, ShouldEqual, io.EOF) |
| 119 }) |
| 120 |
| 121 Convey(`Will use io.ByteReader to read the frame header.`, func(
) { |
| 122 data := []byte{0x13, 0x37, 0xd0, 0x65} |
| 123 tr.loadFrame(data) |
| 124 |
| 125 f, err := r.ReadFrame() |
| 126 So(err, ShouldBeNil) |
| 127 So(f, ShouldResemble, data) |
| 128 So(tr.readBytes, ShouldEqual, 1) |
| 129 }) |
| 130 |
| 131 Convey(`Will fail if the underlying io.Reader returns an error.`
, func() { |
| 132 tr.loadFrame([]byte{}) |
| 133 tr.err = errors.New("test: test-induced error") |
| 134 _, err := r.ReadFrame() |
| 135 So(err, ShouldEqual, tr.err) |
| 136 }) |
| 137 }) |
| 138 } |
| OLD | NEW |