M0=${M0:=/mnt/glusterfs/0}; # 0th mount point for FUSE M1=${M1:=/mnt/glusterfs/1}; # 1st mount point for FUSE M2=${M1:=/mnt/glusterfs/2}; # 2nd mount point for FUSE N0=${N0:=/mnt/nfs/0}; # 0th mount point for NFS N1=${N1:=/mnt/nfs/1}; # 1st mount point for NFS V0=${V0:=patchy}; # volume name to use in tests V1=${V1:=patchy1}; # volume name to use in tests B0=${B0:=/d/backends}; # top level of brick directories CC=cc OSTYPE=$(uname -s) if [ ! -f ${PWD}/tests/env.rc ]; then echo "Aborting." echo echo "env.rc not found" echo echo "Please correct the problem and try again." echo exit 1 fi . ${PWD}/tests/env.rc H0=${H0:=`hostname`}; # hostname MOUNT_TYPE_FUSE="fuse.glusterfs" GREP_MOUNT_OPT_RO="grep (ro" GREP_MOUNT_OPT_RW="grep (rw" PATH=$PATH:${PWD}/tests/utils case $OSTYPE in Linux) H0=${H0:=`hostname --fqdn`}; # hostname ;; NetBSD) MOUNT_TYPE_FUSE="puffs|perfuse|fuse.glusterfs" GREP_MOUNT_OPT_RO="grep (read-only" GREP_MOUNT_OPT_RW="grep -v (read-only" ;; *) ;; esac DEBUG=${DEBUG:=0} # turn on debugging? PROCESS_UP_TIMEOUT=20 NFS_EXPORT_TIMEOUT=20 CHILD_UP_TIMEOUT=20 PROBE_TIMEOUT=20 REBALANCE_TIMEOUT=120 REOPEN_TIMEOUT=20 HEAL_TIMEOUT=60 MARKER_UPDATE_TIMEOUT=20 JANITOR_TIMEOUT=60 UMOUNT_TIMEOUT=5 statedumpdir=`gluster --print-statedumpdir`; # Default directory for statedump CLI="gluster --mode=script --wignore"; GFS="glusterfs --attribute-timeout=0 --entry-timeout=0"; mkdir -p $B0; mkdir -p $M0 $M1; mkdir -p $N0 $N1; testcnt=`egrep '^[[:space:]]*(EXPECT|EXPECT_NOT|TEST|EXPECT_WITHIN|EXPECT_KEYWORD)[[:space:]]' $0 | wc -l` expect_tests=`egrep '^[[:space:]]*TESTS_EXPECTED_IN_LOOP[[:space:]]*' $0` x_ifs=$IFS IFS=$'\n' for line in $expect_tests; do expect_tests=`echo $line | cut -f 2 -d =` testcnt=`expr $testcnt + $expect_tests` done IFS=$x_ifs # Remove space again since `wc -l` on OSX and FreeBSD # adds spurious space which clobbers up TAP output testcnt_nospace=$(echo $testcnt | tr -d ' ') echo 1..$testcnt_nospace t=1 function dbg() { [ "x$DEBUG" = "x0" ] || echo "$*" >&2; } function test_header() { dbg "========================="; dbg "TEST $t (line $TESTLINE): $*"; saved_cmd="$*" } function test_footer() { RET=$? local err=$1 if [ $RET -eq 0 ]; then echo "ok $t"; else echo "not ok $t $err"; # With DEBUG, this was already printed out, so skip it. if [ x"$DEBUG" = x"0" ]; then echo "FAILED COMMAND: $saved_cmd" fi if [ "$EXIT_EARLY" = "1" ]; then exit $RET fi fi dbg "RESULT $t: $RET"; t=`expr $t + 1`; } function test_expect_footer() { local e=$1 local a=$2 local err="" if ! [[ "$a" =~ $e ]]; then err="Got \"$a\" instead of \"$e\"" fi [[ "$a" =~ $e ]]; test_footer "$err"; } function _EXPECT() { TESTLINE=$1; shift; local a="" test_header "$@"; e="$1"; shift; a=$("$@" | tail -1) test_expect_footer "$e" "$a"; } function test_expect_not_footer() { local e=$1 local a=$2 local err="" if [[ "$a" =~ $e ]]; then err="Got \"$a\" when not expecting it" fi ! [[ "$a" =~ "$e" ]]; test_footer "$err"; } function _EXPECT_NOT() { TESTLINE=$1; shift; local a="" test_header "$@"; e="$1"; shift; a=$("$@" | tail -1) if [ "x$e" = "x" ] ; then test_expect_not_footer "x$e" "x$a"; else test_expect_not_footer "$e" "$a"; fi } function _EXPECT_KEYWORD() { TESTLINE=$1; shift; test_header "$@"; e="$1"; shift; "$@" | tail -1 | grep -q "$e" test_footer; } function _TEST() { TESTLINE=$1; shift; local redirect="" test_header "$@"; if [ "$1" = "!" ]; then redirect="2>&1" fi eval "$@" >/dev/null $redirect test_footer; } function _EXPECT_WITHIN() { TESTLINE=$1 shift; local timeout=$1 shift; test_header "$@" e=$1; a=""; shift; local endtime=$(( ${timeout}+`date +%s` )) while [ `date +%s` -lt $endtime ]; do a=$("$@" | tail -1 ; exit ${PIPESTATUS[0]}) ## Check command success if [ $? -ne 0 ]; then break; fi ## Check match success if [[ "$a" =~ "$e" ]]; then break; fi sleep 1; done if [ "x$e" = "x" ] ; then test_expect_footer "x$e" "x$a"; else test_expect_footer "$e" "$a"; fi } function SKIP_TESTS() { dbg "Skipping tests $t-$testcnt"; while [ $t -le $testcnt ]; do true ; test_footer; done } function _TEST_IN_LOOP() { testcnt=`expr $testcnt + 1`; _TEST $@ } which killall > /dev/null || { killall() { pkill $@ } } which pidof > /dev/null || { pidof() { pidof.py $1 } } stat -c %s /dev/null > /dev/null 2>&1 || { stat() { local format="" local f="" if [ "x$1" = "x-c" ] ; then argc=3 format=$2 f=$3 else argc=1 f=$1 fi if [ $# -ne $argc ] ; then echo 'Usage: stat [-c format] file' exit 2; fi if [ "x${format}" = "x" ] ; then `which stat` $f else echo ${format} | sed " s/%u/`$( which stat ) -f %u $f`/g; s/%g/`$( which stat ) -f %g $f`/g; s/%a/`$( which stat ) -f %p $f |sed 's/^..//; s/^0//'`/g; s/%A/`ls -l $f|awk '{print $1}'`/g; s/%s/`$( which stat ) -f %z $f`/g; s/%h/`$( which stat ) -f %l $f`/g; s/%F/`$( which stat ) -f %HT $f | sed ' s/Directory/directory/; s/Fifo file/fifo/; s/Symbolic Link/symbolic link/; s/Regular File/regular file/; s/Block Device/block special file/; s/Character Device/character special file/; ' | sed \"$( test -s $f && echo 's/regular file/regular empty file/g' )\"`/g; s|%n|`$( which stat ) -f %N $f`|g; s/%Y/`$( which stat ) -f %m $f`/g; s/%b/`$( which stat ) -f %b $f`/g; s/%B/512/g; " fi } } function cleanup() { # unmount filesystems before killing daemons to avoid deadllocks MOUNTPOINTS=`mount | grep "$B0/" | awk '{print $3}'` for m in $MOUNTPOINTS; do umount $m done killall -15 glusterfs glusterfsd glusterd 2>/dev/null || true; test "x`uname -s` = "xNetBSD" && pkill -15 perfused || true # allow completion of signal handlers for SIGTERM before issue SIGKILL sleep 1 killall -9 glusterfs glusterfsd glusterd 2>/dev/null || true; test "x`uname -s` = "xNetBSD" && pkill -9 perfused || true # unregister nfs and related services from portmapper/rpcbind ## nfs rpcinfo -d 100003 3 2>/dev/null || true; ## mountd rpcinfo -d 100005 1 2>/dev/null || true; rpcinfo -d 100005 3 2>/dev/null || true; ## nlockmgr rpcinfo -d 100021 1 2>/dev/null || true; rpcinfo -d 100021 4 2>/dev/null || true; ## nfs_acl rpcinfo -d 100227 3 2>/dev/null || true; type cleanup_lvm &>/dev/null && cleanup_lvm || true; case `uname -s` in Linux) LOOPDEVICES=`losetup -a | grep "$B0/" | \ awk '{print $1}' | tr -d :` for l in $LOOPDEVICES; do losetup -d $l done ;; NetBSD) vnd=`vnconfig -l | \ awk '!/not in use/{printf("%s%s:%d ", $1, $2, $5);}'` for l in ${vnd} ; do dev=${l%%:*} tmp=${l#*:} fs=${tmp%%:*} inode=${tmp#*:} file=`find -x ${fs} -inum ${inode} -print -exit` echo ${file} | grep "$B0/" && \ LOOPDEVICES="${LOOPDEVICES} $dev" done for l in $LOOPDEVICES; do vnconfig -u $l done ;; *) echo "`uname -s` loopback device supportmissing" ;; esac if [ -n "${GLUSTERD_WORKDIR}" ] ; then rm -rf $GLUSTERD_WORKDIR/* $B0/* /etc/glusterd/*; fi umount -l $M0 2>/dev/null || umount -f $M0 2>/dev/null || true; umount -l $M1 2>/dev/null || umount -f $M1 2>/dev/null || true; umount -l $N0 2>/dev/null || umount -f $N0 2>/dev/null || true; umount -l $N1 2>/dev/null || umount -f $N1 2>/dev/null || true; } function volinfo_field() { local vol=$1; local field=$2; $CLI volume info $vol | grep "^$field: " | sed 's/.*: //'; } function cleanup_tester () { local exe=$1 rm -f $exe } function build_tester () { local cfile=$1 local fname=$(basename "$cfile") local ext="${fname##*.}" local execname="${fname%.*}" shift local cflags=$* $CC -g -o $(dirname $cfile)/$execname $cfile $cflags } function process_leak_count () { local pid=$1; return $(ls -lh /proc/$pid/fd | grep "(deleted)"| wc -l) } which truncate > /dev/null || { truncate() { local nocreate=0 local ioblocks=0 local fileref="" local newsize="" args=`getopt xor:s: $*` if [ $? -ne 0 ]; then echo 'Usage: truncate [-co](-r file | -s size) file ...' exit 2 fi set -- $args while [ $# -gt 0 ]; do case "$1" in -c) nocreate=1; ;; -o) ioblocks=1; echo "Unimplemented -o option" exit 2 ;; -r) fileref=$2; shift; ;; -s) newsize=$2; shift; ;; --) shift; break; ;; *) echo 'Usage: truncate [-co](-r file | -s size) file ...' exit 2; ;; esac shift done if [ "x$newsize" = "x" -a "x$fileref" = "x" ] ; then echo 'Usage: truncate [-co](-r file | -s size) file ...' exit 2; fi if [ "x$newsize" != "x" -a "x$fileref" != "x" ] ; then echo 'Usage: truncate [-co](-r file | -s size) file ...' exit 2; fi if [ "x$newsize" != "x" ] ; then echo $newsize | grep -q '^[-_<>%/]' && { echo "Unimplemented prefix in ${newsize}" exit 2; } echo $newsize | egrep -q '[GTPEZY]B?$' && { echo "Unit not implemented for ${newsize}" exit 2; } case $newsize in *KB) newsize=$(( ${newsize/KB/} * 1000 )) ;; *K) newsize=$(( ${newsize/K/} * 1024 )) ;; *MB) newsize=$(( ${newsize/MB/} * 1000 * 1000 )) ;; *M) newsize=$(( ${newsize/M/} * 1024 * 1024 )) ;; esac fi if [ "x$fileref" != "x" ] ; then if [ ! -f $fileref ] ; then echo "File does not exists: ${fileref}" exit 2; fi newsize=`ls -l ${fileref}|awk '{print $5}'` fi if [ $# -eq 0 ]; then echo 'Usage: truncate [-co](-r file | -s size) file ...' exit 2; fi for f in $* ; do if [ "x$nocreate" = "x1" -a ! -f $f ] ; then continue; fi dd bs=1 seek=$newsize if=/dev/null of=$f msgfmt=quiet done } } which md5sum > /dev/null || { md5sum() { for f in $* ; do md5 $f | awk -F'[() ]' '{printf("%s %s\n", $6, $3)}' done } } which sha1sum > /dev/null || { sha1sum() { case $OSTYPE in Darwin) for f in $* ; do openssl sha1 $f | awk -F'[() ]' '{printf("%s %s\n", $4, $2)}' done ;; NetBSD | FreeBSD) for f in $* ; do sha1 $f | awk -F'[() ]' '{printf("%s %s\n", $6, $3)}' done ;; esac } } alias EXPECT='_EXPECT $LINENO' alias EXPECT_NOT='_EXPECT_NOT $LINENO' alias TEST='_TEST $LINENO' alias EXPECT_WITHIN='_EXPECT_WITHIN $LINENO' alias EXPECT_KEYWORD='_EXPECT_KEYWORD $LINENO' alias TEST_IN_LOOP='_TEST_IN_LOOP $LINENO' shopt -s expand_aliases if [ x"$OSTYPE" = x"Linux" ]; then alias dd="dd status=none" elif [ x"$OSTYPE" = x"NetBSD" ]; then alias dd="dd msgfmt=quiet" fi # MacOS doesn't seem to support either option. Doing nothing at all is # probably the safest option there and on anything we don't recognize, but # if you want to reduce the noise level and know the correct option for # your favorite platform please feel free to add it here.