vitess.io/vitess@v0.16.2/go/mysql/encoding_test.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 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 agreed to 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 "github.com/stretchr/testify/assert" 24 ) 25 26 func TestEncLenInt(t *testing.T) { 27 tests := []struct { 28 value uint64 29 encoded []byte 30 }{ 31 {0x00, []byte{0x00}}, 32 {0x0a, []byte{0x0a}}, 33 {0xfa, []byte{0xfa}}, 34 {0xfb, []byte{0xfc, 0xfb, 0x00}}, 35 {0xfc, []byte{0xfc, 0xfc, 0x00}}, 36 {0xfd, []byte{0xfc, 0xfd, 0x00}}, 37 {0xfe, []byte{0xfc, 0xfe, 0x00}}, 38 {0xff, []byte{0xfc, 0xff, 0x00}}, 39 {0x0100, []byte{0xfc, 0x00, 0x01}}, 40 {0x876a, []byte{0xfc, 0x6a, 0x87}}, 41 {0xffff, []byte{0xfc, 0xff, 0xff}}, 42 {0x010000, []byte{0xfd, 0x00, 0x00, 0x01}}, 43 {0xabcdef, []byte{0xfd, 0xef, 0xcd, 0xab}}, 44 {0xffffff, []byte{0xfd, 0xff, 0xff, 0xff}}, 45 {0x01000000, []byte{0xfe, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}}, 46 {0xa0a1a2a3a4a5a6a7, []byte{0xfe, 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0}}, 47 } 48 for _, test := range tests { 49 // Check lenEncIntSize first. 50 if got := lenEncIntSize(test.value); got != len(test.encoded) { 51 t.Errorf("lenEncIntSize returned %v but expected %v for %x", got, len(test.encoded), test.value) 52 } 53 54 // Check successful encoding. 55 data := make([]byte, len(test.encoded)) 56 pos := writeLenEncInt(data, 0, test.value) 57 assert.Equal(t, len(test.encoded), pos, "unexpected pos %v after writeLenEncInt(%x), expected %v", pos, test.value, len(test.encoded)) 58 assert.True(t, bytes.Equal(data, test.encoded), "unexpected encoded value for %x, got %v expected %v", test.value, data, test.encoded) 59 60 // Check successful encoding with offset. 61 data = make([]byte, len(test.encoded)+1) 62 pos = writeLenEncInt(data, 1, test.value) 63 assert.Equal(t, len(test.encoded)+1, pos, "unexpected pos %v after writeLenEncInt(%x, 1), expected %v", pos, test.value, len(test.encoded)+1) 64 assert.True(t, bytes.Equal(data[1:], test.encoded), "unexpected encoded value for %x, got %v expected %v", test.value, data, test.encoded) 65 66 // Check successful decoding. 67 got, pos, ok := readLenEncInt(test.encoded, 0) 68 if !ok || got != test.value || pos != len(test.encoded) { 69 t.Errorf("readLenEncInt returned %x/%v/%v but expected %x/%v/%v", got, pos, ok, test.value, len(test.encoded), true) 70 } 71 72 // Check failed decoding. 73 _, _, ok = readLenEncInt(test.encoded[:len(test.encoded)-1], 0) 74 assert.False(t, ok, "readLenEncInt returned ok=true for shorter value %x", test.value) 75 76 } 77 } 78 79 func TestEncUint16(t *testing.T) { 80 data := make([]byte, 10) 81 82 val16 := uint16(0xabcd) 83 84 if got := writeUint16(data, 2, val16); got != 4 { 85 t.Errorf("writeUint16 returned %v but expected 4", got) 86 } 87 88 if data[2] != 0xcd || data[3] != 0xab { 89 t.Errorf("writeUint16 returned bad result: %v", data) 90 } 91 92 got16, pos, ok := readUint16(data, 2) 93 if !ok || got16 != val16 || pos != 4 { 94 t.Errorf("readUint16 returned %v/%v/%v but expected %v/%v/%v", got16, pos, ok, val16, 4, true) 95 } 96 97 _, _, ok = readUint16(data, 9) 98 assert.False(t, ok, "readUint16 returned ok=true for shorter value") 99 100 } 101 102 func TestEncBytes(t *testing.T) { 103 data := make([]byte, 10) 104 105 if got := writeByte(data, 5, 0xab); got != 6 || data[5] != 0xab { 106 t.Errorf("writeByte returned bad result: %v %v", got, data[5]) 107 } 108 109 got, pos, ok := readByte(data, 5) 110 if !ok || got != 0xab || pos != 6 { 111 t.Errorf("readByte returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, 0xab, 6, true) 112 } 113 114 _, _, ok = readByte(data, 10) 115 assert.False(t, ok, "readByte returned ok=true for shorter value") 116 117 b, pos, ok := readBytes(data, 5, 2) 118 expected := []byte{0xab, 0x00} 119 if !ok || !bytes.Equal(b, expected) || pos != 7 { 120 t.Errorf("readBytes returned %v/%v/%v but expected %v/%v/%v", b, pos, ok, expected, 7, true) 121 } 122 123 _, _, ok = readBytes(data, 9, 2) 124 assert.False(t, ok, "readBytes returned ok=true for shorter value") 125 126 } 127 128 func TestEncUint32(t *testing.T) { 129 data := make([]byte, 10) 130 131 val32 := uint32(0xabcdef10) 132 133 if got := writeUint32(data, 2, val32); got != 6 { 134 t.Errorf("writeUint32 returned %v but expected 6", got) 135 } 136 137 if data[2] != 0x10 || data[3] != 0xef || data[4] != 0xcd || data[5] != 0xab { 138 t.Errorf("writeUint32 returned bad result: %v", data) 139 } 140 141 got32, pos, ok := readUint32(data, 2) 142 if !ok || got32 != val32 || pos != 6 { 143 t.Errorf("readUint32 returned %v/%v/%v but expected %v/%v/%v", got32, pos, ok, val32, 6, true) 144 } 145 146 _, _, ok = readUint32(data, 7) 147 assert.False(t, ok, "readUint32 returned ok=true for shorter value") 148 149 } 150 151 func TestEncUint64(t *testing.T) { 152 data := make([]byte, 10) 153 154 val64 := uint64(0xabcdef1011121314) 155 156 if got := writeUint64(data, 1, val64); got != 9 { 157 t.Errorf("writeUint64 returned %v but expected 9", got) 158 } 159 160 if data[1] != 0x14 || data[2] != 0x13 || data[3] != 0x12 || data[4] != 0x11 || 161 data[5] != 0x10 || data[6] != 0xef || data[7] != 0xcd || data[8] != 0xab { 162 t.Errorf("writeUint64 returned bad result: %v", data) 163 } 164 165 got64, pos, ok := readUint64(data, 1) 166 if !ok || got64 != val64 || pos != 9 { 167 t.Errorf("readUint64 returned %v/%v/%v but expected %v/%v/%v", got64, pos, ok, val64, 6, true) 168 } 169 170 _, _, ok = readUint64(data, 7) 171 assert.False(t, ok, "readUint64 returned ok=true for shorter value") 172 173 } 174 175 func TestEncString(t *testing.T) { 176 tests := []struct { 177 value string 178 lenEncoded []byte 179 nullEncoded []byte 180 eofEncoded []byte 181 }{ 182 { 183 "", 184 []byte{0x00}, 185 []byte{0x00}, 186 []byte{}, 187 }, 188 { 189 "a", 190 []byte{0x01, 'a'}, 191 []byte{'a', 0x00}, 192 []byte{'a'}, 193 }, 194 { 195 "0123456789", 196 []byte{0x0a, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}, 197 []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0x00}, 198 []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}, 199 }, 200 } 201 for _, test := range tests { 202 // len encoded tests. 203 204 // Check lenEncStringSize first. 205 if got := lenEncStringSize(test.value); got != len(test.lenEncoded) { 206 t.Errorf("lenEncStringSize returned %v but expected %v for %v", got, len(test.lenEncoded), test.value) 207 } 208 209 // Check lenNullString 210 if got := lenNullString(test.value); got != len(test.nullEncoded) { 211 t.Errorf("lenNullString returned %v but expected %v for %v", got, len(test.nullEncoded), test.value) 212 } 213 214 // Check lenEOFString 215 if got := lenEOFString(test.value); got != len(test.eofEncoded) { 216 t.Errorf("lenNullString returned %v but expected %v for %v", got, len(test.eofEncoded), test.value) 217 } 218 219 // Check successful encoding. 220 data := make([]byte, len(test.lenEncoded)) 221 pos := writeLenEncString(data, 0, test.value) 222 assert.Equal(t, len(test.lenEncoded), pos, "unexpected pos %v after writeLenEncString(%v), expected %v", pos, test.value, len(test.lenEncoded)) 223 assert.True(t, bytes.Equal(data, test.lenEncoded), "unexpected lenEncoded value for %v, got %v expected %v", test.value, data, test.lenEncoded) 224 225 // Check successful encoding with offset. 226 data = make([]byte, len(test.lenEncoded)+1) 227 pos = writeLenEncString(data, 1, test.value) 228 assert.Equal(t, len(test.lenEncoded)+1, pos, "unexpected pos %v after writeLenEncString(%v, 1), expected %v", pos, test.value, len(test.lenEncoded)+1) 229 assert.True(t, bytes.Equal(data[1:], test.lenEncoded), "unexpected lenEncoded value for %v, got %v expected %v", test.value, data[1:], test.lenEncoded) 230 231 // Check successful decoding as string. 232 got, pos, ok := readLenEncString(test.lenEncoded, 0) 233 if !ok || got != test.value || pos != len(test.lenEncoded) { 234 t.Errorf("readLenEncString returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, test.value, len(test.lenEncoded), true) 235 } 236 237 // Check failed decoding with shorter data. 238 _, _, ok = readLenEncString(test.lenEncoded[:len(test.lenEncoded)-1], 0) 239 assert.False(t, ok, "readLenEncString returned ok=true for shorter value %v", test.value) 240 241 // Check failed decoding with no data. 242 _, _, ok = readLenEncString([]byte{}, 0) 243 assert.False(t, ok, "readLenEncString returned ok=true for empty value %v", test.value) 244 245 // Check successful skipping as string. 246 pos, ok = skipLenEncString(test.lenEncoded, 0) 247 if !ok || pos != len(test.lenEncoded) { 248 t.Errorf("skipLenEncString returned %v/%v but expected %v/%v", pos, ok, len(test.lenEncoded), true) 249 } 250 251 // Check failed skipping with shorter data. 252 _, ok = skipLenEncString(test.lenEncoded[:len(test.lenEncoded)-1], 0) 253 assert.False(t, ok, "skipLenEncString returned ok=true for shorter value %v", test.value) 254 255 // Check failed skipping with no data. 256 _, ok = skipLenEncString([]byte{}, 0) 257 assert.False(t, ok, "skipLenEncString returned ok=true for empty value %v", test.value) 258 259 // Check successful decoding as bytes. 260 gotb, pos, ok := readLenEncStringAsBytes(test.lenEncoded, 0) 261 if !ok || string(gotb) != test.value || pos != len(test.lenEncoded) { 262 t.Errorf("readLenEncString returned %v/%v/%v but expected %v/%v/%v", gotb, pos, ok, test.value, len(test.lenEncoded), true) 263 } 264 265 // Check failed decoding as bytes with shorter data. 266 _, _, ok = readLenEncStringAsBytes(test.lenEncoded[:len(test.lenEncoded)-1], 0) 267 assert.False(t, ok, "readLenEncStringAsBytes returned ok=true for shorter value %v", test.value) 268 269 // Check failed decoding as bytes with no data. 270 _, _, ok = readLenEncStringAsBytes([]byte{}, 0) 271 assert.False(t, ok, "readLenEncStringAsBytes returned ok=true for empty value %v", test.value) 272 273 // Check successful decoding as bytes. 274 gotbcopy, posCopy, ok := readLenEncStringAsBytesCopy(test.lenEncoded, 0) 275 if !ok || string(gotb) != test.value || pos != len(test.lenEncoded) { 276 t.Errorf("readLenEncString returned %v/%v/%v but expected %v/%v/%v", gotbcopy, posCopy, ok, test.value, len(test.lenEncoded), true) 277 } 278 279 // Check failed decoding as bytes with shorter data. 280 _, _, ok = readLenEncStringAsBytesCopy(test.lenEncoded[:len(test.lenEncoded)-1], 0) 281 assert.False(t, ok, "readLenEncStringAsBytes returned ok=true for shorter value %v", test.value) 282 283 // Check failed decoding as bytes with no data. 284 _, _, ok = readLenEncStringAsBytesCopy([]byte{}, 0) 285 assert.False(t, ok, "readLenEncStringAsBytes returned ok=true for empty value %v", test.value) 286 287 // null encoded tests. 288 289 // Check successful encoding. 290 data = make([]byte, len(test.nullEncoded)) 291 pos = writeNullString(data, 0, test.value) 292 assert.Equal(t, len(test.nullEncoded), pos, "unexpected pos %v after writeNullString(%v), expected %v", pos, test.value, len(test.nullEncoded)) 293 assert.True(t, bytes.Equal(data, test.nullEncoded), "unexpected nullEncoded value for %v, got %v expected %v", test.value, data, test.nullEncoded) 294 295 // Check successful decoding. 296 got, pos, ok = readNullString(test.nullEncoded, 0) 297 if !ok || got != test.value || pos != len(test.nullEncoded) { 298 t.Errorf("readNullString returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, test.value, len(test.nullEncoded), true) 299 } 300 301 // Check failed decoding with shorter data. 302 _, _, ok = readNullString(test.nullEncoded[:len(test.nullEncoded)-1], 0) 303 assert.False(t, ok, "readNullString returned ok=true for shorter value %v", test.value) 304 305 // EOF encoded tests. 306 307 // Check successful encoding. 308 data = make([]byte, len(test.eofEncoded)) 309 pos = writeEOFString(data, 0, test.value) 310 assert.Equal(t, len(test.eofEncoded), pos, "unexpected pos %v after writeEOFString(%v), expected %v", pos, test.value, len(test.eofEncoded)) 311 assert.True(t, bytes.Equal(data, test.eofEncoded[:len(test.eofEncoded)]), "unexpected eofEncoded value for %v, got %v expected %v", test.value, data, test.eofEncoded) 312 313 // Check successful decoding. 314 got, pos, ok = readEOFString(test.eofEncoded, 0) 315 if !ok || got != test.value || pos != len(test.eofEncoded) { 316 t.Errorf("readEOFString returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, test.value, len(test.eofEncoded), true) 317 } 318 } 319 }