vitess.io/vitess@v0.16.2/go/vt/wrangler/tablet_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 wrangler 18 19 import ( 20 "context" 21 "strings" 22 "testing" 23 24 "vitess.io/vitess/go/vt/logutil" 25 topodatapb "vitess.io/vitess/go/vt/proto/topodata" 26 "vitess.io/vitess/go/vt/topo" 27 "vitess.io/vitess/go/vt/topo/memorytopo" 28 ) 29 30 // TestInitTabletShardConversion makes sure InitTablet converts the 31 // shard name to lower case when it's a keyrange, and populates 32 // KeyRange properly. 33 func TestInitTabletShardConversion(t *testing.T) { 34 cell := "cell1" 35 ts := memorytopo.NewServer(cell) 36 wr := New(logutil.NewConsoleLogger(), ts, nil) 37 38 tablet := &topodatapb.Tablet{ 39 Alias: &topodatapb.TabletAlias{ 40 Cell: cell, 41 Uid: 1, 42 }, 43 Shard: "80-C0", 44 } 45 46 if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { 47 t.Fatalf("InitTablet failed: %v", err) 48 } 49 50 ti, err := ts.GetTablet(context.Background(), tablet.Alias) 51 if err != nil { 52 t.Fatalf("GetTablet failed: %v", err) 53 } 54 if ti.Shard != "80-c0" { 55 t.Errorf("Got wrong tablet.Shard, got %v expected 80-c0", ti.Shard) 56 } 57 if string(ti.KeyRange.Start) != "\x80" || string(ti.KeyRange.End) != "\xc0" { 58 t.Errorf("Got wrong tablet.KeyRange, got %v expected 80-c0", ti.KeyRange) 59 } 60 } 61 62 // TestDeleteTabletBasic tests delete of non-primary tablet 63 func TestDeleteTabletBasic(t *testing.T) { 64 cell := "cell1" 65 ts := memorytopo.NewServer(cell) 66 wr := New(logutil.NewConsoleLogger(), ts, nil) 67 68 tablet := &topodatapb.Tablet{ 69 Alias: &topodatapb.TabletAlias{ 70 Cell: cell, 71 Uid: 1, 72 }, 73 Shard: "0", 74 } 75 76 if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { 77 t.Fatalf("InitTablet failed: %v", err) 78 } 79 80 if _, err := ts.GetTablet(context.Background(), tablet.Alias); err != nil { 81 t.Fatalf("GetTablet failed: %v", err) 82 } 83 84 if err := wr.DeleteTablet(context.Background(), tablet.Alias, false); err != nil { 85 t.Fatalf("DeleteTablet failed: %v", err) 86 } 87 } 88 89 // TestDeleteTabletTruePrimary tests that you can delete a true primary tablet 90 // only if allowPrimary is set to true 91 func TestDeleteTabletTruePrimary(t *testing.T) { 92 cell := "cell1" 93 ts := memorytopo.NewServer(cell) 94 wr := New(logutil.NewConsoleLogger(), ts, nil) 95 96 tablet := &topodatapb.Tablet{ 97 Alias: &topodatapb.TabletAlias{ 98 Cell: cell, 99 Uid: 1, 100 }, 101 Keyspace: "test", 102 Shard: "0", 103 Type: topodatapb.TabletType_PRIMARY, 104 } 105 106 if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { 107 t.Fatalf("InitTablet failed: %v", err) 108 } 109 if _, err := ts.GetTablet(context.Background(), tablet.Alias); err != nil { 110 t.Fatalf("GetTablet failed: %v", err) 111 } 112 113 // set PrimaryAlias and PrimaryTermStartTime on shard to match chosen primary tablet 114 if _, err := ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error { 115 si.PrimaryAlias = tablet.Alias 116 si.PrimaryTermStartTime = tablet.PrimaryTermStartTime 117 return nil 118 }); err != nil { 119 t.Fatalf("UpdateShardFields failed: %v", err) 120 } 121 122 err := wr.DeleteTablet(context.Background(), tablet.Alias, false) 123 wantError := "as it is a primary, use allow_primary flag" 124 if err == nil || !strings.Contains(err.Error(), wantError) { 125 t.Fatalf("DeleteTablet on primary: want error = %v, got error = %v", wantError, err) 126 } 127 128 if err := wr.DeleteTablet(context.Background(), tablet.Alias, true); err != nil { 129 t.Fatalf("DeleteTablet failed: %v", err) 130 } 131 } 132 133 // TestDeleteTabletFalsePrimary tests that you can delete a false primary tablet 134 // with allowPrimary set to false 135 func TestDeleteTabletFalsePrimary(t *testing.T) { 136 cell := "cell1" 137 ts := memorytopo.NewServer(cell) 138 wr := New(logutil.NewConsoleLogger(), ts, nil) 139 140 tablet1 := &topodatapb.Tablet{ 141 Alias: &topodatapb.TabletAlias{ 142 Cell: cell, 143 Uid: 1, 144 }, 145 Keyspace: "test", 146 Shard: "0", 147 Type: topodatapb.TabletType_PRIMARY, 148 } 149 150 if err := wr.TopoServer().InitTablet(context.Background(), tablet1, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { 151 t.Fatalf("InitTablet failed: %v", err) 152 } 153 154 tablet2 := &topodatapb.Tablet{ 155 Alias: &topodatapb.TabletAlias{ 156 Cell: cell, 157 Uid: 2, 158 }, 159 Keyspace: "test", 160 Shard: "0", 161 Type: topodatapb.TabletType_PRIMARY, 162 } 163 if err := wr.TopoServer().InitTablet(context.Background(), tablet2, true /*allowPrimaryOverride*/, false /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { 164 t.Fatalf("InitTablet failed: %v", err) 165 } 166 167 // set PrimaryAlias and PrimaryTermStartTime on shard to match chosen primary tablet 168 if _, err := ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error { 169 si.PrimaryAlias = tablet2.Alias 170 si.PrimaryTermStartTime = tablet2.PrimaryTermStartTime 171 return nil 172 }); err != nil { 173 t.Fatalf("UpdateShardFields failed: %v", err) 174 } 175 176 // Should be able to delete old (false) primary with allowPrimary = false 177 if err := wr.DeleteTablet(context.Background(), tablet1.Alias, false); err != nil { 178 t.Fatalf("DeleteTablet failed: %v", err) 179 } 180 } 181 182 // TestDeleteTabletShardNonExisting tests that you can delete a true primary 183 // tablet if a shard does not exists anymore. 184 func TestDeleteTabletShardNonExisting(t *testing.T) { 185 cell := "cell1" 186 ts := memorytopo.NewServer(cell) 187 wr := New(logutil.NewConsoleLogger(), ts, nil) 188 189 tablet := &topodatapb.Tablet{ 190 Alias: &topodatapb.TabletAlias{ 191 Cell: cell, 192 Uid: 1, 193 }, 194 Keyspace: "test", 195 Shard: "0", 196 Type: topodatapb.TabletType_PRIMARY, 197 } 198 199 if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { 200 t.Fatalf("InitTablet failed: %v", err) 201 } 202 if _, err := ts.GetTablet(context.Background(), tablet.Alias); err != nil { 203 t.Fatalf("GetTablet failed: %v", err) 204 } 205 206 // set PrimaryAlias and PrimaryTermStartTime on shard to match chosen primary tablet 207 if _, err := ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error { 208 si.PrimaryAlias = tablet.Alias 209 si.PrimaryTermStartTime = tablet.PrimaryTermStartTime 210 return nil 211 }); err != nil { 212 t.Fatalf("UpdateShardFields failed: %v", err) 213 } 214 215 // trigger a shard deletion 216 if err := ts.DeleteShard(context.Background(), "test", "0"); err != nil { 217 t.Fatalf("DeleteShard failed: %v", err) 218 } 219 220 // DeleteTablet should not fail if a shard no longer exist 221 if err := wr.DeleteTablet(context.Background(), tablet.Alias, true); err != nil { 222 t.Fatalf("DeleteTablet failed: %v", err) 223 } 224 }