github.com/XiaoMi/Gaea@v1.2.5/mysql/encoding_test.go (about) 1 /* 2 Copyright 2017 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreedto in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package mysql 18 19 import ( 20 "bytes" 21 "testing" 22 ) 23 24 func TestEncLenInt(t *testing.T) { 25 tests := []struct { 26 value uint64 27 encoded []byte 28 }{ 29 {0x00, []byte{0x00}}, 30 {0x0a, []byte{0x0a}}, 31 {0xfa, []byte{0xfa}}, 32 {0xfb, []byte{0xfc, 0xfb, 0x00}}, 33 {0xfc, []byte{0xfc, 0xfc, 0x00}}, 34 {0xfd, []byte{0xfc, 0xfd, 0x00}}, 35 {0xfe, []byte{0xfc, 0xfe, 0x00}}, 36 {0xff, []byte{0xfc, 0xff, 0x00}}, 37 {0x0100, []byte{0xfc, 0x00, 0x01}}, 38 {0x876a, []byte{0xfc, 0x6a, 0x87}}, 39 {0xffff, []byte{0xfc, 0xff, 0xff}}, 40 {0x010000, []byte{0xfd, 0x00, 0x00, 0x01}}, 41 {0xabcdef, []byte{0xfd, 0xef, 0xcd, 0xab}}, 42 {0xffffff, []byte{0xfd, 0xff, 0xff, 0xff}}, 43 {0x01000000, []byte{0xfe, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}}, 44 {0xa0a1a2a3a4a5a6a7, []byte{0xfe, 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0}}, 45 } 46 for _, test := range tests { 47 // Check LenEncIntSize first. 48 if got := LenEncIntSize(test.value); got != len(test.encoded) { 49 t.Errorf("LenEncIntSize returned %v but expected %v for %x", got, len(test.encoded), test.value) 50 } 51 52 // Check successful encoding. 53 data := make([]byte, len(test.encoded)) 54 pos := WriteLenEncInt(data, 0, test.value) 55 if pos != len(test.encoded) { 56 t.Errorf("unexpected pos %v after WriteLenEncInt(%x), expected %v", pos, test.value, len(test.encoded)) 57 } 58 if !bytes.Equal(data, test.encoded) { 59 t.Errorf("unexpected encoded value for %x, got %v expected %v", test.value, data, test.encoded) 60 } 61 62 // Check successful encoding with offset. 63 data = make([]byte, len(test.encoded)+1) 64 pos = WriteLenEncInt(data, 1, test.value) 65 if pos != len(test.encoded)+1 { 66 t.Errorf("unexpected pos %v after WriteLenEncInt(%x, 1), expected %v", pos, test.value, len(test.encoded)+1) 67 } 68 if !bytes.Equal(data[1:], test.encoded) { 69 t.Errorf("unexpected encoded value for %x, got %v expected %v", test.value, data, test.encoded) 70 } 71 72 // Check succesful decoding. 73 got, pos, _, ok := ReadLenEncInt(test.encoded, 0) 74 if !ok || got != test.value || pos != len(test.encoded) { 75 t.Errorf("ReadLenEncInt returned %x/%v/%v but expected %x/%v/%v", got, pos, ok, test.value, len(test.encoded), true) 76 } 77 78 // Check failed decoding. 79 got, pos, _, ok = ReadLenEncInt(test.encoded[:len(test.encoded)-1], 0) 80 if ok { 81 t.Errorf("ReadLenEncInt returned ok=true for shorter value %x", test.value) 82 } 83 } 84 } 85 86 func TestEncUint16(t *testing.T) { 87 data := make([]byte, 10) 88 89 val16 := uint16(0xabcd) 90 91 if got := WriteUint16(data, 2, val16); got != 4 { 92 t.Errorf("WriteUint16 returned %v but expected 4", got) 93 } 94 95 if data[2] != 0xcd || data[3] != 0xab { 96 t.Errorf("WriteUint16 returned bad result: %v", data) 97 } 98 99 got16, pos, ok := ReadUint16(data, 2) 100 if !ok || got16 != val16 || pos != 4 { 101 t.Errorf("ReadUint16 returned %v/%v/%v but expected %v/%v/%v", got16, pos, ok, val16, 4, true) 102 } 103 104 got16, pos, ok = ReadUint16(data, 9) 105 if ok { 106 t.Errorf("ReadUint16 returned ok=true for shorter value") 107 } 108 109 data = []byte{} 110 data = AppendUint16(data, val16) 111 got16, pos, ok = ReadUint16(data, 0) 112 if !ok || got16 != val16 { 113 t.Errorf("AppendUint16 returned %v%v%v, but expected %v%v%v", got16, pos, ok, val16, 2, true) 114 } 115 } 116 117 func TestEncBytes(t *testing.T) { 118 data := make([]byte, 10) 119 120 if got := WriteByte(data, 5, 0xab); got != 6 || data[5] != 0xab { 121 t.Errorf("WriteByte returned bad result: %v %v", got, data[5]) 122 } 123 124 got, pos, ok := ReadByte(data, 5) 125 if !ok || got != 0xab || pos != 6 { 126 t.Errorf("ReadByte returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, 0xab, 6, true) 127 } 128 129 got, pos, ok = ReadByte(data, 10) 130 if ok { 131 t.Errorf("ReadByte returned ok=true for shorter value") 132 } 133 134 b, pos, ok := ReadBytes(data, 5, 2) 135 expected := []byte{0xab, 0x00} 136 if !ok || !bytes.Equal(b, expected) || pos != 7 { 137 t.Errorf("ReadBytes returned %v/%v/%v but expected %v/%v/%v", b, pos, ok, expected, 7, true) 138 } 139 140 b, pos, ok = ReadBytes(data, 9, 2) 141 if ok { 142 t.Errorf("ReadBytes returned ok=true for shorter value") 143 } 144 } 145 146 func TestEncUint32(t *testing.T) { 147 data := make([]byte, 10) 148 149 val32 := uint32(0xabcdef10) 150 151 if got := WriteUint32(data, 2, val32); got != 6 { 152 t.Errorf("WriteUint32 returned %v but expected 6", got) 153 } 154 155 if data[2] != 0x10 || data[3] != 0xef || data[4] != 0xcd || data[5] != 0xab { 156 t.Errorf("WriteUint32 returned bad result: %v", data) 157 } 158 159 got32, pos, ok := ReadUint32(data, 2) 160 if !ok || got32 != val32 || pos != 6 { 161 t.Errorf("ReadUint32 returned %v/%v/%v but expected %v/%v/%v", got32, pos, ok, val32, 6, true) 162 } 163 164 got32, pos, ok = ReadUint32(data, 7) 165 if ok { 166 t.Errorf("ReadUint32 returned ok=true for shorter value") 167 } 168 169 data = []byte{} 170 data = AppendUint32(data, val32) 171 got32, pos, ok = ReadUint32(data, 0) 172 if !ok || got32 != val32 { 173 t.Errorf("AppendUint32 returned %v%v%v, but expected %v%v%v", got32, pos, ok, val32, 4, true) 174 } 175 } 176 177 func TestEncUint64(t *testing.T) { 178 data := make([]byte, 10) 179 180 val64 := uint64(0xabcdef1011121314) 181 182 if got := WriteUint64(data, 1, val64); got != 9 { 183 t.Errorf("writeUint64 returned %v but expected 9", got) 184 } 185 186 if data[1] != 0x14 || data[2] != 0x13 || data[3] != 0x12 || data[4] != 0x11 || 187 data[5] != 0x10 || data[6] != 0xef || data[7] != 0xcd || data[8] != 0xab { 188 t.Errorf("writeUint64 returned bad result: %v", data) 189 } 190 191 got64, pos, ok := ReadUint64(data, 1) 192 if !ok || got64 != val64 || pos != 9 { 193 t.Errorf("ReadUint64 returned %v/%v/%v but expected %v/%v/%v", got64, pos, ok, val64, 6, true) 194 } 195 196 got64, pos, ok = ReadUint64(data, 7) 197 if ok { 198 t.Errorf("ReadUint64 returned ok=true for shorter value") 199 } 200 201 data = []byte{} 202 data = AppendUint64(data, val64) 203 got64, pos, ok = ReadUint64(data, 0) 204 if !ok || got64 != val64 { 205 t.Errorf("AppendUint64 returned %v%v%v, but expected %v%v%v", got64, pos, ok, val64, 2, true) 206 } 207 } 208 209 func TestEncString(t *testing.T) { 210 tests := []struct { 211 value string 212 lenEncoded []byte 213 nullEncoded []byte 214 }{ 215 { 216 "", 217 []byte{0x00}, 218 []byte{0x00}, 219 }, 220 { 221 "a", 222 []byte{0x01, 'a'}, 223 []byte{'a', 0x00}, 224 }, 225 { 226 "0123456789", 227 []byte{0x0a, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}, 228 []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0x00}, 229 }, 230 } 231 for _, test := range tests { 232 // len encoded tests. 233 234 // Check LenEncStringSize first. 235 if got := LenEncStringSize(test.value); got != len(test.lenEncoded) { 236 t.Errorf("LenEncStringSize returned %v but expected %v for %v", got, len(test.lenEncoded), test.value) 237 } 238 239 // Check LenNullString 240 if got := LenNullString(test.value); got != len(test.nullEncoded) { 241 t.Errorf("LenNullString returned %v but expected %v for %v", got, len(test.nullEncoded), test.value) 242 } 243 244 // Check successful encoding. 245 data := make([]byte, len(test.lenEncoded)) 246 pos := WriteLenEncString(data, 0, test.value) 247 if pos != len(test.lenEncoded) { 248 t.Errorf("unexpected pos %v after WriteLenEncString(%v), expected %v", pos, test.value, len(test.lenEncoded)) 249 } 250 if !bytes.Equal(data, test.lenEncoded) { 251 t.Errorf("unexpected lenEncoded value for %v, got %v expected %v", test.value, data, test.lenEncoded) 252 } 253 254 // Check successful encoding with offset. 255 data = make([]byte, len(test.lenEncoded)+1) 256 pos = WriteLenEncString(data, 1, test.value) 257 if pos != len(test.lenEncoded)+1 { 258 t.Errorf("unexpected pos %v after WriteLenEncString(%v, 1), expected %v", pos, test.value, len(test.lenEncoded)+1) 259 } 260 if !bytes.Equal(data[1:], test.lenEncoded) { 261 t.Errorf("unexpected lenEncoded value for %v, got %v expected %v", test.value, data[1:], test.lenEncoded) 262 } 263 264 // Check succesful decoding as string. 265 got, pos, ok := readLenEncString(test.lenEncoded, 0) 266 if !ok || got != test.value || pos != len(test.lenEncoded) { 267 t.Errorf("readLenEncString returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, test.value, len(test.lenEncoded), true) 268 } 269 270 // Check failed decoding with shorter data. 271 got, pos, ok = readLenEncString(test.lenEncoded[:len(test.lenEncoded)-1], 0) 272 if ok { 273 t.Errorf("readLenEncString returned ok=true for shorter value %v", test.value) 274 } 275 276 // Check failed decoding with no data. 277 got, pos, ok = readLenEncString([]byte{}, 0) 278 if ok { 279 t.Errorf("readLenEncString returned ok=true for empty value %v", test.value) 280 } 281 282 // Check succesful skipping as string. 283 pos, ok = skipLenEncString(test.lenEncoded, 0) 284 if !ok || pos != len(test.lenEncoded) { 285 t.Errorf("skipLenEncString returned %v/%v but expected %v/%v", pos, ok, len(test.lenEncoded), true) 286 } 287 288 // Check failed skipping with shorter data. 289 pos, ok = skipLenEncString(test.lenEncoded[:len(test.lenEncoded)-1], 0) 290 if ok { 291 t.Errorf("skipLenEncString returned ok=true for shorter value %v", test.value) 292 } 293 294 // Check failed skipping with no data. 295 pos, ok = skipLenEncString([]byte{}, 0) 296 if ok { 297 t.Errorf("skipLenEncString returned ok=true for empty value %v", test.value) 298 } 299 300 // Check succesful decoding as bytes. 301 gotb, pos, _, ok := ReadLenEncStringAsBytes(test.lenEncoded, 0) 302 if !ok || string(gotb) != test.value || pos != len(test.lenEncoded) { 303 t.Errorf("readLenEncString returned %v/%v/%v but expected %v/%v/%v", gotb, pos, ok, test.value, len(test.lenEncoded), true) 304 } 305 306 // Check failed decoding as bytes with shorter data. 307 gotb, pos, _, ok = ReadLenEncStringAsBytes(test.lenEncoded[:len(test.lenEncoded)-1], 0) 308 if ok { 309 t.Errorf("ReadLenEncStringAsBytes returned ok=true for shorter value %v", test.value) 310 } 311 312 // Check failed decoding as bytes with no data. 313 gotb, pos, _, ok = ReadLenEncStringAsBytes([]byte{}, 0) 314 if ok { 315 t.Errorf("ReadLenEncStringAsBytes returned ok=true for empty value %v", test.value) 316 } 317 318 // null encoded tests. 319 320 // Check successful encoding. 321 data = make([]byte, len(test.nullEncoded)) 322 pos = WriteNullString(data, 0, test.value) 323 if pos != len(test.nullEncoded) { 324 t.Errorf("unexpected pos %v after WriteNullString(%v), expected %v", pos, test.value, len(test.nullEncoded)) 325 } 326 if !bytes.Equal(data, test.nullEncoded) { 327 t.Errorf("unexpected nullEncoded value for %v, got %v expected %v", test.value, data, test.nullEncoded) 328 } 329 330 // Check succesful decoding. 331 got, pos, ok = ReadNullString(test.nullEncoded, 0) 332 if !ok || got != test.value || pos != len(test.nullEncoded) { 333 t.Errorf("ReadNullString returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, test.value, len(test.nullEncoded), true) 334 } 335 336 // Check failed decoding with shorter data. 337 got, pos, ok = ReadNullString(test.nullEncoded[:len(test.nullEncoded)-1], 0) 338 if ok { 339 t.Errorf("ReadNullString returned ok=true for shorter value %v", test.value) 340 } 341 342 // EOF encoded tests. 343 // We use the nullEncoded value, removing the 0 at the end. 344 345 // Check successful encoding. 346 data = make([]byte, len(test.nullEncoded)-1) 347 pos = writeEOFString(data, 0, test.value) 348 if pos != len(test.nullEncoded)-1 { 349 t.Errorf("unexpected pos %v after writeEOFString(%v), expected %v", pos, test.value, len(test.nullEncoded)-1) 350 } 351 if !bytes.Equal(data, test.nullEncoded[:len(test.nullEncoded)-1]) { 352 t.Errorf("unexpected nullEncoded value for %v, got %v expected %v", test.value, data, test.nullEncoded) 353 } 354 355 data = make([]byte, 0, len(test.lenEncoded)+1) 356 data = AppendLenEncStringBytes(data, []byte(test.value)) 357 if !bytes.Equal(data, test.lenEncoded) { 358 t.Errorf("test AppendLenEncStringBytes failed, got: %v, want: %v", data, test.lenEncoded) 359 } 360 } 361 }