github.com/pingcap/tiup@v1.15.1/components/cluster/command/test.go (about) 1 // Copyright 2020 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package command 15 16 import ( 17 "context" 18 "errors" 19 "fmt" 20 21 perrs "github.com/pingcap/errors" 22 "github.com/pingcap/tiup/pkg/cluster/spec" 23 "github.com/pingcap/tiup/pkg/meta" 24 "github.com/pingcap/tiup/pkg/proxy" 25 "github.com/pingcap/tiup/pkg/utils" 26 "github.com/spf13/cobra" 27 "golang.org/x/sync/errgroup" 28 29 // for sql/driver 30 _ "github.com/go-sql-driver/mysql" 31 ) 32 33 func newTestCmd() *cobra.Command { 34 cmd := &cobra.Command{ 35 Use: "_test <cluster-name>", 36 Short: "test toolkit", 37 Hidden: true, 38 RunE: func(cmd *cobra.Command, args []string) error { 39 if len(args) < 1 { 40 return cmd.Help() 41 } 42 43 clusterName := args[0] 44 45 exist, err := tidbSpec.Exist(clusterName) 46 if err != nil { 47 return err 48 } 49 50 if !exist { 51 return perrs.Errorf("cannot start non-exists cluster %s", clusterName) 52 } 53 54 metadata, err := spec.ClusterMetadata(clusterName) 55 if err != nil && !errors.Is(perrs.Cause(err), meta.ErrValidate) { 56 return err 57 } 58 59 tcpProxy := proxy.GetTCPProxy() 60 switch args[1] { 61 case "writable": 62 return writable(metadata.Topology, tcpProxy) 63 case "data": 64 return data(metadata.Topology, tcpProxy) 65 default: 66 fmt.Println("unknown command: ", args[1]) 67 return cmd.Help() 68 } 69 }, 70 } 71 72 return cmd 73 } 74 75 // To check if test.ti_cluster has data 76 func data(topo *spec.Specification, tcpProxy *proxy.TCPProxy) error { 77 errg, _ := errgroup.WithContext(context.Background()) 78 79 for _, spec := range topo.TiDBServers { 80 spec := spec 81 endpoint := utils.JoinHostPort(spec.Host, spec.Port) 82 errg.Go(func() error { 83 if tcpProxy != nil { 84 closeC := tcpProxy.Run([]string{endpoint}) 85 defer tcpProxy.Close(closeC) 86 endpoint = tcpProxy.GetEndpoints()[0] 87 } 88 db, err := createDB(endpoint) 89 if err != nil { 90 return err 91 } 92 93 row := db.QueryRow("select count(*) from test.ti_cluster") 94 count := 0 95 if err := row.Scan(&count); err != nil { 96 return err 97 } 98 99 if count == 0 { 100 return errors.New("table test.ti_cluster is empty") 101 } 102 103 fmt.Printf("check data %s success\n", utils.JoinHostPort(spec.Host, spec.Port)) 104 return nil 105 }) 106 } 107 108 return errg.Wait() 109 } 110 111 func writable(topo *spec.Specification, tcpProxy *proxy.TCPProxy) error { 112 errg, _ := errgroup.WithContext(context.Background()) 113 114 for _, spec := range topo.TiDBServers { 115 spec := spec 116 endpoint := utils.JoinHostPort(spec.Host, spec.Port) 117 errg.Go(func() error { 118 if tcpProxy != nil { 119 closeC := tcpProxy.Run([]string{endpoint}) 120 defer tcpProxy.Close(closeC) 121 endpoint = tcpProxy.GetEndpoints()[0] 122 } 123 db, err := createDB(endpoint) 124 if err != nil { 125 return err 126 } 127 128 _, err = db.Exec("create table if not exists test.ti_cluster(id int AUTO_INCREMENT primary key, v int)") 129 if err != nil { 130 return err 131 } 132 133 _, err = db.Exec("insert into test.ti_cluster (v) values(1)") 134 if err != nil { 135 return err 136 } 137 138 fmt.Printf("write %s success\n", utils.JoinHostPort(spec.Host, spec.Port)) 139 return nil 140 }) 141 } 142 143 return errg.Wait() 144 }