vitess.io/vitess@v0.16.2/go/vt/vtgate/vindexes/lookup_hash_unique_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 "reflect" 22 "testing" 23 24 "github.com/stretchr/testify/assert" 25 "github.com/stretchr/testify/require" 26 27 "vitess.io/vitess/go/sqltypes" 28 "vitess.io/vitess/go/vt/key" 29 topodatapb "vitess.io/vitess/go/vt/proto/topodata" 30 ) 31 32 func TestLookupHashUniqueNew(t *testing.T) { 33 l := createLookup(t, "lookup_hash_unique", false /* writeOnly */) 34 if want, got := l.(*LookupHashUnique).writeOnly, false; got != want { 35 t.Errorf("Create(lookup, false): %v, want %v", got, want) 36 } 37 38 vindex, _ := CreateVindex("lookup_hash_unique", "lookup_hash_unique", map[string]string{ 39 "table": "t", 40 "from": "fromc", 41 "to": "toc", 42 "write_only": "true", 43 }) 44 l = vindex.(SingleColumn) 45 if want, got := l.(*LookupHashUnique).writeOnly, true; got != want { 46 t.Errorf("Create(lookup, false): %v, want %v", got, want) 47 } 48 49 _, err := CreateVindex("lookup_hash_unique", "lookup_hash_unique", map[string]string{ 50 "table": "t", 51 "from": "fromc", 52 "to": "toc", 53 "write_only": "invalid", 54 }) 55 want := "write_only value must be 'true' or 'false': 'invalid'" 56 if err == nil || err.Error() != want { 57 t.Errorf("Create(bad_scatter): %v, want %s", err, want) 58 } 59 } 60 61 func TestLookupHashUniqueInfo(t *testing.T) { 62 lhu := createLookup(t, "lookup_hash_unique", false /* writeOnly */) 63 assert.Equal(t, 10, lhu.Cost()) 64 assert.Equal(t, "lookup_hash_unique", lhu.String()) 65 assert.True(t, lhu.IsUnique()) 66 assert.True(t, lhu.NeedsVCursor()) 67 } 68 69 func TestLookupHashUniqueMap(t *testing.T) { 70 lhu := createLookup(t, "lookup_hash_unique", false /* writeOnly */) 71 vc := &vcursor{numRows: 1} 72 73 got, err := lhu.Map(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}) 74 require.NoError(t, err) 75 want := []key.Destination{ 76 key.DestinationKeyspaceID([]byte("\x16k@\xb4J\xbaK\xd6")), 77 key.DestinationNone{}, 78 } 79 if !reflect.DeepEqual(got, want) { 80 t.Errorf("Map(): %#v, want %+v", got, want) 81 } 82 83 vc.numRows = 0 84 got, err = lhu.Map(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}) 85 require.NoError(t, err) 86 want = []key.Destination{ 87 key.DestinationNone{}, 88 key.DestinationNone{}, 89 } 90 if !reflect.DeepEqual(got, want) { 91 t.Errorf("Map(): %#v, want %+v", got, want) 92 } 93 94 vc.numRows = 2 95 _, err = lhu.Map(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}) 96 wantErr := "LookupHash.Map: unexpected multiple results from vindex t: INT64(1)" 97 if err == nil || err.Error() != wantErr { 98 t.Errorf("lhu(query fail) err: %v, want %s", err, wantErr) 99 } 100 101 // Test conversion fail. 102 vc.result = sqltypes.MakeTestResult( 103 sqltypes.MakeTestFields("b|a", "bigint|varbinary"), 104 "1|notint", 105 ) 106 got, err = lhu.Map(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)}) 107 require.NoError(t, err) 108 want = []key.Destination{ 109 key.DestinationNone{}, 110 } 111 if !reflect.DeepEqual(got, want) { 112 t.Errorf("Map(): %#v, want %+v", got, want) 113 } 114 115 // Test query fail. 116 vc.mustFail = true 117 _, err = lhu.Map(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)}) 118 wantErr = "lookup.Map: execute failed" 119 if err == nil || err.Error() != wantErr { 120 t.Errorf("lhu(query fail) err: %v, want %s", err, wantErr) 121 } 122 vc.mustFail = false 123 } 124 125 func TestLookupHashUniqueMapWriteOnly(t *testing.T) { 126 lhu := createLookup(t, "lookup_hash_unique", true) 127 vc := &vcursor{numRows: 0} 128 129 got, err := lhu.Map(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}) 130 require.NoError(t, err) 131 want := []key.Destination{ 132 key.DestinationKeyRange{ 133 KeyRange: &topodatapb.KeyRange{}, 134 }, 135 key.DestinationKeyRange{ 136 KeyRange: &topodatapb.KeyRange{}, 137 }, 138 } 139 if !reflect.DeepEqual(got, want) { 140 t.Errorf("Map(): %#v, want %+v", got, want) 141 } 142 } 143 144 func TestLookupHashUniqueVerify(t *testing.T) { 145 lhu := createLookup(t, "lookup_hash_unique", false /* writeOnly */) 146 vc := &vcursor{numRows: 1} 147 148 // The check doesn't actually happen. But we give correct values 149 // to avoid confusion. 150 got, err := lhu.Verify(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}, [][]byte{[]byte("\x16k@\xb4J\xbaK\xd6"), []byte("\x06\xe7\xea\"Βp\x8f")}) 151 require.NoError(t, err) 152 want := []bool{true, true} 153 if !reflect.DeepEqual(got, want) { 154 t.Errorf("lhu.Verify(match): %v, want %v", got, want) 155 } 156 157 vc.numRows = 0 158 got, err = lhu.Verify(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)}, [][]byte{[]byte("\x16k@\xb4J\xbaK\xd6")}) 159 require.NoError(t, err) 160 want = []bool{false} 161 if !reflect.DeepEqual(got, want) { 162 t.Errorf("lhu.Verify(mismatch): %v, want %v", got, want) 163 } 164 165 _, err = lhu.Verify(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)}, [][]byte{[]byte("bogus")}) 166 wantErr := "lookup.Verify.vunhash: invalid keyspace id: 626f677573" 167 if err == nil || err.Error() != wantErr { 168 t.Errorf("lhu.Verify(bogus) err: %v, want %s", err, wantErr) 169 } 170 } 171 172 func TestLookupHashUniqueVerifyWriteOnly(t *testing.T) { 173 lhu := createLookup(t, "lookup_hash_unique", true) 174 vc := &vcursor{numRows: 0} 175 176 got, err := lhu.Verify(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)}, [][]byte{[]byte("test")}) 177 require.NoError(t, err) 178 want := []bool{true} 179 if !reflect.DeepEqual(got, want) { 180 t.Errorf("lhu.Verify: %v, want %v", got, want) 181 } 182 if got, want := len(vc.queries), 0; got != want { 183 t.Errorf("vc.queries length: %v, want %v", got, want) 184 } 185 } 186 187 func TestLookupHashUniqueCreate(t *testing.T) { 188 lhu := createLookup(t, "lookup_hash_unique", false /* writeOnly */) 189 vc := &vcursor{} 190 191 err := lhu.(Lookup).Create(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(1)}}, [][]byte{[]byte("\x16k@\xb4J\xbaK\xd6")}, false /* ignoreMode */) 192 require.NoError(t, err) 193 if got, want := len(vc.queries), 1; got != want { 194 t.Errorf("vc.queries length: %v, want %v", got, want) 195 } 196 197 err = lhu.(Lookup).Create(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(1)}}, [][]byte{[]byte("bogus")}, false /* ignoreMode */) 198 want := "lookup.Create.vunhash: invalid keyspace id: 626f677573" 199 if err == nil || err.Error() != want { 200 t.Errorf("lhu.Create(bogus) err: %v, want %s", err, want) 201 } 202 } 203 204 func TestLookupHashUniqueDelete(t *testing.T) { 205 lhu := createLookup(t, "lookup_hash_unique", false /* writeOnly */) 206 vc := &vcursor{} 207 208 err := lhu.(Lookup).Delete(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(1)}}, []byte("\x16k@\xb4J\xbaK\xd6")) 209 require.NoError(t, err) 210 if got, want := len(vc.queries), 1; got != want { 211 t.Errorf("vc.queries length: %v, want %v", got, want) 212 } 213 214 err = lhu.(Lookup).Delete(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(1)}}, []byte("bogus")) 215 want := "lookup.Delete.vunhash: invalid keyspace id: 626f677573" 216 if err == nil || err.Error() != want { 217 t.Errorf("lhu.Delete(bogus) err: %v, want %s", err, want) 218 } 219 } 220 221 func TestLookupHashUniqueUpdate(t *testing.T) { 222 lhu := createLookup(t, "lookup_hash_unique", false /* writeOnly */) 223 vc := &vcursor{} 224 225 err := lhu.(Lookup).Update(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)}, []byte("\x16k@\xb4J\xbaK\xd6"), []sqltypes.Value{sqltypes.NewInt64(2)}) 226 require.NoError(t, err) 227 if got, want := len(vc.queries), 2; got != want { 228 t.Errorf("vc.queries length: %v, want %v", got, want) 229 } 230 }