vitess.io/vitess@v0.16.2/go/vt/vtgate/vindexes/binarymd5_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 vindexes 18 19 import ( 20 "context" 21 "encoding/hex" 22 "fmt" 23 "reflect" 24 "testing" 25 26 "github.com/stretchr/testify/assert" 27 "github.com/stretchr/testify/require" 28 29 "vitess.io/vitess/go/sqltypes" 30 "vitess.io/vitess/go/vt/key" 31 ) 32 33 var binVindex SingleColumn 34 35 func init() { 36 vindex, _ := CreateVindex("binary_md5", "binary_md5_varchar", nil) 37 binVindex = vindex.(SingleColumn) 38 } 39 40 func TestBinaryMD5Info(t *testing.T) { 41 assert.Equal(t, 1, binVindex.Cost()) 42 assert.Equal(t, "binary_md5_varchar", binVindex.String()) 43 assert.True(t, binVindex.IsUnique()) 44 assert.False(t, binVindex.NeedsVCursor()) 45 } 46 47 func TestBinaryMD5Map(t *testing.T) { 48 tcases := []struct { 49 in sqltypes.Value 50 out string 51 }{{ 52 in: sqltypes.NewVarBinary("test1"), 53 out: "Z\x10^\x8b\x9d@\xe12\x97\x80\xd6.\xa2&]\x8a", 54 }, { 55 in: sqltypes.NewVarBinary("TEST"), 56 out: "\x03;\xd9K\x11h\xd7\xe4\xf0\xd6D\xc3\xc9^5\xbf", 57 }, { 58 in: sqltypes.NULL, 59 out: "\xd4\x1d\x8cُ\x00\xb2\x04\xe9\x80\t\x98\xec\xf8B~", 60 }, { 61 in: sqltypes.NewVarBinary("Test"), 62 out: "\f\xbcf\x11\xf5T\vЀ\x9a8\x8d\xc9Za[", 63 }} 64 for _, tcase := range tcases { 65 got, err := binVindex.Map(context.Background(), nil, []sqltypes.Value{tcase.in}) 66 if err != nil { 67 t.Error(err) 68 } 69 out := string(got[0].(key.DestinationKeyspaceID)) 70 if out != tcase.out { 71 t.Errorf("Map(%#v): %#v, want %#v", tcase.in, out, tcase.out) 72 } 73 } 74 } 75 76 func TestBinaryMD5Verify(t *testing.T) { 77 hexValStr := "21cf" 78 hexValStrSQL := fmt.Sprintf("x'%s'", hexValStr) 79 hexNumStrSQL := fmt.Sprintf("0x%s", hexValStr) 80 hexBytes, _ := hex.DecodeString(hexValStr) 81 ids := []sqltypes.Value{sqltypes.NewVarBinary("Test"), sqltypes.NewVarBinary("TEst"), sqltypes.NewHexVal([]byte(hexValStrSQL)), sqltypes.NewHexNum([]byte(hexNumStrSQL))} 82 ksids := [][]byte{[]byte("\f\xbcf\x11\xf5T\vЀ\x9a8\x8d\xc9Za["), []byte("\f\xbcf\x11\xf5T\vЀ\x9a8\x8d\xc9Za["), vMD5Hash(hexBytes), vMD5Hash(hexBytes)} 83 got, err := binVindex.Verify(context.Background(), nil, ids, ksids) 84 if err != nil { 85 t.Fatal(err) 86 } 87 want := []bool{true, false, true, true} 88 if !reflect.DeepEqual(got, want) { 89 t.Errorf("binaryMD5.Verify: %v, want %v", got, want) 90 } 91 } 92 93 func TestSQLValue(t *testing.T) { 94 val := sqltypes.NewVarBinary("Test") 95 got, err := binVindex.Map(context.Background(), nil, []sqltypes.Value{val}) 96 require.NoError(t, err) 97 out := string(got[0].(key.DestinationKeyspaceID)) 98 want := "\f\xbcf\x11\xf5T\vЀ\x9a8\x8d\xc9Za[" 99 if out != want { 100 t.Errorf("Map(%#v): %#v, want %#v", val, out, want) 101 } 102 } 103 104 func BenchmarkMD5Hash(b *testing.B) { 105 for _, benchSize := range []struct { 106 name string 107 n int 108 }{ 109 {"8B", 8}, 110 {"32B", 32}, 111 {"64B", 64}, 112 {"512B", 512}, 113 {"1KB", 1e3}, 114 {"4KB", 4e3}, 115 } { 116 input := make([]byte, benchSize.n) 117 for i := range input { 118 input[i] = byte(i) 119 } 120 121 name := fmt.Sprintf("md5Hash,direct,bytes,n=%s", benchSize.name) 122 b.Run(name, func(b *testing.B) { 123 benchmarkMD5HashBytes(b, input) 124 }) 125 126 } 127 } 128 129 var sinkMD5 []byte 130 131 func benchmarkMD5HashBytes(b *testing.B, input []byte) { 132 b.SetBytes(int64(len(input))) 133 for i := 0; i < b.N; i++ { 134 sinkMD5 = vMD5Hash(input) 135 } 136 }