#! /bin/sh

#================================================================
# segvtest
# Simulate process crash by Segmentatin Fault
#================================================================


# set variables
testcmd="kchashtest"
testsubcmd="order"
testopts="-th 4"
mgrcmd="kchashmgr"
PATH="$PATH:."
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib:."
DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:/usr/local/lib:."
export PATH LD_LIBRARY_PATH DYLD_LIBRARY_PATH


# parse arguments
case "$1" in
kch|hash)
  testcmd="kchashtest"
  mgrcmd="kchashmgr"
  testopts="$testopts -dfunit 8"
  ;;
kct|tree)
  testcmd="kctreetest"
  testopts="$testopts -dfunit 8 -pccap 10k"
  mgrcmd="kctreemgr"
  ;;
kcd|dir)
  testcmd="kcdirtest"
  mgrcmd="kcdirmgr"
  ;;
kcf|forest)
  testcmd="kcforesttest"
  testopts="$testopts -pccap 10k"
  mgrcmd="kcforestmgr"
  ;;
esac
if [ "$2" = "-wicked" ]
then
  testsubcmd="wicked"
  testopts="-th 4 -it 10"
  shift
else
  testopts="$testopts -rnd"
fi
if [ "$2" = "-oat" ]
then
  testopts="$testopts -oat"
  shift
fi
if [ "$2" = "-tran" ]
then
  testopts="$testopts -tran"
  shift
fi
argsleepsec="$2"
loopnum="$3"

# enable libSegFault
unset LD_PRELOAD
if [ -f "/lib/libSegFault.so" ]
then
  LD_PRELOAD="/lib/libSegFault.so"
elif [ -f "/lib/x86_64-linux-gnu/libSegFault.so" ]
then
  LD_PRELOAD="/lib/x86_64-linux-gnu/libSegFault.so"
fi
if [ -n "$LD_PRELOAD" ]
then
  SEGFAULT_SIGNALS="all"
  SEGFAULT_OUTPUT_NAME="$testcmd.log"
  export LD_PRELOAD SEGFAULT_SIGNALS SEGFAULT_OUTPUT_NAME
fi

# set the cleanup handler
rm -f stop.log
trap "touch stop.log" TERM INT
trap "killall $testcmd >/dev/null 2>&1; rm -f stop.log" EXIT


# infinite loop
cnt=0
while [ ! -f stop.log ]
do
  cnt=`expr $cnt + 1`
  if [ -n "$argsleepsec" ]
  then
    sleepsec="$argsleepsec"
  else
    sleepsec=`date +%S`
    sleepinteg=`expr $sleepsec % 6 + 1`
    sleepfract=`expr $sleepsec / 6 % 10`
    sleepsec="$sleepinteg.$sleepfract"
  fi
  printf '\n==== iteration: %d (%.1f sec.)\n\n' "$cnt" "$sleepsec"
  rm -rf casket* "$testcmd.log"
  echo "$testcmd" "$testsubcmd" $testopts casket 10000000
  "$testcmd" "$testsubcmd" $testopts casket 10000000 & \
    ( sleep "$sleepsec" ; killall -SEGV "$testcmd" )
  cp -rf casket casket-back 2>/dev/null
  cp -rf casket.wal casket-back.wal 2>/dev/null
  printf '\n'
  ls -ld casket
  [ -e casket.wal ] && ls -ld casket.wal
  echo "$mgrcmd" check casket
  if "$mgrcmd" check casket
  then
    true
    if [ -n "$loopnum" ] && [ "$cnt" -ge "$loopnum" ]
    then
      break
    fi
  else
    printf '\n==== ERROR\n\n'
    printf "cp -rf casket-back casket ; cp -f casket-back.wal casket.wal ; ./$mgrcmd check casket\n"
    exit 1
  fi
done
printf '\n==== %d tests finished successfully\n\n' "$cnt"


# exit normally
exit 0



# END OF FILE
