vitess.io/vitess@v0.16.2/go/test/endtoend/topoconncache/main_test.go (about) 1 /* 2 Copyright 2022 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 This test cell aliases feature 17 18 We start with no aliases and assert that vtgates can't route to replicas/rondly tablets. 19 Then we add an alias, and these tablets should be routable 20 */ 21 22 package topoconncache 23 24 import ( 25 "flag" 26 "fmt" 27 "net/http" 28 "os" 29 "os/exec" 30 "testing" 31 32 "vitess.io/vitess/go/test/endtoend/cluster" 33 ) 34 35 var ( 36 clusterInstance *cluster.LocalProcessCluster 37 cell1 = "zone1" 38 cell2 = "zone2" 39 hostname = "localhost" 40 keyspaceName = "ks" 41 tableName = "test_table" 42 sqlSchema = ` 43 create table %s( 44 id bigint(20) unsigned auto_increment, 45 msg varchar(64), 46 primary key (id), 47 index by_msg (msg) 48 ) Engine=InnoDB 49 ` 50 commonTabletArg = []string{ 51 "--vreplication_healthcheck_topology_refresh", "1s", 52 "--vreplication_healthcheck_retry_delay", "1s", 53 "--vreplication_retry_delay", "1s", 54 "--degraded_threshold", "5s", 55 "--lock_tables_timeout", "5s", 56 "--watch_replication_stream", 57 "--enable_replication_reporter", 58 "--serving_state_grace_period", "1s", 59 "--binlog_player_protocol", "grpc", 60 } 61 vSchema = ` 62 { 63 "sharded": true, 64 "vindexes": { 65 "hash_index": { 66 "type": "hash" 67 } 68 }, 69 "tables": { 70 "%s": { 71 "column_vindexes": [ 72 { 73 "column": "id", 74 "name": "hash_index" 75 } 76 ] 77 } 78 } 79 } 80 ` 81 shard1Primary *cluster.Vttablet 82 shard1Replica *cluster.Vttablet 83 shard1Rdonly *cluster.Vttablet 84 shard2Primary *cluster.Vttablet 85 shard2Replica *cluster.Vttablet 86 shard2Rdonly *cluster.Vttablet 87 88 shard1 cluster.Shard 89 shard2 cluster.Shard 90 ) 91 92 /* 93 This end-to-end test validates the cache fix in topo/server.go inside ConnForCell. 94 95 The issue was, if we delete and add back a cell with same name but at different path, the map of cells 96 in server.go returned the connection object of the previous cell instead of newly-created one 97 with the same name. 98 Topology: We create a keyspace with two shards , having 3 tablets each. Primaries belong 99 to 'zone1' and replicas/rdonly belongs to cell2. 100 */ 101 func TestMain(m *testing.M) { 102 defer cluster.PanicHandler(nil) 103 flag.Parse() 104 105 exitcode, err := func() (int, error) { 106 clusterInstance = cluster.NewCluster(cell1, hostname) 107 defer clusterInstance.Teardown() 108 clusterInstance.Keyspaces = append(clusterInstance.Keyspaces, cluster.Keyspace{ 109 Name: keyspaceName, 110 }) 111 112 // Start topo server 113 if err := clusterInstance.StartTopo(); err != nil { 114 return 1, err 115 } 116 117 // Adding another cell in the same cluster 118 err := clusterInstance.TopoProcess.ManageTopoDir("mkdir", "/vitess/"+cell2) 119 if err != nil { 120 return 1, err 121 } 122 err = clusterInstance.VtctlProcess.AddCellInfo(cell2) 123 if err != nil { 124 return 1, err 125 } 126 127 vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TmpDirectory) 128 _, err = vtctldClientProcess.ExecuteCommandWithOutput("CreateKeyspace", keyspaceName, "--durability-policy=semi_sync") 129 if err != nil { 130 return 1, err 131 } 132 133 shard1Primary = clusterInstance.NewVttabletInstance("primary", 0, cell1) 134 shard1Replica = clusterInstance.NewVttabletInstance("replica", 0, cell2) 135 shard1Rdonly = clusterInstance.NewVttabletInstance("rdonly", 0, cell2) 136 137 shard2Primary = clusterInstance.NewVttabletInstance("primary", 0, cell1) 138 shard2Replica = clusterInstance.NewVttabletInstance("replica", 0, cell2) 139 shard2Rdonly = clusterInstance.NewVttabletInstance("rdonly", 0, cell2) 140 141 var mysqlProcs []*exec.Cmd 142 for _, tablet := range []*cluster.Vttablet{shard1Primary, shard1Replica, shard1Rdonly, shard2Primary, shard2Replica, shard2Rdonly} { 143 tablet.MysqlctlProcess = *cluster.MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, clusterInstance.TmpDirectory) 144 tablet.VttabletProcess = cluster.VttabletProcessInstance(tablet.HTTPPort, 145 tablet.GrpcPort, 146 tablet.TabletUID, 147 tablet.Cell, 148 "", 149 keyspaceName, 150 clusterInstance.VtctldProcess.Port, 151 tablet.Type, 152 clusterInstance.TopoPort, 153 hostname, 154 clusterInstance.TmpDirectory, 155 commonTabletArg, 156 clusterInstance.DefaultCharset, 157 ) 158 tablet.VttabletProcess.SupportsBackup = true 159 proc, err := tablet.MysqlctlProcess.StartProcess() 160 if err != nil { 161 return 1, err 162 } 163 mysqlProcs = append(mysqlProcs, proc) 164 } 165 for _, proc := range mysqlProcs { 166 if err := proc.Wait(); err != nil { 167 return 1, err 168 } 169 } 170 171 shard1 = cluster.Shard{ 172 Name: "-80", 173 Vttablets: []*cluster.Vttablet{shard1Primary, shard1Replica, shard1Rdonly}, 174 } 175 for idx := range shard1.Vttablets { 176 shard1.Vttablets[idx].VttabletProcess.Shard = shard1.Name 177 } 178 clusterInstance.Keyspaces[0].Shards = append(clusterInstance.Keyspaces[0].Shards, shard1) 179 180 shard2 = cluster.Shard{ 181 Name: "80-", 182 Vttablets: []*cluster.Vttablet{shard2Primary, shard2Replica, shard2Rdonly}, 183 } 184 for idx := range shard2.Vttablets { 185 shard2.Vttablets[idx].VttabletProcess.Shard = shard2.Name 186 } 187 clusterInstance.Keyspaces[0].Shards = append(clusterInstance.Keyspaces[0].Shards, shard2) 188 189 for _, tablet := range shard1.Vttablets { 190 if err := tablet.VttabletProcess.Setup(); err != nil { 191 return 1, err 192 } 193 } 194 if err := clusterInstance.VtctlclientProcess.InitializeShard(keyspaceName, shard1.Name, shard1Primary.Cell, shard1Primary.TabletUID); err != nil { 195 return 1, err 196 } 197 198 // run a health check on source replica so it responds to discovery 199 // (for binlog players) and on the source rdonlys (for workers) 200 for _, tablet := range []string{shard1Replica.Alias, shard1Rdonly.Alias} { 201 if err := clusterInstance.VtctlclientProcess.ExecuteCommand("RunHealthCheck", tablet); err != nil { 202 return 1, err 203 } 204 } 205 206 for _, tablet := range shard2.Vttablets { 207 if err := tablet.VttabletProcess.Setup(); err != nil { 208 return 1, err 209 } 210 } 211 212 if err := clusterInstance.VtctlclientProcess.InitializeShard(keyspaceName, shard2.Name, shard2Primary.Cell, shard2Primary.TabletUID); err != nil { 213 return 1, err 214 } 215 216 if err := clusterInstance.StartVTOrc(keyspaceName); err != nil { 217 return 1, err 218 } 219 220 if err := clusterInstance.VtctlclientProcess.ApplySchema(keyspaceName, fmt.Sprintf(sqlSchema, tableName)); err != nil { 221 return 1, err 222 } 223 if err := clusterInstance.VtctlclientProcess.ApplyVSchema(keyspaceName, fmt.Sprintf(vSchema, tableName)); err != nil { 224 return 1, err 225 } 226 227 _ = clusterInstance.VtctlclientProcess.ExecuteCommand("RebuildKeyspaceGraph", keyspaceName) 228 229 return m.Run(), nil 230 }() 231 if err != nil { 232 fmt.Printf("%v\n", err) 233 os.Exit(1) 234 } else { 235 os.Exit(exitcode) 236 } 237 } 238 239 func testURL(t *testing.T, url string, testCaseName string) { 240 statusCode := getStatusForURL(url) 241 if got, want := statusCode, 200; got != want { 242 t.Errorf("\nurl: %v\nstatus code: %v \nwant %v for %s", url, got, want, testCaseName) 243 } 244 } 245 246 // getStatusForUrl returns the status code for the URL 247 func getStatusForURL(url string) int { 248 resp, err := http.Get(url) 249 if err != nil { 250 return 0 251 } 252 defer resp.Body.Close() 253 return resp.StatusCode 254 }