github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/tests/_utils/test_prepare (about) 1 source env_variables 2 3 # we do clean staff at beginning of each run, so we can keep logs of the latset run 4 function cleanup_data() { 5 rm -rf $WORK_DIR 6 mkdir $WORK_DIR 7 for target_db in "$@"; do 8 run_sql "drop database if exists \`${target_db}\`" $TIDB_PORT $TIDB_PASSWORD 9 done 10 run_sql "drop database if exists dm_meta" $TIDB_PORT $TIDB_PASSWORD 11 } 12 13 function cleanup_data_upstream() { 14 for target_db in "$@"; do 15 run_sql "drop database if exists \`${target_db}\`" $MYSQL_PORT1 $MYSQL_PASSWORD1 16 run_sql "drop database if exists \`${target_db}\`" $MYSQL_PORT2 $MYSQL_PASSWORD2 17 done 18 } 19 20 function cleanup_process() { 21 dm_master_num=$(ps aux >temp && grep "dm-master.test" temp | wc -l && rm temp) 22 echo "$dm_master_num dm-master alive" 23 pkill -hup dm-master.test 2>/dev/null || true 24 25 dm_worker_num=$(ps aux >temp && grep "dm-worker.test" temp | wc -l && rm temp) 26 echo "$dm_worker_num dm-worker alive" 27 pkill -hup dm-worker.test 2>/dev/null || true 28 29 dm_syncer_num=$(ps aux >temp && grep "dm-syncer.test" temp | wc -l && rm temp) 30 echo "$dm_syncer_num dm-syncer alive" 31 pkill -hup dm-syncer.test 2>/dev/null || true 32 33 wait_process_exit dm-master.test 34 wait_process_exit dm-worker.test 35 wait_process_exit dm-syncer.test 36 } 37 38 function cleanup_tidb_server(){ 39 tidb_server_num=$(ps aux >temp && grep "tidb-server" temp | wc -l && rm temp) 40 echo "tidb_server_num tidb-server alive" 41 pkill -hup tidb-server 2>/dev/null || true 42 43 wait_process_exit tidb-server 44 } 45 46 function kill_process() { 47 keyword=$1 48 ps aux | grep $keyword | grep -v 'grep' | awk '{print $2}' | xargs kill || true 49 wait_process_exit $keyword 50 } 51 52 function kill_dm_master() { 53 kill_process dm-master.test 54 } 55 56 function kill_dm_worker() { 57 kill_process dm-worker.test 58 } 59 60 function wait_pattern_exit() { 61 pattern=$1 62 while true 63 do 64 if ! pgrep -f $pattern >/dev/null 2>&1; then 65 echo "pattern $pattern already exit" 66 return 0 67 fi 68 sleep 0.2 69 echo "wait pattern $pattern exit..." 70 done 71 } 72 73 if [ "$RESET_MASTER" = true ]; then 74 run_sql "RESET MASTER" $MYSQL_PORT1 $MYSQL_PASSWORD1 75 run_sql "RESET MASTER" $MYSQL_PORT2 $MYSQL_PASSWORD2 76 fi 77 78 function join_string() { 79 local IFS="$1"; shift; echo "$*"; 80 } 81 82 # shortcut for start task on one DM-worker 83 function dmctl_start_task_standalone() { 84 if [ $# -ge 2 ]; then 85 remove_meta=$2 86 else 87 remove_meta="" 88 fi 89 if [ $# -ge 1 ]; then 90 task_conf=$1 91 else 92 task_conf="$cur/conf/dm-task.yaml" 93 fi 94 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 95 "start-task $task_conf $remove_meta" \ 96 "\"result\": true" 2 \ 97 "\"source\": \"$SOURCE_ID1\"" 1 98 } 99 100 # shortcut for start task on two DM-workers 101 function dmctl_start_task() { 102 if [ $# -ge 2 ]; then 103 remove_meta=$2 104 else 105 remove_meta="" 106 fi 107 if [ $# -ge 1 ]; then 108 task_conf=$1 109 else 110 task_conf="$cur/conf/dm-task.yaml" 111 fi 112 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 113 "start-task $task_conf $remove_meta" \ 114 "\"result\": true" 3 \ 115 "\"source\": \"$SOURCE_ID1\"" 1 \ 116 "\"source\": \"$SOURCE_ID2\"" 1 117 } 118 119 # shortcut for stop task on two DM-workers 120 function dmctl_stop_task() { 121 task_name=$1 122 dmctl_operate_task $task_name stop-task 123 } 124 125 # shortcut for retryable stop task 126 function dmctl_stop_task_with_retry() { 127 task_name=$1 128 master_port=$2 129 for ((k=0; k<10; k++)); do 130 run_dm_ctl $WORK_DIR "127.0.0.1:$master_port" \ 131 "stop-task $task_name" 132 run_dm_ctl $WORK_DIR "127.0.0.1:$master_port" \ 133 "query-status $task_name" \ 134 "task test has no source or not exist" 1 && return 0 135 sleep 1 136 done 137 return 1 138 } 139 140 # shortcut for pause task on two DM-workers 141 function dmctl_pause_task() { 142 task_name=$1 143 dmctl_operate_task $task_name pause-task 144 } 145 146 # shortcut for stop task on two DM-workers 147 function dmctl_resume_task() { 148 task_name=$1 149 dmctl_operate_task $task_name resume-task 150 } 151 152 function dmctl_operate_task() { 153 task_name=$1 154 operate=$2 155 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 156 "$operate $task_name" \ 157 "\"result\": true" 3 \ 158 "\"source\": \"$SOURCE_ID1\"" 1 \ 159 "\"source\": \"$SOURCE_ID2\"" 1 160 } 161 162 function dmctl_operate_source() { 163 operate=$1 164 source_toml=$2 165 source_id=$3 166 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 167 "operate-source $operate $source_toml" \ 168 "\"result\": true" 2 \ 169 "\"source\": \"$source_id\"" 1 170 } 171 172 # use this func to run case 173 # param 1: case name 174 # param 2: task config name 175 # param 3: init_table command 176 # param 4: clean_table command 177 # param 5: shard mode 178 function run_case() { 179 case=$1 180 task_conf=$2 181 init_table_cmd=$3 182 clean_table_cmd=$4 183 shard_mode=$5 184 185 echo "[$(date)] <<<<<< start DM-${case} ${shard_mode} >>>>>>" 186 187 eval ${init_table_cmd} 188 189 truncate -s 0 $WORK_DIR/master/log/dm-master.log 190 truncate -s 0 $WORK_DIR/worker1/log/dm-worker.log 191 truncate -s 0 $WORK_DIR/worker2/log/dm-worker.log 192 193 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 194 "start-task $cur/conf/${task_conf}.yaml --remove-meta" 195 196 # make sure task switch to sync unit 197 # otherwise we may fail because dump schema inconsistent in shardddl 198 # or fail because upstream schema change but down schema unchange in redump when restart worker 199 if [[ "$task_conf" == *"single"* ]]; then 200 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 201 "query-status test" \ 202 "\"unit\": \"Sync\"" 1 203 elif [[ "$task_conf" == *"double"* ]]; then 204 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 205 "query-status test" \ 206 "\"unit\": \"Sync\"" 2 207 fi 208 209 args="" 210 for((i=5;i<=$#;i++)); do 211 j=${!i} 212 args="${args} $j " 213 done 214 DM_${case}_CASE $args 215 216 if [[ "$task_conf" == *"single"* ]]; then 217 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 218 "stop-task test" \ 219 "\"result\": true" 2 220 elif [[ "$task_conf" == *"double"* ]]; then 221 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 222 "stop-task test" \ 223 "\"result\": true" 3 224 fi 225 226 eval ${clean_table_cmd} 227 228 echo "[$(date)] <<<<<< finish DM-${case} ${shard_mode} >>>>>>" 229 } 230 231 # shortcut for run sql in mysql1 232 function run_sql_source1() { 233 run_sql "$1" $MYSQL_PORT1 $MYSQL_PASSWORD1 234 } 235 236 # shortcut for run sql in mysql2 237 function run_sql_source2() { 238 run_sql "$1" $MYSQL_PORT2 $MYSQL_PASSWORD2 239 } 240 241 # shortcut for run sql in both mysql1 and mysql2 242 function run_sql_both_source() { 243 run_sql_source1 "$1" 244 run_sql_source2 "$1" 245 } 246 247 # shortcut for run tidb sql 248 function run_sql_tidb() { 249 run_sql "$1" $TIDB_PORT $TIDB_PASSWORD 250 } 251 252 # shortcut for run tidb sql and check result with retry 253 function run_sql_tidb_with_retry() { 254 rc=0 255 for ((k=1; k<11; k++)); do 256 # in retry scenario sometimes run_sql_tidb will fail because "table not exist", we should keep retrying so turn 257 # off the error option temporarily. 258 set +e 259 run_sql_tidb "$1" 260 set -e 261 if grep -Fq "$2" "$TEST_DIR/sql_res.$TEST_NAME.txt"; then 262 rc=1 263 break 264 fi 265 echo "run tidb sql failed $k-th time, retry later" 266 sleep 2 267 done 268 if [[ $rc = 0 ]]; then 269 echo "TEST FAILED: OUTPUT DOES NOT CONTAIN '$2'" 270 echo "____________________________________" 271 cat "$TEST_DIR/sql_res.$TEST_NAME.txt" 272 echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" 273 exit 1 274 fi 275 } 276 277 # shortcut for run tidb sql and check result with retry 278 function run_sql_tidb_with_retry_times() { 279 rc=0 280 for ((k=1; k<$3; k++)); do 281 run_sql_tidb "$1" 282 if grep -Fq "$2" "$TEST_DIR/sql_res.$TEST_NAME.txt"; then 283 rc=1 284 break 285 fi 286 echo "run tidb sql failed $k-th time, retry later" 287 sleep 2 288 done 289 if [[ $rc = 0 ]]; then 290 echo "TEST FAILED: OUTPUT DOES NOT CONTAIN '$2'" 291 echo "____________________________________" 292 cat "$TEST_DIR/sql_res.$TEST_NAME.txt" 293 echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" 294 exit 1 295 fi 296 } 297 298 # shortcut for run tidb sql and check result with retry 299 # $1: table 300 # $2: fields numbers 301 # $3: value starts range(closed interval) 302 # $4: value ends range(closed interval) 303 # $5: database host 304 # $6: database port 305 # $7: database password 306 function run_sql_with_txn() { 307 template="(?" 308 for _ in {2..$2..1} 309 do 310 template+=",?" 311 done 312 template+=")" 313 echo "begin;" | tee $WORK_DIR/tmp.sql 314 seq $3 $4 | xargs -I\? echo "insert into $1 values $template;" | tee -a $WORK_DIR/tmp.sql 315 echo "commit;" | tee -a $WORK_DIR/tmp.sql 316 run_sql_file $WORK_DIR/tmp.sql $5 $6 $7 317 } 318 319 # shortcut for check log contain with retry 320 function check_log_contain_with_retry() { 321 text=$1 322 log1=$2 323 log2="" 324 if [[ "$#" -ge 3 ]]; then 325 log2=$3 326 fi 327 rc=0 328 for ((k=1;k<61;k++)); do 329 if [[ ! -f $log1 ]]; then 330 sleep 2 331 echo "check log contain failed $k-th time (file not exist), retry later" 332 continue 333 fi 334 got=`grep -a "$text" $log1 | wc -l` 335 if [[ $got -ne 0 ]]; then 336 rc=1 337 break 338 fi 339 if [[ ! "$log2" = "" ]]; then 340 if [[ ! -f $log2 ]]; then 341 sleep 2 342 echo "check log contain failed $k-th time (file not exist), retry later" 343 continue 344 fi 345 got=`grep -a "$text" $log2 | wc -l` 346 if [[ $got -ne 0 ]]; then 347 rc=1 348 break 349 fi 350 fi 351 echo "check log contain failed $k-th time, retry later" 352 sleep 2 353 done 354 if [[ $rc -eq 0 ]]; then 355 echo "log doesn't contain $text" 356 exit 1 357 fi 358 } 359 360 # shortcut for init cluster with one master and two workers 361 function init_cluster(){ 362 run_dm_master $WORK_DIR/master $MASTER_PORT $cur/conf/dm-master.toml 363 check_rpc_alive $cur/../bin/check_master_online 127.0.0.1:$MASTER_PORT 364 365 cp $cur/conf/source1.yaml $WORK_DIR/source1.yaml 366 cp $cur/conf/source2.yaml $WORK_DIR/source2.yaml 367 sed -i "/relay-binlog-name/i\relay-dir: $WORK_DIR/worker1/relay_log" $WORK_DIR/source1.yaml 368 sed -i "/relay-binlog-name/i\relay-dir: $WORK_DIR/worker2/relay_log" $WORK_DIR/source2.yaml 369 370 run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $cur/conf/dm-worker1.toml 371 check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT 372 dmctl_operate_source create $WORK_DIR/source1.yaml $SOURCE_ID1 373 374 run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml 375 check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT 376 dmctl_operate_source create $WORK_DIR/source2.yaml $SOURCE_ID2 377 } 378 379 function get_master_status() { 380 arr=$(echo "show master status;" | MYSQL_PWD=123456 mysql -uroot -h$1 -P$2 | awk 'NR==2') 381 echo $arr 382 } 383 384 function check_master_port_offline() { 385 master_ports_1_indexed=(0 $MASTER_PORT1 $MASTER_PORT2 $MASTER_PORT3 $MASTER_PORT4 $MASTER_PORT5) 386 master_peer_ports_1_indexed=(0 $MASTER_PEER_PORT1 $MASTER_PEER_PORT2 $MASTER_PEER_PORT3 $MASTER_PEER_PORT4 $MASTER_PEER_PORT5) 387 idx=$1 388 check_port_offline ${master_ports_1_indexed[$idx]} 20 389 check_port_offline ${master_peer_ports_1_indexed[$idx]} 20 390 } 391 392 function check_rows_equal() { 393 num=$1 394 check_contains "$num. row" 395 ((num++)) 396 check_not_contains "$num. row" 397 }