# !/bin/bash
# this script will test mysql replication bugs #47142 and #47210, feel free to reuse it anywhere
# To test bug (WARNING script removes all data from all sandboxes)
# 1. set up versions you vant to try like: 
# make_replication_sandbox  ~/Desktop/mysql-enterprise-gpl-5.0.70-linux-x86_64-glibc23.tar.gz
# 2. set VERMASTER variable below with master version 
# 3  enumerate slaves versions into VERSLAVES variables using "_" instead of "." (this will make path to sandbox environment)
# 4. run this script from sandbox root

if [ -z $1 ]; then
  VERMASTER=5_0_58
else
  VERMASTER=$1
fi

if [ -z $2 ]; then
  VERSLAVES="5_0_58 5_0_60 5_0_70 5_0_85"
else
  VERSLAVES="$2 $3 $4 $5 $6 $7 $8 $9"
fi

echo [info] starting tests master="$VERMASTER" slaves="$VERSLAVES"

SLAVE_SERVER_ID_OFFSET=3800

# FLOW
# 1. clear all servers (WARNING!! this will delete all data from all sandboxes)
# 2. clear nodes
# 3. set up replication
# 4. update master
# 5. check slaves are in sync and stop them
# 6. update master more
# 7. remember BINLOG position
# 8. update master more
# 9. START SLAVE UNTIL position in #7.
# 10. check slaves position and report problem if exists
# repeat #6-#10

MASTER=./rsandbox_$VERMASTER/master
m=./rsandbox_$VERMASTER/m

# this is necesssery to make sure that no port/server_id collision (from previous runs with other parameters)
echo clearing all servers
./clear_all

echo start master from $MASTER
# $MASTER/clear
# $MASTER/stop
$MASTER/start || (echo "error starting master" && exit 1)

# start slaves
for VERSLAVE in $VERSLAVES 
do

  NODE=./rsandbox_$VERSLAVE/node1
  s1=./rsandbox_$VERSLAVE/s

  echo start slave from $NODE
#  $NODE/clear
  $NODE/start --server-id=$SLAVE_SERVER_ID_OFFSET || (echo "error starting slave $VERSLAVE" && exit 1)
  let "SLAVE_SERVER_ID_OFFSET=$SLAVE_SERVER_ID_OFFSET+1"
done

# init slaves: first get master port, then send it to slaves

echo init slaves
MASTER_PORT=`grep -m1 port $MASTER/my.sandbox.cnf | awk 'BEGIN {FS="[= ]+"} ; {print $NF}'`

for VERSLAVE in $VERSLAVES 
do
  NODE=./rsandbox_$VERSLAVE/node1
  s1=./rsandbox_$VERSLAVE/s1

  $s1 -u root -e "CHANGE MASTER TO  master_host='127.0.0.1',  master_port=$MASTER_PORT,  master_user='msandbox',  master_password='msandbox'"
done

echo creating table
# do some updates to master and ensure slaves are up-to-date
$m test -e "CREATE TABLE t(id int) engine=myisam;" || (echo "error creating table, exiting" && exit)



function test_bug {

for VERSLAVE in $VERSLAVES 
do
  NODE=./rsandbox_$VERSLAVE/node1
  s1=./rsandbox_$VERSLAVE/s1

  $s1 -u root -e "start slave"
done

for i in `seq $1 $2 $3`
do
  $m test -e "insert into t values( $i)"
done


# remember current binlog file and position
Master_Position=`$m -e "SHOW MASTER STATUS\G" | grep Position | awk '{print $NF}'`
Master_File=`$m -e "SHOW MASTER STATUS\G" | grep File | awk '{print $NF}'`

# 5. check slaves are running and in sync and stop each

echo stop slaves
for VERSLAVE in $VERSLAVES 
do
  NODE=./rsandbox_$VERSLAVE/node1
  s1=./rsandbox_$VERSLAVE/s1

  Slave_SQL_Running=`$s1 -vvt -e "SHOW SLAVE STATUS\G" | grep "Slave_SQL_Running" | awk '{print $NF}'`
  Slave_IO_Running=`$s1 -vvt -e "SHOW SLAVE STATUS\G" | grep "Slave_IO_Running" | awk '{print $NF}'`
  Exec_Master_Log_Pos=`$s1 -vvt -e "SHOW SLAVE STATUS\G" | grep "Exec_Master_Log_Pos" | awk '{print $NF}'`

  if [[ $Slave_SQL_Running != "Yes" || $Slave_IO_Running != "Yes" ]]; then 
    echo "slave $VERSLAVE has problems running replication, check output for {$s1 -e 'SHOW SLAVE STATUS\G'}$ Slave_SQL_Running=$Slave_SQL_Running, Slave_IO_Running=$Slave_IO_Running"
    exit 1;
  fi

  if [ "$Exec_Master_Log_Pos" != "$Master_Position"  ]; then
      echo "slave $VERSLAVE doesn't seem up. 'Exec_Master_Log_Pos'($Exec_Master_Log_Pos) expected to be equal 'Position' from master ($Master_Position)"
      exit 1;
  fi

  $s1 -e "STOP SLAVE"
done


# 6. update master more
echo do tests

$m test -e "insert into t values(6)"


# 7. remember BINLOG position

Master_Position=`$m -e "SHOW MASTER STATUS\G" | grep Position | awk '{print $NF}'`
Master_File=`$m -e "SHOW MASTER STATUS\G" | grep File | awk '{print $NF}'`

# 8. update master more

for i in `seq $1 $2 $3`
do
  $m test -e "insert into t values( $i)"
done


# 9. START SLAVE UNTIL position in #1.

echo [info] start slaves UNTIL \"$Master_File\", \"$Master_Position\"

for VERSLAVE in $VERSLAVES 
do
  NODE=./rsandbox_$VERSLAVE/node1
  s1=./rsandbox_$VERSLAVE/s1

  $s1 -e "START SLAVE UNTIL master_log_file='$Master_File', master_log_pos=$Master_Position"
done

# sleep couple seconds to let slave catch up
echo sleep 5 seconds to let Slaves catch updates
sleep 5


# 10. check slaves position and report problem is exists

echo check SLAVE STATUS

for VERSLAVE in $VERSLAVES 
do
  NODE=./rsandbox_$VERSLAVE/node1
  s1=./rsandbox_$VERSLAVE/s1

  Slave_SQL_Running=`$s1 -vvt -e "SHOW SLAVE STATUS\G" | grep "Slave_SQL_Running" | awk '{print $NF}'`
  Slave_IO_Running=`$s1 -vvt -e "SHOW SLAVE STATUS\G" | grep "Slave_IO_Running" | awk '{print $NF}'`
  Exec_Master_Log_Pos=`$s1 -vvt -e "SHOW SLAVE STATUS\G" | grep "Exec_Master_Log_Pos" | awk '{print $NF}'`
  Until_Log_Pos=`$s1 -vvt -e "SHOW SLAVE STATUS\G" | grep "Until_Log_Pos" | awk '{print $NF}'`

  if [ "$Slave_SQL_Running" != "No" -o "$Slave_IO_Running" != "Yes"  ]; then
      echo "slave $VERSLAVE pas problems wit hsetup, should have IO_Running: 'Yes' (has: $Slave_IO_Running) and SQL_Running: 'No' (has: $Slave_SQL_Running), check output for {$s1 -e 'SHOW SLAVE STATUS\G'}"
      continue;
  fi

  if [ "$Until_Log_Pos" != "$Master_Position"  ]; then
      echo "slave $VERSLAVE has problems with configuration. 'Until_Log_Pos' ($Until_Log_Pos) expected to equal master position ($Master_Position)"
      continue;
  fi

  if [ "$Until_Log_Pos" != "$Exec_Master_Log_Pos"  ]; then
    echo "[*fail*] slave $VERSLAVE has bug: Until_Log_Pos ($Until_Log_Pos) must be equal Exec_Master_Log_Pos ($Exec_Master_Log_Pos). Check {$s1 -e 'SHOW SLAVE STATUS\G'}";
  else
    echo "[pass] slave $VERSLAVE shows no problems. Check {$s1 -e 'SHOW SLAVE STATUS\G'}";
  fi	

done

}

echo [info] iteration 1 with 20 inserts
test_bug 1 20 

echo [info] iteration 2 with 100 inserts
test_bug 21 120

echo [info] iteration 3 with 1000 inserts
test_bug 121 1121
