vitess.io/vitess@v0.16.2/go/vt/wrangler/testlib/reparent_utils_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 testlib 18 19 import ( 20 "testing" 21 "time" 22 23 "vitess.io/vitess/go/vt/vtctl/reparentutil/reparenttestutil" 24 25 "vitess.io/vitess/go/vt/discovery" 26 "vitess.io/vitess/go/vt/vtctl/reparentutil" 27 28 "context" 29 30 "vitess.io/vitess/go/mysql" 31 "vitess.io/vitess/go/vt/logutil" 32 "vitess.io/vitess/go/vt/topo" 33 "vitess.io/vitess/go/vt/topo/memorytopo" 34 "vitess.io/vitess/go/vt/topo/topoproto" 35 "vitess.io/vitess/go/vt/vttablet/tmclient" 36 "vitess.io/vitess/go/vt/wrangler" 37 38 topodatapb "vitess.io/vitess/go/vt/proto/topodata" 39 ) 40 41 func TestShardReplicationStatuses(t *testing.T) { 42 delay := discovery.GetTabletPickerRetryDelay() 43 defer func() { 44 discovery.SetTabletPickerRetryDelay(delay) 45 }() 46 discovery.SetTabletPickerRetryDelay(5 * time.Millisecond) 47 48 ctx := context.Background() 49 ts := memorytopo.NewServer("cell1", "cell2") 50 wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) 51 52 // create shard and tablets 53 if _, err := ts.GetOrCreateShard(ctx, "test_keyspace", "0"); err != nil { 54 t.Fatalf("GetOrCreateShard failed: %v", err) 55 } 56 primary := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_PRIMARY, nil) 57 replica := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) 58 59 // mark the primary inside the shard 60 if _, err := ts.UpdateShardFields(ctx, "test_keyspace", "0", func(si *topo.ShardInfo) error { 61 si.PrimaryAlias = primary.Tablet.Alias 62 return nil 63 }); err != nil { 64 t.Fatalf("UpdateShardFields failed: %v", err) 65 } 66 67 // primary action loop (to initialize host and port) 68 primary.FakeMysqlDaemon.CurrentPrimaryPosition = mysql.Position{ 69 GTIDSet: mysql.MariadbGTIDSet{ 70 5: mysql.MariadbGTID{ 71 Domain: 5, 72 Server: 456, 73 Sequence: 892, 74 }, 75 }, 76 } 77 primary.StartActionLoop(t, wr) 78 defer primary.StopActionLoop(t) 79 80 // replica loop 81 replica.FakeMysqlDaemon.CurrentPrimaryPosition = mysql.Position{ 82 GTIDSet: mysql.MariadbGTIDSet{ 83 5: mysql.MariadbGTID{ 84 Domain: 5, 85 Server: 456, 86 Sequence: 890, 87 }, 88 }, 89 } 90 replica.FakeMysqlDaemon.CurrentSourceHost = primary.Tablet.MysqlHostname 91 replica.FakeMysqlDaemon.CurrentSourcePort = int(primary.Tablet.MysqlPort) 92 replica.FakeMysqlDaemon.SetReplicationSourceInputs = append(replica.FakeMysqlDaemon.SetReplicationSourceInputs, topoproto.MysqlAddr(primary.Tablet)) 93 replica.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ 94 // These 4 statements come from tablet startup 95 "STOP SLAVE", 96 "RESET SLAVE ALL", 97 "FAKE SET MASTER", 98 "START SLAVE", 99 } 100 replica.StartActionLoop(t, wr) 101 defer replica.StopActionLoop(t) 102 103 // run ShardReplicationStatuses 104 ti, rs, err := reparentutil.ShardReplicationStatuses(ctx, wr.TopoServer(), wr.TabletManagerClient(), "test_keyspace", "0") 105 if err != nil { 106 t.Fatalf("ShardReplicationStatuses failed: %v", err) 107 } 108 109 // check result (make primary first in the array) 110 if len(ti) != 2 || len(rs) != 2 { 111 t.Fatalf("ShardReplicationStatuses returned wrong results: %v %v", ti, rs) 112 } 113 if topoproto.TabletAliasEqual(ti[0].Alias, replica.Tablet.Alias) { 114 ti[0], ti[1] = ti[1], ti[0] 115 rs[0], rs[1] = rs[1], rs[0] 116 } 117 if !topoproto.TabletAliasEqual(ti[0].Alias, primary.Tablet.Alias) || 118 !topoproto.TabletAliasEqual(ti[1].Alias, replica.Tablet.Alias) || 119 rs[0].SourceHost != "" || 120 rs[1].SourceHost != primary.Tablet.Hostname { 121 t.Fatalf("ShardReplicationStatuses returend wrong results: %v %v", ti, rs) 122 } 123 } 124 125 func TestReparentTablet(t *testing.T) { 126 delay := discovery.GetTabletPickerRetryDelay() 127 defer func() { 128 discovery.SetTabletPickerRetryDelay(delay) 129 }() 130 discovery.SetTabletPickerRetryDelay(5 * time.Millisecond) 131 132 ctx := context.Background() 133 ts := memorytopo.NewServer("cell1", "cell2") 134 wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) 135 136 // create shard and tablets 137 if _, err := ts.GetOrCreateShard(ctx, "test_keyspace", "0"); err != nil { 138 t.Fatalf("CreateShard failed: %v", err) 139 } 140 primary := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_PRIMARY, nil) 141 replica := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) 142 reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", "semi_sync") 143 144 // mark the primary inside the shard 145 if _, err := ts.UpdateShardFields(ctx, "test_keyspace", "0", func(si *topo.ShardInfo) error { 146 si.PrimaryAlias = primary.Tablet.Alias 147 return nil 148 }); err != nil { 149 t.Fatalf("UpdateShardFields failed: %v", err) 150 } 151 152 // primary action loop (to initialize host and port) 153 primary.StartActionLoop(t, wr) 154 defer primary.StopActionLoop(t) 155 156 // replica loop 157 // We have to set the settings as replicating. Otherwise, 158 // the replication manager intervenes and tries to fix replication, 159 // which ends up making this test unpredictable. 160 replica.FakeMysqlDaemon.Replicating = true 161 replica.FakeMysqlDaemon.IOThreadRunning = true 162 replica.FakeMysqlDaemon.SetReplicationSourceInputs = append(replica.FakeMysqlDaemon.SetReplicationSourceInputs, topoproto.MysqlAddr(primary.Tablet)) 163 replica.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ 164 // These 4 statements come from tablet startup 165 "STOP SLAVE", 166 "RESET SLAVE ALL", 167 "FAKE SET MASTER", 168 "START SLAVE", 169 "STOP SLAVE", 170 "RESET SLAVE ALL", 171 "FAKE SET MASTER", 172 "START SLAVE", 173 } 174 replica.StartActionLoop(t, wr) 175 defer replica.StopActionLoop(t) 176 177 // run ReparentTablet 178 if err := wr.ReparentTablet(ctx, replica.Tablet.Alias); err != nil { 179 t.Fatalf("ReparentTablet failed: %v", err) 180 } 181 182 // check what was run 183 if err := replica.FakeMysqlDaemon.CheckSuperQueryList(); err != nil { 184 t.Fatalf("replica.FakeMysqlDaemon.CheckSuperQueryList failed: %v", err) 185 } 186 checkSemiSyncEnabled(t, false, true, replica) 187 }