vitess.io/vitess@v0.16.2/go/test/endtoend/mysqlctl/mysqlctl_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 mysqlctl 18 19 import ( 20 "flag" 21 "fmt" 22 "os" 23 "os/exec" 24 "testing" 25 26 "github.com/stretchr/testify/require" 27 28 "vitess.io/vitess/go/test/endtoend/cluster" 29 ) 30 31 var ( 32 clusterInstance *cluster.LocalProcessCluster 33 primaryTablet cluster.Vttablet 34 replicaTablet cluster.Vttablet 35 hostname = "localhost" 36 keyspaceName = "test_keyspace" 37 shardName = "0" 38 cell = "zone1" 39 ) 40 41 func TestMain(m *testing.M) { 42 defer cluster.PanicHandler(nil) 43 flag.Parse() 44 45 exitCode := func() int { 46 clusterInstance = cluster.NewCluster(cell, hostname) 47 defer clusterInstance.Teardown() 48 49 // Start topo server 50 err := clusterInstance.StartTopo() 51 if err != nil { 52 return 1 53 } 54 55 if err := clusterInstance.VtctlProcess.CreateKeyspace(keyspaceName); err != nil { 56 return 1 57 } 58 59 initCluster([]string{"0"}, 2) 60 61 // Collect tablet paths and ports 62 tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets 63 for _, tablet := range tablets { 64 if tablet.Type == "primary" { 65 primaryTablet = *tablet 66 } else if tablet.Type != "rdonly" { 67 replicaTablet = *tablet 68 } 69 } 70 71 return m.Run() 72 }() 73 os.Exit(exitCode) 74 } 75 76 func initCluster(shardNames []string, totalTabletsRequired int) { 77 keyspace := cluster.Keyspace{ 78 Name: keyspaceName, 79 } 80 for _, shardName := range shardNames { 81 shard := &cluster.Shard{ 82 Name: shardName, 83 } 84 var mysqlCtlProcessList []*exec.Cmd 85 for i := 0; i < totalTabletsRequired; i++ { 86 // instantiate vttablet object with reserved ports 87 tabletUID := clusterInstance.GetAndReserveTabletUID() 88 tablet := &cluster.Vttablet{ 89 TabletUID: tabletUID, 90 HTTPPort: clusterInstance.GetAndReservePort(), 91 GrpcPort: clusterInstance.GetAndReservePort(), 92 MySQLPort: clusterInstance.GetAndReservePort(), 93 Alias: fmt.Sprintf("%s-%010d", clusterInstance.Cell, tabletUID), 94 } 95 if i == 0 { // Make the first one as primary 96 tablet.Type = "primary" 97 } 98 // Start Mysqlctl process 99 tablet.MysqlctlProcess = *cluster.MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, clusterInstance.TmpDirectory) 100 proc, err := tablet.MysqlctlProcess.StartProcess() 101 if err != nil { 102 return 103 } 104 mysqlCtlProcessList = append(mysqlCtlProcessList, proc) 105 106 // start vttablet process 107 tablet.VttabletProcess = cluster.VttabletProcessInstance( 108 tablet.HTTPPort, 109 tablet.GrpcPort, 110 tablet.TabletUID, 111 clusterInstance.Cell, 112 shardName, 113 keyspaceName, 114 clusterInstance.VtctldProcess.Port, 115 tablet.Type, 116 clusterInstance.TopoProcess.Port, 117 clusterInstance.Hostname, 118 clusterInstance.TmpDirectory, 119 clusterInstance.VtTabletExtraArgs, 120 clusterInstance.DefaultCharset) 121 tablet.Alias = tablet.VttabletProcess.TabletPath 122 123 shard.Vttablets = append(shard.Vttablets, tablet) 124 } 125 for _, proc := range mysqlCtlProcessList { 126 if err := proc.Wait(); err != nil { 127 return 128 } 129 } 130 131 keyspace.Shards = append(keyspace.Shards, *shard) 132 } 133 clusterInstance.Keyspaces = append(clusterInstance.Keyspaces, keyspace) 134 } 135 136 func TestRestart(t *testing.T) { 137 defer cluster.PanicHandler(t) 138 err := primaryTablet.MysqlctlProcess.Stop() 139 require.Nil(t, err) 140 primaryTablet.MysqlctlProcess.CleanupFiles(primaryTablet.TabletUID) 141 err = primaryTablet.MysqlctlProcess.Start() 142 require.Nil(t, err) 143 } 144 145 func TestAutoDetect(t *testing.T) { 146 defer cluster.PanicHandler(t) 147 148 // Start up tablets with an empty MYSQL_FLAVOR, which means auto-detect 149 sqlFlavor := os.Getenv("MYSQL_FLAVOR") 150 os.Setenv("MYSQL_FLAVOR", "") 151 152 err := clusterInstance.Keyspaces[0].Shards[0].Vttablets[0].VttabletProcess.Setup() 153 require.Nil(t, err, "error should be nil") 154 err = clusterInstance.Keyspaces[0].Shards[0].Vttablets[1].VttabletProcess.Setup() 155 require.Nil(t, err, "error should be nil") 156 157 // Reparent tablets, which requires flavor detection 158 err = clusterInstance.VtctlclientProcess.InitializeShard(keyspaceName, shardName, cell, primaryTablet.TabletUID) 159 require.Nil(t, err, "error should be nil") 160 161 //Reset flavor 162 os.Setenv("MYSQL_FLAVOR", sqlFlavor) 163 164 }