github.com/hack0072008/kafka-go@v1.0.1/read_test.go (about) 1 package kafka 2 3 import ( 4 "bufio" 5 "bytes" 6 "io/ioutil" 7 "math" 8 "reflect" 9 "testing" 10 ) 11 12 type VarIntTestCase struct { 13 v int64 14 r int 15 tc []byte 16 } 17 18 func TestReadVarInt(t *testing.T) { 19 testCases := []*VarIntTestCase{ 20 {v: 0, r: 3, tc: []byte{0, 1, 10, 0}}, 21 {v: -1, r: 3, tc: []byte{1, 1, 10, 0}}, 22 {v: 1, r: 3, tc: []byte{2, 1, 10, 0}}, 23 {v: -2, r: 3, tc: []byte{3, 1, 10, 0}}, 24 {v: 2, r: 3, tc: []byte{4, 1, 10, 0}}, 25 {v: 64, r: 2, tc: []byte{128, 1, 10, 0}}, 26 {v: -64, r: 3, tc: []byte{127, 1, 10, 0}}, 27 {v: -196, r: 2, tc: []byte{135, 3, 10, 0}}, 28 {v: -24772, r: 1, tc: []byte{135, 131, 3, 0}}, 29 } 30 31 for _, tc := range testCases { 32 var v int64 33 rd := bufio.NewReader(bytes.NewReader(tc.tc)) 34 remain, err := readVarInt(rd, len(tc.tc), &v) 35 if err != nil { 36 t.Errorf("Failure during reading: %v", err) 37 } 38 if v != tc.v { 39 t.Errorf("Expected %v; got %v", tc.v, v) 40 } 41 if remain != tc.r { 42 t.Errorf("Expected remain %v; got %v", tc.r, remain) 43 } 44 } 45 } 46 47 func TestReadVarIntFailing(t *testing.T) { 48 var v int64 49 testCase := []byte{135, 135} 50 rd := bufio.NewReader(bytes.NewReader(testCase)) 51 _, err := readVarInt(rd, len(testCase), &v) 52 if err != errShortRead { 53 t.Errorf("Expected error while parsing var int: %v", err) 54 } 55 } 56 57 func TestReadStringArray(t *testing.T) { 58 testCases := map[string]struct { 59 Value []string 60 }{ 61 "nil": { 62 Value: nil, 63 }, 64 "multiple elements": { 65 Value: []string{"a", "b", "c"}, 66 }, 67 } 68 69 for label, test := range testCases { 70 t.Run(label, func(t *testing.T) { 71 b := bytes.NewBuffer(nil) 72 w := &writeBuffer{w: b} 73 w.writeStringArray(test.Value) 74 75 var actual []string 76 readStringArray(bufio.NewReader(b), b.Len(), &actual) 77 if !reflect.DeepEqual(test.Value, actual) { 78 t.Errorf("expected %v; got %v", test.Value, actual) 79 } 80 }) 81 } 82 } 83 84 func TestReadMapStringInt32(t *testing.T) { 85 testCases := map[string]struct { 86 Data map[string][]int32 87 }{ 88 "empty": { 89 Data: map[string][]int32{}, 90 }, 91 "single element": { 92 Data: map[string][]int32{ 93 "key": {0, 1, 2}, 94 }, 95 }, 96 } 97 98 for label, test := range testCases { 99 t.Run(label, func(t *testing.T) { 100 b := bytes.NewBuffer(nil) 101 w := &writeBuffer{w: b} 102 w.writeInt32(int32(len(test.Data))) 103 104 for key, values := range test.Data { 105 w.writeString(key) 106 w.writeInt32Array(values) 107 } 108 109 var actual map[string][]int32 110 readMapStringInt32(bufio.NewReader(b), b.Len(), &actual) 111 if !reflect.DeepEqual(test.Data, actual) { 112 t.Errorf("expected %#v; got %#v", test.Data, actual) 113 } 114 }) 115 } 116 } 117 118 func TestReadNewBytes(t *testing.T) { 119 120 t.Run("reads new bytes", func(t *testing.T) { 121 r := bufio.NewReader(bytes.NewReader([]byte("foobar"))) 122 123 b, remain, err := readNewBytes(r, 6, 3) 124 if string(b) != "foo" { 125 t.Error("should have returned 3 bytes") 126 } 127 if remain != 3 { 128 t.Error("should have calculated remaining correctly") 129 } 130 if err != nil { 131 t.Error("should not have errored") 132 } 133 134 b, remain, err = readNewBytes(r, remain, 3) 135 if string(b) != "bar" { 136 t.Error("should have returned 3 bytes") 137 } 138 if remain != 0 { 139 t.Error("should have calculated remaining correctly") 140 } 141 if err != nil { 142 t.Error("should not have errored") 143 } 144 145 b, err = r.Peek(0) 146 if len(b) > 0 { 147 t.Error("not all bytes were consumed") 148 } 149 }) 150 151 t.Run("discards bytes when insufficient", func(t *testing.T) { 152 r := bufio.NewReader(bytes.NewReader([]byte("foo"))) 153 b, remain, err := readNewBytes(bufio.NewReader(r), 3, 4) 154 if string(b) != "foo" { 155 t.Error("should have returned available bytes") 156 } 157 if remain != 0 { 158 t.Error("all bytes should have been consumed") 159 } 160 if err != errShortRead { 161 t.Error("should have returned errShortRead") 162 } 163 b, err = r.Peek(0) 164 if len(b) > 0 { 165 t.Error("not all bytes were consumed") 166 } 167 }) 168 } 169 170 func BenchmarkWriteVarInt(b *testing.B) { 171 wb := &writeBuffer{w: ioutil.Discard} 172 173 for i := 0; i < b.N; i++ { 174 wb.writeVarInt(math.MaxInt64) 175 } 176 } 177 178 func BenchmarkReadVarInt(b *testing.B) { 179 b1 := new(bytes.Buffer) 180 wb := &writeBuffer{w: b1} 181 182 const N = math.MaxInt64 183 wb.writeVarInt(N) 184 185 b2 := bytes.NewReader(b1.Bytes()) 186 rb := bufio.NewReader(b2) 187 n := b1.Len() 188 189 for i := 0; i < b.N; i++ { 190 v := int64(0) 191 r, err := readVarInt(rb, n, &v) 192 193 if err != nil { 194 b.Fatalf("unexpected error reading a varint from the input: %v", err) 195 } 196 197 if r != 0 { 198 b.Fatalf("unexpected bytes remaining to be read in the input (%d B)", r) 199 } 200 201 if v != N { 202 b.Fatalf("value mismatch, expected %d but found %d", N, v) 203 } 204 205 b2.Reset(b1.Bytes()) 206 rb.Reset(b2) 207 } 208 }