diff --git a/Makefile b/Makefile index d665455d60..1a7dfff1a9 100644 --- a/Makefile +++ b/Makefile @@ -99,6 +99,10 @@ dm_integration_test_build: -coverpkg=github.com/pingcap/dm/... \ -o bin/dm-master.test github.com/pingcap/dm/cmd/dm-master \ || { $(FAILPOINT_DISABLE); exit 1; } + $(GOTEST) -c -race -cover -covermode=atomic \ + -coverpkg=github.com/pingcap/dm/... \ + -o bin/dmctl.test github.com/pingcap/dm/cmd/dm-ctl \ + || { $(FAILPOINT_DISABLE); exit 1; } $(GOTEST) -c -race -cover -covermode=atomic \ -coverpkg=github.com/pingcap/dm/... \ -o bin/dm-tracer.test github.com/pingcap/dm/cmd/dm-tracer \ diff --git a/tests/dmctl_tools/dmctl_start_task.go b/cmd/dm-ctl/main_test.go similarity index 61% rename from tests/dmctl_tools/dmctl_start_task.go rename to cmd/dm-ctl/main_test.go index 7011ed1bd9..b5d63be728 100644 --- a/tests/dmctl_tools/dmctl_start_task.go +++ b/cmd/dm-ctl/main_test.go @@ -13,21 +13,25 @@ package main +// Reference: https://dzone.com/articles/measuring-integration-test-coverage-rate-in-pouchc + import ( - "context" "os" - - "github.com/pingcap/dm/tests/utils" + "strings" + "testing" ) -func main() { - cli, err := utils.CreateDmCtl("127.0.0.1:8261") - if err != nil { - utils.ExitWithError(err) - } - conf := os.Args[1] - err = utils.StartTask(context.Background(), cli, conf, nil) - if err != nil { - utils.ExitWithError(err) +func TestRunMain(t *testing.T) { + var args []string + for _, arg := range os.Args { + switch { + case arg == "DEVEL": + case strings.HasPrefix(arg, "-test."): + default: + args = append(args, arg) + } } + + os.Args = args + main() } diff --git a/dm/ctl/master/operate_relay.go b/dm/ctl/common/operate_relay.go similarity index 80% rename from dm/ctl/master/operate_relay.go rename to dm/ctl/common/operate_relay.go index 6385ce368b..91dd877b1c 100644 --- a/dm/ctl/master/operate_relay.go +++ b/dm/ctl/common/operate_relay.go @@ -11,20 +11,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package master +package common import ( "context" - "github.com/pingcap/dm/dm/ctl/common" "github.com/pingcap/dm/dm/pb" ) -// operateRelay does operation on relay unit -func operateRelay(op pb.RelayOp, workers []string) (*pb.OperateWorkerRelayResponse, error) { +// OperateRelay does operation on relay unit +func OperateRelay(op pb.RelayOp, workers []string) (*pb.OperateWorkerRelayResponse, error) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - cli := common.MasterClient() + cli := MasterClient() return cli.OperateWorkerRelayTask(ctx, &pb.OperateWorkerRelayRequest{ Op: op, Workers: workers, diff --git a/dm/ctl/master/operate_task.go b/dm/ctl/common/operate_task.go similarity index 80% rename from dm/ctl/master/operate_task.go rename to dm/ctl/common/operate_task.go index 9019f3a286..361abe2c58 100644 --- a/dm/ctl/master/operate_task.go +++ b/dm/ctl/common/operate_task.go @@ -11,20 +11,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package master +package common import ( "context" - "github.com/pingcap/dm/dm/ctl/common" "github.com/pingcap/dm/dm/pb" ) -// operateTask does operation on task -func operateTask(op pb.TaskOp, name string, workers []string) (*pb.OperateTaskResponse, error) { +// OperateTask does operation on task +func OperateTask(op pb.TaskOp, name string, workers []string) (*pb.OperateTaskResponse, error) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - cli := common.MasterClient() + cli := MasterClient() return cli.OperateTask(ctx, &pb.OperateTaskRequest{ Op: op, Name: name, diff --git a/dm/ctl/ctl.go b/dm/ctl/ctl.go index 448e481209..210f822026 100644 --- a/dm/ctl/ctl.go +++ b/dm/ctl/ctl.go @@ -67,10 +67,10 @@ func Start(args []string) { master.NewSwitchRelayMasterCmd(), master.NewPauseRelayCmd(), master.NewResumeRelayCmd(), - //master.NewStopRelayCmd(), master.NewUpdateMasterConfigCmd(), master.NewUpdateRelayCmd(), master.NewPurgeRelayCmd(), + master.NewMigrateRelayCmd(), ) rootCmd.SetArgs(args) diff --git a/dm/ctl/master/pause_relay.go b/dm/ctl/master/pause_relay.go index d20b38383a..ccd0630568 100644 --- a/dm/ctl/master/pause_relay.go +++ b/dm/ctl/master/pause_relay.go @@ -16,10 +16,11 @@ package master import ( "fmt" - "github.com/pingcap/dm/dm/ctl/common" - "github.com/pingcap/dm/dm/pb" "github.com/pingcap/errors" "github.com/spf13/cobra" + + "github.com/pingcap/dm/dm/ctl/common" + "github.com/pingcap/dm/dm/pb" ) // NewPauseRelayCmd creates a PauseRelay command @@ -49,7 +50,7 @@ func pauseRelayFunc(cmd *cobra.Command, _ []string) { return } - resp, err := operateRelay(pb.RelayOp_PauseRelay, workers) + resp, err := common.OperateRelay(pb.RelayOp_PauseRelay, workers) if err != nil { common.PrintLines("can not pause relay unit:\n%v", errors.ErrorStack(err)) return diff --git a/dm/ctl/master/pause_task.go b/dm/ctl/master/pause_task.go index 305d6821c4..154b9d4f54 100644 --- a/dm/ctl/master/pause_task.go +++ b/dm/ctl/master/pause_task.go @@ -16,10 +16,11 @@ package master import ( "fmt" - "github.com/pingcap/dm/dm/ctl/common" - "github.com/pingcap/dm/dm/pb" "github.com/pingcap/errors" "github.com/spf13/cobra" + + "github.com/pingcap/dm/dm/ctl/common" + "github.com/pingcap/dm/dm/pb" ) // NewPauseTaskCmd creates a PauseTask command @@ -46,7 +47,7 @@ func pauseTaskFunc(cmd *cobra.Command, _ []string) { return } - resp, err := operateTask(pb.TaskOp_Pause, name, workers) + resp, err := common.OperateTask(pb.TaskOp_Pause, name, workers) if err != nil { common.PrintLines("can not pause task %s:\n%v", name, errors.ErrorStack(err)) return diff --git a/dm/ctl/master/resume_relay.go b/dm/ctl/master/resume_relay.go index cc002d10e5..c708ff6f72 100644 --- a/dm/ctl/master/resume_relay.go +++ b/dm/ctl/master/resume_relay.go @@ -16,10 +16,11 @@ package master import ( "fmt" - "github.com/pingcap/dm/dm/ctl/common" - "github.com/pingcap/dm/dm/pb" "github.com/pingcap/errors" "github.com/spf13/cobra" + + "github.com/pingcap/dm/dm/ctl/common" + "github.com/pingcap/dm/dm/pb" ) // NewResumeRelayCmd creates a ResumeRelay command @@ -49,7 +50,7 @@ func resumeRelayFunc(cmd *cobra.Command, _ []string) { return } - resp, err := operateRelay(pb.RelayOp_ResumeRelay, workers) + resp, err := common.OperateRelay(pb.RelayOp_ResumeRelay, workers) if err != nil { common.PrintLines("can not resume relay unit:\n%v", errors.ErrorStack(err)) return diff --git a/dm/ctl/master/resume_task.go b/dm/ctl/master/resume_task.go index dd08b108de..1bdf88aba9 100644 --- a/dm/ctl/master/resume_task.go +++ b/dm/ctl/master/resume_task.go @@ -16,10 +16,11 @@ package master import ( "fmt" - "github.com/pingcap/dm/dm/ctl/common" - "github.com/pingcap/dm/dm/pb" "github.com/pingcap/errors" "github.com/spf13/cobra" + + "github.com/pingcap/dm/dm/ctl/common" + "github.com/pingcap/dm/dm/pb" ) // NewResumeTaskCmd creates a ResumeTask command @@ -46,7 +47,7 @@ func resumeTaskFunc(cmd *cobra.Command, _ []string) { return } - resp, err := operateTask(pb.TaskOp_Resume, name, workers) + resp, err := common.OperateTask(pb.TaskOp_Resume, name, workers) if err != nil { common.PrintLines("can not resume task %s:\n%v", name, errors.ErrorStack(err)) return diff --git a/dm/ctl/master/sql_skip.go b/dm/ctl/master/sql_skip.go index 8c366d4a0f..7c83a8f107 100644 --- a/dm/ctl/master/sql_skip.go +++ b/dm/ctl/master/sql_skip.go @@ -18,10 +18,11 @@ import ( "fmt" "strings" - "github.com/pingcap/dm/dm/ctl/common" - "github.com/pingcap/dm/dm/pb" "github.com/pingcap/errors" "github.com/spf13/cobra" + + "github.com/pingcap/dm/dm/ctl/common" + "github.com/pingcap/dm/dm/pb" ) // NewSQLSkipCmd creates a SQLSkip command diff --git a/dm/ctl/master/stop_relay.go b/dm/ctl/master/stop_relay.go deleted file mode 100644 index 2cd88e17b0..0000000000 --- a/dm/ctl/master/stop_relay.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2019 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// See the License for the specific language governing permissions and -// limitations under the License. - -package master - -import ( - "fmt" - - "github.com/pingcap/dm/dm/ctl/common" - "github.com/pingcap/dm/dm/pb" - "github.com/pingcap/errors" - "github.com/spf13/cobra" -) - -// NewStopRelayCmd creates a StopRelay command -func NewStopRelayCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "stop-relay <-w worker ...>", - Short: "stop dm-worker's relay unit", - Run: stopRelayFunc, - } - return cmd -} - -// stopRelayFunc does stop relay request -func stopRelayFunc(cmd *cobra.Command, _ []string) { - if len(cmd.Flags().Args()) > 0 { - fmt.Println(cmd.Usage()) - return - } - - workers, err := common.GetWorkerArgs(cmd) - if err != nil { - common.PrintLines("%s", errors.ErrorStack(err)) - return - } - if len(workers) == 0 { - fmt.Println("must specify at least one dm-worker (`-w` / `--worker`)") - return - } - - resp, err := operateRelay(pb.RelayOp_StopRelay, workers) - if err != nil { - common.PrintLines("can not stop relay unit:\n%v", errors.ErrorStack(err)) - return - } - - common.PrettyPrintResponse(resp) -} diff --git a/dm/ctl/master/stop_task.go b/dm/ctl/master/stop_task.go index a3aeed3360..6252f57941 100644 --- a/dm/ctl/master/stop_task.go +++ b/dm/ctl/master/stop_task.go @@ -16,10 +16,11 @@ package master import ( "fmt" - "github.com/pingcap/dm/dm/ctl/common" - "github.com/pingcap/dm/dm/pb" "github.com/pingcap/errors" "github.com/spf13/cobra" + + "github.com/pingcap/dm/dm/ctl/common" + "github.com/pingcap/dm/dm/pb" ) // NewStopTaskCmd creates a StopTask command @@ -46,7 +47,7 @@ func stopTaskFunc(cmd *cobra.Command, _ []string) { return } - resp, err := operateTask(pb.TaskOp_Stop, name, workers) + resp, err := common.OperateTask(pb.TaskOp_Stop, name, workers) if err != nil { common.PrintLines("can not stop task %s:\n%v", name, errors.ErrorStack(err)) return diff --git a/tests/README.md b/tests/README.md index d7cf4c5f2f..3f1ebe06cf 100644 --- a/tests/README.md +++ b/tests/README.md @@ -51,6 +51,7 @@ Several convenient commands are provided: * `run_dm_master ` — Starts `dm-master` using config provided, on given port, running in workdir. * `run_dm_worker ` — Starts `dm-worker` using config provided, on given port, running in workdir. +* `run_dm_ctl ` - Runs `dmctl` with given command in non-interactive mode. * `run_sql ` — Executes an SQL query in database based on port provided * `run_sql_file ` — Executes all SQLs in given file to the database on port provided * `run_sql_file_online_ddl ` — Executes all SQLs in given file, will auto switch DDL to online DDL command. diff --git a/tests/_utils/check_sync_diff b/tests/_utils/check_sync_diff index 33312355c4..54e72faf54 100755 --- a/tests/_utils/check_sync_diff +++ b/tests/_utils/check_sync_diff @@ -1,10 +1,15 @@ #!/bin/bash # parameter 1: work directory # parameter 2: config file for sync_diff_inspector +# parameter 3: max check times workdir=$1 conf=$2 -check_time=10 +if [ $# -ge 3 ]; then + check_time=$3 +else + check_time=10 +fi PWD=$(pwd) binary=$PWD/bin/sync_diff_inspector diff --git a/tests/_utils/run_dm_ctl b/tests/_utils/run_dm_ctl new file mode 100755 index 0000000000..d4a768386e --- /dev/null +++ b/tests/_utils/run_dm_ctl @@ -0,0 +1,31 @@ +#!/bin/bash +# tools to run dmctl from command line +# parameter 1: work directory +# parameter 2: master-addr port +# parameter 3: command +# parameter 4...: check output content and count + +workdir=$1 +master_addr=$2 +cmd=$3 + +shift 3 + +PWD=$(pwd) +binary=$PWD/bin/dmctl.test +ts=$(date +"%s") +dmctl_log=$workdir/dmctl.$ts.log +echo "dmctl test cmd: \"$cmd\"" +echo "$cmd" | $binary -test.coverprofile="$TEST_DIR/cov.$TEST_NAME.dmctl.$ts.out" DEVEL -master-addr=$master_addr > $dmctl_log 2>&1 + +for ((i=1; i<$#; i+=2)); do + j=$((i+1)) + value=${!i} + expected=${!j} + got=$(sed "s/$value/$value\n/g" $dmctl_log | grep -c "$value") + if [ "$got" != "$expected" ]; then + echo "command: $cmd $value count: $got != expected: $expected" + cat $dmctl_log + exit 1 + fi +done diff --git a/tests/_utils/test_prepare b/tests/_utils/test_prepare index 20d1112251..9a7d4fabb8 100644 --- a/tests/_utils/test_prepare +++ b/tests/_utils/test_prepare @@ -33,3 +33,40 @@ fi function join_string() { local IFS="$1"; shift; echo "$*"; } + +# shortcut for start task on one DM-worker +function dmctl_start_task_standalone() { + if [ $# -ge 1 ]; then + task_conf=$1 + else + task_conf="$cur/conf/dm-task.yaml" + fi + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "start-task $task_conf" \ + "\"result\": true" 2 \ + "\"worker\": \"127.0.0.1:$WORKER1_PORT\"" 1 +} + +# shortcut for start task on two DM-workers +function dmctl_start_task() { + if [ $# -ge 1 ]; then + task_conf=$1 + else + task_conf="$cur/conf/dm-task.yaml" + fi + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "start-task $task_conf" \ + "\"result\": true" 3 \ + "\"worker\": \"127.0.0.1:$WORKER1_PORT\"" 1 \ + "\"worker\": \"127.0.0.1:$WORKER2_PORT\"" 1 +} + +# shortcut for stop task on two DM-workers +function dmctl_stop_task() { + task_name=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "stop-task $task_name" \ + "\"result\": true" 3 \ + "\"worker\": \"127.0.0.1:$WORKER1_PORT\"" 1 \ + "\"worker\": \"127.0.0.1:$WORKER2_PORT\"" 1 +} diff --git a/tests/all_mode/run.sh b/tests/all_mode/run.sh index 730ecf3859..63eb019037 100755 --- a/tests/all_mode/run.sh +++ b/tests/all_mode/run.sh @@ -20,7 +20,7 @@ function run() { check_rpc_alive $cur/../bin/check_master_online 127.0.0.1:$MASTER_PORT # start DM task only - $cur/../bin/dmctl_start_task "$cur/conf/dm-task.yaml" + dmctl_start_task # use sync_diff_inspector to check full dump loader check_sync_diff $WORK_DIR $cur/conf/diff_config.toml diff --git a/tests/dmctl_advance/check_list/break_ddl_lock.sh b/tests/dmctl_advance/check_list/break_ddl_lock.sh new file mode 100644 index 0000000000..3dc93fa5e4 --- /dev/null +++ b/tests/dmctl_advance/check_list/break_ddl_lock.sh @@ -0,0 +1,33 @@ +#!bin/bash + +function break_ddl_lock_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "break-ddl-lock" \ + "break-ddl-lock <-w worker ...> \[--remove-id\] \[--exec\] \[--skip\] \[flags\]" 1 +} + +function break_ddl_lock_without_worker() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "break-ddl-lock test" \ + "must specify at least one dm-worker (\`-w\` \/ \`--worker\`)" 1 +} + +function break_ddl_lock_shoud_specify_at_least_one() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "break-ddl-lock test -w 127.0.0.1:$WORKER1_PORT" \ + "\`remove-id\`, \`exec\`, \`skip\` must specify at least one" 1 +} + +function break_ddl_lock_exec_skip_conflict() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "break-ddl-lock test -w 127.0.0.1:$WORKER1_PORT --exec --skip" \ + "\`exec\` and \`skip\` can not specify both at the same time" 1 +} + +function break_ddl_lock_while_master_down() { + # worker address is only a placeholder in this test case, its value makes no sense + worker_addr="127.0.0.1:$WORKER1_PORT" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "break-ddl-lock test -w $worker_addr --exec" \ + "can not break DDL lock (in workers \[$worker_addr\]):" 1 +} diff --git a/tests/dmctl_advance/check_list/migrate_relay.sh b/tests/dmctl_advance/check_list/migrate_relay.sh new file mode 100644 index 0000000000..28bfa01f96 --- /dev/null +++ b/tests/dmctl_advance/check_list/migrate_relay.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +function migrate_relay_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "migrate-relay" \ + "migrate-relay \[flags\]" 1 +} + +function migrate_relay_without_worker() { + binlog_pos="invalid-binlog-pos" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "migrate-relay 127.0.0.1:$WORKER1_PORT bin-000001 $binlog_pos" \ + "strconv.Atoi: parsing \"$binlog_pos\": invalid syntax" 1 +} + +function migrate_relay_while_master_down() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "migrate-relay 127.0.0.1:$WORKER1_PORT bin-000001 194" \ + "can not migrate relay config:" 1 +} diff --git a/tests/dmctl_advance/check_list/query_error.sh b/tests/dmctl_advance/check_list/query_error.sh new file mode 100644 index 0000000000..0e8d5b43dc --- /dev/null +++ b/tests/dmctl_advance/check_list/query_error.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +function query_error_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "query-error wrong_args_count more_than_one" \ + "query-error \[-w worker ...\] \[task_name\]" 1 +} + +function query_error_while_master_down() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "query-error -w 127.0.0.1:$WORKER1_PORT test-task" \ + "query error failed" 1 +} diff --git a/tests/dmctl_advance/check_list/refresh_worker_tasks.sh b/tests/dmctl_advance/check_list/refresh_worker_tasks.sh new file mode 100644 index 0000000000..cf3a84cfc2 --- /dev/null +++ b/tests/dmctl_advance/check_list/refresh_worker_tasks.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +function refresh_worker_tasks_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "refresh-worker-tasks invalid_arg" \ + "refresh-worker-tasks \[flags\]" 1 +} + +function refresh_worker_tasks_while_master_down() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "refresh-worker-tasks" \ + "can not refresh workerTasks:" 1 +} diff --git a/tests/dmctl_advance/check_list/sql_inject.sh b/tests/dmctl_advance/check_list/sql_inject.sh new file mode 100644 index 0000000000..a9bf588e2f --- /dev/null +++ b/tests/dmctl_advance/check_list/sql_inject.sh @@ -0,0 +1 @@ +#!/bin/bash diff --git a/tests/dmctl_advance/check_list/sql_replace.sh b/tests/dmctl_advance/check_list/sql_replace.sh new file mode 100644 index 0000000000..81af82c79b --- /dev/null +++ b/tests/dmctl_advance/check_list/sql_replace.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +function sql_replace_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "sql-replace" \ + "sql-replace <-w worker> \[-b binlog-pos\] \[-s sql-pattern\] \[--sharding\] \[flags\]" 1 +} + +function sql_replace_invalid_binlog_pos() { + binlog_pos="mysql-bin:shoud-bin-digital" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "sql-replace test-task --binlog-pos $binlog_pos sql1" \ + "invalid --binlog-pos $binlog_pos in sql operation: the pos should be digital" 1 +} + +function sql_replace_non_sharding_without_one_worker() { + worker1="127.0.0.1:$WORKER1_PORT" + worker2="127.0.0.1:$WORKER2_PORT" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "sql-replace test-task --worker $worker1,$worker2 --binlog-pos mysql-bin:13426 sql1" \ + "should only specify one worker, but got \[$worker1 $worker2\]" 1 +} + +function sql_replace_while_master_down() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "sql-replace test-task --sharding --sql-pattern ~(?i)ALTER\\s+TABLE\\s+ ALTER TABLE tbl DROP COLUMN col" \ + "can not replace SQL:" 1 +} diff --git a/tests/dmctl_advance/check_list/sql_skip.sh b/tests/dmctl_advance/check_list/sql_skip.sh new file mode 100644 index 0000000000..d888fdf2ac --- /dev/null +++ b/tests/dmctl_advance/check_list/sql_skip.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +function sql_skip_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "sql-skip" \ + "sql-skip <-w worker> \[-b binlog-pos\] \[-s sql-pattern\] \[--sharding\] \[flags\]" 1 +} + +function sql_skip_binlogpos_sqlpattern_conflict() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "sql-skip test-task --binlog-pos mysql-bin:194 --sql-pattern ~(?i)ALTER\\s+TABLE\\s+" \ + "cannot specify both --binlog-pos and --sql-pattern in sql operation" 1 +} + +function sql_skip_invalid_binlog_pos() { + binlog_pos="mysql-bin:shoud-bin-digital" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "sql-skip test-task --binlog-pos $binlog_pos" \ + "invalid --binlog-pos $binlog_pos in sql operation: the pos should be digital" 1 +} + +function sql_skip_invalid_regex() { + regex="~(\[a-z\])\\1" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "sql-skip test-task --sql-pattern $regex" \ + "invalid --sql-pattern .* in sql operation:" 1 +} + +function sql_skip_sharding_with_binlogpos() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "sql-skip test-task --sharding --binlog-pos mysql-bin:13426" \ + "cannot specify --binlog-pos with --sharding in sql operation" 1 +} + +function sql_skip_non_sharding_without_one_worker() { + worker1="127.0.0.1:$WORKER1_PORT" + worker2="127.0.0.1:$WORKER2_PORT" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "sql-skip test-task --worker $worker1,$worker2 --binlog-pos mysql-bin:13426" \ + "should only specify one worker, but got \[$worker1 $worker2\]" 1 +} + +function sql_skip_while_master_down() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "sql-skip test-task --sharding --sql-pattern ~(?i)ALTER\\s+TABLE\\s+" \ + "can not skip SQL:" 1 +} diff --git a/tests/dmctl_advance/check_list/switch_relay_master.sh b/tests/dmctl_advance/check_list/switch_relay_master.sh new file mode 100644 index 0000000000..637ac2d56f --- /dev/null +++ b/tests/dmctl_advance/check_list/switch_relay_master.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +function switch_relay_master_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "switch-relay-master invalid_arg" \ + "switch-relay-master <-w worker ...> \[flags\]" 1 +} + +function switch_relay_master_without_worker() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "switch-relay-master" \ + "must specify at least one dm-worker (\`-w\` \/ \`--worker\`)" 1 +} + +function switch_relay_master_while_master_down() { + # worker_addr's value makes no sense + worker_addr="127.0.0.1:$WORKER1_PORT" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "switch-relay-master -w $worker_addr" \ + "can not switch relay's master server (in workers \[$worker_addr\]):" 1 +} diff --git a/tests/dmctl_advance/check_list/unlock_ddl_lock.sh b/tests/dmctl_advance/check_list/unlock_ddl_lock.sh new file mode 100644 index 0000000000..c0286d8e39 --- /dev/null +++ b/tests/dmctl_advance/check_list/unlock_ddl_lock.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +function unlock_ddl_lock_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "unlock-ddl-lock" \ + "unlock-ddl-lock \[-w worker ...\] \[flags\]" 1 +} + +function unlock_ddl_lock_invalid_force_remove() { + force_remove_val="invalid-force-remove" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "unlock-ddl-lock lock_id --force-remove=$force_remove_val" \ + "Error: invalid argument \"$force_remove_val\" for \"-f, --force-remove\"" 1 +} +function unlock_ddl_lock_while_master_down() { + lock_id="test-\`shard_db\`.\`shard_table\`" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "unlock-ddl-lock $lock_id" \ + "can not unlock DDL lock $lock_id (in workers \[\]):" 1 +} diff --git a/tests/dmctl_advance/run.sh b/tests/dmctl_advance/run.sh new file mode 100755 index 0000000000..a023f253a6 --- /dev/null +++ b/tests/dmctl_advance/run.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +set -eu + +cur=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +source $cur/../_utils/test_prepare +WORK_DIR=$TEST_DIR/$TEST_NAME +TASK_CONF=$cur/conf/dm-task.yaml +TASK_NAME="test" +WORKER1_CONF=$cur/conf/dm-worker1.toml +SQL_RESULT_FILE="$TEST_DIR/sql_res.$TEST_NAME.txt" + +# used to coverage wrong usage of dmctl command +function usage_and_arg_test() { + break_ddl_lock_wrong_arg + break_ddl_lock_without_worker + break_ddl_lock_shoud_specify_at_least_one + break_ddl_lock_exec_skip_conflict + break_ddl_lock_while_master_down + + migrate_relay_wrong_arg + migrate_relay_without_worker + migrate_relay_while_master_down + + refresh_worker_tasks_wrong_arg + refresh_worker_tasks_while_master_down + + switch_relay_master_wrong_arg + switch_relay_master_without_worker + switch_relay_master_while_master_down + + unlock_ddl_lock_wrong_arg + unlock_ddl_lock_invalid_force_remove + unlock_ddl_lock_while_master_down + + query_error_wrong_arg + query_error_while_master_down + + sql_skip_wrong_arg + sql_skip_binlogpos_sqlpattern_conflict + sql_skip_invalid_binlog_pos + sql_skip_invalid_regex + sql_skip_sharding_with_binlogpos + sql_skip_non_sharding_without_one_worker + sql_skip_while_master_down + + sql_replace_wrong_arg + sql_replace_invalid_binlog_pos + sql_replace_non_sharding_without_one_worker + # TODO: check SQLs error test + sql_replace_while_master_down +} + +function run() { + cd $cur + for file in "check_list"/*; do + source $file + done + cd - + + usage_and_arg_test +} + +cleanup1 dmctl_advance +# also cleanup dm processes in case of last run failed +cleanup2 $* +run $* +cleanup2 $* + +wait_process_exit dm-master.test +wait_process_exit dm-worker.test + +echo "[$(date)] <<<<<< test case $TEST_NAME success! >>>>>>" diff --git a/tests/dmctl_basic/check_list/check_task.sh b/tests/dmctl_basic/check_list/check_task.sh new file mode 100644 index 0000000000..c1b873ab67 --- /dev/null +++ b/tests/dmctl_basic/check_list/check_task.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +function check_task_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "check-task" \ + "check-task \[flags\]" 1 +} + +function check_task_wrong_config_file() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "check-task not_exists_config_file" \ + "get file content error" 1 +} + +# run this check if DM-master is not available +function check_task_while_master_down() { + task_conf=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "check-task $task_conf" \ + "fail to check task" 1 +} + +function check_task_pass() { + task_conf=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "check-task $task_conf" \ + "\"msg\": \"check pass!!!\"" 1 \ + "\"result\": true" 1 +} + +function check_task_not_pass() { + task_conf=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "check-task $task_conf" \ + "\"result\": false" 1 +} diff --git a/tests/dmctl_basic/check_list/pause_relay.sh b/tests/dmctl_basic/check_list/pause_relay.sh new file mode 100644 index 0000000000..82b8fcb7dd --- /dev/null +++ b/tests/dmctl_basic/check_list/pause_relay.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +function pause_relay_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "pause-relay wrong_arg" \ + "pause-relay <-w worker ...> \[flags\]" 1 +} + +function pause_relay_wihout_worker() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "pause-relay" \ + "must specify at least one dm-worker" 1 +} + +function pause_relay_while_master_down() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "pause-relay -w 127.0.0.1:$WORKER1_PORT -w 127.0.0.1:$WORKER2_PORT" \ + "can not pause relay unit:" 1 +} + +function pause_relay_success() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "pause-relay -w 127.0.0.1:$WORKER1_PORT -w 127.0.0.1:$WORKER2_PORT" \ + "\"result\": true" 3 +} + +function pause_relay_fail() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "pause-relay -w 127.0.0.1:$WORKER1_PORT -w 127.0.0.1:$WORKER2_PORT" \ + "\"result\": true" 1 \ + "\"result\": false" 2 \ + "\"msg\": \"current stage is Paused, Running required" 2 +} diff --git a/tests/dmctl_basic/check_list/pause_task.sh b/tests/dmctl_basic/check_list/pause_task.sh new file mode 100644 index 0000000000..1c7fdcad60 --- /dev/null +++ b/tests/dmctl_basic/check_list/pause_task.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +function pause_task_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "pause-task" \ + "pause-task \[-w worker ...\] \[flags\]" 1 +} + +function pause_task_while_master_down() { + task_name="any_task_name" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "pause-task $task_name" \ + "can not pause task $task_name:" 1 +} + +function pause_task_success() { + task_name=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "pause-task $task_name" \ + "\"result\": true" 3 \ + "\"op\": \"Pause\"" 3 +} diff --git a/tests/dmctl_basic/check_list/purge_relay.sh b/tests/dmctl_basic/check_list/purge_relay.sh new file mode 100644 index 0000000000..93a52656aa --- /dev/null +++ b/tests/dmctl_basic/check_list/purge_relay.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +function purge_relay_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "purge-relay wrong_arg" \ + "purge-relay <-w worker> \[--filename\] \[--sub-dir\] \[flags\]" 1 +} + +function purge_relay_wihout_worker() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "purge-relay" \ + "must specify at least one dm-worker (\`-w\` \/ \`--worker\`)" 1 +} + +function purge_relay_filename_with_multi_workers() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "purge-relay --filename bin-000001 -w 127.0.0.1:$WORKER1_PORT -w 127.0.0.1:$WORKER2_PORT" \ + "for --filename, can only specify one dm-worker per time" 1 +} + +function purge_relay_while_master_down() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "purge-relay --filename bin-000001 -w 127.0.0.1:$WORKER1_PORT" \ + "can not purge relay log files:" 1 +} + +function purge_relay_success() { + binlog_file=$1 + worker_addr=$2 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "purge-relay --filename $binlog_file -w $worker_addr" \ + "\"result\": true" 2 +} diff --git a/tests/dmctl_basic/check_list/query_status.sh b/tests/dmctl_basic/check_list/query_status.sh new file mode 100644 index 0000000000..7a9584261e --- /dev/null +++ b/tests/dmctl_basic/check_list/query_status.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +function query_status_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "query-status wrong_args_count more_than_one" \ + "query-status \[-w worker ...\] \[task_name\]" 1 +} + +function query_status_wrong_params() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "query-status -w worker-x task-y" \ + "can not query task-y task's status(in workers \[worker-x\]):" 1 +} + +function query_status_with_no_tasks() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "query-status" \ + "\"result\": true" 3 \ + "\"msg\": \"no sub task started\"" 2 +} + +function query_status_with_tasks() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "query-status" \ + "\"result\": true" 3 \ + "\"unit\": \"Sync\"" 2 \ + "\"stage\": \"Running\"" 4 +} + +function query_status_stopped_relay() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "query-status" \ + "\"result\": true" 3 \ + "\"stage\": \"Paused\"" 2 +} diff --git a/tests/dmctl_basic/check_list/resume_relay.sh b/tests/dmctl_basic/check_list/resume_relay.sh new file mode 100644 index 0000000000..2e7caf784a --- /dev/null +++ b/tests/dmctl_basic/check_list/resume_relay.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +: ' +TODO +» resume-relay -w 172.17.0.6:8262 -w 172.17.0.2:8262 +{ + "op": "InvalidRelayOp", + "result": true, + "msg": "", + "workers": [ + { + "op": "ResumeRelay", + "result": true, + "worker": "172.17.0.2:8262", + "msg": "" + }, + { + "op": "ResumeRelay", + "result": true, + "worker": "172.17.0.6:8262", + "msg": "" + } + ] +} +' + +function resume_relay_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "resume-relay wrong_arg" \ + "resume-relay <-w worker ...> \[flags\]" 1 +} + +function resume_relay_wihout_worker() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "resume-relay" \ + "must specify at least one dm-worker" 1 +} + +function resume_relay_while_master_down() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "resume-relay -w 127.0.0.1:$WORKER1_PORT -w 127.0.0.1:$WORKER2_PORT" \ + "can not resume relay unit:" 1 +} + +function resume_relay_success() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "resume-relay -w 127.0.0.1:$WORKER1_PORT -w 127.0.0.1:$WORKER2_PORT" \ + "\"result\": true" 3 +} diff --git a/tests/dmctl_basic/check_list/resume_task.sh b/tests/dmctl_basic/check_list/resume_task.sh new file mode 100644 index 0000000000..57cfb92053 --- /dev/null +++ b/tests/dmctl_basic/check_list/resume_task.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +function resume_task_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "resume-task" \ + "resume-task \[-w worker ...\] \[flags\]" 1 +} + +function resume_task_while_master_down() { + task_name="any_task_name" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "resume-task $task_name" \ + "can not resume task $task_name:" 1 +} + +function resume_task_success() { + task_name=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "resume-task $task_name" \ + "\"result\": true" 3 \ + "\"op\": \"Resume\"" 3 +} diff --git a/tests/dmctl_basic/check_list/show_ddl_locks.sh b/tests/dmctl_basic/check_list/show_ddl_locks.sh new file mode 100644 index 0000000000..e9c540eaa1 --- /dev/null +++ b/tests/dmctl_basic/check_list/show_ddl_locks.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +function show_ddl_locks_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "show-ddl-locks a b" \ + "show-ddl-locks \[-w worker ...\] \[task_name\] \[flags\]" 1 +} + +function show_ddl_locks_while_master_down() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "show-ddl-locks task_name -w 127.0.0.1:8262" \ + "can not show DDL locks for task task_name and workers \[127.0.0.1:8262\]" 1 +} + +function show_ddl_locks_no_locks() { + task_name=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "show-ddl-locks $task_name" \ + "\"msg\": \"no DDL lock exists\"" 1 +} + +function show_ddl_locks_with_locks() { + lock_id=$1 + ddl=$2 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "show-ddl-locks" \ + "\"ID\": \"$lock_id\"" 1 \ + "$ddl" 1 +} diff --git a/tests/dmctl_basic/check_list/start_task.sh b/tests/dmctl_basic/check_list/start_task.sh new file mode 100644 index 0000000000..90f3ea3754 --- /dev/null +++ b/tests/dmctl_basic/check_list/start_task.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +function start_task_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "start-task" \ + "start-task \[-w worker ...\] \[flags\]" 1 +} + +function start_task_wrong_config_file() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "start-task not_exists_config_file" \ + "get file content error" 1 +} + +function start_task_while_master_down() { + task_conf=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "start-task $task_conf" \ + "can not start task:" 1 +} diff --git a/tests/dmctl_basic/check_list/stop_task.sh b/tests/dmctl_basic/check_list/stop_task.sh new file mode 100644 index 0000000000..aa00fa11a0 --- /dev/null +++ b/tests/dmctl_basic/check_list/stop_task.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +function stop_task_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "stop-task" \ + "stop-task \[-w worker ...\] \[flags\]" 1 +} + +function stop_task_while_master_down() { + task_name="any_task_name" + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "stop-task $task_name" \ + "can not stop task $task_name:" 1 +} diff --git a/tests/dmctl_basic/check_list/update_master_config.sh b/tests/dmctl_basic/check_list/update_master_config.sh new file mode 100644 index 0000000000..06ffca2f63 --- /dev/null +++ b/tests/dmctl_basic/check_list/update_master_config.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +function update_master_config_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-master-config" \ + "update-master-config \[flags\]" 1 +} + +function update_master_config_wrong_config_file() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-master-config not_exists_config_file" \ + "get file content error" 1 +} + +function update_master_config_while_master_down() { + master_conf=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-master-config $master_conf" \ + "can not update master config:" 1 +} + +function update_master_config_success() { + master_conf=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-master-config $master_conf" \ + "\"result\": true" 3 \ + "\"unit\": \"Sync\"" 2 \ + "\"stage\": \"Running\"" 4 +} diff --git a/tests/dmctl_basic/check_list/update_relay.sh b/tests/dmctl_basic/check_list/update_relay.sh new file mode 100644 index 0000000000..68c5196fdf --- /dev/null +++ b/tests/dmctl_basic/check_list/update_relay.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +function update_relay_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-relay" \ + "update-relay \[-w worker ...\] \[flags\]" 1 +} + +function update_relay_wrong_config_file() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-relay not_exists_config_file" \ + "get file content error" 1 +} + +function update_relay_should_specify_one_dm_worker() { + task_conf=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-relay $task_conf" \ + "must specify one dm-worker (\`-w\` \/ \`--worker\`)" 1 +} + +function update_relay_while_master_down() { + task_conf=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-relay $task_conf -w 127.0.0.1:$WORKER1_PORT" \ + "can not update relay config:" 1 +} + +function update_relay_success() { + task_conf=$1 + worker_addr=$2 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-relay $task_conf -w $worker_addr" \ + "\"result\": true" 1 +} diff --git a/tests/dmctl_basic/check_list/update_task.sh b/tests/dmctl_basic/check_list/update_task.sh new file mode 100644 index 0000000000..031ffd834a --- /dev/null +++ b/tests/dmctl_basic/check_list/update_task.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +function update_task_wrong_arg() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-task" \ + "update-task \[-w worker ...\] \[flags\]" 1 +} + +function update_task_wrong_config_file() { + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-task not_exists_config_file" \ + "get file content error" 1 +} + +function update_task_while_master_down() { + task_conf=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-task $task_conf" \ + "can not update task:" 1 +} + +function update_task_worker_not_found() { + task_conf=$1 + not_found_worker_addr=$2 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-task $task_conf -w $not_found_worker_addr " \ + "\"result\": true" 1 \ + "\"result\": false" 1 \ + "\"worker\": \"$not_found_worker_addr\"" 1 \ + "\"msg\": \"worker not found in task's config or deployment config\"" 1 +} + +function update_task_not_paused() { + task_conf=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-task $task_conf" \ + "\"result\": true" 1 \ + "\"result\": false" 2 \ + "can only update task on Paused stage, but current stage is Running" 2 +} + +function update_task_success_single_worker() { + task_conf=$1 + worker_addr=$2 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-task $task_conf -w $worker_addr" \ + "\"result\": true" 2 \ + "\"worker\": \"$worker_addr\"" 1 +} + +function update_task_success() { + task_conf=$1 + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "update-task $task_conf" \ + "\"result\": true" 3 +} diff --git a/tests/dmctl_basic/conf/diff_config.toml b/tests/dmctl_basic/conf/diff_config.toml new file mode 100644 index 0000000000..e4f9cfac3b --- /dev/null +++ b/tests/dmctl_basic/conf/diff_config.toml @@ -0,0 +1,57 @@ +# diff Configuration. + +log-level = "info" + +chunk-size = 10 + +check-thread-count = 4 + +sample-percent = 100 + +use-rowid = false + +use-checksum = true + +fix-sql-file = "fix.sql" + +# tables need to check. +[[check-tables]] +schema = "dmctl" +tables = ["t_target"] + +[[table-config]] +schema = "dmctl" +table = "t_target" +remove-columns = ["id"] +is-sharding = true +index-fields = "b" + +[[table-config.source-tables]] +instance-id = "source-1" +schema = "dmctl" +table = "~t_.*" + +[[table-config.source-tables]] +instance-id = "source-2" +schema = "dmctl" +table = "~t_.*" + +[[source-db]] +host = "127.0.0.1" +port = 3306 +user = "root" +password = "" +instance-id = "source-1" + +[[source-db]] +host = "127.0.0.1" +port = 3307 +user = "root" +password = "" +instance-id = "source-2" + +[target-db] +host = "127.0.0.1" +port = 4000 +user = "root" +password = "" diff --git a/tests/dmctl_basic/conf/dm-master.toml b/tests/dmctl_basic/conf/dm-master.toml new file mode 100644 index 0000000000..334e0de993 --- /dev/null +++ b/tests/dmctl_basic/conf/dm-master.toml @@ -0,0 +1,9 @@ +# Master Configuration. + +[[deploy]] +source-id = "mysql-replica-01" +dm-worker = "127.0.0.1:8262" + +[[deploy]] +source-id = "mysql-replica-02" +dm-worker = "127.0.0.1:8263" diff --git a/tests/dmctl_basic/conf/dm-task.yaml b/tests/dmctl_basic/conf/dm-task.yaml new file mode 100644 index 0000000000..4d7933ca30 --- /dev/null +++ b/tests/dmctl_basic/conf/dm-task.yaml @@ -0,0 +1,87 @@ +--- +name: test +task-mode: all +is-sharding: true +meta-schema: "dm_meta" +remove-meta: false +enable-heartbeat: true +timezone: "Asia/Shanghai" + +target-database: + host: "127.0.0.1" + port: 4000 + user: "root" + password: "" + +mysql-instances: + - source-id: "mysql-replica-01" + server-id: 101 + black-white-list: "instance" + route-rules: ["sharding-route-rules-table", "sharding-route-rules-schema"] + column-mapping-rules: ["instance-1"] + mydumper-config-name: "global" + loader-config-name: "global" + syncer-config-name: "global" + + - source-id: "mysql-replica-02" + server-id: 102 + black-white-list: "instance" + route-rules: ["sharding-route-rules-table", "sharding-route-rules-schema"] + column-mapping-rules: ["instance-2"] + mydumper-config-name: "global" + loader-config-name: "global" + syncer-config-name: "global" + +black-white-list: + instance: + do-dbs: ["dmctl"] + do-tables: + - db-name: "dmctl" + tbl-name: "~^t_[\\d]+" + +routes: + sharding-route-rules-table: + schema-pattern: dmctl + table-pattern: t_* + target-schema: dmctl + target-table: t_target + + sharding-route-rules-schema: + schema-pattern: dmctl + target-schema: dmctl + +column-mappings: + instance-1: + schema-pattern: "dmctl" + table-pattern: "t_*" + expression: "partition id" + source-column: "id" + target-column: "id" + arguments: ["1", "", "t_"] + + instance-2: + schema-pattern: "dmctl" + table-pattern: "t_*" + expression: "partition id" + source-column: "id" + target-column: "id" + arguments: ["2", "", "t_"] + +mydumpers: + global: + mydumper-path: "./bin/mydumper" + threads: 4 + chunk-filesize: 64 + skip-tz-utc: true + extra-args: "--regex '^dmctl.*'" + +loaders: + global: + pool-size: 16 + dir: "./dumped_data" + +syncers: + global: + worker-count: 16 + batch: 100 + max-retry: 100 diff --git a/tests/dmctl_basic/conf/dm-task2.yaml b/tests/dmctl_basic/conf/dm-task2.yaml new file mode 100644 index 0000000000..49e1588629 --- /dev/null +++ b/tests/dmctl_basic/conf/dm-task2.yaml @@ -0,0 +1,2 @@ +--- +description: "invalid task config" diff --git a/tests/dmctl_basic/conf/dm-worker1.toml b/tests/dmctl_basic/conf/dm-worker1.toml new file mode 100644 index 0000000000..62157e6cd2 --- /dev/null +++ b/tests/dmctl_basic/conf/dm-worker1.toml @@ -0,0 +1,15 @@ +# Worker Configuration. + +server-id = 101 +source-id = "mysql-replica-01" +flavor = "mysql" +meta-file = "relay.meta" +enable-gtid = false +relay-binlog-name = "" +relay-binlog-gtid = "" + +[from] +host = "127.0.0.1" +user = "root" +password = "" +port = 3306 diff --git a/tests/dmctl_basic/conf/dm-worker2.toml b/tests/dmctl_basic/conf/dm-worker2.toml new file mode 100644 index 0000000000..7edb4c5415 --- /dev/null +++ b/tests/dmctl_basic/conf/dm-worker2.toml @@ -0,0 +1,15 @@ +# Worker Configuration. + +server-id = 102 +source-id = "mysql-replica-02" +flavor = "mysql" +meta-file = "relay.meta" +enable-gtid = false +relay-binlog-name = "" +relay-binlog-gtid = "" + +[from] +host = "127.0.0.1" +user = "root" +password = "" +port = 3307 diff --git a/tests/dmctl_basic/data/db1.increment.sql b/tests/dmctl_basic/data/db1.increment.sql new file mode 100644 index 0000000000..1e2e6c30fe --- /dev/null +++ b/tests/dmctl_basic/data/db1.increment.sql @@ -0,0 +1,18 @@ +UPDATE `dmctl`.`t_2` SET `c` = 'lnVaSBHOTnAatvUmHZIZ' WHERE `id` = 6; +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1207302373,'slOcgVAMoRUmxBpRdUHe','h',10); +UPDATE `dmctl`.`t_1` SET `c` = 'uvSLJRmOHYLDDMM' WHERE `id` = 9; +DELETE FROM `dmctl`.`t_1` WHERE `id` = 2; +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (617131993,'Klf','dZLD',11); +UPDATE `dmctl`.`t_2` SET `d` = 'k' WHERE `id` = 3; +UPDATE `dmctl`.`t_1` SET `d` = 'Nlh' WHERE `id` = 4; +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (241968486,'LT','JRvYDYFX',12); +UPDATE `dmctl`.`t_1` SET `c` = 'BZbKSuZKitYG' WHERE `id` = 7; +DELETE FROM `dmctl`.`t_2` WHERE `id` = 3; +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (207449096,'upYYtysTjztxkYGprAHD','drBN',11); +UPDATE `dmctl`.`t_2` SET `c` = 'AVKxHwiUZHXXKqODQoE' WHERE `id` = 8; +UPDATE `dmctl`.`t_2` SET `d` = 'eLmCZwCA' WHERE `id` = 9; +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (683005299,'lsATr','mNOpyfu',12); +UPDATE `dmctl`.`t_2` SET `d` = 'uVNNR' WHERE `id` = 6; +DELETE FROM `dmctl`.`t_2` WHERE `id` = 5; +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (373155634,'uoxJTwvCSEuaRbWGq','xzCteQqZwU',13); +UPDATE `dmctl`.`t_1` SET `d` = 'GzYx' WHERE `id` = 6; diff --git a/tests/dmctl_basic/data/db1.increment2.sql b/tests/dmctl_basic/data/db1.increment2.sql new file mode 100644 index 0000000000..a2fb356b83 --- /dev/null +++ b/tests/dmctl_basic/data/db1.increment2.sql @@ -0,0 +1,16 @@ +alter table `dmctl`.`t_1` drop column d; +alter table `dmctl`.`t_2` drop column d; +UPDATE `dmctl`.`t_1` SET `c` = 'QFEcT' WHERE `id` = 10; +DELETE FROM `dmctl`.`t_1` WHERE `id` = 11; +UPDATE `dmctl`.`t_1` SET `c` = 'ZRmjDMtWnZPBZvhSro' WHERE `id` = 6; +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`id`) VALUES (313784820,'ZkbuUB',13); +UPDATE `dmctl`.`t_2` SET `c` = 'svFHgFGGyNxhYgVbBQb' WHERE `id` = 11; +DELETE FROM `dmctl`.`t_1` WHERE `id` = 7; +UPDATE `dmctl`.`t_1` SET `c` = 'qgS' WHERE `id` = 6; +UPDATE `dmctl`.`t_2` SET `c` = 'tGkT' WHERE `id` = 6; +DELETE FROM `dmctl`.`t_1` WHERE `id` = 3; +UPDATE `dmctl`.`t_2` SET `c` = 'VbHXy' WHERE `id` = 11; +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`id`) VALUES (1650592031,'zPoGCCQaFWKK',14); +UPDATE `dmctl`.`t_1` SET `c` = 'FXKXbvEYVFCuohnU' WHERE `id` = 6; +DELETE FROM `dmctl`.`t_2` WHERE `id` = 2; +UPDATE `dmctl`.`t_1` SET `c` = 'hZGaWSRlrcmd' WHERE `id` = 5; diff --git a/tests/dmctl_basic/data/db1.prepare.sql b/tests/dmctl_basic/data/db1.prepare.sql new file mode 100644 index 0000000000..7340744445 --- /dev/null +++ b/tests/dmctl_basic/data/db1.prepare.sql @@ -0,0 +1,24 @@ +drop database if exists `dmctl`; +create database `dmctl`; +use `dmctl`; +create table t_1(id bigint auto_increment, b int, c varchar(20), d varchar(10), primary key id(id), unique key b(b)); +create table t_2(id bigint auto_increment, b int, c varchar(20), d varchar(10), primary key id(id), unique key b(b)); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (1795844527,'mpNYtz','JugWqaHw',1); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (816772144,'jjoPwqhBWpJyUUvgGWkp','FgPbiUqrvS',2); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (1058572812,'dCmAIAuZrNUJxBl','wiaFgp',3); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1825468799,'DWzgtMAwUcoqZvupwm','GsusfUlbB',1); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (265700472,'rEsjuTsIS','JPTd',2); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (763390433,'TE','jbO',4); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1112494892,'XDbXXvYTtJFLaF','zByU',3); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (61186151,'gXhXNtk','Hi',5); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (1190671373,'WGP','jUXxu',6); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (1192770284,'SyMVcUeK','MIZNFu',7); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1647531504,'yNvqWnrbtTxc','ogSwAofM',4); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1041099481,'zrO','C',5); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (1635431660,'pum','MMtT',8); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (208389298,'ZvhKh','Zt',6); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (2128788808,'hgWB','poUlMgBSX',9); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (1758036092,'CxSfGQNebY','OY',10); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1649664004,'eIXDUjODpLjRkXu','NWlGjQq',7); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1402446429,'xQMCGsfckXpoe','R',8); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (800180420,'JuUIxUacksp','sX',9); diff --git a/tests/dmctl_basic/data/db2.increment.sql b/tests/dmctl_basic/data/db2.increment.sql new file mode 100644 index 0000000000..250cf448a4 --- /dev/null +++ b/tests/dmctl_basic/data/db2.increment.sql @@ -0,0 +1,24 @@ +UPDATE `dmctl`.`t_2` SET `d` = 'S' WHERE `id` = 8; +DELETE FROM `dmctl`.`t_1` WHERE `id` = 7; +UPDATE `dmctl`.`t_2` SET `c` = 'pvHeDtXdNQBzc' WHERE `id` = 9; +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1533333567,'BEY','nQE',10); +UPDATE `dmctl`.`t_1` SET `c` = 'UcRjvtdgeAMmmTdd' WHERE `id` = 2; +DELETE FROM `dmctl`.`t_1` WHERE `id` = 7; +UPDATE `dmctl`.`t_1` SET `c` = 'oZTluknwkIgUYEkPdB' WHERE `id` = 7; +UPDATE `dmctl`.`t_1` SET `c` = 'ZcjYaJnh' WHERE `id` = 5; +DELETE FROM `dmctl`.`t_2` WHERE `id` = 6; +UPDATE `dmctl`.`t_1` SET `d` = 'QVAzYmqx' WHERE `id` = 4; +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (815122675,'AkDfRfFpyuMPyU','nOZwdjK',11); +UPDATE `dmctl`.`t_1` SET `c` = 'SNceJrNMU' WHERE `id` = 6; +DELETE FROM `dmctl`.`t_2` WHERE `id` = 9; +UPDATE `dmctl`.`t_1` SET `d` = 'VACozkE' WHERE `id` = 11; +UPDATE `dmctl`.`t_2` SET `d` = 'Xczvw' WHERE `id` = 4; +DELETE FROM `dmctl`.`t_1` WHERE `id` = 2; +UPDATE `dmctl`.`t_2` SET `c` = 'WgFBYecVDGxyytTQNF' WHERE `id` = 7; +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1929704764,'hKXJjNu','PzUETJSZdU',12); +UPDATE `dmctl`.`t_1` SET `d` = 'ZMdgI' WHERE `id` = 4; +DELETE FROM `dmctl`.`t_2` WHERE `id` = 1; +UPDATE `dmctl`.`t_1` SET `c` = 'oP' WHERE `id` = 9; +UPDATE `dmctl`.`t_1` SET `c` = 'fNxtLysT' WHERE `id` = 10; +DELETE FROM `dmctl`.`t_1` WHERE `id` = 3; +UPDATE `dmctl`.`t_1` SET `d` = 'gQjjJwwJ' WHERE `id` = 10; diff --git a/tests/dmctl_basic/data/db2.increment2.sql b/tests/dmctl_basic/data/db2.increment2.sql new file mode 100644 index 0000000000..01e90cc9ac --- /dev/null +++ b/tests/dmctl_basic/data/db2.increment2.sql @@ -0,0 +1,18 @@ +alter table `dmctl`.`t_1` drop column d; +alter table `dmctl`.`t_2` drop column d; +UPDATE `dmctl`.`t_1` SET `c` = 'ex' WHERE `id` = 12; +DELETE FROM `dmctl`.`t_1` WHERE `id` = 5; +UPDATE `dmctl`.`t_2` SET `c` = 'KOhDazkRuLagpqgq' WHERE `id` = 7; +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`id`) VALUES (2046853891,'YiPcpg',13); +UPDATE `dmctl`.`t_1` SET `c` = 'TRBVSNLTT' WHERE `id` = 5; +DELETE FROM `dmctl`.`t_2` WHERE `id` = 3; +UPDATE `dmctl`.`t_2` SET `c` = 'pEUUHDOepmEqQ' WHERE `id` = 3; +UPDATE `dmctl`.`t_1` SET `c` = 'yYVYjZd' WHERE `id` = 1; +DELETE FROM `dmctl`.`t_2` WHERE `id` = 8; +UPDATE `dmctl`.`t_2` SET `c` = 'kQPauwPFQgoNkBK' WHERE `id` = 2; +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`id`) VALUES (1328787895,'zGpfwmts',9); +UPDATE `dmctl`.`t_1` SET `c` = 'CDzG' WHERE `id` = 12; +DELETE FROM `dmctl`.`t_1` WHERE `id` = 1; +UPDATE `dmctl`.`t_2` SET `c` = 'IWAyZsgmEdrO' WHERE `id` = 2; +UPDATE `dmctl`.`t_1` SET `c` = 'OQyXDeydLVAEIwrRrTG' WHERE `id` = 11; +DELETE FROM `dmctl`.`t_2` WHERE `id` = 2; diff --git a/tests/dmctl_basic/data/db2.prepare.sql b/tests/dmctl_basic/data/db2.prepare.sql new file mode 100644 index 0000000000..bdc6c149fa --- /dev/null +++ b/tests/dmctl_basic/data/db2.prepare.sql @@ -0,0 +1,23 @@ +drop database if exists `dmctl`; +create database `dmctl`; +use `dmctl`; +create table t_1(id bigint auto_increment, b int, c varchar(20), d varchar(10), primary key id(id), unique key b(b)); +create table t_2(id bigint auto_increment, b int, c varchar(20), d varchar(10), primary key id(id), unique key b(b)); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (536247973,'FdkqoydEmwL','cnmrQHkMMD',1); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (625546463,'dgwvtEydzZa','rvuaa',1); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1339059405,'DS','rRbbWfXU',2); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (1021801725,'izDZdmGeoeYpyn','YHX',2); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (1547191572,'qkdHwHe','OZI',3); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (804011834,'cDVHrSBD','ZGzWk',3); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (1258473138,'nnTUUdsTOnYsHD','Nz',4); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (161128134,'arowzAebwoHBc','Wnux',4); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (783636444,'OYlOy','BMkikT',5); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1272018652,'DYpcqArfWolhOhiab','QyzbNqC',6); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (1674064434,'HcgEkwijLzTp','CKAuh',7); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (275890580,'iroFHGFVsqQyTOvILGTB','jyo',8); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (751446388,'MJcpP','aNMJ',5); +INSERT INTO `dmctl`.`t_1` (`b`,`c`,`d`,`id`) VALUES (844436321,'IxWEwsmadiKId','fw',9); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (1394310997,'DLRg','KzhFXaFV',6); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (399622170,'sE','DwDwBOEiJ',7); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (584262288,'caXN','SN',8); +INSERT INTO `dmctl`.`t_2` (`b`,`c`,`d`,`id`) VALUES (611154797,'zcsTrw','WRqA',9); diff --git a/tests/dmctl_basic/run.sh b/tests/dmctl_basic/run.sh new file mode 100755 index 0000000000..3b65f955f9 --- /dev/null +++ b/tests/dmctl_basic/run.sh @@ -0,0 +1,190 @@ +#!/bin/bash + +set -eu + +cur=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +source $cur/../_utils/test_prepare +WORK_DIR=$TEST_DIR/$TEST_NAME +TASK_CONF=$cur/conf/dm-task.yaml +TASK_NAME="test" +WORKER1_CONF=$cur/conf/dm-worker1.toml +SQL_RESULT_FILE="$TEST_DIR/sql_res.$TEST_NAME.txt" + +# used to coverage wrong usage of dmctl command +function usage_and_arg_test() { + check_task_wrong_arg + check_task_wrong_config_file + check_task_while_master_down $TASK_CONF + + pause_relay_wrong_arg + pause_relay_wihout_worker + pause_relay_while_master_down + + resume_relay_wrong_arg + resume_relay_wihout_worker + resume_relay_while_master_down + + pause_task_wrong_arg + pause_task_while_master_down + + resume_task_wrong_arg + resume_task_while_master_down + + query_status_wrong_arg + query_status_wrong_params + + start_task_wrong_arg + start_task_wrong_config_file + start_task_while_master_down $TASK_CONF + + stop_task_wrong_arg + stop_task_while_master_down + + show_ddl_locks_wrong_arg + show_ddl_locks_while_master_down + + update_relay_wrong_arg + update_relay_wrong_config_file + update_relay_should_specify_one_dm_worker $WORKER1_CONF + update_relay_while_master_down $WORKER1_CONF + + update_task_wrong_arg + update_task_wrong_config_file + update_task_while_master_down $TASK_CONF + + update_master_config_wrong_arg + update_master_config_wrong_config_file + update_master_config_while_master_down $cur/conf/dm-master.toml + + purge_relay_wrong_arg + purge_relay_wihout_worker + purge_relay_filename_with_multi_workers + purge_relay_while_master_down +} + +function recover_max_binlog_size() { + run_sql "set @@global.max_binlog_size = $1" $MYSQL_PORT1 + run_sql "set @@global.max_binlog_size = $2" $MYSQL_PORT2 +} + +function run() { + run_sql "show variables like 'max_binlog_size'\G" $MYSQL_PORT1 + max_binlog_size1=$(tail -n 1 "$TEST_DIR/sql_res.$TEST_NAME.txt" | awk '{print $NF}') + run_sql "show variables like 'max_binlog_size'\G" $MYSQL_PORT2 + max_binlog_size2=$(tail -n 1 "$TEST_DIR/sql_res.$TEST_NAME.txt" | awk '{print $NF}') + run_sql "set @@global.max_binlog_size = 16384" $MYSQL_PORT1 + run_sql "set @@global.max_binlog_size = 16384" $MYSQL_PORT2 + trap "recover_max_binlog_size $max_binlog_size1 $max_binlog_size2" EXIT + + run_sql_file $cur/data/db1.prepare.sql $MYSQL_HOST1 $MYSQL_PORT1 + run_sql_file $cur/data/db2.prepare.sql $MYSQL_HOST2 $MYSQL_PORT2 + + cd $cur + for file in "check_list"/*; do + source $file + done + cd - + + usage_and_arg_test + + mkdir -p $WORK_DIR/master $WORK_DIR/worker1 $WORK_DIR/worker2 + dm_master_conf="$WORK_DIR/master/dm-master.toml" + dm_worker1_conf="$WORK_DIR/worker1/dm-worker.toml" + dm_worker2_conf="$WORK_DIR/worker2/dm-worker.toml" + cp $cur/conf/dm-worker1.toml $dm_worker1_conf + cp $cur/conf/dm-worker2.toml $dm_worker2_conf + cp $cur/conf/dm-master.toml $dm_master_conf + + run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $dm_worker1_conf + check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT + run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $dm_worker2_conf + check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT + run_dm_master $WORK_DIR/master $MASTER_PORT $dm_master_conf + check_rpc_alive $cur/../bin/check_master_online 127.0.0.1:$MASTER_PORT + + pause_relay_success + query_status_stopped_relay + pause_relay_fail + resume_relay_success + query_status_with_no_tasks + + check_task_pass $TASK_CONF + check_task_not_pass $cur/conf/dm-task2.yaml + + dmctl_start_task + check_sync_diff $WORK_DIR $cur/conf/diff_config.toml + update_task_not_paused $TASK_CONF + + show_ddl_locks_no_locks $TASK_NAME + query_status_with_tasks + pause_task_success $TASK_NAME + + update_task_worker_not_found $TASK_CONF 127.0.0.1:9999 + update_task_success_single_worker $TASK_CONF 127.0.0.1:$WORKER1_PORT + update_task_success $TASK_CONF + + run_sql_file $cur/data/db1.increment.sql $MYSQL_HOST1 $MYSQL_PORT1 + run_sql_file $cur/data/db2.increment.sql $MYSQL_HOST2 $MYSQL_PORT2 + resume_task_success $TASK_NAME + check_sync_diff $WORK_DIR $cur/conf/diff_config.toml 20 + + update_relay_success $dm_worker1_conf 127.0.0.1:$WORKER1_PORT + update_relay_success $dm_worker2_conf 127.0.0.1:$WORKER2_PORT + # check worker config backup file is correct + [ -f $WORK_DIR/worker1/dm-worker-config.bak ] && cmp $WORK_DIR/worker1/dm-worker-config.bak $cur/conf/dm-worker1.toml + [ -f $WORK_DIR/worker2/dm-worker-config.bak ] && cmp $WORK_DIR/worker2/dm-worker-config.bak $cur/conf/dm-worker2.toml + # check worker config has been changed + md5_new_worker1=$(md5sum $dm_worker1_conf | awk '{print $1}') + md5_new_worker2=$(md5sum $dm_worker2_conf | awk '{print $1}') + md5_old_worker1=$(md5sum $cur/conf/dm-worker1.toml | awk '{print $1}') + md5_old_worker2=$(md5sum $cur/conf/dm-worker2.toml | awk '{print $1}') + [ "md5_new_worker1" != "md5_old_worker1" ] + [ "md5_new_worker2" != "md5_old_worker2" ] + + update_master_config_success $dm_master_conf + cmp $dm_master_conf $cur/conf/dm-master.toml + + run_sql_file $cur/data/db1.increment2.sql $MYSQL_HOST1 $MYSQL_PORT1 + set +e + i=0 + while [ $i -lt 10 ] + do + show_ddl_locks_with_locks "$TASK_NAME-\`dmctl\`.\`t_target\`" "ALTER TABLE \`dmctl\`.\`t_target\` DROP COLUMN \`d\`" + ((i++)) + if [ "$?" != 0 ]; then + echo "wait 1s and check for the $i-th time" + sleep 1 + else + break + fi + done + set -e + if [ $i -ge 10 ]; then + echo "show_ddl_locks_with_locks check timeout" + exit 1 + fi + run_sql_file $cur/data/db2.increment2.sql $MYSQL_HOST2 $MYSQL_PORT2 + check_sync_diff $WORK_DIR $cur/conf/diff_config.toml 10 + show_ddl_locks_no_locks $TASK_NAME + + server_uuid=$(tail -n 1 $WORK_DIR/worker1/relay_log/server-uuid.index) + run_sql "show binary logs\G" $MYSQL_PORT1 + max_binlog_name=$(grep Log_name "$SQL_RESULT_FILE"| tail -n 1 | awk -F":" '{print $NF}') + binlog_count=$(grep Log_name "$SQL_RESULT_FILE" | wc -l) + relay_log_count=$(($(ls $WORK_DIR/worker1/relay_log/$server_uuid | wc -l) - 1)) + [ "$binlog_count" -eq "$relay_log_count" ] + purge_relay_success $max_binlog_name 127.0.0.1:$WORKER1_PORT + new_relay_log_count=$(($(ls $WORK_DIR/worker1/relay_log/$server_uuid | wc -l) - 1)) + [ "$new_relay_log_count" -eq 1 ] +} + +cleanup1 dmctl +# also cleanup dm processes in case of last run failed +cleanup2 $* +run $* +cleanup2 $* + +wait_process_exit dm-master.test +wait_process_exit dm-worker.test + +echo "[$(date)] <<<<<< test case $TEST_NAME success! >>>>>>" diff --git a/tests/dmctl_tools/dmctl_operate_task.go b/tests/dmctl_tools/dmctl_operate_task.go deleted file mode 100644 index d097dfb831..0000000000 --- a/tests/dmctl_tools/dmctl_operate_task.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2019 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "context" - "fmt" - "os" - - "github.com/pingcap/dm/dm/pb" - "github.com/pingcap/dm/tests/utils" -) - -func main() { - if len(os.Args) != 3 { - utils.ExitWithError(fmt.Errorf("invlid args: %v", os.Args)) - } - cli, err := utils.CreateDmCtl("127.0.0.1:8261") - if err != nil { - utils.ExitWithError(err) - } - op, ok := pb.TaskOp_value[os.Args[1]] - if !ok { - utils.ExitWithError(fmt.Errorf("invalid op: %s", op)) - } - taskName := os.Args[2] - err = utils.OperateTask(context.Background(), cli, pb.TaskOp(op), taskName, nil) - if err != nil { - utils.ExitWithError(err) - } -} diff --git a/tests/incremental_mode/run.sh b/tests/incremental_mode/run.sh index c16e3e6338..f04bc5d087 100755 --- a/tests/incremental_mode/run.sh +++ b/tests/incremental_mode/run.sh @@ -26,11 +26,11 @@ function run() { # avoid cannot unmarshal !!str `binlog-...` into uint32 error sed -i "s/binlog-pos-placeholder-1/4/g" $WORK_DIR/dm-task.yaml sed -i "s/binlog-pos-placeholder-2/4/g" $WORK_DIR/dm-task.yaml - $cur/../bin/dmctl_start_task "$WORK_DIR/dm-task.yaml" + dmctl_start_task $WORK_DIR/dm-task.yaml check_sync_diff $WORK_DIR $cur/conf/diff_config.toml - $cur/../bin/dmctl_operate_task Stop $TASK_NAME + dmctl_stop_task $TASK_NAME run_sql_file $cur/data/db1.increment.sql $MYSQL_HOST1 $MYSQL_PORT1 run_sql_file $cur/data/db2.increment.sql $MYSQL_HOST2 $MYSQL_PORT2 @@ -46,7 +46,7 @@ function run() { sed -i "s/binlog-pos-placeholder-1/$pos1/g" $WORK_DIR/dm-task.yaml sed -i "s/binlog-name-placeholder-2/$name2/g" $WORK_DIR/dm-task.yaml sed -i "s/binlog-pos-placeholder-2/$pos2/g" $WORK_DIR/dm-task.yaml - $cur/../bin/dmctl_start_task "$WORK_DIR/dm-task.yaml" + dmctl_start_task $WORK_DIR/dm-task.yaml check_sync_diff $WORK_DIR $cur/conf/diff_config.toml } diff --git a/tests/load_interrupt/run.sh b/tests/load_interrupt/run.sh index f6aa9138b7..027eacbe7c 100755 --- a/tests/load_interrupt/run.sh +++ b/tests/load_interrupt/run.sh @@ -49,7 +49,7 @@ function run() { run_dm_master $WORK_DIR/master $MASTER_PORT $cur/conf/dm-master.toml check_rpc_alive $cur/../bin/check_master_online 127.0.0.1:$MASTER_PORT - $cur/../bin/dmctl_start_task "$cur/conf/dm-task.yaml" + dmctl_start_task check_port_offline $WORKER1_PORT 20 check_port_offline $WORKER2_PORT 20 diff --git a/tests/online_ddl/run.sh b/tests/online_ddl/run.sh index 1f534d6b19..4da580455a 100755 --- a/tests/online_ddl/run.sh +++ b/tests/online_ddl/run.sh @@ -24,7 +24,7 @@ function real_run() { # start DM task only cp $cur/conf/dm-task.yaml $WORK_DIR/dm-task-${online_ddl_scheme}.yaml sed -i "s/online-ddl-scheme-placeholder/${online_ddl_scheme}/g" $WORK_DIR/dm-task-${online_ddl_scheme}.yaml - $cur/../bin/dmctl_start_task "$WORK_DIR/dm-task-${online_ddl_scheme}.yaml" + dmctl_start_task "$WORK_DIR/dm-task-${online_ddl_scheme}.yaml" # use sync_diff_inspector to check full dump loader check_sync_diff $WORK_DIR $cur/conf/diff_config.toml diff --git a/tests/print_status/run.sh b/tests/print_status/run.sh index 46d2f6cea9..7186eb9c79 100755 --- a/tests/print_status/run.sh +++ b/tests/print_status/run.sh @@ -26,7 +26,7 @@ function run() { check_rpc_alive $cur/../bin/check_master_online 127.0.0.1:$MASTER_PORT # start DM task only - $cur/../bin/dmctl_start_task "$cur/conf/dm-task.yaml" + dmctl_start_task_standalone # use sync_diff_inspector to check full dump loader check_sync_diff $WORK_DIR $cur/conf/diff_config.toml diff --git a/tests/safe_mode/run.sh b/tests/safe_mode/run.sh index 2882dd48db..73450a66ec 100755 --- a/tests/safe_mode/run.sh +++ b/tests/safe_mode/run.sh @@ -22,7 +22,7 @@ function run() { run_dm_tracer $WORK_DIR/tracer $TRACER_PORT $cur/conf/dm-tracer.toml check_port_alive $TRACER_PORT - $cur/../bin/dmctl_start_task "$cur/conf/dm-task.yaml" + dmctl_start_task check_sync_diff $WORK_DIR $cur/conf/diff_config.toml # DM-worker exit during re-sync after sharding group synced diff --git a/tests/sharding/run.sh b/tests/sharding/run.sh index 7b35e9f727..5dd15cddbd 100755 --- a/tests/sharding/run.sh +++ b/tests/sharding/run.sh @@ -30,7 +30,7 @@ function run() { check_rpc_alive $cur/../bin/check_master_online 127.0.0.1:$MASTER_PORT # start DM task only - $cur/../bin/dmctl_start_task "$cur/conf/dm-task.yaml" + dmctl_start_task # TODO: check sharding partition id # use sync_diff_inspector to check full dump loader