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  }