github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/tests/dmctl_command/run.sh (about)

     1  #!/bin/bash
     2  
     3  set -eu
     4  
     5  cur=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
     6  source $cur/../_utils/test_prepare
     7  WORK_DIR=$TEST_DIR/$TEST_NAME
     8  
     9  db_name=$TEST_NAME
    10  
    11  # 43 normal help message + 1 "PASS" line
    12  help_cnt=44
    13  
    14  function get_uuid() {
    15  	uuid=$(echo "show variables like '%server_uuid%';" | MYSQL_PWD=123456 mysql -uroot -h$1 -P$2 | awk 'FNR == 2 {print $2}')
    16  	echo $uuid
    17  }
    18  
    19  function run() {
    20  	# check dmctl output with help flag
    21  	# it should usage for root command
    22  	$PWD/bin/dmctl.test DEVEL --help >$WORK_DIR/help.log
    23  	# since golang 1.20 there's one coverage line for each package, so we filter them
    24  	help_msg=$(cat $WORK_DIR/help.log | grep -v 'coverage:')
    25  	help_msg_cnt=$(echo "${help_msg}" | wc -l | xargs)
    26  	if [ "$help_msg_cnt" != $help_cnt ]; then
    27  		echo "dmctl case 1 help failed: $help_msg"
    28  		exit 1
    29  	fi
    30  
    31  	run_dm_master $WORK_DIR/master $MASTER_PORT $cur/conf/dm-master.toml
    32  	check_rpc_alive $cur/../bin/check_master_online 127.0.0.1:$MASTER_PORT
    33  	# check dmctl command start-task output with master-addr
    34  	# it should usage for start-task
    35  	$PWD/bin/dmctl.test DEVEL --master-addr=:$MASTER_PORT start-task >$WORK_DIR/help.log 2>&1 && exit 1 || echo "exit code should be not zero"
    36  	help_msg=$(cat $WORK_DIR/help.log)
    37  
    38  	echo $help_msg | grep -q "dmctl start-task"
    39  	if [ $? -ne 0 ]; then
    40  		echo "dmctl case 2 help failed: $help_msg"
    41  		exit 1
    42  	fi
    43  
    44  	# check dmctl command start-task output with master-addr and unknown flag
    45  	# it should print unknown command xxxx
    46  	$PWD/bin/dmctl.test DEVEL --master-addr=:$MASTER_PORT xxxx start-task >$WORK_DIR/help.log 2>&1 && exit 1 || echo "exit code should be not zero"
    47  	help_msg=$(cat $WORK_DIR/help.log)
    48  	help_msg_cnt=$(echo "${help_msg}" | wc -l | xargs)
    49  	if [ "$help_msg_cnt" -lt 1 ]; then
    50  		echo "dmctl case 3 help failed: $help_msg"
    51  		exit 1
    52  	fi
    53  	echo $help_msg | grep -q "unknown command \"xxxx\" for \"dmctl\""
    54  	if [ $? -ne 0 ]; then
    55  		echo "dmctl case 3 help failed: $help_msg"
    56  		exit 1
    57  	fi
    58  
    59  	# check dmctl command start-task --help
    60  	# it should print the usage for start-task
    61  	$PWD/bin/dmctl.test DEVEL start-task --help >$WORK_DIR/help.log
    62  	help_msg=$(cat $WORK_DIR/help.log)
    63  	help_msg_cnt=$(echo "${help_msg}" | grep "Usage:" | wc -l)
    64  	if [ "$help_msg_cnt" -ne 1 ]; then
    65  		echo "dmctl case 4 help failed: $help_msg"
    66  		exit 1
    67  	fi
    68  
    69  	# run normal task with command
    70  	run_sql_file $cur/data/db1.prepare.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1
    71  	check_contains 'Query OK, 2 rows affected'
    72  	run_sql_file $cur/data/db2.prepare.sql $MYSQL_HOST2 $MYSQL_PORT2 $MYSQL_PASSWORD2
    73  	check_contains 'Query OK, 3 rows affected'
    74  
    75  	run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $cur/conf/dm-worker1.toml
    76  	check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT
    77  	run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml
    78  	check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT
    79  
    80  	# without set secret-key-path, we cannot use encrypted password
    81  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
    82  		"operate-source create $cur/conf/source1-encrypted-pass.yaml" \
    83  		"\"result\": false" 1 \
    84  		"Access denied for user" 1
    85  
    86  	# check wrong backoff-max
    87  	cp $cur/conf/source1.yaml $WORK_DIR/wrong-source.yaml
    88  	sed -i "/relay-binlog-name/i\relay-dir: $WORK_DIR/worker1/relay_log" $WORK_DIR/wrong-source.yaml
    89  	sed -i "s/backoff-max: 5m/backoff-max: 0.1s/g" $WORK_DIR/wrong-source.yaml
    90  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
    91  		"operate-source create $WORK_DIR/wrong-source.yaml" \
    92  		"\"result\": false" 1 \
    93  		"Please increase \`backoff-max\`" 1
    94  
    95  	# operate mysql config to worker
    96  	cp $cur/conf/source1.yaml $WORK_DIR/source1.yaml
    97  	cp $cur/conf/source2.yaml $WORK_DIR/source2.yaml
    98  	sed -i "/relay-binlog-name/i\relay-dir: $WORK_DIR/worker1/relay_log" $WORK_DIR/source1.yaml
    99  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   100  		"operate-source create $WORK_DIR/source1.yaml -w $WORKER1_NAME" \
   101  		"\"result\": true" 2 \
   102  		"\"source\": \"mysql-replica-01\"" 1
   103  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   104  		"list-member --name worker1" \
   105  		"\"stage\": \"bound\"" 1 \
   106  		"\"source\": \"mysql-replica-01\"" 1
   107  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   108  		"operate-source create $WORK_DIR/source2.yaml -w wrong-worker" \
   109  		"\"result\": false" 1 \
   110  		"not exists" 1
   111  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   112  		"operate-source create $WORK_DIR/source2.yaml -w worker1" \
   113  		"\"result\": false" 1 \
   114  		"not free" 1
   115  	dmctl_operate_source create $WORK_DIR/source2.yaml $SOURCE_ID2
   116  
   117  	# check wrong do-tables
   118  	cp $cur/conf/dm-task.yaml $WORK_DIR/wrong-dm-task.yaml
   119  	sed -i "/do-dbs:/a\    do-tables:\n    - db-name: \"dmctl_command\"" $WORK_DIR/wrong-dm-task.yaml
   120  	sed -i "/do-dbs:/d" $WORK_DIR/wrong-dm-task.yaml
   121  	echo "ignore-checking-items: [\"all\"]" >>$WORK_DIR/wrong-dm-task.yaml
   122  
   123  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   124  		"start-task $WORK_DIR/wrong-dm-task.yaml" \
   125  		"Table string cannot be empty" 1
   126  
   127  	# check wrong chunk-filesize
   128  	cp $cur/conf/dm-task.yaml $WORK_DIR/wrong-dm-task.yaml
   129  	sed -i "s/chunk-filesize: 64/chunk-filesize: 6qwe4/g" $WORK_DIR/wrong-dm-task.yaml
   130  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   131  		"start-task $WORK_DIR/wrong-dm-task.yaml" \
   132  		"invalid \`chunk-filesize\` 6qwe4" 1
   133  
   134  	# start DM task with command mode
   135  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   136  		"start-task $cur/conf/dm-task.yaml" \
   137  		"\`remove-meta\` in task config is deprecated, please use \`start-task ... --remove-meta\` instead" 1
   138  	check_log_contains $WORK_DIR/master/log/dm-master.log "\`remove-meta\` in task config is deprecated, please use \`start-task ... --remove-meta\` instead"
   139  
   140  	# use sync_diff_inspector to check full dump loader
   141  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml
   142  
   143  	run_sql_file $cur/data/db1.increment.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1
   144  	run_sql_file $cur/data/db2.increment.sql $MYSQL_HOST2 $MYSQL_PORT2 $MYSQL_PASSWORD2
   145  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml
   146  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   147  		"validation status test" \
   148  		"\"processedRowsStatus\": \"insert\/update\/delete: 2\/1\/1\"" 1 \
   149  		"\"processedRowsStatus\": \"insert\/update\/delete: 0\/0\/1\"" 1 \
   150  		"pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 2 \
   151  		"new\/ignored\/resolved: 0\/0\/0" 2
   152  
   153  	# query status with command mode
   154  	$PWD/bin/dmctl.test DEVEL --master-addr=:$MASTER_PORT query-status >$WORK_DIR/query-status.log
   155  
   156  	# use DM_MASTER_ADDR env
   157  	export DM_MASTER_ADDR="127.0.0.1:$MASTER_PORT"
   158  	run_dm_ctl_with_retry $WORK_DIR "" \
   159  		"query-status test" \
   160  		"worker1" 1
   161  
   162  	running_task=$(grep -r Running $WORK_DIR/query-status.log | wc -l | xargs)
   163  
   164  	if [ "$running_task" != 1 ]; then
   165  		echo "query status failed with command: $running_task task"
   166  		exit 1
   167  	fi
   168  }
   169  
   170  function check_privilege() {
   171  	# test no enough privilege
   172  	cp $cur/conf/dm-task3.yaml $WORK_DIR/temp.yaml
   173  	sed -i "s/  user: \"root\"/  user: \"test1\"/g" $WORK_DIR/temp.yaml
   174  	run_sql_tidb "drop user if exists test1"
   175  	run_sql_tidb "create user test1;"
   176  	run_sql_tidb "grant select, create, insert, delete, alter, drop, index on *.* to test1;" # no super privilege
   177  	run_sql_tidb "flush privileges;"
   178  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   179  		"check-task $WORK_DIR/temp.yaml" \
   180  		"lack of Super global" 1
   181  	run_sql_tidb "drop user test1;"
   182  
   183  	run_sql_source1 "set @@GLOBAL.max_connections=151;"
   184  	run_sql_source2 "set @@GLOBAL.max_connections=151;"
   185  	run_sql_tidb "set @@GLOBAL.max_connections=151;"
   186  }
   187  
   188  function check_task_lightning() {
   189  	# unlimited connections: no need to warn
   190  	run_sql_tidb "set @@GLOBAL.max_connections=0;"
   191  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   192  		"check-task $cur/conf/dm-task2.yaml" \
   193  		"task precheck cannot accurately check the number of connection needed for Lightning" 0
   194  	run_sql_tidb "set @@GLOBAL.max_connections=5;"
   195  	# fail but give warning, because it's using Lightining
   196  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   197  		"check-task $cur/conf/dm-task2.yaml" \
   198  		"task precheck cannot accurately check the number of connection needed for Lightning" 1
   199  }
   200  
   201  function run_validation_start_stop_cmd {
   202  	cleanup_data dmctl_command
   203  	cleanup_data_upstream dmctl_command
   204  	cleanup_process $*
   205  
   206  	export GO_FAILPOINTS=""
   207  	run_dm_master $WORK_DIR/master $MASTER_PORT $cur/conf/dm-master.toml
   208  	check_rpc_alive $cur/../bin/check_master_online 127.0.0.1:$MASTER_PORT
   209  	run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $cur/conf/dm-worker1.toml
   210  	check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT
   211  	run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml
   212  	check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT
   213  
   214  	run_sql_file $cur/data/db1.prepare.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1
   215  	run_sql_file $cur/data/db2.prepare.sql $MYSQL_HOST2 $MYSQL_PORT2 $MYSQL_PASSWORD2
   216  
   217  	dmctl_operate_source create $cur/conf/source1.yaml $SOURCE_ID1
   218  	dmctl_operate_source create $cur/conf/source2.yaml $SOURCE_ID2
   219  	dmctl_start_task $cur/conf/dm-task-no-validator.yaml --remove-meta
   220  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   221  		"query-status test" \
   222  		"\"unit\": \"Sync\"" 2
   223  
   224  	echo "--> (fail) validation start: missing mode value"
   225  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   226  		"validation start --mode" \
   227  		"Error: flag needs an argument: --mode" 1
   228  
   229  	echo "--> (fail) validation start: invalid mode"
   230  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   231  		"validation start --mode xxx" \
   232  		"Error: mode should be either \`full\` or \`fast\`" 1
   233  
   234  	echo "--> (fail) validation start: missing start-time value"
   235  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   236  		"validation start --start-time" \
   237  		"Error: flag needs an argument: --start-time" 1
   238  
   239  	echo "--> (fail) validation start: invalid start-time"
   240  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   241  		"validation start --start-time xx" \
   242  		"Error: start-time should be in the format like '2006-01-02 15:04:05' or '2006-01-02T15:04:05'" 1
   243  
   244  	echo "--> (fail) validation start: without all-task and task-name"
   245  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   246  		"validation start --mode full" \
   247  		"Error: either \`task-name\` or \`all-task\` should be set" 1
   248  
   249  	echo "--> (fail) validation start: with both all-task and task-name"
   250  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   251  		"validation start --all-task test" \
   252  		"Error: either \`task-name\` or \`all-task\` should be set" 1
   253  
   254  	echo "--> (fail) validation start: too many arguments"
   255  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   256  		"validation start test test2" \
   257  		"Error: too many arguments are specified" 1
   258  
   259  	echo "--> (fail) validation start: non-existed subtask"
   260  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   261  		"validation start xxxxx" \
   262  		"\"result\": false" 1 \
   263  		"cannot get subtask by task name \`xxxxx\` and sources" 1
   264  
   265  	echo "--> (fail) validation start: non-exist source"
   266  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   267  		"validation start -s xxxxx --all-task" \
   268  		"\"result\": false" 1 \
   269  		"cannot get subtask by sources" 1
   270  
   271  	echo "--> (fail) validation stop: without all-task and task-name"
   272  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   273  		"validation stop" \
   274  		"Error: either \`task-name\` or \`all-task\` should be set" 1
   275  
   276  	echo "--> (fail) validation stop: with both all-task and task-name"
   277  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   278  		"validation stop --all-task test" \
   279  		"Error: either \`task-name\` or \`all-task\` should be set" 1
   280  
   281  	echo "--> (fail) validation stop: too many arguments"
   282  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   283  		"validation stop test test2" \
   284  		"Error: too many arguments are specified" 1
   285  
   286  	echo "--> (fail) validation stop: non-existed subtask"
   287  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   288  		"validation stop xxxxx" \
   289  		"\"result\": false" 1 \
   290  		"cannot get subtask by task name \`xxxxx\` and sources" 1
   291  
   292  	echo "--> (fail) validation stop: non-exist source"
   293  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   294  		"validation stop -s xxxxx --all-task" \
   295  		"\"result\": false" 1 \
   296  		"cannot get subtask by sources" 1
   297  
   298  	echo "--> (fail) validation stop: stop not-enabled validator"
   299  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   300  		"validation stop -s $SOURCE_ID1 test" \
   301  		"\"result\": false" 1 \
   302  		"some target validator(test with source $SOURCE_ID1) is not enabled" 1
   303  
   304  	echo "--> (success) validation start: start validation without explicit mode for source 1"
   305  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   306  		"validation start -s $SOURCE_ID1 test" \
   307  		"\"result\": true" 1
   308  	# right now validation status cannot check status of subtask.
   309  	# in the following case, it will be checked.
   310  
   311  	echo "--> (fail) validation start: start all validator with explicit mode, but 1 subtask already enabled"
   312  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   313  		"validation start --mode full test" \
   314  		"\"result\": false" 1 \
   315  		"some of target validator(test with source $SOURCE_ID1) has already enabled" 1
   316  
   317  	echo "--> (fail) validation start: start validation with explicit mode for source 1 again"
   318  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   319  		"validation start -s $SOURCE_ID1 --mode full test" \
   320  		"\"result\": false" 1 \
   321  		"all target validator has enabled, cannot do 'validation start' with explicit mode or start-time" 1
   322  
   323  	echo "--> (fail) validation start: start all validator without explicit mode"
   324  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   325  		"validation start test" \
   326  		"\"result\": false" 1 \
   327  		"some of target validator(test with source $SOURCE_ID1) has already enabled" 1
   328  
   329  	echo "--> (fail) validation stop: stop all but 1 subtask is not enabled"
   330  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   331  		"validation stop test" \
   332  		"\"result\": false" 1 \
   333  		"some target validator(test with source $SOURCE_ID2) is not enabled" 1
   334  
   335  	echo "--> (success) validation start: start validation with fast mode and start-time for source 2"
   336  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   337  		"validation start -s $SOURCE_ID2 --mode fast --start-time '2020-01-01 00:01:00' test" \
   338  		"\"result\": true" 1
   339  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   340  		"validation status test" \
   341  		"\"result\": true" 1 \
   342  		"\"mode\": \"full\"" 1 \
   343  		"\"mode\": \"fast\"" 1 \
   344  		"\"stage\": \"Running\"" 2 \
   345  		"\"stage\": \"Stopped\"" 0
   346  
   347  	echo "--> (success) validation start: start all validator of the task without explicit param again, i.e. resuming"
   348  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   349  		"validation start test" \
   350  		"\"result\": true" 1
   351  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   352  		"validation status test" \
   353  		"\"result\": true" 1 \
   354  		"\"mode\": \"full\"" 1 \
   355  		"\"mode\": \"fast\"" 1 \
   356  		"\"stage\": \"Running\"" 2 \
   357  		"\"stage\": \"Stopped\"" 0
   358  
   359  	echo "--> (success) validation stop: stop validation of source 1"
   360  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   361  		"validation stop -s $SOURCE_ID1 test" \
   362  		"\"result\": true" 1
   363  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   364  		"validation status test" \
   365  		"\"result\": true" 1 \
   366  		"\"mode\": \"full\"" 1 \
   367  		"\"mode\": \"fast\"" 1 \
   368  		"\"stage\": \"Running\"" 1 \
   369  		"\"stage\": \"Stopped\"" 1
   370  
   371  	echo "--> (success) validation stop: stop all of test"
   372  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   373  		"validation stop test" \
   374  		"\"result\": true" 1
   375  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   376  		"validation status test" \
   377  		"\"result\": true" 1 \
   378  		"\"mode\": \"full\"" 1 \
   379  		"\"mode\": \"fast\"" 1 \
   380  		"\"stage\": \"Running\"" 0 \
   381  		"\"stage\": \"Stopped\"" 2
   382  
   383  	echo "--> (success) validation stop: stop all of test again"
   384  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   385  		"validation stop test" \
   386  		"\"result\": true" 1
   387  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   388  		"validation status test" \
   389  		"\"result\": true" 1 \
   390  		"\"mode\": \"full\"" 1 \
   391  		"\"mode\": \"fast\"" 1 \
   392  		"\"stage\": \"Running\"" 0 \
   393  		"\"stage\": \"Stopped\"" 2
   394  
   395  	echo "--> (success) validation start: start all of test"
   396  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   397  		"validation start test" \
   398  		"\"result\": true" 1
   399  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   400  		"validation status test" \
   401  		"\"result\": true" 1 \
   402  		"\"mode\": \"full\"" 1 \
   403  		"\"mode\": \"fast\"" 1 \
   404  		"\"stage\": \"Running\"" 2 \
   405  		"\"stage\": \"Stopped\"" 0
   406  
   407  	echo "--> (success) validation stop: multiple source"
   408  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   409  		"validation stop -s $SOURCE_ID1 -s $SOURCE_ID2 test" \
   410  		"\"result\": true" 1
   411  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   412  		"validation status test" \
   413  		"\"result\": true" 1 \
   414  		"\"mode\": \"full\"" 1 \
   415  		"\"mode\": \"fast\"" 1 \
   416  		"\"stage\": \"Running\"" 0 \
   417  		"\"stage\": \"Stopped\"" 2
   418  
   419  	echo "--> (success) validation start: multiple source"
   420  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   421  		"validation start -s $SOURCE_ID1 -s $SOURCE_ID2 test" \
   422  		"\"result\": true" 1
   423  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   424  		"validation status test" \
   425  		"\"result\": true" 1 \
   426  		"\"mode\": \"full\"" 1 \
   427  		"\"mode\": \"fast\"" 1 \
   428  		"\"stage\": \"Running\"" 2 \
   429  		"\"stage\": \"Stopped\"" 0
   430  
   431  	dmctl_stop_task "test"
   432  	dmctl_start_task $cur/conf/dm-task-no-validator.yaml --remove-meta
   433  	dmctl_start_task_standalone $cur/conf/dm-task2-no-validator.yaml --remove-meta
   434  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   435  		"query-status test" \
   436  		"\"unit\": \"Sync\"" 2
   437  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   438  		"query-status test2" \
   439  		"\"unit\": \"Sync\"" 1
   440  	uuid=($(get_uuid $MYSQL_HOST2 $MYSQL_PORT2))
   441  	echo "--> (fail) validation update: on non-existed validator"
   442  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   443  		"validation update test -s $SOURCE_ID2 --cutover-binlog-gtid $uuid:1-999" \
   444  		"\"result\": false" 1 \
   445  		"validator not found for task" 1
   446  
   447  	echo "--> (success) validation start: start all tasks"
   448  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   449  		"validation start --all-task --mode fast" \
   450  		"\"result\": true" 1
   451  
   452  	echo "--> (fail) validation update: missing task-name"
   453  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   454  		"validation update" \
   455  		"\`task-name\` should be set" 1
   456  	echo "--> (fail) validation update: multi tasks"
   457  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   458  		"validation update test test2" \
   459  		"should specify only one" 1
   460  	echo "--> (fail) validation update: non-existed subtask"
   461  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   462  		"validation update xxxxx" \
   463  		"\"result\": false" 1 \
   464  		"cannot get subtask by task name \`xxxxx\`" 1
   465  	echo "--> (fail) validation update: non-exist source"
   466  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   467  		"validation update -s xxxxx test" \
   468  		"\"result\": false" 1 \
   469  		"cannot get subtask by task name \`test\` and sources" 1
   470  	echo "--> (fail) validation update: not specify cutover-binlog-gtid"
   471  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   472  		"validation update test -s $SOURCE_ID2" \
   473  		"\"result\": false" 1 \
   474  		"didn't specify cutover-binlog-gtid" 1
   475  	echo "--> (fail) validation update: not specify cutover-binlog-pos"
   476  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   477  		"validation update test2 -s $SOURCE_ID1" \
   478  		"\"result\": false" 1 \
   479  		"didn't specify cutover-binlog-pos" 1
   480  	echo "--> (fail) validation update: invalid cutover-binlog-pos"
   481  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   482  		"validation update test -s $SOURCE_ID1 --cutover-binlog-pos xxx" \
   483  		"invalid binlog pos" 1
   484  	echo "--> (fail) validation update: specify both cutover-binlog-pos and cutover-binlog-gtid"
   485  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   486  		"validation update test -s $SOURCE_ID1 --cutover-binlog-pos '(mysql-bin.000001, 2345)' --cutover-binlog-gtid $uuid:1-999" \
   487  		"you must specify either one of" 1
   488  	echo "--> (success) validation update: on exist source"
   489  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   490  		"validation update test -s $SOURCE_ID2 --cutover-binlog-gtid $uuid:1-999" \
   491  		"\"result\": true" 2
   492  
   493  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   494  		"validation status test" \
   495  		"\"result\": true" 1 \
   496  		"\"mode\": \"full\"" 0 \
   497  		"\"mode\": \"fast\"" 2 \
   498  		"\"stage\": \"Running\"" 2 \
   499  		"\"stage\": \"Stopped\"" 0 \
   500  		"\"cutoverBinlogPos\"" 2 \
   501  		"\"cutoverBinlogGtid\": \"$uuid:1-999\"" 1
   502  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   503  		"validation status test2" \
   504  		"\"result\": true" 1 \
   505  		"\"mode\": \"full\"" 0 \
   506  		"\"mode\": \"fast\"" 1 \
   507  		"\"stage\": \"Running\"" 1 \
   508  		"\"stage\": \"Stopped\"" 0 \
   509  		"\"cutoverBinlogPos\"" 1 \
   510  		"\"cutoverBinlogGtid\": \"$uuid:1-999\"" 0
   511  
   512  	echo "--> (success) validation stop: stop all tasks"
   513  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   514  		"validation stop --all-task" \
   515  		"\"result\": true" 1
   516  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   517  		"validation status test" \
   518  		"\"result\": true" 1 \
   519  		"\"mode\": \"full\"" 0 \
   520  		"\"mode\": \"fast\"" 2 \
   521  		"\"stage\": \"Running\"" 0 \
   522  		"\"stage\": \"Stopped\"" 2
   523  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   524  		"validation status test2" \
   525  		"\"result\": true" 1 \
   526  		"\"mode\": \"full\"" 0 \
   527  		"\"mode\": \"fast\"" 1 \
   528  		"\"stage\": \"Running\"" 0 \
   529  		"\"stage\": \"Stopped\"" 1
   530  }
   531  function query_status_disable_validator() {
   532  	dmctl_start_task $cur/conf/dm-task2.yaml --remove-meta
   533  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   534  		"query-status test2" \
   535  		"\"validation\": null"
   536  	dmctl_stop_task "test2"
   537  }
   538  
   539  function trigger_checkpoint_flush() {
   540  	sleep 1.5
   541  	run_sql_source1 "alter table $db_name.t1 comment 'a';" # force flush checkpoint
   542  }
   543  
   544  function prepare_for_validator_cmd {
   545  	cleanup_process $*
   546  	cleanup_data $db_name
   547  	cleanup_data_upstream $db_name
   548  	run_dm_master $WORK_DIR/master $MASTER_PORT $cur/conf/dm-master.toml
   549  	check_rpc_alive $cur/../bin/check_master_online 127.0.0.1:$MASTER_PORT
   550  	# skip incremental rows with id <= 2
   551  	export GO_FAILPOINTS='github.com/pingcap/tiflow/dm/syncer/SkipDML=return(2)'
   552  	run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $cur/conf/dm-worker1.toml
   553  	check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT
   554  	run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml
   555  	check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT
   556  
   557  	run_sql_file $cur/data/db1.prepare.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1
   558  	run_sql_file $cur/data/db2.prepare.sql $MYSQL_HOST2 $MYSQL_PORT2 $MYSQL_PASSWORD2
   559  
   560  	cp $cur/conf/source1.yaml $WORK_DIR/source1.yaml
   561  	cp $cur/conf/source2.yaml $WORK_DIR/source2.yaml
   562  	dmctl_operate_source create $WORK_DIR/source1.yaml $SOURCE_ID1
   563  	dmctl_operate_source create $WORK_DIR/source2.yaml $SOURCE_ID2
   564  
   565  	query_status_disable_validator
   566  
   567  	dmctl_start_task $cur/conf/dm-task.yaml --remove-meta
   568  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml
   569  
   570  	run_sql_source1 "insert into dmctl_command.t1 values(0,'ignore-row')"
   571  	run_sql_source1 "insert into dmctl_command.t1 values(-1,'ignore-row')"
   572  	run_sql_file $cur/data/db1.increment.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1
   573  	run_sql_file $cur/data/db2.increment.sql $MYSQL_HOST2 $MYSQL_PORT2 $MYSQL_PASSWORD2
   574  	# do not do sync diff this time, will fail
   575  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   576  		"validation status test" \
   577  		"\"processedRowsStatus\": \"insert\/update\/delete: 4\/1\/1\"" 1 \
   578  		"\"processedRowsStatus\": \"insert\/update\/delete: 0\/0\/1\"" 1 \
   579  		"pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 2 \
   580  		"new\/ignored\/resolved: 0\/0\/0" 1 \
   581  		"new\/ignored\/resolved: 4\/0\/0" 1 \
   582  		"\"stage\": \"Running\"" 4 \
   583  		"\"stage\": \"Stopped\"" 1
   584  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   585  		"query-status test" \
   586  		"insert\/update\/delete: 4\/1\/1\"" 1 \
   587  		"insert\/update\/delete: 0\/0\/1\"" 1 \
   588  		"new\/ignored\/resolved: 0\/0\/0" 1 \
   589  		"new\/ignored\/resolved: 4\/0\/0" 1
   590  	trigger_checkpoint_flush
   591  }
   592  
   593  function run_validator_cmd {
   594  	prepare_for_validator_cmd
   595  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   596  		"validation status test" \
   597  		"\"stage\": \"Running\"" 4 \
   598  		"\"stage\": \"Stopped\"" 1
   599  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   600  		"validation status --table-stage running test" \
   601  		"\"stage\": \"Running\"" 4 \
   602  		"\"stage\": \"Stopped\"" 0
   603  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   604  		"validation status --table-stage stopped test" \
   605  		"\"stage\": \"Running\"" 2 \
   606  		"\"stage\": \"Stopped\"" 1 \
   607  		"no primary key" 1
   608  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   609  		"validation show-error --error all test" \
   610  		"\"id\": \"1\"" 1 \
   611  		"\"id\": \"2\"" 1 \
   612  		"\"id\": \"3\"" 1 \
   613  		"\"id\": \"4\"" 1
   614  	run_validator_cmd_error
   615  	# resolve error 1
   616  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   617  		"validation resolve-error test 1"
   618  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   619  		"validation status test" \
   620  		"new\/ignored\/resolved: 3\/0\/1" 1
   621  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   622  		"validation show-error --error unprocessed test" \
   623  		"\"id\": \"2\"" 1 \
   624  		"\"id\": \"3\"" 1 \
   625  		"\"id\": \"4\"" 1
   626  	# default we show unprocessed
   627  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   628  		"validation show-error test" \
   629  		"\"id\": \"2\"" 1 \
   630  		"\"id\": \"3\"" 1 \
   631  		"\"id\": \"4\"" 1
   632  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   633  		"validation show-error --error all test" \
   634  		"\"id\": \"1\"" 1 \
   635  		"\"id\": \"2\"" 1 \
   636  		"\"id\": \"3\"" 1 \
   637  		"\"id\": \"4\"" 1
   638  	# ignore error 2
   639  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   640  		"validation ignore-error test 2"
   641  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   642  		"validation status test" \
   643  		"new\/ignored\/resolved: 2\/1\/1" 1
   644  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   645  		"validation show-error --error ignored test" \
   646  		"\"id\": \"2\"" 1
   647  	# clear error 1
   648  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   649  		"validation clear-error test 1"
   650  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   651  		"validation status test" \
   652  		"new\/ignored\/resolved: 2\/1\/0" 1
   653  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   654  		"validation show-error --error ignored test" \
   655  		"\"id\": \"2\"" 1
   656  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   657  		"validation clear-error test 2"
   658  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   659  		"validation status test" \
   660  		"new\/ignored\/resolved: 2\/0\/0" 1
   661  	# test we can get validation status even when it's stopped
   662  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   663  		"validation stop test" \
   664  		"\"result\": true" 1
   665  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   666  		"validation status test" \
   667  		"\"processedRowsStatus\": \"insert\/update\/delete: 4\/1\/1\"" 1 \
   668  		"\"processedRowsStatus\": \"insert\/update\/delete: 0\/0\/1\"" 1 \
   669  		"pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 2 \
   670  		"new\/ignored\/resolved: 0\/0\/0" 1 \
   671  		"new\/ignored\/resolved: 2\/0\/0" 1 \
   672  		"\"stage\": \"Running\"" 2 \
   673  		"\"stage\": \"Stopped\"" 3
   674  	# check the validator is stopped but syncer remains active
   675  	curl 127.0.0.1:$WORKER1_PORT/debug/pprof/goroutine?debug=2 >$WORK_DIR/goroutine.worker1
   676  	check_log_not_contains $WORK_DIR/goroutine.worker1 "validator"
   677  	check_log_contains $WORK_DIR/goroutine.worker1 "syncer"
   678  	curl 127.0.0.1:$WORKER2_PORT/debug/pprof/goroutine?debug=2 >$WORK_DIR/goroutine.worker2
   679  	check_log_not_contains $WORK_DIR/goroutine.worker2 "validator"
   680  	check_log_contains $WORK_DIR/goroutine.worker2 "syncer"
   681  	# still able to query validation error
   682  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   683  		"validation show-error --error all test" \
   684  		"\"id\": \"3\"" 1 \
   685  		"\"id\": \"4\"" 1
   686  	# still able to operate validation error
   687  	# ignore error 3
   688  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   689  		"validation ignore-error test 3"
   690  	# resolve error 4
   691  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   692  		"validation resolve-error test 4"
   693  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   694  		"validation status test" \
   695  		"new\/ignored\/resolved: 0\/1\/1" 1
   696  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   697  		"validation clear-error test --all"
   698  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   699  		"validation status test" \
   700  		"new\/ignored\/resolved: 0\/0\/0" 2
   701  	run_sql_source1 "insert into dmctl_command.t1 values(-10,'ignore-row')"
   702  	run_sql_source1 "create table dmctl_command.t_trigger_flush110(id int primary key)" # trigger flush
   703  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   704  		"query-status test" \
   705  		"\"synced\": true" 2 \
   706  		"\"stage\": \"Stopped\"" 2
   707  	run_sql_tidb "select * from dmctl_command.t1"
   708  	check_not_contains "id: -10" # sync failed due to GO_FAILPOINTS
   709  	# no validation error, because validator has been stopped
   710  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   711  		"validation status test" \
   712  		"new\/ignored\/resolved: 0\/0\/0" 2
   713  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   714  		"query-status test" \
   715  		"insert\/update\/delete: 4\/1\/1\"" 1 \
   716  		"insert\/update\/delete: 0\/0\/1\"" 1 \
   717  		"new\/ignored\/resolved: 0\/0\/0" 2
   718  
   719  	dmctl_stop_task "test"
   720  	echo "clean up data" # pre-check will not pass, since there is a table without pk
   721  	cleanup_data_upstream dmctl_command
   722  	cp $cur/conf/dm-task.yaml $WORK_DIR/dm-task.yaml
   723  	sed -i "s/    mode: full/    mode: none/g" $WORK_DIR/dm-task.yaml
   724  	dmctl_start_task $WORK_DIR/dm-task.yaml --remove-meta
   725  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   726  		"validation status test" \
   727  		"validator not found for task" 2
   728  
   729  	echo "--> validation resolve-error --all"
   730  	prepare_for_validator_cmd
   731  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   732  		"validation show-error test" \
   733  		"\"id\": \"1\"" 1 \
   734  		"\"id\": \"2\"" 1 \
   735  		"\"id\": \"3\"" 1 \
   736  		"\"id\": \"4\"" 1
   737  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   738  		"validation resolve-error test --all"
   739  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   740  		"validation show-error test" \
   741  		"\"id\": " 0
   742  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   743  		"validation status test" \
   744  		"new\/ignored\/resolved: 0\/0\/4" 1
   745  
   746  	echo "--> validation ignore-error --all"
   747  	prepare_for_validator_cmd
   748  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   749  		"validation show-error test" \
   750  		"\"id\": \"1\"" 1 \
   751  		"\"id\": \"2\"" 1 \
   752  		"\"id\": \"3\"" 1 \
   753  		"\"id\": \"4\"" 1
   754  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   755  		"validation ignore-error test --all"
   756  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   757  		"validation show-error test" \
   758  		"\"id\": " 0
   759  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   760  		"validation status test" \
   761  		"new\/ignored\/resolved: 0\/4\/0" 1
   762  }
   763  
   764  function run_check_task() {
   765  	source $cur/../dmctl_basic/check_list/check_task.sh
   766  	run_dm_master $WORK_DIR/master $MASTER_PORT $cur/conf/dm-master.toml
   767  	check_rpc_alive $cur/../bin/check_master_online 127.0.0.1:$MASTER_PORT
   768  	export GO_FAILPOINTS='github.com/pingcap/tiflow/dm/loader/longLoadProcess=return(20)'
   769  
   770  	run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $cur/conf/dm-worker1.toml
   771  	check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT
   772  	run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml
   773  	check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT
   774  
   775  	run_sql_file $cur/data/db1.prepare.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1
   776  	run_sql_file $cur/data/db2.prepare.sql $MYSQL_HOST2 $MYSQL_PORT2 $MYSQL_PASSWORD2
   777  
   778  	cp $cur/conf/source1.yaml $WORK_DIR/source1.yaml
   779  	cp $cur/conf/source2.yaml $WORK_DIR/source2.yaml
   780  	dmctl_operate_source create $WORK_DIR/source1.yaml $SOURCE_ID1
   781  	dmctl_operate_source create $WORK_DIR/source2.yaml $SOURCE_ID2
   782  	run_sql_source1 "set @@GLOBAL.max_connections=151;"
   783  	run_sql_source2 "set @@GLOBAL.max_connections=151;"
   784  	check_task_lightning
   785  	check_privilege
   786  	run_sql_source1 "set @@GLOBAL.max_connections=151;"
   787  	run_sql_source2 "set @@GLOBAL.max_connections=151;"
   788  	run_sql_tidb "set @@GLOBAL.max_connections=0;" # set default (unlimited), or other tests will fail
   789  }
   790  
   791  function run_validator_cmd_error() {
   792  	# status: without taskname
   793  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   794  		"validation status --table-stage stopped" \
   795  		"Error: task name should be specified" 1
   796  	# status: invalid stage
   797  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   798  		"validation status --table-stage start test" \
   799  		"Error: stage should be either" 1
   800  
   801  	# show errors: resolved error is illegal
   802  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   803  		"validation show-error --error resolved test" \
   804  		"Error: error flag should be either" 1
   805  	# show errors: no task name
   806  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   807  		"validation show-error --error all" \
   808  		"Error: task name should be specified" 1
   809  
   810  	# operate error: conflict id and --all flag
   811  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   812  		"validation ignore-error test 100 --all" \
   813  		"Error: either \`--all\` or \`error-id\` should be set" 1
   814  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   815  		"validation resolve-error test 100 --all" \
   816  		"Error: either \`--all\` or \`error-id\` should be set" 1
   817  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   818  		"validation clear-error test 100 --all" \
   819  		"Error: either \`--all\` or \`error-id\` should be set" 1
   820  
   821  	# operate error: more than one arguments
   822  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   823  		"validation ignore-error test 100 101" \
   824  		"Error: too many arguments are specified" 1
   825  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   826  		"validation resolve-error test 100 101" \
   827  		"Error: too many arguments are specified" 1
   828  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   829  		"validation clear-error test 100 101" \
   830  		"Error: too many arguments are specified" 1
   831  
   832  	# operate error: NaN id
   833  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   834  		"validation ignore-error test error-id" \
   835  		"Error: \`error-id\` should be integer when \`--all\` is not set" 1
   836  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   837  		"validation resolve-error test error-id" \
   838  		"Error: \`error-id\` should be integer when \`--all\` is not set" 1
   839  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   840  		"validation clear-error test error-id" \
   841  		"Error: \`error-id\` should be integer when \`--all\` is not set" 1
   842  
   843  	# operate error: neither all nor id
   844  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   845  		"validation ignore-error test" \
   846  		"Error: either \`--all\` or \`error-id\` should be set" 1
   847  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   848  		"validation resolve-error test" \
   849  		"Error: either \`--all\` or \`error-id\` should be set" 1
   850  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   851  		"validation clear-error test" \
   852  		"Error: either \`--all\` or \`error-id\` should be set" 1
   853  
   854  	# operate error: no task name
   855  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   856  		"validation ignore-error" \
   857  		"Error: task name should be specified" 1
   858  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   859  		"validation resolve-error" \
   860  		"Error: task name should be specified" 1
   861  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   862  		"validation clear-error" \
   863  		"Error: task name should be specified" 1
   864  
   865  	# operate error: invalid task name
   866  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   867  		"validation ignore-error non-exist-task-name 1" \
   868  		"cannot get subtask by task name" 1
   869  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   870  		"validation resolve-error non-exist-task-name 1" \
   871  		"cannot get subtask by task name" 1
   872  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   873  		"validation clear-error non-exist-task-name 1" \
   874  		"cannot get subtask by task name" 1
   875  }
   876  
   877  cleanup_data dmctl_command
   878  # also cleanup dm processes in case of last run failed
   879  cleanup_process $*
   880  run $*
   881  cleanup_process $*
   882  
   883  # run validator commands
   884  cleanup_data dmctl_command
   885  run_validator_cmd $*
   886  run_validation_start_stop_cmd
   887  cleanup_process $*
   888  
   889  # run check task
   890  cleanup_data dmctl_command
   891  run_check_task
   892  cleanup_process $*
   893  
   894  echo "[$(date)] <<<<<< test case $TEST_NAME success! >>>>>>"