Skip to content

Commit

Permalink
Make vttestserver docker image work with vtctldclient (#14665)
Browse files Browse the repository at this point in the history
Signed-off-by: Manan Gupta <[email protected]>
  • Loading branch information
GuptaManan100 authored Dec 5, 2023
1 parent f156a10 commit 3d53207
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 16 deletions.
8 changes: 8 additions & 0 deletions changelog/19.0/19.0.0/summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
- [Stream Consolidations](#stream-consolidations)
- **[VTGate](#vtgate)**
- [`FOREIGN_KEY_CHECKS` is now a Vitess Aware Variable](#fk-checks-vitess-aware)
- **[Vttestserver](#vttestserver)**
- [`--vtcombo-bind-host` flag](#vtcombo-bind-host)
- **[Query Compatibility](#query-compatibility)**
- [`SHOW VSCHEMA KEYSPACES` Query](#show-vschema-keyspaces)
- **[Planned Reparent Shard](#planned-reparent-shard)**
Expand Down Expand Up @@ -57,6 +59,12 @@ Prior to 19.0 VTTablet reported how much time non-streaming executions spend wai

When VTGate receives a query to change the `FOREIGN_KEY_CHECKS` value for a session, instead of sending the value down to MySQL, VTGate now keeps track of the value and changes the queries by adding `SET_VAR(FOREIGN_KEY_CHECKS=On/Off)` style query optimizer hints wherever required.

### <a id="vttestserver"/>Vttestserver

#### <a id="vtcombo-bind-host"/>`--vtcombo-bind-host` flag

A new flag `--vtcombo-bind-host` has been added to vttestserver that allows the users to configure the bind host that vtcombo uses. This is especially useful when running vttestserver as a docker image and you want to run vtctld commands and look at the vtcombo `/debug/status` dashboard.

### <a id="query-compatibility"/>Query Compatibility

#### <a id="show-vschema-keyspaces"/>`SHOW VSCHEMA KEYSPACES` Query
Expand Down
1 change: 1 addition & 0 deletions docker/vttestserver/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ rm -vf "$VTDATAROOT"/"$tablet_dir"/{mysql.sock,mysql.sock.lock}
--keyspaces "$KEYSPACES" \
--num_shards "$NUM_SHARDS" \
--mysql_bind_host "${MYSQL_BIND_HOST:-127.0.0.1}" \
--vtcombo-bind-host "${VTCOMBO_BIND_HOST:-127.0.0.1}" \
--mysql_server_version "${MYSQL_SERVER_VERSION:-$1}" \
--charset "${CHARSET:-utf8mb4}" \
--foreign_key_mode "${FOREIGN_KEY_MODE:-allow}" \
Expand Down
3 changes: 3 additions & 0 deletions go/cmd/vttestserver/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ func New() (cmd *cobra.Command) {
cmd.Flags().StringVar(&config.MySQLBindHost, "mysql_bind_host", "localhost",
"which host to bind vtgate mysql listener to")

cmd.Flags().StringVar(&config.VtComboBindAddress, "vtcombo-bind-host", "localhost",
"which host to bind vtcombo servenv listener to")

cmd.Flags().StringVar(&mycnf, "extra_my_cnf", "",
"extra files to add to the config, separated by ':'")

Expand Down
1 change: 1 addition & 0 deletions go/flags/endtoend/vttestserver.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ Flags:
-v, --version print binary version
--vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging
--vschema_ddl_authorized_users string Comma separated list of users authorized to execute vschema ddl operations via vtgate
--vtcombo-bind-host string which host to bind vtcombo servenv listener to (default "localhost")
--vtctl_client_protocol string Protocol to use to talk to the vtctl server. (default "grpc")
--vtctld_grpc_ca string the server ca to use to validate servers when connecting
--vtctld_grpc_cert string the cert to use to connect
Expand Down
13 changes: 8 additions & 5 deletions go/test/endtoend/docker/vttestserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type vttestserver struct {
keyspaces []string
numShards []int
mysqlMaxConnecetions int
port int
basePort int
}

func newVttestserver(dockerImage string, keyspaces []string, numShards []int, mysqlMaxConnections, port int) *vttestserver {
Expand All @@ -48,7 +48,7 @@ func newVttestserver(dockerImage string, keyspaces []string, numShards []int, my
keyspaces: keyspaces,
numShards: numShards,
mysqlMaxConnecetions: mysqlMaxConnections,
port: port,
basePort: port,
}
}

Expand All @@ -64,13 +64,16 @@ func (v *vttestserver) teardown() {
func (v *vttestserver) startDockerImage() error {
cmd := exec.Command("docker", "run")
cmd.Args = append(cmd.Args, "--name=vttestserver-end2end-test")
cmd.Args = append(cmd.Args, "-p", fmt.Sprintf("%d:33577", v.port))
cmd.Args = append(cmd.Args, "-e", "PORT=33574")
cmd.Args = append(cmd.Args, "-p", fmt.Sprintf("%d:%d", v.basePort, v.basePort))
cmd.Args = append(cmd.Args, "-p", fmt.Sprintf("%d:%d", v.basePort+1, v.basePort+1))
cmd.Args = append(cmd.Args, "-p", fmt.Sprintf("%d:%d", v.basePort+3, v.basePort+3))
cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("PORT=%d", v.basePort))
cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("KEYSPACES=%s", strings.Join(v.keyspaces, ",")))
cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("NUM_SHARDS=%s", strings.Join(convertToStringSlice(v.numShards), ",")))
cmd.Args = append(cmd.Args, "-e", "MYSQL_BIND_HOST=0.0.0.0")
cmd.Args = append(cmd.Args, "-e", "VTCOMBO_BIND_HOST=0.0.0.0")
cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("MYSQL_MAX_CONNECTIONS=%d", v.mysqlMaxConnecetions))
cmd.Args = append(cmd.Args, "--health-cmd", "mysqladmin ping -h127.0.0.1 -P33577")
cmd.Args = append(cmd.Args, "--health-cmd", fmt.Sprintf("mysqladmin ping -h127.0.0.1 -P%d", v.basePort+3))
cmd.Args = append(cmd.Args, "--health-interval=5s")
cmd.Args = append(cmd.Args, "--health-timeout=2s")
cmd.Args = append(cmd.Args, "--health-retries=5")
Expand Down
40 changes: 32 additions & 8 deletions go/test/endtoend/docker/vttestserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"os"
"testing"

"vitess.io/vitess/go/test/endtoend/cluster"
"vitess.io/vitess/go/test/endtoend/utils"

"vitess.io/vitess/go/mysql"
Expand All @@ -44,7 +45,7 @@ func TestUnsharded(t *testing.T) {
dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image}
for _, image := range dockerImages {
t.Run(image, func(t *testing.T) {
vtest := newVttestserver(image, []string{"unsharded_ks"}, []int{1}, 1000, 33577)
vtest := newVttestserver(image, []string{"unsharded_ks"}, []int{1}, 1000, 33574)
err := vtest.startDockerImage()
require.NoError(t, err)
defer vtest.teardown()
Expand All @@ -56,7 +57,7 @@ func TestUnsharded(t *testing.T) {
ctx := context.Background()
vttestParams := mysql.ConnParams{
Host: "localhost",
Port: vtest.port,
Port: vtest.basePort + 3,
}
conn, err := mysql.Connect(ctx, &vttestParams)
require.NoError(t, err)
Expand All @@ -73,7 +74,7 @@ func TestSharded(t *testing.T) {
dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image}
for _, image := range dockerImages {
t.Run(image, func(t *testing.T) {
vtest := newVttestserver(image, []string{"ks"}, []int{2}, 1000, 33577)
vtest := newVttestserver(image, []string{"ks"}, []int{2}, 1000, 33574)
err := vtest.startDockerImage()
require.NoError(t, err)
defer vtest.teardown()
Expand All @@ -85,7 +86,7 @@ func TestSharded(t *testing.T) {
ctx := context.Background()
vttestParams := mysql.ConnParams{
Host: "localhost",
Port: vtest.port,
Port: vtest.basePort + 3,
}
conn, err := mysql.Connect(ctx, &vttestParams)
require.NoError(t, err)
Expand All @@ -103,7 +104,7 @@ func TestMysqlMaxCons(t *testing.T) {
dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image}
for _, image := range dockerImages {
t.Run(image, func(t *testing.T) {
vtest := newVttestserver(image, []string{"ks"}, []int{2}, 100000, 33577)
vtest := newVttestserver(image, []string{"ks"}, []int{2}, 100000, 33574)
err := vtest.startDockerImage()
require.NoError(t, err)
defer vtest.teardown()
Expand All @@ -115,7 +116,7 @@ func TestMysqlMaxCons(t *testing.T) {
ctx := context.Background()
vttestParams := mysql.ConnParams{
Host: "localhost",
Port: vtest.port,
Port: vtest.basePort + 3,
}
conn, err := mysql.Connect(ctx, &vttestParams)
require.NoError(t, err)
Expand All @@ -125,6 +126,29 @@ func TestMysqlMaxCons(t *testing.T) {
}
}

// TestVtctldCommands tests that vtctld commands can be run with the docker image.
func TestVtctldCommands(t *testing.T) {
dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image}
for _, image := range dockerImages {
t.Run(image, func(t *testing.T) {
vtest := newVttestserver(image, []string{"long_ks_name"}, []int{2}, 100, 33574)
err := vtest.startDockerImage()
require.NoError(t, err)
defer vtest.teardown()

// wait for the docker to be setup
err = vtest.waitUntilDockerHealthy(10)
require.NoError(t, err)

vtctldClient := cluster.VtctldClientProcessInstance("localhost", vtest.basePort+1, os.TempDir())
res, err := vtctldClient.ExecuteCommandWithOutput("GetKeyspaces")
require.NoError(t, err)
// We verify that the command succeeds, and the keyspace name is present in the output.
require.Contains(t, res, "long_ks_name")
})
}
}

func TestLargeNumberOfKeyspaces(t *testing.T) {
dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image}
for _, image := range dockerImages {
Expand All @@ -136,7 +160,7 @@ func TestLargeNumberOfKeyspaces(t *testing.T) {
numShards = append(numShards, 1)
}

vtest := newVttestserver(image, keyspaces, numShards, 100000, 33577)
vtest := newVttestserver(image, keyspaces, numShards, 100000, 33574)
err := vtest.startDockerImage()
require.NoError(t, err)
defer vtest.teardown()
Expand All @@ -148,7 +172,7 @@ func TestLargeNumberOfKeyspaces(t *testing.T) {
ctx := context.Background()
vttestParams := mysql.ConnParams{
Host: "localhost",
Port: vtest.port,
Port: vtest.basePort + 3,
}
conn, err := mysql.Connect(ctx, &vttestParams)
require.NoError(t, err)
Expand Down
7 changes: 6 additions & 1 deletion go/vt/vttest/local_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ type Config struct {
// cluster startup if the data directory does not already exist.
PersistentMode bool

// VtCombo bind address.
// vtcombo will bind to this address when running the servenv.
VtComboBindAddress string

// MySQL protocol bind address.
// vtcombo will bind to this address when exposing the mysql protocol socket
MySQLBindHost string
Expand Down Expand Up @@ -641,6 +645,7 @@ func (db *LocalCluster) JSONConfig() any {
}

config := map[string]any{
"bind_address": db.vt.BindAddress,
"port": db.vt.Port,
"socket": db.mysql.UnixSocket(),
"vtcombo_mysql_port": db.Env.PortForProtocol("vtcombo_mysql_port", ""),
Expand Down Expand Up @@ -783,7 +788,7 @@ func (db *LocalCluster) VTProcess() *VtProcess {
// a pointer to the interface. To read this vschema, the caller must convert it to a map
func (vt *VtProcess) ReadVSchema() (*interface{}, error) {
httpClient := &http.Client{Timeout: 5 * time.Second}
resp, err := httpClient.Get(fmt.Sprintf("http://%s:%d/debug/vschema", "127.0.0.1", vt.Port))
resp, err := httpClient.Get(fmt.Sprintf("http://%s:%d/debug/vschema", vt.BindAddress, vt.Port))
if err != nil {
return nil, err
}
Expand Down
10 changes: 8 additions & 2 deletions go/vt/vttest/vtprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type VtProcess struct {
Binary string
ExtraArgs []string
Env []string
BindAddress string
Port int
PortGrpc int
HealthCheck HealthChecker
Expand Down Expand Up @@ -91,7 +92,7 @@ func (vtp *VtProcess) IsHealthy() bool {
// Address returns the main address for this Vitess process.
// This is usually the main HTTP endpoint for the service.
func (vtp *VtProcess) Address() string {
return fmt.Sprintf("localhost:%d", vtp.Port)
return fmt.Sprintf("%s:%d", vtp.BindAddress, vtp.Port)
}

// WaitTerminate attempts to gracefully shutdown the Vitess process by sending
Expand Down Expand Up @@ -128,7 +129,7 @@ func (vtp *VtProcess) WaitStart() (err error) {
vtp.proc = exec.Command(
vtp.Binary,
"--port", fmt.Sprintf("%d", vtp.Port),
"--bind-address", "127.0.0.1",
"--bind-address", vtp.BindAddress,
"--log_dir", vtp.LogDirectory,
"--alsologtostderr",
)
Expand Down Expand Up @@ -196,11 +197,16 @@ var QueryServerArgs = []string{
// configured with the given Config.
// The process must be manually started by calling WaitStart()
func VtcomboProcess(environment Environment, args *Config, mysql MySQLManager) (*VtProcess, error) {
vtcomboBindAddress := "127.0.0.1"
if args.VtComboBindAddress != "" {
vtcomboBindAddress = args.VtComboBindAddress
}
vt := &VtProcess{
Name: "vtcombo",
Directory: environment.Directory(),
LogDirectory: environment.LogDirectory(),
Binary: environment.BinaryPath("vtcombo"),
BindAddress: vtcomboBindAddress,
Port: environment.PortForProtocol("vtcombo", ""),
PortGrpc: environment.PortForProtocol("vtcombo", "grpc"),
HealthCheck: environment.ProcessHealthCheck("vtcombo"),
Expand Down

0 comments on commit 3d53207

Please sign in to comment.