зеркало из https://github.com/github/vitess-gh.git
367 строки
12 KiB
Go
367 строки
12 KiB
Go
/*
|
|
Copyright 2019 The Vitess Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package mysql
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
)
|
|
|
|
func TestEncLenInt(t *testing.T) {
|
|
tests := []struct {
|
|
value uint64
|
|
encoded []byte
|
|
}{
|
|
{0x00, []byte{0x00}},
|
|
{0x0a, []byte{0x0a}},
|
|
{0xfa, []byte{0xfa}},
|
|
{0xfb, []byte{0xfc, 0xfb, 0x00}},
|
|
{0xfc, []byte{0xfc, 0xfc, 0x00}},
|
|
{0xfd, []byte{0xfc, 0xfd, 0x00}},
|
|
{0xfe, []byte{0xfc, 0xfe, 0x00}},
|
|
{0xff, []byte{0xfc, 0xff, 0x00}},
|
|
{0x0100, []byte{0xfc, 0x00, 0x01}},
|
|
{0x876a, []byte{0xfc, 0x6a, 0x87}},
|
|
{0xffff, []byte{0xfc, 0xff, 0xff}},
|
|
{0x010000, []byte{0xfd, 0x00, 0x00, 0x01}},
|
|
{0xabcdef, []byte{0xfd, 0xef, 0xcd, 0xab}},
|
|
{0xffffff, []byte{0xfd, 0xff, 0xff, 0xff}},
|
|
{0x01000000, []byte{0xfe, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}},
|
|
{0xa0a1a2a3a4a5a6a7, []byte{0xfe, 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0}},
|
|
}
|
|
for _, test := range tests {
|
|
// Check lenEncIntSize first.
|
|
if got := lenEncIntSize(test.value); got != len(test.encoded) {
|
|
t.Errorf("lenEncIntSize returned %v but expected %v for %x", got, len(test.encoded), test.value)
|
|
}
|
|
|
|
// Check successful encoding.
|
|
data := make([]byte, len(test.encoded))
|
|
pos := writeLenEncInt(data, 0, test.value)
|
|
if pos != len(test.encoded) {
|
|
t.Errorf("unexpected pos %v after writeLenEncInt(%x), expected %v", pos, test.value, len(test.encoded))
|
|
}
|
|
if !bytes.Equal(data, test.encoded) {
|
|
t.Errorf("unexpected encoded value for %x, got %v expected %v", test.value, data, test.encoded)
|
|
}
|
|
|
|
// Check successful encoding with offset.
|
|
data = make([]byte, len(test.encoded)+1)
|
|
pos = writeLenEncInt(data, 1, test.value)
|
|
if pos != len(test.encoded)+1 {
|
|
t.Errorf("unexpected pos %v after writeLenEncInt(%x, 1), expected %v", pos, test.value, len(test.encoded)+1)
|
|
}
|
|
if !bytes.Equal(data[1:], test.encoded) {
|
|
t.Errorf("unexpected encoded value for %x, got %v expected %v", test.value, data, test.encoded)
|
|
}
|
|
|
|
// Check successful decoding.
|
|
got, pos, ok := readLenEncInt(test.encoded, 0)
|
|
if !ok || got != test.value || pos != len(test.encoded) {
|
|
t.Errorf("readLenEncInt returned %x/%v/%v but expected %x/%v/%v", got, pos, ok, test.value, len(test.encoded), true)
|
|
}
|
|
|
|
// Check failed decoding.
|
|
_, _, ok = readLenEncInt(test.encoded[:len(test.encoded)-1], 0)
|
|
if ok {
|
|
t.Errorf("readLenEncInt returned ok=true for shorter value %x", test.value)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestEncUint16(t *testing.T) {
|
|
data := make([]byte, 10)
|
|
|
|
val16 := uint16(0xabcd)
|
|
|
|
if got := writeUint16(data, 2, val16); got != 4 {
|
|
t.Errorf("writeUint16 returned %v but expected 4", got)
|
|
}
|
|
|
|
if data[2] != 0xcd || data[3] != 0xab {
|
|
t.Errorf("writeUint16 returned bad result: %v", data)
|
|
}
|
|
|
|
got16, pos, ok := readUint16(data, 2)
|
|
if !ok || got16 != val16 || pos != 4 {
|
|
t.Errorf("readUint16 returned %v/%v/%v but expected %v/%v/%v", got16, pos, ok, val16, 4, true)
|
|
}
|
|
|
|
_, _, ok = readUint16(data, 9)
|
|
if ok {
|
|
t.Errorf("readUint16 returned ok=true for shorter value")
|
|
}
|
|
}
|
|
|
|
func TestEncBytes(t *testing.T) {
|
|
data := make([]byte, 10)
|
|
|
|
if got := writeByte(data, 5, 0xab); got != 6 || data[5] != 0xab {
|
|
t.Errorf("writeByte returned bad result: %v %v", got, data[5])
|
|
}
|
|
|
|
got, pos, ok := readByte(data, 5)
|
|
if !ok || got != 0xab || pos != 6 {
|
|
t.Errorf("readByte returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, 0xab, 6, true)
|
|
}
|
|
|
|
_, _, ok = readByte(data, 10)
|
|
if ok {
|
|
t.Errorf("readByte returned ok=true for shorter value")
|
|
}
|
|
|
|
b, pos, ok := readBytes(data, 5, 2)
|
|
expected := []byte{0xab, 0x00}
|
|
if !ok || !bytes.Equal(b, expected) || pos != 7 {
|
|
t.Errorf("readBytes returned %v/%v/%v but expected %v/%v/%v", b, pos, ok, expected, 7, true)
|
|
}
|
|
|
|
_, _, ok = readBytes(data, 9, 2)
|
|
if ok {
|
|
t.Errorf("readBytes returned ok=true for shorter value")
|
|
}
|
|
}
|
|
|
|
func TestEncUint32(t *testing.T) {
|
|
data := make([]byte, 10)
|
|
|
|
val32 := uint32(0xabcdef10)
|
|
|
|
if got := writeUint32(data, 2, val32); got != 6 {
|
|
t.Errorf("writeUint32 returned %v but expected 6", got)
|
|
}
|
|
|
|
if data[2] != 0x10 || data[3] != 0xef || data[4] != 0xcd || data[5] != 0xab {
|
|
t.Errorf("writeUint32 returned bad result: %v", data)
|
|
}
|
|
|
|
got32, pos, ok := readUint32(data, 2)
|
|
if !ok || got32 != val32 || pos != 6 {
|
|
t.Errorf("readUint32 returned %v/%v/%v but expected %v/%v/%v", got32, pos, ok, val32, 6, true)
|
|
}
|
|
|
|
_, _, ok = readUint32(data, 7)
|
|
if ok {
|
|
t.Errorf("readUint32 returned ok=true for shorter value")
|
|
}
|
|
}
|
|
|
|
func TestEncUint64(t *testing.T) {
|
|
data := make([]byte, 10)
|
|
|
|
val64 := uint64(0xabcdef1011121314)
|
|
|
|
if got := writeUint64(data, 1, val64); got != 9 {
|
|
t.Errorf("writeUint64 returned %v but expected 9", got)
|
|
}
|
|
|
|
if data[1] != 0x14 || data[2] != 0x13 || data[3] != 0x12 || data[4] != 0x11 ||
|
|
data[5] != 0x10 || data[6] != 0xef || data[7] != 0xcd || data[8] != 0xab {
|
|
t.Errorf("writeUint64 returned bad result: %v", data)
|
|
}
|
|
|
|
got64, pos, ok := readUint64(data, 1)
|
|
if !ok || got64 != val64 || pos != 9 {
|
|
t.Errorf("readUint64 returned %v/%v/%v but expected %v/%v/%v", got64, pos, ok, val64, 6, true)
|
|
}
|
|
|
|
_, _, ok = readUint64(data, 7)
|
|
if ok {
|
|
t.Errorf("readUint64 returned ok=true for shorter value")
|
|
}
|
|
}
|
|
|
|
func TestEncString(t *testing.T) {
|
|
tests := []struct {
|
|
value string
|
|
lenEncoded []byte
|
|
nullEncoded []byte
|
|
eofEncoded []byte
|
|
}{
|
|
{
|
|
"",
|
|
[]byte{0x00},
|
|
[]byte{0x00},
|
|
[]byte{},
|
|
},
|
|
{
|
|
"a",
|
|
[]byte{0x01, 'a'},
|
|
[]byte{'a', 0x00},
|
|
[]byte{'a'},
|
|
},
|
|
{
|
|
"0123456789",
|
|
[]byte{0x0a, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'},
|
|
[]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0x00},
|
|
[]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'},
|
|
},
|
|
}
|
|
for _, test := range tests {
|
|
// len encoded tests.
|
|
|
|
// Check lenEncStringSize first.
|
|
if got := lenEncStringSize(test.value); got != len(test.lenEncoded) {
|
|
t.Errorf("lenEncStringSize returned %v but expected %v for %v", got, len(test.lenEncoded), test.value)
|
|
}
|
|
|
|
// Check lenNullString
|
|
if got := lenNullString(test.value); got != len(test.nullEncoded) {
|
|
t.Errorf("lenNullString returned %v but expected %v for %v", got, len(test.nullEncoded), test.value)
|
|
}
|
|
|
|
// Check lenEOFString
|
|
if got := lenEOFString(test.value); got != len(test.eofEncoded) {
|
|
t.Errorf("lenNullString returned %v but expected %v for %v", got, len(test.eofEncoded), test.value)
|
|
}
|
|
|
|
// Check successful encoding.
|
|
data := make([]byte, len(test.lenEncoded))
|
|
pos := writeLenEncString(data, 0, test.value)
|
|
if pos != len(test.lenEncoded) {
|
|
t.Errorf("unexpected pos %v after writeLenEncString(%v), expected %v", pos, test.value, len(test.lenEncoded))
|
|
}
|
|
if !bytes.Equal(data, test.lenEncoded) {
|
|
t.Errorf("unexpected lenEncoded value for %v, got %v expected %v", test.value, data, test.lenEncoded)
|
|
}
|
|
|
|
// Check successful encoding with offset.
|
|
data = make([]byte, len(test.lenEncoded)+1)
|
|
pos = writeLenEncString(data, 1, test.value)
|
|
if pos != len(test.lenEncoded)+1 {
|
|
t.Errorf("unexpected pos %v after writeLenEncString(%v, 1), expected %v", pos, test.value, len(test.lenEncoded)+1)
|
|
}
|
|
if !bytes.Equal(data[1:], test.lenEncoded) {
|
|
t.Errorf("unexpected lenEncoded value for %v, got %v expected %v", test.value, data[1:], test.lenEncoded)
|
|
}
|
|
|
|
// Check successful decoding as string.
|
|
got, pos, ok := readLenEncString(test.lenEncoded, 0)
|
|
if !ok || got != test.value || pos != len(test.lenEncoded) {
|
|
t.Errorf("readLenEncString returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, test.value, len(test.lenEncoded), true)
|
|
}
|
|
|
|
// Check failed decoding with shorter data.
|
|
_, _, ok = readLenEncString(test.lenEncoded[:len(test.lenEncoded)-1], 0)
|
|
if ok {
|
|
t.Errorf("readLenEncString returned ok=true for shorter value %v", test.value)
|
|
}
|
|
|
|
// Check failed decoding with no data.
|
|
_, _, ok = readLenEncString([]byte{}, 0)
|
|
if ok {
|
|
t.Errorf("readLenEncString returned ok=true for empty value %v", test.value)
|
|
}
|
|
|
|
// Check successful skipping as string.
|
|
pos, ok = skipLenEncString(test.lenEncoded, 0)
|
|
if !ok || pos != len(test.lenEncoded) {
|
|
t.Errorf("skipLenEncString returned %v/%v but expected %v/%v", pos, ok, len(test.lenEncoded), true)
|
|
}
|
|
|
|
// Check failed skipping with shorter data.
|
|
_, ok = skipLenEncString(test.lenEncoded[:len(test.lenEncoded)-1], 0)
|
|
if ok {
|
|
t.Errorf("skipLenEncString returned ok=true for shorter value %v", test.value)
|
|
}
|
|
|
|
// Check failed skipping with no data.
|
|
_, ok = skipLenEncString([]byte{}, 0)
|
|
if ok {
|
|
t.Errorf("skipLenEncString returned ok=true for empty value %v", test.value)
|
|
}
|
|
|
|
// Check successful decoding as bytes.
|
|
gotb, pos, ok := readLenEncStringAsBytes(test.lenEncoded, 0)
|
|
if !ok || string(gotb) != test.value || pos != len(test.lenEncoded) {
|
|
t.Errorf("readLenEncString returned %v/%v/%v but expected %v/%v/%v", gotb, pos, ok, test.value, len(test.lenEncoded), true)
|
|
}
|
|
|
|
// Check failed decoding as bytes with shorter data.
|
|
_, _, ok = readLenEncStringAsBytes(test.lenEncoded[:len(test.lenEncoded)-1], 0)
|
|
if ok {
|
|
t.Errorf("readLenEncStringAsBytes returned ok=true for shorter value %v", test.value)
|
|
}
|
|
|
|
// Check failed decoding as bytes with no data.
|
|
_, _, ok = readLenEncStringAsBytes([]byte{}, 0)
|
|
if ok {
|
|
t.Errorf("readLenEncStringAsBytes returned ok=true for empty value %v", test.value)
|
|
}
|
|
|
|
// Check successful decoding as bytes.
|
|
gotbcopy, posCopy, ok := readLenEncStringAsBytesCopy(test.lenEncoded, 0)
|
|
if !ok || string(gotb) != test.value || pos != len(test.lenEncoded) {
|
|
t.Errorf("readLenEncString returned %v/%v/%v but expected %v/%v/%v", gotbcopy, posCopy, ok, test.value, len(test.lenEncoded), true)
|
|
}
|
|
|
|
// Check failed decoding as bytes with shorter data.
|
|
_, _, ok = readLenEncStringAsBytesCopy(test.lenEncoded[:len(test.lenEncoded)-1], 0)
|
|
if ok {
|
|
t.Errorf("readLenEncStringAsBytes returned ok=true for shorter value %v", test.value)
|
|
}
|
|
|
|
// Check failed decoding as bytes with no data.
|
|
_, _, ok = readLenEncStringAsBytesCopy([]byte{}, 0)
|
|
if ok {
|
|
t.Errorf("readLenEncStringAsBytes returned ok=true for empty value %v", test.value)
|
|
}
|
|
|
|
// null encoded tests.
|
|
|
|
// Check successful encoding.
|
|
data = make([]byte, len(test.nullEncoded))
|
|
pos = writeNullString(data, 0, test.value)
|
|
if pos != len(test.nullEncoded) {
|
|
t.Errorf("unexpected pos %v after writeNullString(%v), expected %v", pos, test.value, len(test.nullEncoded))
|
|
}
|
|
if !bytes.Equal(data, test.nullEncoded) {
|
|
t.Errorf("unexpected nullEncoded value for %v, got %v expected %v", test.value, data, test.nullEncoded)
|
|
}
|
|
|
|
// Check successful decoding.
|
|
got, pos, ok = readNullString(test.nullEncoded, 0)
|
|
if !ok || got != test.value || pos != len(test.nullEncoded) {
|
|
t.Errorf("readNullString returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, test.value, len(test.nullEncoded), true)
|
|
}
|
|
|
|
// Check failed decoding with shorter data.
|
|
_, _, ok = readNullString(test.nullEncoded[:len(test.nullEncoded)-1], 0)
|
|
if ok {
|
|
t.Errorf("readNullString returned ok=true for shorter value %v", test.value)
|
|
}
|
|
|
|
// EOF encoded tests.
|
|
|
|
// Check successful encoding.
|
|
data = make([]byte, len(test.eofEncoded))
|
|
pos = writeEOFString(data, 0, test.value)
|
|
if pos != len(test.eofEncoded) {
|
|
t.Errorf("unexpected pos %v after writeEOFString(%v), expected %v", pos, test.value, len(test.eofEncoded))
|
|
}
|
|
if !bytes.Equal(data, test.eofEncoded[:len(test.eofEncoded)]) {
|
|
t.Errorf("unexpected eofEncoded value for %v, got %v expected %v", test.value, data, test.eofEncoded)
|
|
}
|
|
|
|
// Check successful decoding.
|
|
got, pos, ok = readEOFString(test.eofEncoded, 0)
|
|
if !ok || got != test.value || pos != len(test.eofEncoded) {
|
|
t.Errorf("readEOFString returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, test.value, len(test.eofEncoded), true)
|
|
}
|
|
}
|
|
}
|