github.com/segmentio/kafka-go@v0.4.48-0.20240318174348-3f6244eb34fd/protocol/protocol_test.go (about) 1 package protocol 2 3 import ( 4 "bytes" 5 "math" 6 "reflect" 7 "testing" 8 ) 9 10 type testType struct { 11 Field1 string `kafka:"min=v0,max=v4,nullable"` 12 Field2 int16 `kafka:"min=v2,max=v4"` 13 Field3 []byte `kafka:"min=v2,max=v4,nullable"` 14 SubTypes []testSubType `kafka:"min=v1,max=v4"` 15 16 TaggedField1 int8 `kafka:"min=v3,max=v4,tag=0"` 17 TaggedField2 string `kafka:"min=v4,max=v4,tag=1"` 18 } 19 20 type testSubType struct { 21 SubField1 int8 `kafka:"min=v1,max=v4"` 22 } 23 24 func TestMakeFlexibleTypes(t *testing.T) { 25 types := makeTypes(reflect.TypeOf(&testType{}).Elem()) 26 if len(types) != 5 { 27 t.Error( 28 "Wrong number of types", 29 "expected", 5, 30 "got", len(types), 31 ) 32 } 33 34 fv := []int16{} 35 36 for _, to := range types { 37 if to.flexible { 38 fv = append(fv, to.version) 39 } 40 } 41 42 if !reflect.DeepEqual([]int16{3, 4}, fv) { 43 t.Error( 44 "Unexpected flexible versions", 45 "expected", []int16{3, 4}, 46 "got", fv, 47 ) 48 } 49 } 50 51 func TestEncodeDecodeFlexibleType(t *testing.T) { 52 f := &testType{ 53 Field1: "value1", 54 Field2: 15, 55 Field3: []byte("hello"), 56 SubTypes: []testSubType{ 57 { 58 SubField1: 2, 59 }, 60 { 61 SubField1: 3, 62 }, 63 }, 64 65 TaggedField1: 34, 66 TaggedField2: "taggedValue2", 67 } 68 69 b := &bytes.Buffer{} 70 e := &encoder{writer: b} 71 72 types := makeTypes(reflect.TypeOf(&testType{}).Elem()) 73 ft := types[4] 74 ft.encode(e, valueOf(f)) 75 if e.err != nil { 76 t.Error( 77 "Error during encoding", 78 "expected", nil, 79 "got", e.err, 80 ) 81 } 82 83 exp := []byte{ 84 // size of "value1" + 1 85 7, 86 // "value1" 87 118, 97, 108, 117, 101, 49, 88 // 15 as 16-bit int 89 0, 15, 90 // size of []byte("hello") + 1 91 6, 92 // []byte("hello") 93 104, 101, 108, 108, 111, 94 // size of []SubTypes + 1 95 3, 96 // 2 as 8-bit int 97 2, 98 // tag buffer for first SubType struct 99 0, 100 // 3 as 8-bit int 101 3, 102 // tag buffer for second SubType struct 103 0, 104 // number of tagged fields 105 2, 106 // id of first tagged field 107 0, 108 // size of first tagged field 109 1, 110 // 34 as 8-bit int 111 34, 112 // id of second tagged field 113 1, 114 // size of second tagged field 115 13, 116 // size of "taggedValue2" + 1 117 13, 118 // "taggedValue2" 119 116, 97, 103, 103, 101, 100, 86, 97, 108, 117, 101, 50, 120 } 121 122 if !reflect.DeepEqual(exp, b.Bytes()) { 123 t.Error( 124 "Wrong encoded output", 125 "expected", exp, 126 "got", b.Bytes(), 127 ) 128 } 129 130 b = &bytes.Buffer{} 131 b.Write(exp) 132 d := &decoder{reader: b, remain: len(exp)} 133 134 f2 := &testType{} 135 ft.decode(d, valueOf(f2)) 136 if d.err != nil { 137 t.Error( 138 "Error during decoding", 139 "expected", nil, 140 "got", e.err, 141 ) 142 } 143 144 if !reflect.DeepEqual(f, f2) { 145 t.Error( 146 "Decoded value does not equal encoded one", 147 "expected", *f, 148 "got", *f2, 149 ) 150 } 151 } 152 153 func TestVarInts(t *testing.T) { 154 type tc struct { 155 input int64 156 expVarInt []byte 157 expUVarInt []byte 158 } 159 160 tcs := []tc{ 161 { 162 input: 12, 163 expVarInt: []byte{24}, 164 expUVarInt: []byte{12}, 165 }, 166 { 167 input: 63, 168 expVarInt: []byte{126}, 169 expUVarInt: []byte{63}, 170 }, 171 { 172 input: -64, 173 expVarInt: []byte{127}, 174 expUVarInt: []byte{192, 255, 255, 255, 255, 255, 255, 255, 255, 1}, 175 }, 176 { 177 input: 64, 178 expVarInt: []byte{128, 1}, 179 expUVarInt: []byte{64}, 180 }, 181 { 182 input: 127, 183 expVarInt: []byte{254, 1}, 184 expUVarInt: []byte{127}, 185 }, 186 { 187 input: 128, 188 expVarInt: []byte{128, 2}, 189 expUVarInt: []byte{128, 1}, 190 }, 191 { 192 input: 129, 193 expVarInt: []byte{130, 2}, 194 expUVarInt: []byte{129, 1}, 195 }, 196 { 197 input: 12345, 198 expVarInt: []byte{242, 192, 1}, 199 expUVarInt: []byte{185, 96}, 200 }, 201 { 202 input: 123456789101112, 203 expVarInt: []byte{240, 232, 249, 224, 144, 146, 56}, 204 expUVarInt: []byte{184, 244, 188, 176, 136, 137, 28}, 205 }, 206 } 207 208 for _, tc := range tcs { 209 b := &bytes.Buffer{} 210 e := &encoder{writer: b} 211 e.writeVarInt(tc.input) 212 if e.err != nil { 213 t.Errorf( 214 "Unexpected error encoding %d as varInt: %+v", 215 tc.input, 216 e.err, 217 ) 218 } 219 if !reflect.DeepEqual(b.Bytes(), tc.expVarInt) { 220 t.Error( 221 "Wrong output encoding value", tc.input, "as varInt", 222 "expected", tc.expVarInt, 223 "got", b.Bytes(), 224 ) 225 } 226 expLen := sizeOfVarInt(tc.input) 227 if expLen != len(b.Bytes()) { 228 t.Error( 229 "Wrong sizeOf for", tc.input, "as varInt", 230 "expected", expLen, 231 "got", len(b.Bytes()), 232 ) 233 } 234 235 d := &decoder{reader: b, remain: len(b.Bytes())} 236 v := d.readVarInt() 237 if v != tc.input { 238 t.Error( 239 "Decoded varInt value does not equal encoded one", 240 "expected", tc.input, 241 "got", v, 242 ) 243 } 244 245 b = &bytes.Buffer{} 246 e = &encoder{writer: b} 247 e.writeUnsignedVarInt(uint64(tc.input)) 248 if e.err != nil { 249 t.Errorf( 250 "Unexpected error encoding %d as unsignedVarInt: %+v", 251 tc.input, 252 e.err, 253 ) 254 } 255 if !reflect.DeepEqual(b.Bytes(), tc.expUVarInt) { 256 t.Error( 257 "Wrong output encoding value", tc.input, "as unsignedVarInt", 258 "expected", tc.expUVarInt, 259 "got", b.Bytes(), 260 ) 261 } 262 expLen = sizeOfUnsignedVarInt(uint64(tc.input)) 263 if expLen != len(b.Bytes()) { 264 t.Error( 265 "Wrong sizeOf for", tc.input, "as unsignedVarInt", 266 "expected", expLen, 267 "got", len(b.Bytes()), 268 ) 269 } 270 271 d = &decoder{reader: b, remain: len(b.Bytes())} 272 v = int64(d.readUnsignedVarInt()) 273 if v != tc.input { 274 t.Error( 275 "Decoded unsignedVarInt value does not equal encoded one", 276 "expected", tc.input, 277 "got", v, 278 ) 279 } 280 281 } 282 } 283 284 func TestFloat64(t *testing.T) { 285 type tc struct { 286 input float64 287 expected []byte 288 } 289 290 tcs := []tc{ 291 { 292 input: 0.0, 293 expected: []byte{0, 0, 0, 0, 0, 0, 0, 0}, 294 }, 295 { 296 input: math.MaxFloat64, 297 expected: []byte{127, 239, 255, 255, 255, 255, 255, 255}, 298 }, 299 { 300 input: -math.MaxFloat64, 301 expected: []byte{255, 239, 255, 255, 255, 255, 255, 255}, 302 }, 303 { 304 input: math.SmallestNonzeroFloat64, 305 expected: []byte{0, 0, 0, 0, 0, 0, 0, 1}, 306 }, 307 { 308 input: -math.SmallestNonzeroFloat64, 309 expected: []byte{128, 0, 0, 0, 0, 0, 0, 1}, 310 }, 311 } 312 313 for _, tc := range tcs { 314 b := &bytes.Buffer{} 315 e := &encoder{writer: b} 316 e.writeFloat64(tc.input) 317 if e.err != nil { 318 t.Errorf( 319 "Unexpected error encoding %f as float64: %+v", 320 tc.input, 321 e.err, 322 ) 323 } 324 if !reflect.DeepEqual(b.Bytes(), tc.expected) { 325 t.Error( 326 "Wrong output encoding value", tc.input, "as float64", 327 "expected", tc.expected, 328 "got", b.Bytes(), 329 ) 330 } 331 332 d := &decoder{reader: b, remain: len(b.Bytes())} 333 v := d.readFloat64() 334 if v != tc.input { 335 t.Error( 336 "Decoded float64 value does not equal encoded one", 337 "expected", tc.input, 338 "got", v, 339 ) 340 } 341 } 342 }