CVS User Account cvsuser
Tue Oct 25 20:31:26 PDT 2005
Log Message:
-----------
First round of a new testing framework.  This framework does not rely on pgbench, or xterms.  Currently it should NOT be used as a replacement to all the tests found in src/ducttape. To run the tests a simple ./run_test.sh <testname> should sufice.  At the moment there are two tests, test1 and test2.

Added Files:
-----------
    slony1-engine/tests:
        poll_cluster.sh (r1.1)
        run_test.sh (r1.1)
        settings.ik (r1.1)
        support_funcs.sh (r1.1)
    slony1-engine/tests/test1:
        generate_dml.sh (r1.1)
        init_add_tables.ik (r1.1)
        init_cluster.ik (r1.1)
        init_create_set.ik (r1.1)
        init_data.sql (r1.1)
        init_schema.sql (r1.1)
        init_subscribe_set.ik (r1.1)
        schema.diff (r1.1)
        settings.ik (r1.1)
    slony1-engine/tests/test2:
        generate_dml.sh (r1.1)
        init_add_tables.ik (r1.1)
        init_cluster.ik (r1.1)
        init_create_set.ik (r1.1)
        init_data.sql (r1.1)
        init_dropnode.ik (r1.1)
        init_failover.ik (r1.1)
        init_schema.sql (r1.1)
        init_subscribe_set.ik (r1.1)
        schema.diff (r1.1)
        settings.ik (r1.1)

-------------- next part --------------
--- /dev/null
+++ tests/settings.ik
@@ -0,0 +1,56 @@
+CLUSTER1=${CLUSTER1:-"slony_regress1"}
+CLUSTER2=${CLUSTER2:-"slony_regress2"}
+CLUSTER3=${CLUSTER3:-"slony_regress3"}
+
+DB1=${DB1:-"slonyregress1"}
+HOST1=${HOST1:-"localhost"}
+USER1=${USER1:-${PGUSER:-"postgres"}}
+
+DB2=${DB2:-"slonyregress2"}
+HOST2=${HOST2:-"localhost"}
+USER2=${USER2:-${PGUSER:-"postgres"}} 
+
+DB3=${DB3:-"slonyregress3"}
+HOST3=${HOST2:-"localhost"}
+USER3=${USER2:-${PGUSER:-"postgres"}}
+
+DB4=${DB4:-"slonyregress4"}
+HOST4=${HOST4:-"localhost"}
+USER4=${USER4:-${PGUSER:-"postgres"}}
+
+DB5=${DB5:-"slonyregress5"}
+HOST5=${HOST5:-"localhost"}
+USER5=${USER5:-${PGUSER:-"postgres"}}
+
+DB6=${DB6:-"slonyregress6"}
+HOST6=${HOST6:-"localhost"}
+USER6=${USER6:-${PGUSER:-"postgres"}}
+
+DB7=${DB7:-"slonyregress7"}
+HOST7=${HOST7:-"localhost"}
+USER7=${USER7:-${PGUSER:-"postgres"}}
+
+DB8=${DB8:-"slonyregress8"}
+HOST8=${HOST8:-"localhost"}
+USER8=${USER8:-${PGUSER:-"postgres"}}
+
+DB9=${DB9:-"slonyregress9"}
+HOST9=${HOST9:-"localhost"}
+USER9=${USER9:-${PGUSER:-"postgres"}}
+
+DB10=${DB10:-"slonyregress10"}
+HOST10=${HOST10:-"localhost"}
+USER10=${USER10:-${PGUSER:-"postgres"}}
+
+DB11=${DB11:-"slonyregress11"}
+HOST11=${HOST11:-"localhost"}
+USER11=${USER11:-${PGUSER:-"postgres"}}
+
+DB12=${DB12:-"slonyregress12"}
+HOST12=${HOST12:-"localhost"}
+USER12=${USER12:-${PGUSER:-"postgres"}}
+
+DB13=${DB13:-"slonyregress13"}
+HOST13=${HOST13:-"localhost"}
+USER13=${USER13:-${PGUSER:-"postgres"}}
+
--- /dev/null
+++ tests/support_funcs.sh
@@ -0,0 +1,188 @@
+
+err()
+{
+    exitval=$1
+    shift
+    echo 1>&2 "$0: ERROR: $*"
+    numerrors=`expr ${numerrors} + 1`
+    exit $exitval
+}
+
+warn()
+{
+	shift
+	echo 1>&2 "$0: WARNING: $*"
+	numerrors=`expr ${numerrors} + 1`
+}
+
+status()
+{
+	if [ "x$SHLVL" != "x" ]; then
+      case `uname` in
+        MINGW32*)
+	      echo "$*"
+          ;;
+        *)
+          echo "$*" > `tty`
+          ;;
+      esac
+    fi
+}
+
+_check_pid()
+{
+	if [ $# -ne 3 ]; then
+	  err 3 'USAGE: _check_pid procname pid ppid'
+	fi
+	case `uname` in
+        FreeBSD)
+        	_psargs="-j"
+            _fp_args='_user _pid _ppid _pgid _sess _jobc _stat _tt _time _command'
+            ;;
+        MINGW32*)
+            _psargs="-ef"
+            _fp_args='_user _pid _ppid _tt _time _command'
+            ;;
+        *)
+            _psargs="-ef"
+            _fp_args='_user _pid _ppid _c _stat _tt _time _command'
+            ;;
+	esac
+
+	_procname=$1
+	_qpid=$2
+	_qppid=$3
+
+	_proccheck=
+	_fp_match=
+
+	if [ ! $_qpid -gt 0 ]; then
+		err 3 'not a valid PID'
+	fi
+	  _procnamebn=${_procname##*/}
+	  _fp_match="case \"\$_command\" in
+	    *${_procname}*)"
+
+	eval _proccheck='
+		ps 2>/dev/null '"$_psargs"' |
+		while read '"$_fp_args"'; do
+			case "$_pid" in
+			  PID)
+				continue ;;
+			esac ; '"$_fp_match"'
+			  	if [ "$_pid" -eq  "$_qpid" ]; then 
+					echo -n "$_qpid" ;
+				fi
+			  ;;
+			esac
+		done'
+}
+
+random_number()
+{
+  if [ $# -ne 2 ]; then
+    err 3 'USAGE: random_number lowerbound upperbound'
+  fi
+
+  _lowerbound=$1
+  _upperbound=$2
+
+  case `uname` in
+  FreeBSD)
+    rannum=`jot -r 1 ${_lowerbound} ${_upperbound}`
+    ;;
+  AIX|MINGW32*)
+    rannum=`echo | awk -v _upperbound=${_upperbound} -v _lowerbound=${_lowerbound} '{srand(); printf "%.0d\n", (rand() * _upperbound) + _lowerbound;}'` 
+    ;;
+  Linux)
+    rannum=`echo | awk -v _upperbound=${_upperbound} -v _lowerbound=${_lowerbound} '{srand(); printf "%.0d\n", (rand() * _upperbound) + _lowerbound;}'`
+    ;;
+  SunOS)
+    rannum=`echo | nawk -v _upperbound=${_upperbound} -v _lowerbound=${_lowerbound} '{srand(); printf "%.0d\n", (rand() * _upperbound) + _lowerbound;}'`
+    ;;
+  *)
+    originnode=${ORIGINNODE:-"1"}
+    eval odb=\$DB${originnode}
+    eval ohost=\$HOST${originnode}
+    eval ouser=\$USER${originnode}
+    eval _upperbound=${_upperbound}    
+    eval _lowerbound=${_lowerbound}
+    rannum=`psql -c "SELECT round(random()* ${_upperbound} + ${_lowerbound});" -t -A -h ${ohost} ${odb} ${ouser}`
+  ;;
+  esac
+  echo ${rannum}
+}
+
+random_string()
+{
+  if [ $# -ne 1 ]; then
+    err 3 'USAGE: random_string length'
+  fi
+
+  _length=$1
+  case `uname` in
+  FreeBSD)
+    ranstring=`jot -r -c ${_length} a Z | rs -g 0 ${_length}`
+    ;;
+  AIX|MINGW32*)
+    ranstring=`echo | awk -v _length=${_length} '{srand(); {for (i=0; i<= _length ; i++) printf "%c", (rand() * (122-48))+48};}'`
+    ;;
+  SunOS)
+    ranstring=`echo | nawk -v _length=${_length} '{srand(); {for (i=0; i<= _length ; i++) printf "%c", (rand() * (122-48))+48};}'`
+    ;;
+  *)
+    originnode=${ORIGINNODE:-"1"}
+    eval odb=\$DB${originnode}
+    eval ohost=\$HOST${originnode}
+    eval ouser=\$USER${originnode}
+    alias=${_length}
+    while : ; do
+      ranstring=${ranstring}`psql -c "SELECT chr(round(random()*((122-48))+48)::int4);" -t -A -h ${ohost} ${odb} ${ouser}`
+      if [ ${alias} -ge ${_length} ]; then
+        break;
+      else
+        alias=$((${alias} + 1))
+      fi
+    done;
+  ;;
+  esac
+
+  echo ${ranstring}
+}
+
+random_az()
+{
+  if [ $# -ne 1 ]; then
+    err 3 'USAGE: random_string length'
+  fi
+
+  _length=$1
+  case `uname` in
+  FreeBSD)
+    ranstring=`jot -r -c ${_length} a Z | rs -g 0 ${_length}`
+    ;;
+  AIX|MINGW32*)
+    ranstring=`echo | awk -v _length=${_length} '{srand(); {for (i=0; i<= _length ; i++) printf "%c", (rand() * ((122)-97))+97};}'`
+    ;;
+  SunOS)
+    ranstring=`echo | nawk -v _length=${_length} '{srand(); {for (i=0; i<= _length ; i++) printf "%c", (rand() * ((122)-97))+97};}'`
+    ;;
+  *)
+    originnode=${ORIGINNODE:-"1"}
+    eval odb=\$DB${originnode}
+    eval ohost=\$HOST${originnode}
+    eval ouser=\$USER${originnode}
+    alias=${_length}
+    while : ; do
+      ranstring=${ranstring}`psql -c "SELECT chr(round(random()*(((122)-97))+97)::int4);" -t -A -h ${ohost} ${odb} ${ouser}`
+      if [ ${alias} -ge ${_length} ]; then
+        break;
+      else
+        alias=$((${alias} + 1))
+      fi
+    done;
+  ;;
+  esac
+
+  echo ${ranstring}
+}
--- /dev/null
+++ tests/run_test.sh
@@ -0,0 +1,644 @@
+#!/bin/sh
+
+pgbindir=${PGBINDIR:-"/usr/local/pgsql/bin"}
+numerrors=0
+testname=$1
+
+if [ -z "$testname" ]; then
+  echo "usage $0 testname"
+  exit 1;
+fi
+
+if [ ! -d "$testname" ]; then
+  echo "No such test $testname"
+  exit 1;
+fi
+
+if [ -z "$2" ]; then
+  case `uname` in
+    SunOS*)
+      bash $0 $1 1
+      retcode=$?
+      if [ $retcode -eq 127 ]; then
+        echo "Under SunOS (Solaris) we require you have bash installed, and in your path $testname"
+      fi
+      exit $retcode
+    ;;
+    AIX*)
+       bash $0 $1 1
+       retcode=$?
+       if [ $retcode -eq 127 ]; then
+         echo "Under AIX we require you have bash installed, and in your path to run $testname"
+       fi
+       exit $retcode
+    ;;
+    *)
+    ;;
+  esac
+fi
+
+if [ ! -x "$pgbindir/psql" ]; then
+  echo "please set the PGBINDIR envvar to the directory containing psql, createdb, ..."
+  exit 1;
+fi
+
+#load settings
+
+. settings.ik
+. $testname/settings.ik
+. support_funcs.sh
+
+trap '
+	echo ""
+	echo "**** user abort"
+	stop_processes
+	exit 1
+' 2 15
+
+stop_processes()
+{
+	alias=1
+	while : ; do
+	  eval workerpid=\$worker${alias}_pid
+	  if [ ! -z $workerpid ]; then
+	    echo "**** killing worker $alias"
+	    kill -15 $workerpid
+	  fi
+	  if [ ${alias} -ge ${WORKERS} ]; then
+	    break;
+	  else
+	    alias=`expr ${alias} + 1`
+	  fi
+	done
+	stop_poll
+	stop_slons
+}
+
+stop_poll()
+{
+	if [ ! -z ${poll_pid} ]; then
+          case `uname` in
+            MINGW32*)
+              foo=`ps |awk '{ print $1 }'| grep ${poll_pid}`
+              if [ ! -z "$foo" ]; then
+  	        echo "***** killing poll_cluster"
+	        kill -15 ${poll_pid}
+              fi
+            ;;
+            *)
+	      ps -p ${poll_pid} >/dev/null
+              if [ $? -eq 0 ]; then
+  	        echo "***** killing poll_cluster"
+	        kill -15 ${poll_pid}
+	      fi
+            ;;
+          esac
+        fi
+}
+
+stop_slons()
+{
+	alias=1
+        while : ; do
+          eval slonpid=\$slon${alias}_pid
+	  if [ ! -z $slonpid ]; then
+            echo "**** killing slon node $alias"
+            kill -15 $slonpid
+	  fi
+          if [ ${alias} -ge ${NUMNODES} ]; then
+            break;
+          else
+            alias=`expr ${alias} + 1`
+          fi
+        done
+}
+
+
+init_preamble() {
+	alias=1
+	while : ; do
+	  eval cluster=\$CLUSTER${alias}
+	  if [ -n "${cluster}" ]; then
+	    echo "CLUSTER NAME = ${cluster};" > $mktmp/slonik.script
+	    if [ ${alias} -ge ${NUMCLUSTERS} ]; then
+	      break;
+	    else
+	      alias=expr ${alias} + 1
+	    fi
+	  else
+	    break;
+	  fi
+	done
+
+	alias=1
+
+	while : ; do
+	  eval db=\$DB${alias}
+	  eval host=\$HOST${alias}
+	  eval user=\$USER${alias}
+	
+	  if [ -n "${db}" -a "${host}" -a "${user}" ]; then
+	    conninfo="dbname=${db} host=${host} user=${user}"
+	    echo "NODE ${alias} ADMIN CONNINFO = '${conninfo}';" >> $mktmp/slonik.script
+	    if [ ${alias} -ge ${NUMNODES} ]; then
+	      break;
+	    else
+	      alias=`expr ${alias} + 1`
+	    fi   
+	  else
+	    break;
+	  fi
+	done
+}
+
+
+store_node()
+{
+  originnode=${ORIGINNODE:-"1"}
+  eval odb=\$DB${originnode}
+  eval ohost=\$HOST${originnode}
+  eval ouser=\$USER${originnode}
+
+  if [ -n "${odb}" -a "${ohost}" -a "${ouser}" ]; then
+    alias=1
+    while : ; do
+      eval db=\$DB${alias}
+      eval host=\$HOST${alias}
+      eval user=\$USER${alias}
+
+      if [ -n "${db}" -a "${host}" -a "${user}" ]; then
+        if [ ${alias} -ne ${originnode} ]; then
+          echo "STORE NODE (id=${alias}, comment='node ${alias}');" >> $mktmp/slonik.script
+        fi
+        if [ ${alias} -ge ${NUMNODES} ]; then
+          break;
+        else
+          alias=$((${alias} + 1))
+        fi
+      else
+        break;
+      fi
+    done
+  else
+    err 3 "No origin in  ${odb} ${ohost} ${ouser}"
+  fi
+}
+
+store_path()
+{
+  i=1
+  while : ; do
+    eval db=\$DB${i}
+    eval host=\$HOST${i}
+    eval user=\$USER${i}
+
+    if [ -n "${db}" -a "${host}" -a "${user}" ]; then
+      j=1
+      while : ; do
+        if [ ${i} -ne ${j} ]; then
+          eval bdb=\$DB${j}
+          eval bhost=\$HOST${j}
+          eval buser=\$USER${j}
+          if [ -n "${bdb}" -a "${bhost}" -a "${buser}" ]; then
+	    echo "STORE PATH (SERVER=${i}, CLIENT=${j}, CONNINFO='dbname=${db} host=${host} user=${user}');" >> $mktmp/slonik.script
+          else
+            err 3 "No conninfo"
+          fi
+        fi
+        if [ ${j} -ge ${NUMNODES} ]; then
+          break;
+        else
+          j=$((${j} + 1))
+        fi
+      done
+      if [ ${i} -ge ${NUMNODES} ]; then
+        break;
+      else
+        i=$((${i} +1))
+      fi
+    else
+      err 3 "no DB"
+    fi
+  done
+}
+
+init_origin_rdbms()
+{
+	originnode=${ORIGINNODE:-"1"}
+        eval db=\$DB${originnode}
+        eval host=\$HOST${originnode}
+        eval user=\$USER${originnode}
+
+	if [ -n "${db}" -a "${host}" -a "${user}" ]; then
+	  status "creating origin DB: $user -h $host -U $user $db"
+  	  $pgbindir/createdb -O $user -h $host -U $user $db 1> ${mktmp}/createdb.${originnode} 2> ${mktmp}/createdb.${originnode}
+	  if [ $? -ne 0 ]; then	   
+	    err 3 "An error occured trying to $pgbindir/createdb -O $user -h $host -U $user $db, ${mktmp}/createdb.${originnode} for details"
+	  fi
+	else
+	  err 3 "No db '${db}' or host '${host}' or user '${user}' specified"
+	fi
+	status "loading origin DB with $testname/init_schema.sql"
+	$pgbindir/psql -h $host $db $user < $testname/init_schema.sql 1> ${mktmp}/init_schema.sql.${originnode} 2>${mktmp}/init_schema.sql.${originnode}
+	status "done"
+}
+
+create_subscribers()
+{
+        originnode=${ORIGINNODE:-"1"}
+        eval odb=\$DB${originnode}
+        eval ohost=\$HOST${originnode}
+        eval ouser=\$USER${originnode}
+
+        if [ -n "${odb}" -a "${ohost}" -a "${ouser}" ]; then
+          alias=1
+          while : ; do
+            eval db=\$DB${alias}
+            eval host=\$HOST${alias}
+            eval user=\$USER${alias}
+
+            if [ -n "${db}" -a "${host}" -a "${user}" ]; then
+              if [ ${alias} -ne ${originnode} ]; then
+		status "creating subscriber ${alias} DB: $user -h $host -U $user $db"
+	        $pgbindir/createdb -O $user -h $host -U $user $db 1> ${mktmp}/createdb.${alias} 2> ${mktmp}/createdb.${alias}
+		status "loading subscriber ${alias} DB from $odb"
+	        $pgbindir/pg_dump -s  -h $ohost -U $ouser $odb | $pgbindir/psql -h $host $db $user 1> ${mktmp}/init_schema.sql.${alias} 2> ${mktmp}/init_schema.sql.${alias}
+		status "done"
+              fi
+              if [ ${alias} -ge ${NUMNODES} ]; then
+                break;
+              else
+                alias=$((${alias} + 1))
+              fi   
+            else
+              break;
+            fi
+          done
+	else
+	
+	  err 3 "No ORIGINNODE defined"
+	fi
+}
+
+drop_databases()
+{
+	alias=1
+	status "dropping database"
+	while : ; do
+	  eval db=\$DB${alias}
+	  eval host=\$HOST${alias}
+	  eval user=\$USER${alias}
+
+	  status "${db}"
+
+	  if [ -n "${db}" -a "${host}" -a "${user}" ]; then
+	    $pgbindir/dropdb -U $user -h $host $db 1> ${mktmp}/dropdb.${alias} 2> ${mktmp}/dropdb.${alias}
+	    if [ ${alias} -ge ${NUMNODES} ]; then
+              break;
+            else
+              alias=$((${alias} + 1))
+            fi
+	  else
+            break;
+          fi
+        done
+	status "done"
+}
+
+cleanup()
+{
+	if [ ${numerrors} -eq 0 ]; then
+		rm -rf $mktmp
+	        echo "***************************"
+        	echo "test ${testname} completed successfully"
+	        echo "***************************"
+	else
+		echo "there were ${numerrors} warnings during the run of $testname, check the files in $mktmp for more details"
+	fi
+}
+
+create_set()
+{
+	if [ -f $testname/init_create_set.ik ]; then
+	  cat $testname/init_create_set.ik >> $mktmp/slonik.script
+	fi
+}
+
+add_tables()
+{	if [ -f $testname/init_add_tables.ik ]; then
+	  cat $testname/init_add_tables.ik >> $mktmp/slonik.script
+	fi
+}
+
+init_cluster()
+{
+	if [ -f $testname/init_cluster.ik ]; then
+	  cat $testname/init_cluster.ik >> $mktmp/slonik.script
+	fi
+}
+
+subscribe_set()
+{
+	if [ -f $testname/init_subscribe_set.ik ]; then
+          cat $testname/init_subscribe_set.ik >> $mktmp/slonik.script
+	fi
+}
+
+load_data()
+{
+        eval odb=\$DB${originnode}
+        eval ohost=\$HOST${originnode}
+        eval ouser=\$USER${originnode}
+	if [ -n "${odb}" -a "${ohost}" -a "${ouser}" ]; then
+		
+	  if [ -f $testname/init_data.sql ]; then
+	    $pgbindir/psql -h $ohost $odb $ouser < $testname/init_data.sql 1> $mktmp/init_data.sql.log 2> $mktmp/init_data.sql.log
+	    if [ $? -ne 0 ]; then
+              warn 3 "$testname/init_data.sql generated an error see $mktmp/init_data.sql.log for details"
+	    fi
+	  fi
+        else
+          err 3 "No origin found in ${odb} ${ohost} ${ouser}"
+	fi
+}
+
+
+do_ik()
+{
+	if [ -f $mktmp/slonik.script ]; then
+#	  cat $mktmp/slonik.script >`tty`
+	  $pgbindir/slonik < $mktmp/slonik.script > $mktmp/slonik.log 2>&1
+	  if [ $? -ne 0 ]; then
+	    err 3 "Slonik error see $mktmp/slonik.log for details"
+	  fi
+	fi
+}
+
+launch_poll()
+{
+  originnode=${ORIGINNODE:-"1"}
+  eval odb=\$DB${originnode}
+  eval ohost=\$HOST${originnode}
+  eval ouser=\$USER${originnode}
+  eval cluster=\$CLUSTER1
+  conninfo="-h ${ohost} ${odb} ${ouser}"
+  status "launching polling script"
+  case `uname` in
+    MINGW32*)
+      ./poll_cluster.sh "$mktmp" "${cluster}" "${conninfo}" "${pgbindir}" /dev/tty &
+      poll_pid=$!
+      ;;
+    *)
+      if [ "x$SHLVL" != "x" ]; then
+        ./poll_cluster.sh "$mktmp" "${cluster}" "${conninfo}" "${pgbindir}" `tty` &
+      else
+        ./poll_cluster.sh "$mktmp" "${cluster}" "${conninfo}" "${pgbindir}" /dev/null &
+      fi
+      tmppid=$!
+      tmpppid=$$
+      sleep 1
+      foo=$(_check_pid poll_cluster ${tmppid} ${tmpppid})
+      poll_pid=${foo}
+      if [ -z "${foo}" -o "${tmppid}" != "${foo}" ]; then
+        warn 3 "Failed to launch poll_cluster check $mktmp/poll.log for details"
+      fi
+      ;;
+  esac
+}
+
+launch_slon()
+{
+  alias=1
+  originnode=${ORIGINNODE:-"1"}
+  eval odb=\$DB${originnode}
+  eval ohost=\$HOST${originnode}
+  eval ouser=\$USER${originnode}
+  eval cluster=\$CLUSTER1
+
+  conninfo="dbname=${odb} host=${ohost} user=${ouser}"
+  status "launching originnode : $pgbindir/slon -s500 -g10 $cluster \"$conninfo\""
+  $pgbindir/slon -s500 -g10 $cluster "$conninfo" 1> $mktmp/slon_log.${originnode} 2> $mktmp/slon_log.${originnode} &
+  tmppid=$!
+  tmpppid=$$
+  sleep 1
+  foo=$(_check_pid slon ${tmppid} ${tmpppid})
+          
+  eval slon${originnode}_pid=${foo}
+  if [ -z "${foo}" -o "${tmppid}" != "${foo}" ]; then
+    warn 3 "Failed to launch slon on node ${originnode} check $mktmp/slon_log.${originnode} for details"
+  fi
+
+  sleep 10
+
+  while : ; do
+    if [ ${alias} -ne ${originnode} ]; then
+
+      eval db=\$DB${alias}
+      eval host=\$HOST${alias}
+      eval user=\$USER${alias}
+      eval cluster=\$CLUSTER1
+
+      if [ -n "${db}" -a "${host}" -a "${user}" ]; then
+        unset conninfo
+
+        unset tmppid
+        unset tmpppid
+        eval slon${alias}_pid=
+
+        conninfo="dbname=${db} host=${host} user=${user}"
+
+        status "launching: $pgbindir/slon -s500 -g10 $cluster \"$conninfo\""
+
+        $pgbindir/slon -s500 -g10 $cluster "$conninfo" 1>> $mktmp/slon_log.${alias} 2>&1 &
+        tmppid=$!
+        tmpppid=$$
+        sleep 1
+
+        foo=$(_check_pid slon ${tmppid} ${tmpppid})
+
+
+        eval slon${alias}_pid=${foo}
+        if [ -z "${foo}" -o "${tmppid}" != "${foo}" ]; then
+          warn 3 "Failed to launch slon on node ${alias} check $mktmp/slon_log.${alias} for details"
+        fi
+      fi
+    fi
+    if [ ${alias} -ge ${NUMNODES} ]; then
+      break;
+    else
+      alias=$((${alias} + 1))
+    fi
+  done
+}
+
+poll_cluster()
+{
+  originnode=${ORIGINNODE:-"1"}
+  eval odb=\$DB${originnode}
+  eval ohost=\$HOST${originnode}
+  eval ouser=\$USER${originnode}
+
+  alias=1
+  while : ; do
+    eval cluster=\$CLUSTER${alias}
+    if [ -n "${cluster}" ]; then
+      SQL="SELECT * FROM \"_${cluster}\".sl_status"
+      ${pgbindir}/psql -c "${SQL}" -h ${ohost} ${odb} ${ouser}
+      if [ ${alias} -ge ${NUMCLUSTERS} ]; then
+        break;
+      else
+        alias=expr ${alias} + 1
+      fi
+    else
+      break;
+    fi
+  done
+}      
+
+wait_for_catchup()
+{
+  alias=1
+  status "waiting for nodes to catchup"
+
+  poll_cluster
+
+  sleep 20
+
+  poll_cluster
+  status "done"
+}
+
+diff_db()
+{
+  originnode=${ORIGINNODE:-"1"}
+  eval odb=\$DB${originnode}
+  eval ohost=\$HOST${originnode}
+  eval ouser=\$USER${originnode}
+
+  if [ -f ${mktmp}/db_${originnode}.dmp ]; then
+    err 3 "${mktmp}/db_${originnode}.dmp exists but should not"
+  fi
+  status "getting data from origin DB for diffing"
+  cat ${testname}/schema.diff | while read SQL; do
+    ${pgbindir}/psql -c "${SQL}" -h ${ohost} ${odb} ${ouser} >> ${mktmp}/db_${originnode}.dmp
+  done
+  status "done"
+  alias=1
+  while : ; do
+    eval db=\$DB${alias}
+    eval host=\$HOST${alias}
+    eval user=\$USER${alias}
+
+    if [ -n "${db}" -a "${host}" -a "${user}" ]; then
+      if [ ${alias} -ne ${originnode} ]; then
+        if [ -f ${mktmp}/db_${alias}.dmp ]; then
+          err 3 "${mktmp}/db_${alias}.dmp exists but should not"
+        fi
+	status "getting data from node ${alias} for diffing against origin"
+        cat ${testname}/schema.diff | while read SQL; do
+          ${pgbindir}/psql -h ${host} -c "${SQL}" ${db} ${user} >> ${mktmp}/db_${alias}.dmp
+        done
+	status "comparing"
+	diff ${mktmp}/db_${originnode}.dmp ${mktmp}/db_${alias}.dmp > ${mktmp}/db_diff.${alias}
+        if [ $? -ne 0 ]; then
+          warn 3 "${mktmp}/db_${originnode}.dmp ${mktmp}/db_${alias}.dmp differ, see ${mktmp}/db_diff.${alias} for details"
+	else
+	  echo "subscriber node ${alias} is the same as origin node ${originnode}"
+        fi
+	status "done"
+      fi
+    else
+      err 3 "Not Found ${db} -a ${host} ${user}"
+    fi
+    if [ ${alias} -ge ${NUMNODES} ]; then
+      break;
+    else
+      alias=$((${alias} + 1))
+    fi
+  done
+}
+
+case `uname` in
+  SunOS|AIX|MINGW32*)
+        for i in /tmp /usr/tmp /var/tmp; do
+      if [ -d $i ]; then
+        tmpdir=$i
+        break
+      fi
+    done
+    if [ -z $tmpdir ]; then
+       err 3 "unable to create tmp dir"
+       exit
+    fi
+
+    # do this 10 times else fail
+    rstring=$(random_az 8)
+    rstring=slony-regress.$rstring
+    
+    mkdir $tmpdir/$rstring
+    retcode=$?
+    if [ $retcode -ne 0 ]; then
+      err $retcode "unable to create temp dir"
+    else
+      mktmp=$tmpdir/$rstring
+    fi
+  ;;
+  *)
+    mktmp=`mktemp -d -t slony-regress`
+    if [ ! -d $mktmp ]; then
+      err 3 "mktemp failed"
+    fi
+  ;;
+esac
+
+
+
+. $testname/generate_dml.sh
+
+init_origin_rdbms
+
+load_data
+create_subscribers
+
+init_preamble
+init_cluster
+create_set
+add_tables
+status "creating cluster"
+do_ik
+status "done"
+
+status "storing nodes"
+init_preamble
+store_node
+do_ik
+status "done"
+
+status "storing paths"
+init_preamble
+store_path
+do_ik
+status "done"
+
+launch_slon
+status "subscribing"
+init_preamble
+subscribe_set
+do_ik 
+status "done"
+
+do_initdata
+if [ ! -z ${poll_pid} ]; then
+  wait ${poll_pid}
+fi
+
+diff_db
+
+stop_processes
+
+status "waiting for slons to die"
+sleep 5
+status "done"
+
+drop_databases
+cleanup
--- /dev/null
+++ tests/poll_cluster.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+
+mktmp=$1
+cluster=$2
+conninfo=$3
+pgbindir=$4
+tty=$5
+
+if [ -z "$6" ]; then
+  case `uname` in
+    SunOS*)
+      bash "$0" "$1" "$2" "$3" "$4" "$5" 1
+      retcode=$?
+      if [ $retcode -eq 127 ]; then
+        echo "Under SunOS (Solaris) we require you have bash installed, and in your path $testname"
+      fi
+      exit $retcode
+    ;;
+    AIX*)
+      bash "$0" "$1" "$2" "$3" "$4" "$5" 1
+      retcode=$?
+      if [ $retcode -eq 127 ]; then
+        echo "Under AIX we require you have bash installed, and in your path $testname"
+      fi
+      exit $retcode
+    ;;
+    *)
+    ;;
+  esac
+fi
+. ./support_funcs.sh
+
+if [ -n "${cluster}" ]; then
+  sleep 15
+  SQL="SELECT count(l.*) FROM \"_${cluster}\".sl_log_1 l WHERE l.log_xid > (SELECT ev_maxxid FROM \"_${cluster}\".sl_event WHERE ev_timestamp = (SELECT max(ev_timestamp) FROM \"_${cluster}\".sl_event))"
+  SQL2="SELECT max(st_lag_num_events) FROM \"_${cluster}\".sl_status"
+  while : ; do
+    lag=`${pgbindir}/psql -q -A -t -c "${SQL}" ${conninfo} 2>>$mktmp/poll.log | sed -e '/^$/d'`
+    if [ ! -z "${lag}" ]; then
+      if [ ${lag} -eq 0 ]; then
+	    sleep 3
+        lag=`${pgbindir}/psql -q -A -t -c "${SQL}" ${conninfo} 2>>$mktmp/poll.log | sed -e '/^$/d'`
+        if [ ${lag} -eq 0 ]; then
+          sleep 2
+          lag=`${pgbindir}/psql -q -A -t -c "${SQL}" ${conninfo} 2>>$mktmp/poll.log | sed -e '/^$/d'`
+          lag2=`${pgbindir}/psql -q -A -t -c "${SQL2}" ${conninfo} 2>>$mktmp/poll.log | sed -e '/^$/d'`
+          lag3=`expr $lag + $lag2`
+	      if [ ${lag3} -eq 0 ]; then
+            echo "slony is caught up" > $tty
+            exit
+          else
+            echo "$lag3 rows behind" > $tty
+	        sleep 1
+          fi
+        else
+          echo "$lag rows behind" > $tty
+          sleep 4
+        fi
+      else
+	    echo "$lag rows behind" > $tty
+        sleep 5
+      fi
+    fi
+  done
+else
+  err 2 "$0 has no cluster - dying"
+fi
--- /dev/null
+++ tests/test1/init_add_tables.ik
@@ -0,0 +1,5 @@
+set add table(id=1, set id=1, origin=1, fully qualified name = 'public.table1', comment='accounts table');
+set add table(id=2, set id=1, origin=1, fully qualified name = 'public.table2', key='table2_id_key');
+table add key (node id = 1, fully qualified name = 'public.table3');
+set add table(id=3, set id=1, origin=1, fully qualified name = 'public.table3', key = SERIAL);
+
--- /dev/null
+++ tests/test1/init_cluster.ik
@@ -0,0 +1 @@
+init cluster ( id=1, comment = 'Regress test node');
--- /dev/null
+++ tests/test1/init_data.sql
@@ -0,0 +1,3 @@
+INSERT INTO table1(data) VALUES ('placeholder 1');
+INSERT INTO table2(table1_id,data) VALUES (1,'placeholder 1');
+INSERT INTO table3(table2_id) VALUES (1);
--- /dev/null
+++ tests/test1/init_schema.sql
@@ -0,0 +1,20 @@
+CREATE TABLE table1(
+  id		SERIAL		PRIMARY KEY, 
+  data		TEXT
+);
+
+CREATE TABLE table2(
+  id		SERIAL		UNIQUE NOT NULL, 
+  table1_id	INT4		REFERENCES table1(id) 
+					ON UPDATE CASCADE ON DELETE CASCADE, 
+  data		TEXT
+);
+
+CREATE TABLE table3(
+  id		SERIAL,
+  table2_id	INT4		REFERENCES table2(id)
+					ON UPDATE SET NULL ON DELETE SET NULL,
+  mod_date	TIMESTAMPTZ	NOT NULL DEFAULT now(),
+  data		FLOAT		NOT NULL DEFAULT random()
+  CONSTRAINT table3_date_check	CHECK (mod_date <= now())
+); 
--- /dev/null
+++ tests/test1/settings.ik
@@ -0,0 +1,4 @@
+NUMCLUSTERS=${NUMCLUSTERS:-"1"}
+NUMNODES=${NUMNODES:-"2"}
+ORIGINNODE=1
+WORKERS=${WORKERS:-"1"}
--- /dev/null
+++ tests/test1/init_subscribe_set.ik
@@ -0,0 +1 @@
+subscribe set ( id = 1, provider = 1, receiver = 2, forward = no);
--- /dev/null
+++ tests/test1/init_create_set.ik
@@ -0,0 +1 @@
+create set (id=1, origin=1, comment='All test1 tables');
--- /dev/null
+++ tests/test1/generate_dml.sh
@@ -0,0 +1,73 @@
+. support_funcs.sh
+
+init_dml()
+{
+  echo "init_dml()"
+}
+
+begin()
+{
+  echo "begin()"
+}
+
+rollback()
+{
+  echo "rollback()"
+}
+
+commit()
+{
+  echo "commit()"
+}
+
+generate_initdata()
+{
+  numrows=$(random_number 50 1000)
+  i=0;
+  trippoint=`expr $numrows / 20`
+  j=0;
+  percent=0
+  status "generating ${numrows} tranactions of random data"
+  percent=`expr $j \* 5`
+  status "$percent %"
+  while : ; do
+    txtalen=$(random_number 1 100)
+    txta=$(random_string ${txtalen})
+    txta=`echo ${txta} | sed -e "s/\\\\\\\/\\\\\\\\\\\\\\/g" -e "s/'/''/g"`
+    txtblen=$(random_number 1 100)
+    txtb=$(random_string ${txtblen})
+    txtb=`echo ${txtb} | sed -e "s/\\\\\\\/\\\\\\\\\\\\\\/g" -e "s/'/''/g"`
+
+    echo "INSERT INTO table1(data) VALUES ('${txta}');" > $mktmp/generate.data
+    echo "INSERT INTO table2(table1_id,data) SELECT id, '${txtb}' FROM table1 WHERE data='${txta}';" > $mktmp/generate.data
+    echo "INSERT INTO table3(table2_id) SELECT id FROM table2 WHERE data ='${txtb}';" > $mktmp/generate.data
+    if [ ${i} -ge ${numrows} ]; then
+      break;
+    else
+      i=$((${i} +1))
+      working=`expr $i % $trippoint`
+      if [ $working -eq 0 ]; then
+        j=`expr $j + 1`
+        percent=`expr $j \* 5`
+        status "$percent %"
+      fi 
+    fi
+  done
+  status "done"
+}
+
+do_initdata()
+{
+   originnode=${ORIGINNODE:-"1"}
+  eval db=\$DB${originnode}
+   eval host=\$HOST${originnode}
+  eval user=\$USER${originnode}
+  generate_initdata
+  launch_poll
+  status "loading data"
+  $pgbindir/psql -h $host $db $user < $mktmp/generate.data 1> $mktmp/initdata.log 2> $mktmp/initdata.log
+  if [ $? -ne 0 ]; then
+    warn 3 "do_initdata failed, see $mktmp/initdata.log for details"
+  fi 
+  status "done"
+}
--- /dev/null
+++ tests/test1/schema.diff
@@ -0,0 +1,3 @@
+SELECT id,data FROM table1 ORDER BY id
+SELECT id,table1_id,data FROM table2 ORDER BY id
+SELECT id,table2_id,mod_date, data FROM table3 ORDER BY id
--- /dev/null
+++ tests/test2/init_dropnode.ik
@@ -0,0 +1,5 @@
+CLUSTER NAME = slony_regress1;
+NODE 1 ADMIN CONNINFO = 'dbname=slonyregress1 host=localhost user=pgsql';
+NODE 3 ADMIN CONNINFO = 'dbname=slonyregress3 host=localhost user=pgsql';
+drop node (id = 2);
+
--- /dev/null
+++ tests/test2/init_add_tables.ik
@@ -0,0 +1,5 @@
+set add table(id=1, set id=1, origin=1, fully qualified name = 'public.table1', comment='accounts table');
+set add table(id=2, set id=1, origin=1, fully qualified name = 'public.table2', key='table2_id_key');
+table add key (node id = 1, fully qualified name = 'public.table3');
+set add table(id=3, set id=1, origin=1, fully qualified name = 'public.table3', key = SERIAL);
+
--- /dev/null
+++ tests/test2/init_cluster.ik
@@ -0,0 +1 @@
+init cluster ( id=1, comment = 'Regress test node');
--- /dev/null
+++ tests/test2/init_data.sql
@@ -0,0 +1,3 @@
+INSERT INTO table1(data) VALUES ('placeholder 1');
+INSERT INTO table2(table1_id,data) VALUES (1,'placeholder 1');
+INSERT INTO table3(table2_id) VALUES (1);
--- /dev/null
+++ tests/test2/init_schema.sql
@@ -0,0 +1,20 @@
+CREATE TABLE table1(
+  id		SERIAL		PRIMARY KEY, 
+  data		TEXT
+);
+
+CREATE TABLE table2(
+  id		SERIAL		UNIQUE NOT NULL, 
+  table1_id	INT4		REFERENCES table1(id) 
+					ON UPDATE CASCADE ON DELETE CASCADE, 
+  data		TEXT
+);
+
+CREATE TABLE table3(
+  id		SERIAL,
+  table2_id	INT4		REFERENCES table2(id)
+					ON UPDATE SET NULL ON DELETE SET NULL,
+  mod_date	TIMESTAMPTZ	NOT NULL DEFAULT now(),
+  data		FLOAT		NOT NULL DEFAULT random()
+  CONSTRAINT table3_date_check	CHECK (mod_date <= now())
+); 
--- /dev/null
+++ tests/test2/init_failover.ik
@@ -0,0 +1,3 @@
+failover (id = 2, backup node = 3);
+wait for event (origin = 1, confirmed = 3);
+#drop node (id = 2);
--- /dev/null
+++ tests/test2/settings.ik
@@ -0,0 +1,4 @@
+NUMCLUSTERS=${NUMCLUSTERS:-"1"}
+NUMNODES=${NUMNODES:-"3"}
+ORIGINNODE=1
+WORKERS=${WORKERS:-"1"}
--- /dev/null
+++ tests/test2/init_subscribe_set.ik
@@ -0,0 +1,4 @@
+	subscribe set ( id = 1, provider = 1, receiver = 2, forward = yes);
+wait for event (origin = 1, confirmed = 2);
+	subscribe set ( id = 1, provider = 2, receiver = 3, forward = no);
+wait for event (origin = 1, confirmed = 3);
--- /dev/null
+++ tests/test2/init_create_set.ik
@@ -0,0 +1 @@
+create set (id=1, origin=1, comment='All test1 tables');
--- /dev/null
+++ tests/test2/generate_dml.sh
@@ -0,0 +1,110 @@
+. support_funcs.sh
+
+init_dml()
+{
+  echo "init_dml()"
+}
+
+begin()
+{
+  echo "begin()"
+}
+
+rollback()
+{
+  echo "rollback()"
+}
+
+commit()
+{
+  echo "commit()"
+}
+
+generate_initdata()
+{
+  numrows=$(random_number 50 1000)
+  i=0;
+  trippoint=`expr $numrows / 20`
+  j=0;
+  percent=0
+  status "generating ${numrows} tranactions of random data"
+  percent=`expr $j \* 5`
+  status "$percent %"
+  while : ; do
+    txtalen=$(random_number 1 100)
+    txta=$(random_string ${txtalen})
+    txta=`echo ${txta} | sed -e "s/\\\\\\\/\\\\\\\\\\\\\\/g" -e "s/'/''/g"`
+    txtblen=$(random_number 1 100)
+    txtb=$(random_string ${txtblen})
+    txtb=`echo ${txtb} | sed -e "s/\\\\\\\/\\\\\\\\\\\\\\/g" -e "s/'/''/g"`
+
+    echo "INSERT INTO table1(data) VALUES ('${txta}');" >> $mktmp/generate.data
+    echo "INSERT INTO table2(table1_id,data) SELECT id, '${txtb}' FROM table1 WHERE data='${txta}';" >> $mktmp/generate.data
+    echo "INSERT INTO table3(table2_id) SELECT id FROM table2 WHERE data ='${txtb}';" >> $mktmp/generate.data
+    if [ ${i} -ge ${numrows} ]; then
+      break;
+    else
+      i=$((${i} +1))
+      working=`expr $i % $trippoint`
+      if [ $working -eq 0 ]; then
+        j=`expr $j + 1`
+        percent=`expr $j \* 5`
+        status "$percent %"
+      fi 
+    fi
+  done
+  status "done"
+}
+
+do_initdata()
+{
+  originnode=${ORIGINNODE:-"1"}
+  eval db=\$DB${originnode}
+  eval host=\$HOST${originnode}
+  eval user=\$USER${originnode}
+  generate_initdata
+  launch_poll
+  rows=`wc -l ${mktmp}/generate.data | awk '{print($1)}'`
+  if [ -f ${testname}/init_failover.ik ]; then
+    splitsize=`expr $rows / 3`
+    split -l $splitsize ${mktmp}/generate.data ${mktmp}/generate.data.
+    status "loading ${splitsize} rows of data"
+    $pgbindir/psql -h $host $db $user < $mktmp/generate.data.aa 1> $mktmp/initdata.log 2> $mktmp/initdata.log
+    if [ $? -ne 0 ]; then
+      warn 3 "do_initdata failed, see $mktmp/initdata.log for details"
+    fi
+echo "preamble"
+    stop_poll
+    stop_slons
+    sleep 3
+#    $pgbindir/dropdb -h $host $db
+    $pgbindir/dropdb -h $host slonyregress2
+    sleep 1
+    launch_slon
+    
+    init_preamble
+    cat ${testname}/init_failover.ik  >> $mktmp/slonik.script
+    do_ik
+echo "ik done"
+    launch_poll
+    status "loading second set of ${splitsize} rows of data"
+    $pgbindir/psql -h $host $db $user < $mktmp/generate.data.ab 1>> $mktmp/initdata.log 2> $mktmp/initdata.log
+    if [ $? -ne 0 ]; then
+      warn 3 "do_initdata failed, see $mktmp/initdata.log for details"
+    fi
+    status "loading remaining rows of data"
+    cat ${testname}/init_dropnode.ik > $mktmp/slonik.script
+    do_ik
+    $pgbindir/psql -h $host $db $user < $mktmp/generate.data.ac 1>> $mktmp/initdata.log 2> $mktmp/initdata.log
+    if [ $? -ne 0 ]; then
+      warn 3 "do_initdata failed, see $mktmp/initdata.log for details"
+    fi
+  else    
+    status "loading ${rows} rows of data"
+    $pgbindir/psql -h $host $db $user < $mktmp/generate.data 1> $mktmp/initdata.log 2> $mktmp/initdata.log
+    if [ $? -ne 0 ]; then
+      warn 3 "do_initdata failed, see $mktmp/initdata.log for details"
+    fi
+  fi 
+  status "done"
+}
--- /dev/null
+++ tests/test2/schema.diff
@@ -0,0 +1,3 @@
+SELECT id,data FROM table1 ORDER BY id
+SELECT id,table1_id,data FROM table2 ORDER BY id
+SELECT id,table2_id,mod_date, data FROM table3 ORDER BY id


More information about the Slony1-commit mailing list