diff options
Diffstat (limited to 'tests/basic')
31 files changed, 3101 insertions, 0 deletions
diff --git a/tests/basic/afr/gfid-mismatch.t b/tests/basic/afr/gfid-mismatch.t new file mode 100644 index 000000000..05f48d43a --- /dev/null +++ b/tests/basic/afr/gfid-mismatch.t @@ -0,0 +1,26 @@ +#!/bin/bash +#Test that GFID mismatches result in EIO + +. $(dirname $0)/../../include.rc +cleanup; + +#Init +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 2 $H0:$B0/brick{0,1} +TEST $CLI volume set $V0 self-heal-daemon off +TEST $CLI volume set $V0 stat-prefetch off +TEST $CLI volume start $V0 +TEST $CLI volume set $V0 cluster.background-self-heal-count 0 +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0 --entry-timeout=0 --attribute-timeout=0; + +#Test +TEST touch $M0/file +TEST setfattr -n trusted.gfid -v 0sBfz5vAdHTEK1GZ99qjqTIg== $B0/brick0/file +TEST ! "find $M0/file | xargs stat" + +#Cleanup +TEST umount $M0 +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 +TEST rm -rf $B0/* diff --git a/tests/basic/afr/read-subvol-data.t b/tests/basic/afr/read-subvol-data.t new file mode 100644 index 000000000..7db4988fa --- /dev/null +++ b/tests/basic/afr/read-subvol-data.t @@ -0,0 +1,33 @@ +#!/bin/bash +#Test if the source is selected based on data transaction for a regular file. + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +cleanup; + +#Init +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 2 $H0:$B0/brick{0,1} +TEST $CLI volume set $V0 self-heal-daemon off +TEST $CLI volume set $V0 stat-prefetch off +TEST $CLI volume start $V0 +TEST $CLI volume set $V0 cluster.background-self-heal-count 0 +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0 --entry-timeout=0 --attribute-timeout=0; + +#Test +TEST $CLI volume set $V0 cluster.read-subvolume $V0-client-1 +TEST $CLI volume set $V0 cluster.data-self-heal off +TEST $CLI volume set $V0 cluster.metadata-self-heal off +TEST $CLI volume set $V0 cluster.entry-self-heal off +TEST dd if=/dev/urandom of=$M0/afr_success_5.txt bs=1M count=1 +TEST kill_brick $V0 $H0 $B0/brick0 +TEST dd if=/dev/urandom of=$M0/afr_success_5.txt bs=1M count=10 +TEST $CLI volume start $V0 force +EXPECT_WITHIN 5 "10485760" echo `ls -l $M0/afr_success_5.txt | awk '{ print $5}'` + +#Cleanup +TEST umount $M0 +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 +TEST rm -rf $B0/* diff --git a/tests/basic/afr/read-subvol-entry.t b/tests/basic/afr/read-subvol-entry.t new file mode 100644 index 000000000..91110b8cd --- /dev/null +++ b/tests/basic/afr/read-subvol-entry.t @@ -0,0 +1,35 @@ +#!/bin/bash +#Test if the read child is selected based on entry transaction for directory + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +cleanup; + +#Init +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 2 $H0:$B0/brick{0,1} +TEST $CLI volume set $V0 self-heal-daemon off +TEST $CLI volume set $V0 stat-prefetch off +TEST $CLI volume start $V0 +TEST $CLI volume set $V0 cluster.background-self-heal-count 0 +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0 --entry-timeout=0 --attribute-timeout=0; + +#Test +TEST mkdir -p $M0/abc/def + +TEST $CLI volume set $V0 cluster.data-self-heal off +TEST $CLI volume set $V0 cluster.metadata-self-heal off +TEST $CLI volume set $V0 cluster.entry-self-heal off + +TEST kill_brick $V0 $H0 $B0/brick0 + +TEST touch $M0/abc/def/ghi +TEST $CLI volume start $V0 force +EXPECT_WITHIN 5 "ghi" echo `ls $M0/abc/def/` + +#Cleanup +TEST umount $M0 +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 +TEST rm -rf $B0/* diff --git a/tests/basic/afr/self-heal.t b/tests/basic/afr/self-heal.t new file mode 100644 index 000000000..df9526bcf --- /dev/null +++ b/tests/basic/afr/self-heal.t @@ -0,0 +1,237 @@ +#!/bin/bash +#Self-heal tests + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +cleanup; + +#Init +AREQUAL_PATH=$(dirname $0)/../../utils +build_tester $AREQUAL_PATH/arequal-checksum.c +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 2 $H0:$B0/brick{0,1} +TEST $CLI volume set $V0 stat-prefetch off +TEST $CLI volume start $V0 +TEST $CLI volume set $V0 cluster.background-self-heal-count 0 +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0 --entry-timeout=0 --attribute-timeout=0; + +############################################################################### +#1.Test successful data, metadata and entry self-heal + +#Test +TEST mkdir -p $M0/abc/def $M0/abc/ghi +TEST dd if=/dev/urandom of=$M0/abc/file_abc.txt bs=1M count=2 2>/dev/null +TEST dd if=/dev/urandom of=$M0/abc/def/file_abc_def_1.txt bs=1M count=2 2>/dev/null +TEST dd if=/dev/urandom of=$M0/abc/def/file_abc_def_2.txt bs=1M count=3 2>/dev/null +TEST dd if=/dev/urandom of=$M0/abc/ghi/file_abc_ghi.txt bs=1M count=4 2>/dev/null + +TEST kill_brick $V0 $H0 $B0/brick0 +TEST truncate -s 0 $M0/abc/def/file_abc_def_1.txt +NEW_UID=36 +NEW_GID=36 +TEST chown $NEW_UID:$NEW_GID $M0/abc/def/file_abc_def_2.txt +TEST rm -rf $M0/abc/ghi +TEST mkdir -p $M0/def/ghi $M0/jkl/mno +TEST dd if=/dev/urandom of=$M0/def/ghi/file1.txt bs=1M count=2 2>/dev/null +TEST dd if=/dev/urandom of=$M0/def/ghi/file2.txt bs=1M count=3 2>/dev/null +TEST dd if=/dev/urandom of=$M0/jkl/mno/file.txt bs=1M count=4 2>/dev/null +TEST chown $NEW_UID:$NEW_GID $M0/def/ghi/file2.txt + +TEST $CLI volume start $V0 force +EXPECT_WITHIN 20 "1" afr_child_up_status $V0 0 +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 1 +TEST $CLI volume heal $V0 +EXPECT_WITHIN 20 "0" afr_get_pending_heal_count $V0 + +#check all files created/deleted on brick1 are also replicated on brick 0 +#(i.e. no reverse heal has happened) +TEST ls $B0/brick0/def/ghi/file1.txt +TEST ls $B0/brick0/def/ghi/file2.txt +TEST ls $B0/brick0/jkl/mno/file.txt +TEST ! ls $B0/brick0/abc/ghi +EXPECT "$NEW_UID$NEW_GID" stat --printf=%u%g $B0/brick0/abc/def/file_abc_def_2.txt +TEST diff <($AREQUAL_PATH/arequal-checksum -p $B0/brick0 -i .glusterfs) <($AREQUAL_PATH/arequal-checksum -p $B0/brick1 -i .glusterfs) + +#Cleanup +TEST rm -rf $M0/* +############################################################################### + +#2.Test successful self-heal of different file types. + +#Test +TEST touch $M0/file +TEST kill_brick $V0 $H0 $B0/brick0 +TEST rm -f $M0/file +TEST mkdir $M0/file + +TEST $CLI volume start $V0 force +EXPECT_WITHIN 20 "1" afr_child_up_status $V0 0 +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 1 +TEST $CLI volume heal $V0 +EXPECT_WITHIN 20 "0" afr_get_pending_heal_count $V0 + +#check heal has happened in the correct direction +TEST test -d $B0/brick0/file +TEST diff <($AREQUAL_PATH/arequal-checksum -p $B0/brick0 -i .glusterfs) <($AREQUAL_PATH/arequal-checksum -p $B0/brick1 -i .glusterfs) + +#Cleanup +TEST rm -rf $M0/* +############################################################################### + +#3.Test successful self-heal of file permissions. + +#Test +TEST touch $M0/file +TEST chmod 666 $M0/file +TEST kill_brick $V0 $H0 $B0/brick0 +TEST chmod 777 $M0/file +TEST $CLI volume start $V0 force +EXPECT_WITHIN 20 "1" afr_child_up_status $V0 0 +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 1 +TEST $CLI volume heal $V0 +EXPECT_WITHIN 20 "0" afr_get_pending_heal_count $V0 + +#check heal has happened in the correct direction +EXPECT "777" stat --printf=%a $B0/brick0/file +TEST diff <($AREQUAL_PATH/arequal-checksum -p $B0/brick0 -i .glusterfs) <($AREQUAL_PATH/arequal-checksum -p $B0/brick1 -i .glusterfs) + +#Cleanup +TEST rm -rf $M0/* +############################################################################### + +#4.Test successful self-heal of file ownership + +#Test +TEST touch $M0/file +TEST kill_brick $V0 $H0 $B0/brick0 +NEW_UID=36 +NEW_GID=36 +TEST chown $NEW_UID:$NEW_GID $M0/file +TEST $CLI volume start $V0 force +EXPECT_WITHIN 20 "1" afr_child_up_status $V0 0 +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 1 +TEST $CLI volume heal $V0 +EXPECT_WITHIN 20 "0" afr_get_pending_heal_count $V0 + +#check heal has happened in the correct direction +EXPECT "$NEW_UID$NEW_GID" stat --printf=%u%g $B0/brick0/file +TEST diff <($AREQUAL_PATH/arequal-checksum -p $B0/brick0 -i .glusterfs) <($AREQUAL_PATH/arequal-checksum -p $B0/brick1 -i .glusterfs) + +#Cleanup +TEST rm -rf $M0/* +############################################################################### + +#5.File size test + +#Test +TEST touch $M0/file +TEST `echo "write1">$M0/file` +TEST kill_brick $V0 $H0 $B0/brick0 +TEST `echo "write2">>$M0/file` +TEST $CLI volume start $V0 force +EXPECT_WITHIN 20 "1" afr_child_up_status $V0 0 +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 1 +TEST $CLI volume heal $V0 +TEST kill_brick $V0 $H0 $B0/brick1 +TEST truncate -s 0 $M0/file +TEST $CLI volume start $V0 force +EXPECT_WITHIN 20 "1" afr_child_up_status $V0 1 +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 1 +TEST $CLI volume heal $V0 +EXPECT_WITHIN 20 "0" afr_get_pending_heal_count $V0 + +#check heal has happened in the correct direction +EXPECT 0 stat --printf=%s $B0/brick1/file +TEST diff <($AREQUAL_PATH/arequal-checksum -p $B0/brick0 -i .glusterfs) <($AREQUAL_PATH/arequal-checksum -p $B0/brick1 -i .glusterfs) + +#Cleanup +TEST rm -rf $M0/* +############################################################################### + +#6.GFID heal + +#Test +TEST touch $M0/file +TEST kill_brick $V0 $H0 $B0/brick0 +TEST rm -f $M0/file +TEST touch $M0/file +GFID=$(gf_get_gfid_xattr $B1/brick1/file) +TEST $CLI volume start $V0 force +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 1 +TEST $CLI volume heal $V0 +EXPECT_WITHIN 20 "0" afr_get_pending_heal_count $V0 + +#check heal has happened in the correct direction +EXPECT "$GFID" gf_get_gfid_xattr $B0/brick0/file + +#Cleanup +TEST rm -rf $M0/* +############################################################################### + +#7. Link/symlink heal + +#Test +TEST touch $M0/file +TEST ln $M0/file $M0/link_to_file +TEST kill_brick $V0 $H0 $B0/brick0 +TEST rm -f $M0/link_to_file +TEST ln -s $M0/file $M0/link_to_file +TEST ln $M0/file $M0/hard_link_to_file +TEST $CLI volume start $V0 force +EXPECT_WITHIN 20 "1" afr_child_up_status $V0 0 +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 1 +TEST $CLI volume heal $V0 +EXPECT_WITHIN 20 "0" afr_get_pending_heal_count $V0 + +#check heal has happened in the correct direction +TEST test -f $B0/brick0/hard_link_to_file +TEST test -h $B0/brick0/link_to_file +TEST diff <($AREQUAL_PATH/arequal-checksum -p $B0/brick0 -i .glusterfs) <($AREQUAL_PATH/arequal-checksum -p $B0/brick1 -i .glusterfs) + +#Cleanup +TEST rm -rf $M0/* +############################################################################### + +#8. Heal xattrs set by application + +#Test +TEST touch $M0/file +TEST setfattr -n user.myattr_1 -v My_attribute_1 $M0/file +TEST setfattr -n user.myattr_2 -v "My_attribute_2" $M0/file +TEST kill_brick $V0 $H0 $B0/brick0 +TEST setfattr -n user.myattr_1 -v "My_attribute_1_modified" $M0/file +TEST setfattr -n user.myattr_3 -v "My_attribute_3" $M0/file +TEST $CLI volume start $V0 force +EXPECT_WITHIN 20 "1" afr_child_up_status $V0 0 +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 1 +TEST $CLI volume heal $V0 +EXPECT_WITHIN 20 "0" afr_get_pending_heal_count $V0 + +TEST diff <(echo "user.myattr_1=\"My_attribute_1_modified\"") <(getfattr -n user.myattr_1 $B0/brick1/file|grep user.myattr_1) +TEST diff <(echo "user.myattr_3=\"My_attribute_3\"") <(getfattr -n user.myattr_3 $B0/brick1/file|grep user.myattr_3) + +#Cleanup +TEST rm -rf $M0/* +############################################################################### + +TEST rm -rf $AREQUAL_PATH/arequal-checksum +cleanup; diff --git a/tests/basic/afr/sparse-file-self-heal.t b/tests/basic/afr/sparse-file-self-heal.t new file mode 100644 index 000000000..9b795c331 --- /dev/null +++ b/tests/basic/afr/sparse-file-self-heal.t @@ -0,0 +1,121 @@ +#!/bin/bash + +#This file checks if self-heal of files with holes is working properly or not +#bigger is 2M, big is 1M, small is anything less +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1} +TEST $CLI volume set $V0 data-self-heal-algorithm full +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 +TEST dd if=/dev/urandom of=$M0/small count=1 bs=1M +TEST dd if=/dev/urandom of=$M0/bigger2big count=1 bs=2M +TEST dd if=/dev/urandom of=$M0/big2bigger count=1 bs=1M + +TEST kill_brick $V0 $H0 $B0/${V0}0 + +#File with >128k size hole +TEST truncate -s 1M $M0/big +big_md5sum=$(md5sum $M0/big | awk '{print $1}') + +#File with <128k hole +TEST truncate -s 0 $M0/small +TEST truncate -s 64k $M0/small +small_md5sum=$(md5sum $M0/small | awk '{print $1}') + +#Bigger file truncated to big size hole. +TEST truncate -s 0 $M0/bigger2big +TEST truncate -s 1M $M0/bigger2big +bigger2big_md5sum=$(md5sum $M0/bigger2big | awk '{print $1}') + +#Big file truncated to Bigger size hole +TEST truncate -s 2M $M0/big2bigger +big2bigger_md5sum=$(md5sum $M0/big2bigger | awk '{print $1}') + +$CLI volume start $V0 force +EXPECT_WITHIN 20 "1" afr_child_up_status $V0 0 +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 1 +TEST gluster volume heal $V0 full +EXPECT_WITHIN 20 "0" afr_get_pending_heal_count $V0 + +big_md5sum_0=$(md5sum $B0/${V0}0/big | awk '{print $1}') +small_md5sum_0=$(md5sum $B0/${V0}0/small | awk '{print $1}') +bigger2big_md5sum_0=$(md5sum $B0/${V0}0/bigger2big | awk '{print $1}') +big2bigger_md5sum_0=$(md5sum $B0/${V0}0/big2bigger | awk '{print $1}') + +EXPECT $big_md5sum echo $big_md5sum_0 +EXPECT $small_md5sum echo $small_md5sum_0 +EXPECT $big2bigger_md5sum echo $big2bigger_md5sum_0 +EXPECT $bigger2big_md5sum echo $bigger2big_md5sum_0 + + +EXPECT "1" has_holes $B0/${V0}0/big +#Because self-heal writes the final chunk hole should not be there for +#files < 128K +EXPECT "0" has_holes $B0/${V0}0/small +# Since source is smaller than sink, self-heal does blind copy so no holes will +# be present +EXPECT "0" has_holes $B0/${V0}0/bigger2big +EXPECT "1" has_holes $B0/${V0}0/big2bigger + +TEST rm -f $M0/* + +#check the same tests with diff self-heal +TEST $CLI volume set $V0 data-self-heal-algorithm diff + +TEST dd if=/dev/urandom of=$M0/small count=1 bs=1M +TEST dd if=/dev/urandom of=$M0/big2bigger count=1 bs=1M +TEST dd if=/dev/urandom of=$M0/bigger2big count=1 bs=2M + +TEST kill_brick $V0 $H0 $B0/${V0}0 + +#File with >128k size hole +TEST truncate -s 1M $M0/big +big_md5sum=$(md5sum $M0/big | awk '{print $1}') + +#File with <128k hole +TEST truncate -s 0 $M0/small +TEST truncate -s 64k $M0/small +small_md5sum=$(md5sum $M0/small | awk '{print $1}') + +#Bigger file truncated to big size hole +TEST truncate -s 0 $M0/bigger2big +TEST truncate -s 1M $M0/bigger2big +bigger2big_md5sum=$(md5sum $M0/bigger2big | awk '{print $1}') + +#Big file truncated to Bigger size hole +TEST truncate -s 2M $M0/big2bigger +big2bigger_md5sum=$(md5sum $M0/big2bigger | awk '{print $1}') + +$CLI volume start $V0 force +EXPECT_WITHIN 20 "1" afr_child_up_status $V0 0 +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 1 +TEST gluster volume heal $V0 full +EXPECT_WITHIN 20 "0" afr_get_pending_heal_count $V0 + +big_md5sum_0=$(md5sum $B0/${V0}0/big | awk '{print $1}') +small_md5sum_0=$(md5sum $B0/${V0}0/small | awk '{print $1}') +bigger2big_md5sum_0=$(md5sum $B0/${V0}0/bigger2big | awk '{print $1}') +big2bigger_md5sum_0=$(md5sum $B0/${V0}0/big2bigger | awk '{print $1}') + +EXPECT $big_md5sum echo $big_md5sum_0 +EXPECT $small_md5sum echo $small_md5sum_0 +EXPECT $big2bigger_md5sum echo $big2bigger_md5sum_0 +EXPECT $bigger2big_md5sum echo $bigger2big_md5sum_0 + +EXPECT "1" has_holes $B0/${V0}0/big +EXPECT "1" has_holes $B0/${V0}0/big2bigger +EXPECT "0" has_holes $B0/${V0}0/bigger2big +EXPECT "0" has_holes $B0/${V0}0/small + +cleanup diff --git a/tests/basic/afr/stale-file-lookup.t b/tests/basic/afr/stale-file-lookup.t new file mode 100644 index 000000000..24a478d5c --- /dev/null +++ b/tests/basic/afr/stale-file-lookup.t @@ -0,0 +1,30 @@ +#!/bin/bash + +#This file checks if stale file lookup fails or not. +#A file is deleted when a brick was down. Before self-heal could happen to it +#the file is accessed. It should fail. +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1} +TEST $CLI volume set $V0 self-heal-daemon off +TEST $CLI volume set $V0 cluster.metadata-self-heal off +TEST $CLI volume set $V0 cluster.entry-self-heal off +TEST $CLI volume set $V0 cluster.data-self-heal off +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 +TEST touch $M0/a +TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST rm -f $M0/a +TEST $CLI volume start $V0 force +EXPECT_WITHIN 20 "1" afr_child_up_status $V0 0 +TEST stat $B0/${V0}0/a +TEST ! stat $B0/${V0}1/a +TEST ! ls -l $M0/a + +cleanup diff --git a/tests/basic/bd.t b/tests/basic/bd.t new file mode 100755 index 000000000..eb6305414 --- /dev/null +++ b/tests/basic/bd.t @@ -0,0 +1,131 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc + +function execute() +{ + cmd=$1 + shift + ${cmd} $@ >/dev/null 2>&1 +} + +function bd_cleanup() +{ + execute vgremove -f ${V0} + execute pvremove ${ld} + execute losetup -d ${ld} + execute rm ${BD_DISK} + cleanup +} + +function check() +{ + if [ $? -ne 0 ]; then + echo prerequsite $@ failed + bd_cleanup + exit + fi +} + +SIZE=256 #in MB + +bd_cleanup; + +## Configure environment needed for BD backend volumes +## Create a file with configured size and +## set it as a temporary loop device to create +## physical volume & VG. These are basic things needed +## for testing BD xlator if anyone of these steps fail, +## test script exits +function configure() +{ + GLDIR=`$CLI system:: getwd` + BD_DISK=${GLDIR}/bd_disk + + execute truncate -s${SIZE}M ${BD_DISK} + check ${BD_DISK} creation + + execute losetup -f + check losetup + ld=`losetup -f` + + execute losetup ${ld} ${BD_DISK} + check losetup ${BD_DISK} + execute pvcreate -f ${ld} + check pvcreate ${ld} + execute vgcreate ${V0} ${ld} + check vgcreate ${V0} + execute lvcreate --thin ${V0}/pool --size 128M +} + +function volinfo_field() +{ + local vol=$1; + local field=$2; + $CLI volume info $vol | grep "^$field: " | sed 's/.*: //'; +} + +function volume_type() +{ + getfattr -n volume.type $M0/. --only-values --absolute-names -e text +} + +TEST glusterd +TEST pidof glusterd +configure + +TEST $CLI volume create $V0 ${H0}:/$B0/$V0?${V0} +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; + +## Start volume and verify +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status' + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 +EXPECT '1' volume_type + +## Create posix file +TEST touch $M0/posix + +TEST touch $M0/lv +gfid=`getfattr -n glusterfs.gfid.string $M0/lv --only-values --absolute-names` +TEST setfattr -n user.glusterfs.bd -v "lv:4MB" $M0/lv +# Check if LV is created +TEST stat /dev/$V0/${gfid} + +## Create filesystem +sleep 1 +TEST mkfs.ext4 -qF $M0/lv +# Cloning +TEST touch $M0/lv_clone +gfid=`getfattr -n glusterfs.gfid.string $M0/lv_clone --only-values --absolute-names` +TEST setfattr -n clone -v ${gfid} $M0/lv +TEST stat /dev/$V0/${gfid} + +sleep 1 +## Check mounting +TEST mount -o loop $M0/lv $M1 +umount $M1 + +# Snapshot +TEST touch $M0/lv_sn +gfid=`getfattr -n glusterfs.gfid.string $M0/lv_sn --only-values --absolute-names` +TEST setfattr -n snapshot -v ${gfid} $M0/lv +TEST stat /dev/$V0/${gfid} + +# Merge +sleep 1 +TEST setfattr -n merge -v "$M0/lv_sn" $M0/lv_sn +TEST ! stat $M0/lv_sn +TEST ! stat /dev/$V0/${gfid} + + +rm $M0/* -f + +TEST umount $M0 +TEST $CLI volume stop ${V0} +EXPECT 'Stopped' volinfo_field $V0 'Status'; +TEST $CLI volume delete ${V0} + +bd_cleanup diff --git a/tests/basic/cdc.t b/tests/basic/cdc.t new file mode 100755 index 000000000..70d2171a8 --- /dev/null +++ b/tests/basic/cdc.t @@ -0,0 +1,133 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd + +## Create a volume with one brick +TEST $CLI volume create $V0 $H0:$B0/${V0}1; +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT '1' brick_count $V0 + +## Turn off performance translators +## This is required for testing readv calls +TEST $CLI volume set $V0 performance.io-cache off +EXPECT 'off' volinfo_field $V0 'performance.io-cache' +TEST $CLI volume set $V0 performance.quick-read off +EXPECT 'off' volinfo_field $V0 'performance.quick-read' + +TEST $CLI volume set $V0 performance.strict-write-ordering on +EXPECT 'on' volinfo_field $V0 'performance.strict-write-ordering' + +## Turn on cdc xlator by setting network.compression to on +TEST $CLI volume set $V0 network.compression on +EXPECT 'on' volinfo_field $V0 'network.compression' + +## Make sure that user cannot change network.compression.mode +## This would break the cdc xlator if allowed! +TEST ! $CLI volume set $V0 network.compression.mode client + +## Turn on network.compression.debug option +## This will dump compressed data onto disk as gzip file +## This is used to check if compression actually happened +TEST $CLI volume set $V0 network.compression.debug on +EXPECT 'on' volinfo_field $V0 'network.compression.debug' + +## Start the volume +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +sleep 2 +## Mount FUSE with caching disabled +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 -s $H0 --volfile-id $V0 $M0; + +#################### +## Testing writev ## +#################### + +## Create a 1K file locally and find the md5sum +TEST dd if=/dev/zero of=/tmp/cdc-orig count=1 bs=1K 2>/dev/null +checksum[original-file]=`md5sum /tmp/cdc-orig | cut -d' ' -f1` + +## Copy the file to mountpoint and find its md5sum on brick +TEST dd if=/tmp/cdc-orig of=$M0/cdc-server count=1 bs=1K 2>/dev/null +checksum[brick-file]=`md5sum $B0/${V0}1/cdc-server | cut -d' ' -f1` + +## Uncompress the gzip dump file and find its md5sum +EXPECT '/tmp/cdcdump.gz: application/x-gzip; charset=binary' file -i /tmp/cdcdump.gz +TEST gunzip -f /tmp/cdcdump.gz +checksum[dump-file-writev]=`md5sum /tmp/cdcdump | cut -d' ' -f1` + +## Check if all 3 checksums are same +TEST test ${checksum[original-file]} = ${checksum[brick-file]} +TEST test ${checksum[brick-file]} = ${checksum[dump-file-writev]} + +## Cleanup files +TEST rm -f /tmp/cdcdump.gz + +################### +## Testing readv ## +################### + +## Copy file from mount point to client and find checksum +TEST dd if=$M0/cdc-server of=/tmp/cdc-client count=1 bs=1K 2>/dev/null +checksum[client-file]=`md5sum /tmp/cdc-client | cut -d' ' -f1` + +## Uncompress the gzip dump file and find its md5sum +EXPECT '/tmp/cdcdump.gz: application/x-gzip; charset=binary' file -i /tmp/cdcdump.gz +TEST gunzip -f /tmp/cdcdump.gz +checksum[dump-file-readv]=`md5sum /tmp/cdcdump | cut -d' ' -f1` + +## Check if all 3 checksums are same +TEST test ${checksum[brick-file]} = ${checksum[client-file]} +TEST test ${checksum[client-file]} = ${checksum[dump-file-readv]} + +## Cleanup files and unmount +TEST rm -f /tmp/cdc* $M0/cdc* +TEST umount $M0 + +## Stop the volume +TEST $CLI volume stop $V0; +EXPECT 'Stopped' volinfo_field $V0 'Status'; + +## Turn on network.compression.min-size and set it to 100 bytes +## Compression should not take place if file size +## is less than 100 bytes +TEST $CLI volume set $V0 network.compression.min-size 100 +EXPECT '100' volinfo_field $V0 'network.compression.min-size' + +## Start the volume +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +## Mount FUSE with caching disabled +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 -s $H0 --volfile-id $V0 $M0; + +## Create a file of size 99 bytes on mountpoint +## This is should not be compressed +TEST dd if=/dev/zero of=$M0/cdc-small count=1 bs=99 2>/dev/null +TEST ! test -e /tmp/cdcdump.gz + +## Cleanup files and unmount +TEST rm -f /tmp/cdc* $M0/cdc* +TEST umount $M0 + +## Reset the network.compression options +TEST $CLI volume reset $V0 network.compression.debug +TEST $CLI volume reset $V0 network.compression.min-size +TEST $CLI volume reset $V0 network.compression + +## Stop the volume +TEST $CLI volume stop $V0; +EXPECT 'Stopped' volinfo_field $V0 'Status'; + +## Delete the volume +TEST $CLI volume delete $V0; +TEST ! $CLI volume info $V0; + +cleanup; diff --git a/tests/basic/file-snapshot.t b/tests/basic/file-snapshot.t new file mode 100755 index 000000000..36908192b --- /dev/null +++ b/tests/basic/file-snapshot.t @@ -0,0 +1,56 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 $H0:$B0/$V0; + +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST $CLI volume set $V0 features.file-snapshot on; + +TEST $CLI volume set $V0 performance.quick-read off; +TEST $CLI volume set $V0 performance.io-cache off; +TEST glusterfs -s $H0 --volfile-id $V0 $M0 --attribute-timeout=0; + +TEST touch $M0/big-file; + +TEST setfattr -n trusted.glusterfs.block-format -v qcow2:10GB $M0/big-file; + +TEST ls -al $M0 # test readdirplus +TEST [ `stat -c '%s' $M0/big-file` = 10737418240 ] + +echo 'ABCDEFGHIJ' > $M0/data-file1 +TEST dd if=$M0/data-file1 of=$M0/big-file conv=notrunc; +TEST setfattr -n trusted.glusterfs.block-snapshot-create -v image1 $M0/big-file; + +echo '1234567890' > $M0/data-file2 +TEST dd if=$M0/data-file2 of=$M0/big-file conv=notrunc; +TEST setfattr -n trusted.glusterfs.block-snapshot-create -v image2 $M0/big-file; + +TEST setfattr -n trusted.glusterfs.block-snapshot-goto -v image1 $M0/big-file; +TEST dd if=$M0/big-file of=$M0/out-file1 bs=11 count=1; + +TEST setfattr -n trusted.glusterfs.block-snapshot-goto -v image2 $M0/big-file; +TEST dd if=$M0/big-file of=$M0/out-file2 bs=11 count=1; + +TEST cmp $M0/data-file1 $M0/out-file1; +TEST cmp $M0/data-file2 $M0/out-file2; + +TEST $CLI volume stop $V0; +EXPECT 'Stopped' volinfo_field $V0 'Status'; + +TEST $CLI volume delete $V0; +TEST ! $CLI volume info $V0; + +cleanup; diff --git a/tests/basic/four-brick.t b/tests/basic/four-brick.t new file mode 100755 index 000000000..a8d9cd400 --- /dev/null +++ b/tests/basic/four-brick.t @@ -0,0 +1,85 @@ +#!/bin/bash + +# Test *very basic* NSR functionality - startup, mount, simplest possible file +# write. + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +function get_rep_count { + v=$(getfattr --only-values -e text -n trusted.nsr.rep-count $1 2> /dev/null) + #echo $v > /dev/tty + echo $v +} + +function ping_file { + dd if=/dev/urandom of=$1 bs=4k count=100 2> /dev/null +} + +function kill_brick { + bpid=$(cat /var/lib/glusterd/vols/${V0}/run/*-${V0}${1}.pid) + rpid=$(cat /var/lib/glusterd/vols/${V0}/run/*-${V0}${1}-recon.pid) + echo "brick PID = $bpid" > /dev/tty + echo "recon PID = $rpid" > /dev/tty + kill -9 $bpid $rpid +} + +function count_matches { + n=0 + for f in $B0/$V0[1234]/$1; do + cmp $M0/$1 $f 2> /dev/null + if [ $? = 0 ]; then + n=$((n+1)) + fi + done + echo $n +} + +cleanup + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info + +TEST mkdir -p ${V0}{1,2,3,4} +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2,3,4} + +EXPECT "$V0" volinfo_field $V0 'Volume Name' +EXPECT 'Created' volinfo_field $V0 'Status' +EXPECT '4' brick_count $V0 + +TEST $CLI volume set $V0 cluster.nsr on +TEST $CLI volume set $V0 cluster.nsr.recon on + +TEST $CLI volume start $V0 +EXPECT 'Started' volinfo_field $V0 'Status' + +## Mount FUSE with caching disabled (read-only) +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 -s $H0 --volfile-id $V0 $M0 + +# Give the bricks a chance to connect to each other. +EXPECT_WITHIN 10 "2" get_rep_count $M0 + +TEST ping_file $M0/probe +TEST cmp ${M0}/probe ${B0}/${V0}1/probe +TEST cmp ${M0}/probe ${B0}/${V0}2/probe + +# Kill one brick from each pair. +TEST kill_brick 1 +TEST kill_brick 3 +sleep 10 + +# Make sure only one copy makes it while degraded. +TEST ping_file $M0/probe2 +TEST [ $(count_matches probe2) = 1 ] + +# Restart the brick and give reconciliation a chance to run. +# TBD: figure out why reconciliation takes so $#@! long to run +TEST $CLI volume start $V0 force +sleep 20 + +# Make sure *both* copies are valid after reconciliation. +TEST [ $(count_matches probe2) = 2 ] + +cleanup +#killall -9 etcd diff --git a/tests/basic/logchecks-messages.h b/tests/basic/logchecks-messages.h new file mode 100644 index 000000000..50efe9dfa --- /dev/null +++ b/tests/basic/logchecks-messages.h @@ -0,0 +1,84 @@ +/* + Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. + */ + +#ifndef _LOGCHECKS_MESSAGES_H_ +#define _LOGCHECKS_MESSAGES_H_ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "glfs-message-id.h" + +/* NOTE: Rules for message additions + * 1) Each instance of a message is _better_ left with a unique message ID, even + * if the message format is the same. Reasoning is that, if the message + * format needs to change in one instance, the other instances are not + * impacted or the new change does not change the ID of the instance being + * modified. + * 2) Addition of a message, + * - Should increment the GLFS_NUM_MESSAGES + * - Append to the list of messages defined, towards the end + * - Retain macro naming as glfs_msg_X (for redability across developers) + * NOTE: Rules for message format modifications + * 3) Check acorss the code if the message ID macro in question is reused + * anywhere. If reused then then the modifications should ensure correctness + * everywhere, or needs a new message ID as (1) above was not adhered to. If + * not used anywhere, proceed with the required modification. + * NOTE: Rules for message deletion + * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used + * anywhere, then can be deleted, but will leave a hole by design, as + * addition rules specify modification to the end of the list and not filling + * holes. + */ + +#define GLFS_COMP_BASE 1000 +#define GLFS_NUM_MESSAGES 19 +#define GLFS_MSGID_END (GLFS_COMP_BASE + GLFS_NUM_MESSAGES + 1) +/* Messaged with message IDs */ +#define glfs_msg_start_x GLFS_COMP_BASE, "Invalid: Start of messages" +/*------------*/ +#define logchecks_msg_1 (GLFS_COMP_BASE + 1), "Informational: Testing logging" \ + " in gluster" +#define logchecks_msg_2 (GLFS_COMP_BASE + 2), "Informational: Format testing:" \ + " %d:%s:%x" +#define logchecks_msg_3 (GLFS_COMP_BASE + 3), "Critical: Testing logging" \ + " in gluster" +#define logchecks_msg_4 (GLFS_COMP_BASE + 4), "Critical: Format testing:" \ + " %d:%s:%x" +#define logchecks_msg_5 (GLFS_COMP_BASE + 5), "Critical: Rotated the log" +#define logchecks_msg_6 (GLFS_COMP_BASE + 6), "Critical: Flushed the log" +#define logchecks_msg_7 (GLFS_COMP_BASE + 7), "Informational: gf_msg_callingfn" +#define logchecks_msg_8 (GLFS_COMP_BASE + 8), "Informational: " \ + "gf_msg_callingfn: Format testing: %d:%s:%x" +#define logchecks_msg_9 (GLFS_COMP_BASE + 9), "Critical: gf_msg_callingfn" +#define logchecks_msg_10 (GLFS_COMP_BASE + 10), "Critical: " \ + "gf_msg_callingfn: Format testing: %d:%s:%x" +#define logchecks_msg_11 (GLFS_COMP_BASE + 11), "==========================" +#define logchecks_msg_12 (GLFS_COMP_BASE + 12), "Test 1: Only stderr and" \ + " partial syslog" +#define logchecks_msg_13 (GLFS_COMP_BASE + 13), "Test 2: Only checklog and" \ + " partial syslog" +#define logchecks_msg_14 (GLFS_COMP_BASE + 14), "Test 5: Changing to" \ + " traditional format" +#define logchecks_msg_15 (GLFS_COMP_BASE + 15), "Test 6: Changing log level" \ + " to critical and above" +#define logchecks_msg_16 (GLFS_COMP_BASE + 16), "Test 7: Only to syslog" +#define logchecks_msg_17 (GLFS_COMP_BASE + 17), "Test 8: Only to syslog," \ + " traditional format" +#define logchecks_msg_18 (GLFS_COMP_BASE + 18), "Test 9: Only to syslog," \ + " only critical and above" +#define logchecks_msg_19 (GLFS_COMP_BASE + 19), "Pre init message, not to be" \ + " seen in logs" +/*------------*/ +#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" + +#endif /* !_component_MESSAGES_H_ */
\ No newline at end of file diff --git a/tests/basic/logchecks.c b/tests/basic/logchecks.c new file mode 100644 index 000000000..4f858a7fc --- /dev/null +++ b/tests/basic/logchecks.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com> + * This file is part of GlusterFS. + * + * This file is licensed to you under your choice of the GNU Lesser + * General Public License, version 3 or any later version (LGPLv3 or + * later), or the GNU General Public License, version 2 (GPLv2), in all + * cases as published by the Free Software Foundation. + */ + +#include <stdio.h> +#include <unistd.h> + +#include "glusterfs.h" +#include "globals.h" +#include "logging.h" + +#include "logchecks-messages.h" +#include "../../libglusterfs/src/logging.h" + +glusterfs_ctx_t *ctx = NULL; + +#define TEST_FILENAME "/tmp/logchecks.log" +#define GF_LOG_CONTROL_FILE "/etc/glusterfs/logger.conf" + +int +go_log_vargs(gf_loglevel_t level, const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + gf_msg_vplain (level, fmt, ap); + va_end (ap); + + return 0; +} + +int +go_log (void) +{ + /*** gf_msg ***/ + gf_msg ("logchecks", GF_LOG_INFO, 0, logchecks_msg_1); + gf_msg ("logchecks", GF_LOG_INFO, 22, logchecks_msg_2, 42, "Forty-Two", + 42); + /* change criticality */ + gf_msg ("logchecks", GF_LOG_CRITICAL, 0, logchecks_msg_3); + gf_msg ("logchecks", GF_LOG_CRITICAL, 22, logchecks_msg_4, 42, + "Forty-Two", 42); + + /*** msg_nomem ***/ + gf_msg_nomem ("logchecks", GF_LOG_ALERT, 555); + gf_msg_nomem ("logchecks", GF_LOG_INFO, 555); + + /*** msg_plain ***/ + gf_msg_plain (GF_LOG_INFO, "Informational: gf_msg_plain with" + " args %d:%s:%x", 42, "Forty-Two", 42); + gf_msg_plain (GF_LOG_ALERT, "Alert: gf_msg_plain with" + " args %d:%s:%x", 42, "Forty-Two", 42); + + /*** msg_vplain ***/ + go_log_vargs (GF_LOG_INFO, "Informational: gf_msg_vplain: No args!!!"); + go_log_vargs (GF_LOG_INFO, "Informational: gf_msg_vplain: Some" + " args %d:%s:%x", 42, "Forty-Two", 42); + go_log_vargs (GF_LOG_INFO, "Critical: gf_msg_vplain: No args!!!"); + go_log_vargs (GF_LOG_INFO, "Critical: gf_msg_vplain: Some" + " args %d:%s:%x", 42, "Forty-Two", 42); + + /*** msg_plain_nomem ***/ + gf_msg_plain_nomem (GF_LOG_INFO, "Informational: gf_msg_plain_nomem"); + gf_msg_plain_nomem (GF_LOG_ALERT, "Alert: gf_msg_plain_nomem"); + + /*** msg_backtrace_nomem ***/ + // TODO: Need to create a stack depth and then call + gf_msg_backtrace_nomem (GF_LOG_INFO, 5); + gf_msg_backtrace_nomem (GF_LOG_ALERT, 5); + + /*** gf_msg_callingfn ***/ + // TODO: Need to create a stack depth and then call + gf_msg_callingfn ("logchecks", GF_LOG_INFO, 0, logchecks_msg_7); + gf_msg_callingfn ("logchecks", GF_LOG_INFO, 0, logchecks_msg_8, 42, + "Forty-Two", 42); + gf_msg_callingfn ("logchecks", GF_LOG_CRITICAL, 0, logchecks_msg_9); + gf_msg_callingfn ("logchecks", GF_LOG_CRITICAL, 0, logchecks_msg_10, 42, + "Forty-Two", 42); + + /*** gf_msg_debug ***/ + gf_msg_debug ("logchecks", 0, "Debug: Hello World!!!"); + gf_msg_debug ("logchecks", 22, "Debug: With args %d:%s:%x", 42, + "Forty-Two", 42); + + /*** gf_msg_trace ***/ + gf_msg_trace ("logchecks", 0, "Trace: Hello World!!!"); + gf_msg_trace ("logchecks", 22, "Trace: With args %d:%s:%x", 42, + "Forty-Two", 42); + + /*** gf_msg_backtrace ***/ + // TODO: Test with lower callstr values to check truncation + + return 0; +} + +int +main (int argc, char *argv[]) +{ + int ret = -1; + + unlink (GF_LOG_CONTROL_FILE); + creat (GF_LOG_CONTROL_FILE, O_RDONLY); + ctx = glusterfs_ctx_new (); + if (!ctx) + return -1; + + ret = glusterfs_globals_init (ctx); + if (ret) { + printf ("Error from glusterfs_globals_init [%s]\n", + strerror (errno)); + return ret; + } + + /* Pre init test, message should not be printed */ + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_19); + + THIS->ctx = ctx; + + /* TEST 1: messages before initializing the log, goes to stderr + * and syslog based on criticality */ + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_12); + go_log (); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + + /* TEST 2: messages post initialization, goes to glusterlog and + * syslog based on severity */ + ret = gf_log_init(ctx, TEST_FILENAME, "logchecks"); + if (ret != 0) { + printf ("Error from gf_log_init [%s]\n", strerror (errno)); + return -1; + } + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_13); + go_log (); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + + /* TEST 3: Test rotation */ + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + gf_log_logrotate (0); + gf_msg ("logchecks", GF_LOG_CRITICAL, 0, logchecks_msg_5); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + + /* TEST 4: Check flush, nothing noticable should occur :) */ + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + gf_log_flush (); + gf_msg ("logchecks", GF_LOG_CRITICAL, 0, logchecks_msg_6); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + + /* TEST 5: Change format */ + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + gf_log_set_logformat (gf_logformat_traditional); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_14); + go_log (); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + + /* TEST 6: Change level */ + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + gf_log_set_loglevel (GF_LOG_CRITICAL); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_15); + go_log (); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + + /* Reset to run with syslog */ + gf_log_set_logformat (gf_logformat_withmsgid); + gf_log_set_loglevel (GF_LOG_INFO); + + /* Run tests with logger changed to syslog */ + /* TEST 7: No more gluster logs */ + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + gf_log_set_logger (gf_logger_syslog); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_16); + go_log (); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + + /* TEST 8: Change format */ + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + gf_log_set_logformat (gf_logformat_traditional); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_14); + go_log (); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + + /* TEST 9: Change level */ + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + gf_log_set_loglevel (GF_LOG_CRITICAL); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_15); + go_log (); + gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11); + + // TODO: signal crash prints, but not yet feasible here + // TODO: Graph printing + // TODO: Multi threaded logging + + /* Close out the logging */ + gf_log_fini (ctx); + gf_log_globals_fini (); + + unlink (GF_LOG_CONTROL_FILE); + unlink (TEST_FILENAME); + + return 0; +}
\ No newline at end of file diff --git a/tests/basic/mgmt_v3-locks.t b/tests/basic/mgmt_v3-locks.t new file mode 100644 index 000000000..22ca27b9f --- /dev/null +++ b/tests/basic/mgmt_v3-locks.t @@ -0,0 +1,121 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../cluster.rc + +function check_peers { + $CLI_1 peer status | grep 'Peer in Cluster (Connected)' | wc -l +} + +function volume_count { + local cli=$1; + if [ $cli -eq '1' ] ; then + $CLI_1 volume info | grep 'Volume Name' | wc -l; + else + $CLI_2 volume info | grep 'Volume Name' | wc -l; + fi +} + +function volinfo_field() +{ + local vol=$1; + local field=$2; + + $CLI_1 volume info $vol | grep "^$field: " | sed 's/.*: //'; +} + +function two_diff_vols_create { + # Both volume creates should be successful + $CLI_1 volume create $V0 $H1:$B1/$V0 $H2:$B2/$V0 $H3:$B3/$V0 & + PID_1=$! + + $CLI_2 volume create $V1 $H1:$B1/$V1 $H2:$B2/$V1 $H3:$B3/$V1 & + PID_2=$! + + wait $PID_1 $PID_2 +} + +function two_diff_vols_start { + # Both volume starts should be successful + $CLI_1 volume start $V0 & + PID_1=$! + + $CLI_2 volume start $V1 & + PID_2=$! + + wait $PID_1 $PID_2 +} + +function two_diff_vols_stop_force { + # Force stop, so that if rebalance from the + # remove bricks is in progress, stop can + # still go ahead. Both volume stops should + # be successful + $CLI_1 volume stop $V0 force & + PID_1=$! + + $CLI_2 volume stop $V1 force & + PID_2=$! + + wait $PID_1 $PID_2 +} + +function same_vol_remove_brick { + + # Running two same vol commands at the same time can result in + # two success', two failures, or one success and one failure, all + # of which are valid. The only thing that shouldn't happen is a + # glusterd crash. + + local vol=$1 + local brick=$2 + $CLI_1 volume remove-brick $1 $2 start & + $CLI_2 volume remove-brick $1 $2 start +} + +cleanup; + +TEST launch_cluster 3; +TEST $CLI_1 peer probe $H2; +TEST $CLI_1 peer probe $H3; + +EXPECT_WITHIN 20 2 check_peers + +two_diff_vols_create +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT 'Created' volinfo_field $V1 'Status'; + +two_diff_vols_start +EXPECT 'Started' volinfo_field $V0 'Status'; +EXPECT 'Started' volinfo_field $V1 'Status'; + +same_vol_remove_brick $V0 $H2:$B2/$V0 +# Checking glusterd crashed or not after same volume remove brick +# on both nodes. +EXPECT_WITHIN 20 2 check_peers + +same_vol_remove_brick $V1 $H2:$B2/$V1 +# Checking glusterd crashed or not after same volume remove brick +# on both nodes. +EXPECT_WITHIN 20 2 check_peers + +$CLI_1 volume set $V0 diagnostics.client-log-level DEBUG & +$CLI_1 volume set $V1 diagnostics.client-log-level DEBUG +kill_glusterd 3 +$CLI_1 volume status $V0 +$CLI_2 volume status $V1 +$CLI_1 peer status +EXPECT_WITHIN 20 1 check_peers +EXPECT 'Started' volinfo_field $V0 'Status'; +EXPECT 'Started' volinfo_field $V1 'Status'; + +TEST $glusterd_3 +$CLI_1 volume status $V0 +$CLI_2 volume status $V1 +$CLI_1 peer status +#EXPECT_WITHIN 20 2 check_peers +#EXPECT 'Started' volinfo_field $V0 'Status'; +#EXPECT 'Started' volinfo_field $V1 'Status'; +#two_diff_vols_stop_force +#EXPECT_WITHIN 20 2 check_peers +cleanup; diff --git a/tests/basic/mount-options.disabled b/tests/basic/mount-options.disabled new file mode 100644 index 000000000..86d945ac5 --- /dev/null +++ b/tests/basic/mount-options.disabled @@ -0,0 +1,140 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd --xlator-option=*.rpc-auth-allow-insecure=on +TEST pidof glusterd +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1,2,3,4,5} +TEST $CLI volume set $V0 server.allow-insecure on +TEST $CLI volume start $V0 + +#test all the options available to see if the mount succeeds with those options +#or not. This does not test functionality. This is added to prevent options +#being removed in future breaking backward-compatibility. + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --entry-timeout=0 +TEST umount -l $M0 + +TEST glusterfs --volfile=/var/lib/glusterd/vols/$V0/${V0}-fuse.vol $M0 +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 --log-file=/tmp/a.txt --log-level=DEBUG $M0 +EXPECT_NOT "0" wc -l /tmp/a.txt +TEST grep " D " /tmp/a.txt +TEST rm -f /tmp/a.txt +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --acl +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --aux-gfid-mount +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --enable-ino32 +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --fopen-keep-cache=yes +TEST umount -l $M0 +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --fopen-keep-cache=no +TEST umount -l $M0 +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --fopen-keep-cache=fail + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --mac-compat=yes +TEST umount -l $M0 +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --mac-compat=no +TEST umount -l $M0 +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --mac-compat=fail + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --use-readdirp=yes +TEST umount -l $M0 +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --use-readdirp=no +TEST umount -l $M0 +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --use-readdirp=fail + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --direct-io-mode=yes +TEST umount -l $M0 +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --direct-io-mode=no +TEST umount -l $M0 +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --direct-io-mode=fail + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --read-only +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --selinux +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --worm +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --volfile-check +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --dump-fuse=/tmp/a.txt +EXPECT "0" stat /tmp/a.txt +TEST rm -f /tmp/a.txt +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --gid-timeout=0 +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --gid-timeout=-1 +TEST umount -l $M0 + +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --gid-timeout=abc + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --background-qlen=16 +TEST umount -l $M0 + +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --background-qlen=abc + +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --background-qlen=-1 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --congestion-threshold=12 +TEST umount -l $M0 + +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --congestion-threshold=abc + +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --congestion=threshold=-1 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --negative-timeout=10 +TEST umount -l $M0 + +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --negative-timeout=abc +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --negative-timeout=-1 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --pid-file=/tmp/a.txt +EXPECT_NOT "0" wc -l /tmp/a.txt +TEST rm -f /tmp/a.txt +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --volfile-server-port=24007 +TEST umount -l $M0 + +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --volfile-server-port=2400 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --volfile-server-transport=tcp +TEST umount -l $M0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --volfile-server-transport=ib-verbs +TEST umount -l $M0 + +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --volfile-server-port=socket + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --volume-name=$V0 +TEST umount -l $M0 + +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --volume-name=abcd + +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --invalid-option + +TEST ! glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --invalid-option=abc +cleanup; diff --git a/tests/basic/mount.t b/tests/basic/mount.t new file mode 100755 index 000000000..8163975d6 --- /dev/null +++ b/tests/basic/mount.t @@ -0,0 +1,79 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../nfs.rc + +cleanup; + + +## Start and create a volume +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 stripe 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8}; + +function volinfo_field() +{ + local vol=$1; + local field=$2; + + $CLI volume info $vol | grep "^$field: " | sed 's/.*: //'; +} + + +## Verify volume is is created +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; + + +## Start volume and verify +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + + +## Make volume tightly consistent for metdata +TEST $CLI volume set $V0 performance.stat-prefetch off; + +## Mount FUSE with caching disabled (read-write) +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 -s $H0 --volfile-id $V0 $M0; + +## Check consistent "rw" option +TEST 'mount -t fuse.glusterfs | grep -E "^$H0:$V0 .+ \(rw,"'; +TEST 'grep -E "^$H0:$V0 .+ ,?rw," /proc/mounts'; + +## Mount FUSE with caching disabled (read-only) +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 --read-only -s $H0 --volfile-id $V0 $M1; + +## Check consistent "ro" option +TEST 'mount -t fuse.glusterfs | grep -E "^$H0:$V0 .+ \(ro,"'; +TEST 'grep -E "^$H0:$V0 .+ ,?ro,.+" /proc/mounts'; + +## Wait for volume to register with rpc.mountd +EXPECT_WITHIN 20 "1" is_nfs_export_available; + +## Mount NFS +TEST mount -t nfs -o nolock,soft,intr $H0:/$V0 $N0; + + +## Test for consistent views between NFS and FUSE mounts +## write access to $M1 should fail +TEST ! stat $M0/newfile; +TEST ! touch $M1/newfile; +TEST touch $M0/newfile; +TEST stat $M1/newfile; +TEST stat $N0/newfile; +TEST ! rm $M1/newfile; +TEST rm $N0/newfile; +TEST ! stat $M0/newfile; +TEST ! stat $M1/newfile; + + +## Finish up +TEST $CLI volume stop $V0; +EXPECT 'Stopped' volinfo_field $V0 'Status'; + +TEST $CLI volume delete $V0; +TEST ! $CLI volume info $V0; + +cleanup; diff --git a/tests/basic/nsr.t b/tests/basic/nsr.t new file mode 100755 index 000000000..5dd97f2bf --- /dev/null +++ b/tests/basic/nsr.t @@ -0,0 +1,47 @@ +#!/bin/bash + +# Test *very basic* NSR functionality - startup, mount, simplest possible file +# write. + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +function get_rep_count { + v=$(getfattr --only-values -e text -n trusted.nsr.rep-count $1 2> /dev/null) + #echo $v > /dev/tty + echo $v +} + +function ping_file { + dd if=/dev/urandom of=$1 bs=4k count=100 2> /dev/null +} + +cleanup + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info + +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2} + +EXPECT "$V0" volinfo_field $V0 'Volume Name' +EXPECT 'Created' volinfo_field $V0 'Status' +EXPECT '2' brick_count $V0 + +TEST $CLI volume set $V0 cluster.nsr on + +TEST $CLI volume start $V0 +EXPECT 'Started' volinfo_field $V0 'Status' + +## Mount FUSE with caching disabled (read-only) +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 -s $H0 --volfile-id $V0 $M0 + +# Give the bricks a chance to connect to each other. +EXPECT_WITHIN 10 "2" get_rep_count $M0 + +TEST ping_file $M0/probe +TEST cmp ${M0}/probe ${B0}/${V0}1/probe +TEST cmp ${M0}/probe ${B0}/${V0}2/probe + +cleanup +killall -9 etcd diff --git a/tests/basic/nufa.t b/tests/basic/nufa.t new file mode 100644 index 000000000..0d4c229a0 --- /dev/null +++ b/tests/basic/nufa.t @@ -0,0 +1,32 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 stripe 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8}; + +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT '8' brick_count $V0 + +TEST $CLI volume set $V0 nufa on; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +## Mount FUSE with caching disabled (read-only) +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 --read-only -s $H0 --volfile-id $V0 $M1; + +## Wait for volume to register with rpc.mountd +sleep 5; + +## Mount NFS +TEST mount -t nfs -o nolock,soft,intr $H0:/$V0 $N0; + +cleanup; diff --git a/tests/basic/pgfid-feat.t b/tests/basic/pgfid-feat.t new file mode 100644 index 000000000..3978f9c97 --- /dev/null +++ b/tests/basic/pgfid-feat.t @@ -0,0 +1,35 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +function get_ancestry_path() { + local path=$1 + local ancestry=$(getfattr --absolute-names -e text -n glusterfs.ancestry.path "$M0/$path" | grep "^glusterfs.ancestry.path" | cut -d"=" -f2 | tr -d \"); + echo $ancestry; +} + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2,3,4}; +TEST $CLI volume start $V0; +TEST glusterfs -s $H0 --volfile-id $V0 $M0; + +TEST $CLI volume set $V0 build-pgfid on; + +TEST mkdir $M0/a; +TEST touch $M0/a/b; + +EXPECT "/a/b" get_ancestry_path "/a/b"; + +TEST $CLI volume set $V0 build-pgfid off; +EXPECT "" get_ancestry_path "/a/b"; + +TEST $CLI volume stop $V0; +TEST $CLI volume delete $V0; + +cleanup; diff --git a/tests/basic/posixonly.t b/tests/basic/posixonly.t new file mode 100755 index 000000000..b9de317a4 --- /dev/null +++ b/tests/basic/posixonly.t @@ -0,0 +1,30 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc + +cleanup; + +TEST mkdir -p $B0/posixonly +cat > $B0/posixonly.vol <<EOF +volume poisxonly + type storage/posix + option directory $B0/posixonly +end-volume +EOF + +TEST glusterfs -f $B0/posixonly.vol $M0; + +TEST touch $M0/filename; +TEST stat $M0/filename; +TEST mkdir $M0/dirname; +TEST stat $M0/dirname; +TEST touch $M0/dirname/filename; +TEST stat $M0/dirname/filename; +TEST ln $M0/dirname/filename $M0/dirname/linkname; +TEST chown 100:100 $M0/dirname/filename; +TEST chown 100:100 $M0/dirname; +TEST rm -rf $M0/filename $M0/dirname; + +TEST umount $M0; + +cleanup; diff --git a/tests/basic/pump.t b/tests/basic/pump.t new file mode 100644 index 000000000..23bdc187d --- /dev/null +++ b/tests/basic/pump.t @@ -0,0 +1,44 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 $H0:$B0/${V0}0 +TEST $CLI volume start $V0 +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 +cd $M0 +for i in {1..3} +do + for j in {1..10} + do + dd if=/dev/urandom of=file$j bs=128K count=10 2>/dev/null 1>/dev/null + done + mkdir dir$i && cd dir$i +done +cd +TEST umount $M0 +TEST $CLI volume replace-brick $V0 $H0:$B0/${V0}0 $H0:$B0/${V0}1 start +EXPECT_WITHIN 600 "Y" gd_is_replace_brick_completed $H0 $V0 $H0:$B0/${V0}0 $H0:$B0/${V0}1 +TEST $CLI volume replace-brick $V0 $H0:$B0/${V0}0 $H0:$B0/${V0}1 commit +TEST $CLI volume stop $V0 +TEST diff -r --exclude=.glusterfs $B0/${V0}0 $B0/${V0}1 + +files="" + +cd $B0/${V0}0 +for f in `find . -path ./.glusterfs -prune -o -print`; +do + if [ -d $f ]; then continue; fi + cmp $f $B0/${V0}1/$f + if [ $? -ne 0 ]; then + files="$files $f" + fi +done + +EXPECT "" echo $files + +cleanup diff --git a/tests/basic/quorum.t b/tests/basic/quorum.t new file mode 100644 index 000000000..b8fc9cf3a --- /dev/null +++ b/tests/basic/quorum.t @@ -0,0 +1,64 @@ +#!/bin/bash + +# Test *very basic* NSR functionality - startup, mount, simplest possible file +# write. + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +function get_rep_count { + v=$(getfattr --only-values -e text -n trusted.nsr.rep-count $1 2> /dev/null) + #echo $v > /dev/tty + echo $v +} + +function kill_a_brick { + for r in /var/lib/glusterd/vols/${V0}/run/*-recon.pid; do + rpid=$(cat $r) + #echo "recon PID = $rpid" > /dev/tty + b=$(echo $r | sed '/\(.*\):\(.*\)-recon.pid/s//\1\2.pid/') + bpid=$(cat $b) + #echo "brick PID = $bpid" > /dev/tty + kill -9 $bpid $rpid + return 0 + done + + # No bricks?!? + return 1 +} + +cleanup + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info + +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2} + +EXPECT "$V0" volinfo_field $V0 'Volume Name' +EXPECT 'Created' volinfo_field $V0 'Status' +EXPECT '2' brick_count $V0 + +TEST $CLI volume set $V0 cluster.nsr on +TEST $CLI volume set $V0 cluster.nsr.recon on + +TEST $CLI volume start $V0 +EXPECT 'Started' volinfo_field $V0 'Status' + +## Mount FUSE with caching disabled (read-only) +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 -s $H0 --volfile-id $V0 $M0 + +# Give the bricks a chance to connect to each other. +EXPECT_WITHIN 10 "2" get_rep_count $M0 + +TEST kill_a_brick +EXPECT_WITHIN 10 "1" get_rep_count $M0 + +# Make sure writes fail while degraded. +tmpfile=$(mktemp) +trap "rm $tmpfile" EXIT +dd if=/dev/urandom of=$M0/probe bs=4k count=100 status=none 2> $tmpfile +TEST [ x"$?" != x"0" ] +TEST grep -qs 'Read-only file system' $tmpfile + +cleanup diff --git a/tests/basic/quota-anon-fd-nfs.t b/tests/basic/quota-anon-fd-nfs.t new file mode 100755 index 000000000..be7bc35db --- /dev/null +++ b/tests/basic/quota-anon-fd-nfs.t @@ -0,0 +1,84 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../fileio.rc + +cleanup; + +TESTS_EXPECTED_IN_LOOP=16 +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 $H0:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + + +# The test makes use of inode-lru-limit to hit a scenario, where we +# find an inode whose ancestry is not there. Following is the +# hypothesis (which is confirmed by seeing logs indicating that +# codepath has been executed, but not through a good understanding of +# NFS internals). + +# At the end of an fop, the reference count of an inode would be +# zero. The inode (and its ancestry) persists in memory only +# because of non-zero lookup count. These looked up inodes are put +# in an lru queue of size 1 (here). So, there can be at most one +# such inode in memory. + +# NFS Server makes use of anonymous fds. So, if it cannot find +# valid fd, it does a nameless lookup. This gives us an inode +# whose ancestry is NULL. When a write happens on this inode, +# quota-enforcer/marker finds a NULL ancestry and asks +# storage/posix to build it. + +TEST $CLI volume set $V0 network.inode-lru-limit 1 +TEST $CLI volume set $V0 performance.nfs.write-behind off + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST $CLI volume quota $V0 enable +TEST $CLI volume quota $V0 limit-usage / 1 + +TEST mount -t nfs -o noac,soft,nolock,vers=3 $H0:/$V0 $N0 +deep=/0/1/2/3/4/5/6/7/8/9 +TEST mkdir -p $N0/$deep + +TEST touch $N0/$deep/file1 $N0/$deep/file2 $N0/$deep/file3 $N0/$deep/file4 + +TEST fd_open 3 'w' "$N0/$deep/file1" +TEST fd_open 4 'w' "$N0/$deep/file2" +TEST fd_open 5 'w' "$N0/$deep/file3" +TEST fd_open 6 'w' "$N0/$deep/file4" + +# consume all quota +TEST ! dd if=/dev/zero of="$N0/$deep/file" bs=1MB count=1 + +# At the end of each fop in server, reference count of the +# inode associated with each of the file above drops to zero and hence +# put into lru queue. Since lru-limit is set to 1, an fop next file +# will displace the current inode from itable. This will ensure that +# when writes happens on same fd, fd resolution results in +# nameless lookup from server and quota_writev encounters an fd +# associated with an inode whose parent is not present in itable. + +for j in $(seq 1 2); do + for i in $(seq 3 6); do + # failing writes indicate that we are enforcing quota set on / + # even with anonymous fds. + TEST_IN_LOOP ! fd_write $i "content" + TEST_IN_LOOP sync + done +done + +exec 3>&- +exec 4>&- +exec 5>&- +exec 6>&- + +$CLI volume statedump $V0 all + +TEST umount -l $N0 + +cleanup; diff --git a/tests/basic/quota.t b/tests/basic/quota.t new file mode 100755 index 000000000..cfc4f0695 --- /dev/null +++ b/tests/basic/quota.t @@ -0,0 +1,195 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc +. $(dirname $0)/../dht.rc + +cleanup; + +TESTS_EXPECTED_IN_LOOP=19 + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2,3,4}; + +function hard_limit() +{ + local QUOTA_PATH=$1; + $CLI volume quota $V0 list $QUOTA_PATH | grep "$QUOTA_PATH" | awk '{print $2}' +} + +function soft_limit() +{ + local QUOTA_PATH=$1; + $CLI volume quota $V0 list $QUOTA_PATH | grep "$QUOTA_PATH" | awk '{print $3}' +} + +function usage() +{ + local QUOTA_PATH=$1; + $CLI volume quota $V0 list $QUOTA_PATH | grep "$QUOTA_PATH" | awk '{print $4}' +} + +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT '4' brick_count $V0 + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST glusterfs -s $H0 --volfile-id $V0 $M0; + +TEST mkdir -p $M0/test_dir/in_test_dir + +## ------------------------------ +## Verify quota commands +## ------------------------------ +TEST $CLI volume quota $V0 enable + +TEST $CLI volume quota $V0 limit-usage /test_dir 100MB + +TEST $CLI volume quota $V0 limit-usage /test_dir/in_test_dir 150MB + +EXPECT "150.0MB" hard_limit "/test_dir/in_test_dir"; +EXPECT "80%" soft_limit "/test_dir/in_test_dir"; + +TEST $CLI volume quota $V0 remove /test_dir/in_test_dir + +EXPECT "100.0MB" hard_limit "/test_dir"; + +TEST $CLI volume quota $V0 limit-usage /test_dir 10MB +EXPECT "10.0MB" hard_limit "/test_dir"; +EXPECT "80%" soft_limit "/test_dir"; + +TEST $CLI volume quota $V0 soft-timeout 0 +TEST $CLI volume quota $V0 hard-timeout 0 + +## ------------------------------ +## Verify quota enforcement +## ----------------------------- + +TEST ! dd if=/dev/urandom of=$M0/test_dir/1.txt bs=1M count=12 +TEST rm $M0/test_dir/1.txt + +# wait for marker's accounting to complete +EXPECT_WITHIN 10 "0Bytes" usage "/test_dir" + +TEST dd if=/dev/urandom of=$M0/test_dir/2.txt bs=1M count=8 +EXPECT_WITHIN 20 "8.0MB" usage "/test_dir" +TEST rm $M0/test_dir/2.txt +EXPECT_WITHIN 10 "0Bytes" usage "/test_dir" + +## rename tests +TEST dd if=/dev/urandom of=$M0/test_dir/2 bs=1M count=8 +EXPECT_WITHIN 20 "8.0MB" usage "/test_dir" +TEST mv $M0/test_dir/2 $M0/test_dir/0 +EXPECT_WITHIN 10 "8.0MB" usage "/test_dir" +TEST rm $M0/test_dir/0 +EXPECT_WITHIN 10 "0Bytes" usage "/test_dir" + +## --------------------------- + +## ------------------------------ +## Check if presence of nfs mount results in ESTALE errors for I/O +# on a fuse mount. Note: Quota command internally uses a fuse mount, +# though this may change. +## ----------------------------- + +TEST mount -t nfs -o nolock,soft,intr $H0:/$V0 $N0; +TEST $CLI volume quota $V0 limit-usage /test_dir 100MB + +TEST $CLI volume quota $V0 limit-usage /test_dir/in_test_dir 150MB + +EXPECT "150.0MB" hard_limit "/test_dir/in_test_dir"; +## ----------------------------- + + +################################################### +## ------------------------------------------------ +## <Test quota functionality in add-brick senarios> +## ------------------------------------------------ +################################################### +QUOTALIMIT=100 +QUOTALIMITROOT=2048 +TESTDIR="addbricktest" + +rm -rf $M0/*; + +## <Create directories and test> +## ----------------------------- +# 41-42 +TEST mkdir $M0/$TESTDIR +TEST mkdir $M0/$TESTDIR/dir{1..10}; + + +# 43-52 +## <set limits> +## ----------------------------- +TEST $CLI volume quota $V0 limit-usage / "$QUOTALIMITROOT"MB; +for i in {1..10}; do + TEST_IN_LOOP $CLI volume quota $V0 limit-usage /$TESTDIR/dir$i \ + "$QUOTALIMIT"MB; +done +## </Enable quota and set limits> + +#53-62 +for i in `seq 1 9`; do + TEST_IN_LOOP dd if=/dev/urandom of="$M0/$TESTDIR/dir1/10MBfile$i" \ + bs=1M count=10; +done + +# 63-64 +## <Add brick and start rebalance> +## ------------------------------- +TEST $CLI volume add-brick $V0 $H0:$B0/brick{3,4} +TEST $CLI volume rebalance $V0 start; + +## Wait for rebalance +while true; do + rebalance_completed + if [ $? -eq 1 ]; then + sleep 1; + else + break; + fi +done + +## <Try creating data beyond limit> +## -------------------------------- +for i in `seq 1 200`; do + dd if=/dev/urandom of="$M0/$TESTDIR/dir1/1MBfile$i" bs=1M count=1 \ + &>/dev/null +done + +# 65 +## <Test whether quota limit crossed more than 10% of limit> +## --------------------------------------------------------- +USED_KB=`du -s $M0/$TESTDIR/dir1 | cut -f1`; +USED_MB=$(($USED_KB/1024)); +TEST [ $USED_MB -le $((($QUOTALIMIT * 110) / 100)) ] + +# 66-67 +## <Test the xattrs healed to new brick> +## ------------------------------------- +TEST getfattr -d -m "trusted.glusterfs.quota.limit-set" -e hex \ + --absolute-names $B0/brick{3,4}/$TESTDIR/dir{1..10}; +# Test on root. +TEST getfattr -d -m "trusted.glusterfs.quota.limit-set" -e hex \ + --absolute-names $B0/brick{3,4}; + +## ------------------------------------------------- +## </Test quota functionality in add-brick senarios> +## ------------------------------------------------- + +TEST $CLI volume quota $V0 disable +TEST $CLI volume stop $V0; +EXPECT 'Stopped' volinfo_field $V0 'Status'; + +TEST $CLI volume delete $V0; +TEST ! $CLI volume info $V0; + +umount -l $N0 + +cleanup; diff --git a/tests/basic/recon.t b/tests/basic/recon.t new file mode 100755 index 000000000..e0fbea749 --- /dev/null +++ b/tests/basic/recon.t @@ -0,0 +1,190 @@ +#!/bin/bash + +# Test *very basic* NSR functionality - startup, mount, simplest possible file +# write. + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +function my_getfattr { + getfattr --only-values -e text $* 2> /dev/null +} + +function get_rep_count { + v=$(my_getfattr -n trusted.nsr.rep-count $1) + #echo $v > /dev/tty + echo $v +} + +function create_file { + dd if=/dev/urandom of=$1 bs=4k count=$2 conv=sync 2> /dev/null +} + +function kill_a_brick { + for r in /var/lib/glusterd/vols/${V0}/run/*-recon.pid; do + rpid=$(cat $r) + echo "recon PID = $rpid" > /dev/tty + b=$(echo $r | sed '/\(.*\):\(.*\)-recon.pid/s//\1\2.pid/') + bpid=$(cat $b) + echo "brick PID = $bpid" > /dev/tty + kill -9 $bpid $rpid + return 0 + done + + # No bricks?!? + return 1 +} + +# Functions to check reconciliation for specific operation types. + +function check_create_write { + for b in $*; do + cmp $tmpdir/create-write $b/create-write || return 1 + done + return 0 +} + +function check_truncate { + truncate --size=8192 $tmpdir/truncate + for b in $*; do + cmp $tmpdir/truncate $b/truncate || return 1 + done + return 0 +} + +function check_hard_link { + for b in $*; do + inum1=$(ls -i $b/hard-link-1 | cut -d' ' -f1) + inum2=$(ls -i $b/hard-link-2 | cut -d' ' -f1) + [ "$inum1" = "$inum2" ] || return 1 + done + return 0 +} + +function check_soft_link { + for b in $*; do + [ "$(readlink $b/soft-link)" = "soft-link-tgt" ] || return 1 + done + return 0 +} + +function check_unlink { + for b in $*; do + [ ! -e $b/unlink ] || return 1 + done + return 0 +} + +function check_mkdir { + for b in $*; do + [ -d $b/mkdir ] || return 1 + done + return 0 +} + +function check_rmdir { + for b in $*; do + [ ! -e $b/rmdir ] || return 1 + done +} + +function check_setxattr { + for b in $*; do + v=$(my_getfattr -n user.foo $b/setxattr) + [ "$v" = "ash_nazg_durbatuluk" ] || return 1 + done + return 0 +} + +function check_removexattr { + for b in $*; do + my_getfattr -n user.bar $b/removexattr 2> /dev/null + [ $? = 0 ] && return 1 + done + return 0 +} + +cleanup + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info + +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2} + +EXPECT "$V0" volinfo_field $V0 'Volume Name' +EXPECT 'Created' volinfo_field $V0 'Status' +EXPECT '2' brick_count $V0 + +TEST $CLI volume set $V0 cluster.nsr on +TEST $CLI volume set $V0 cluster.nsr.recon on + +# This would normally be a terrible idea, but it's handy for issuing ops that +# will have to be reconciled later. +TEST $CLI volume set $V0 cluster.nsr.quorum-percent 0 + +TEST $CLI volume start $V0 +EXPECT 'Started' volinfo_field $V0 'Status' + +# Mount FUSE with caching disabled +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 -s $H0 --volfile-id $V0 $M0 + +# Give the bricks a chance to connect to each other. +EXPECT_WITHIN 10 "2" get_rep_count $M0 + +# Create local files for comparisons etc. +tmpdir=$(mktemp -d) +trap "rm -rf $tmpdir" EXIT +TEST create_file $tmpdir/create-write 10 +TEST create_file $tmpdir/truncate 10 + +# Prepare files and directories we'll need later. +TEST cp $tmpdir/truncate $M0/ +TEST touch $M0/hard-link-1 +TEST touch $M0/unlink +TEST mkdir $M0/rmdir +TEST touch $M0/setxattr +TEST touch $M0/removexattr +TEST setfattr -n user.bar -v "ash_nazg_gimbatul" $M0/removexattr + +# Kill a brick and wait for a new leader to take over. +TEST kill_a_brick +sleep 10 + +# Test create+write +TEST cp $tmpdir/create-write $M0/ +# Test truncate +TEST truncate --size=8192 $M0/truncate +# Test hard link +TEST ln $M0/hard-link-1 $M0/hard-link-2 +# Test soft link +# Disabled here because it not only fails but crashes the recon daemon. +TEST ln -s soft-link-tgt $M0/soft-link +# Test unlink +TEST rm $M0/unlink +# Test mkdir +TEST mkdir $M0/mkdir +# Test rmdir +TEST rmdir $M0/rmdir +# Test setxattr +TEST setfattr -n user.foo -v "ash_nazg_durbatuluk" $M0/setxattr +# Test removexattr +TEST setfattr -x user.bar $M0/removexattr + +# Restart the brick and give reconciliation a chance to run. +TEST $CLI volume start $V0 force +sleep 20 + +# Make sure everything is as it should be. +TEST check_create_write $B0/${V0}{1,2} +TEST check_truncate $B0/${V0}{1,2} +TEST check_hard_link $B0/${V0}{1,2} +TEST check_soft_link $B0/${V0}{1,2} +TEST check_unlink $B0/${V0}{1,2} +TEST check_mkdir $B0/${V0}{1,2} +TEST check_rmdir $B0/${V0}{1,2} +#EST check_setxattr $B0/${V0}{1,2} +#EST check_removexattr $B0/${V0}{1,2} + +cleanup +#killall -9 etcd diff --git a/tests/basic/rpc-coverage.sh b/tests/basic/rpc-coverage.sh new file mode 100755 index 000000000..dc66969d0 --- /dev/null +++ b/tests/basic/rpc-coverage.sh @@ -0,0 +1,483 @@ +#!/bin/bash + +# This script can be used to provoke 35 fops (if afr is used), +# 28 fops (if afr is not used) (-fstat,-readdirp, and lk,xattrop calls) +# Pending are 7 procedures. +# getspec, fsyncdir, access, fentrylk, fsetxattr, fgetxattr, rchecksum +# TODO: add commands which can generate fops for missing fops + +## Script tests below File Operations over RPC (when afr is used) + +# CREATE +# ENTRYLK +# FINODELK +# FLUSH +# FSTAT +# FSYNC +# FTRUNCATE +# FXATTROP +# GETXATTR +# INODELK +# LINK +# LK +# LOOKUP +# MKDIR +# MKNOD +# OPEN +# OPENDIR +# READ +# READDIR +# READDIRP +# READLINK +# RELEASE +# RELEASEDIR +# REMOVEXATTR +# RENAME +# RMDIR +# SETATTR +# SETXATTR +# STAT +# STATFS +# SYMLINK +# TRUNCATE +# UNLINK +# WRITE +# XATTROP + +#set -e; +set -o pipefail; + +function fail() { + echo "$*: failed."; + exit 1; +} + +function test_mkdir() +{ + mkdir -p $PFX/dir; + test $(stat -c '%F' $PFX/dir) == "directory" || fail "mkdir" +} + + +function test_create() +{ + : > $PFX/dir/file; + + test "$(stat -c '%F' $PFX/dir/file)" == "regular empty file" || fail "create" +} + + +function test_statfs() +{ + local size; + + size=$(stat -f -c '%s' $PFX/dir/file); + test "x$size" != "x0" || fail "statfs" +} + + +function test_open() +{ + exec 4<$PFX/dir/file || fail "open" + exec 4>&- || fail "open" +} + + +function test_write() +{ + dd if=/dev/zero of=$PFX/dir/file bs=65536 count=16 2>/dev/null; + test $(stat -c '%s' $PFX/dir/file) == 1048576 || fail "open" +} + + +function test_read() +{ + local count; + + count=$(dd if=$PFX/dir/file bs=64k count=16 2>/dev/null | wc -c); + test $count == 1048576 || fail "read" +} + + +function test_truncate() +{ + truncate -s 512 $PFX/dir/file; + test $(stat -c '%s' $PFX/dir/file) == 512 || fail "truncate" + + truncate -s 0 $PFX/dir/file; + test $(stat -c '%s' $PFX/dir/file) == 0 || fail "truncate" +} + + +function test_fstat() +{ + local msg; + + export PFX; + msg=$(sh -c 'tail -f $PFX/dir/file --pid=$$ & sleep 1 && echo hooha > $PFX/dir/file && sleep 1'); + test "x$msg" == "xhooha" || fail "fstat" +} + + +function test_mknod() +{ + mknod -m 0666 $PFX/dir/block b 13 42; + test "$(stat -c '%F %a %t %T' $PFX/dir/block)" == "block special file 666 d 2a" \ + || fail "mknod for block device" + + mknod -m 0666 $PFX/dir/char c 13 42; + test "$(stat -c '%F %a %t %T' $PFX/dir/char)" == "character special file 666 d 2a" \ + || fail "mknod for character device" + + mknod -m 0666 $PFX/dir/fifo p; + test "$(stat -c '%F %a' $PFX/dir/fifo)" == "fifo 666" || \ + fail "mknod for fifo" +} + + +function test_symlink() +{ + local msg; + + pushd; + cd $PFX/dir; + ln -s file symlink; + popd; + test "$(stat -c '%F' $PFX/dir/symlink)" == "symbolic link" || fail "Creation of symlink" + + msg=$(cat $PFX/dir/symlink); + test "x$msg" == "xhooha" || fail "Content match for symlink" +} + + +function test_hardlink() +{ + local ino1; + local ino2; + local nlink1; + local nlink2; + local msg; + + ln $PFX/dir/file $PFX/dir/hardlink; + + ino1=$(stat -c '%i' $PFX/dir/file); + nlink1=$(stat -c '%h' $PFX/dir/file); + ino2=$(stat -c '%i' $PFX/dir/hardlink); + nlink2=$(stat -c '%h' $PFX/dir/hardlink); + + test $ino1 == $ino2 || fail "Inode comparison for hardlink" + test $nlink1 == 2 || fail "Link count for hardlink" + test $nlink2 == 2 || fail "Link count for hardlink" + + msg=$(cat $PFX/dir/hardlink); + + test "x$msg" == "xhooha" || fail "Content match for hardlinks" +} + + +function test_rename() +{ + local ino1; + local ino2; + local ino3; + local msg; + + #### file + + ino1=$(stat -c '%i' $PFX/dir/file); + + mv $PFX/dir/file $PFX/dir/file2 || fail "mv" + msg=$(cat $PFX/dir/file2); + test "x$msg" == "xhooha" || fail "File contents comparison after mv" + + ino2=$(stat -c '%i' $PFX/dir/file2); + test $ino1 == $ino2 || fail "Inode comparison after mv" + + mv $PFX/dir/file2 $PFX/dir/file; + msg=$(cat $PFX/dir/file); + test "x$msg" == "xhooha" || fail "File contents comparison after mv" + + ino3=$(stat -c '%i' $PFX/dir/file); + test $ino1 == $ino3 || fail "Inode comparison after mv" + + #### dir + + ino1=$(stat -c '%i' $PFX/dir); + + mv $PFX/dir $PFX/dir2 || fail "Directory mv" + ino2=$(stat -c '%i' $PFX/dir2); + test $ino1 == $ino2 || fail "Inode comparison after directory mv" + + mv $PFX/dir2 $PFX/dir || fail "Directory mv" + ino3=$(stat -c '%i' $PFX/dir); + test $ino1 == $ino3 || fail "Inode comparison after directory mv" +} + + +function test_chmod() +{ + local mode0; + local mode1; + local mode2; + + + #### file + + mode0=$(stat -c '%a' $PFX/dir/file); + chmod 0753 $PFX/dir/file || fail "chmod" + + mode1=$(stat -c '%a' $PFX/dir/file); + test 0$mode1 == 0753 || fail "Mode comparison after chmod" + + chmod 0$mode0 $PFX/dir/file || fail "chmod" + mode2=$(stat -c '%a' $PFX/dir/file); + test 0$mode2 == 0$mode0 || fail "Mode comparison after chmod" + + #### dir + + mode0=$(stat -c '%a' $PFX/dir); + chmod 0753 $PFX/dir || fail "chmod" + + mode1=$(stat -c '%a' $PFX/dir); + test 0$mode1 == 0753 || fail "Mode comparison after chmod" + + chmod 0$mode0 $PFX/dir || fail "chmod" + mode2=$(stat -c '%a' $PFX/dir); + test 0$mode2 == 0$mode0 || fail "Mode comparison after chmod" +} + + +function test_chown() +{ + local user1; + local user2; + local group1; + local group2; + + #### file + + user1=$(stat -c '%u' $PFX/dir/file); + group1=$(stat -c '%g' $PFX/dir/file); + + chown 13:42 $PFX/dir/file || fail "chown" + + user2=$(stat -c '%u' $PFX/dir/file); + group2=$(stat -c '%g' $PFX/dir/file); + + test $user2 == 13 || fail "User comparison after chown" + test $group2 == 42 || fail "Group comparison after chown" + + chown $user1:$group1 $PFX/dir/file || fail "chown" + + user2=$(stat -c '%u' $PFX/dir/file); + group2=$(stat -c '%g' $PFX/dir/file); + + test $user2 == $user1 || fail "User comparison after chown" + test $group2 == $group1 || fail "Group comparison after chown" + + #### dir + + user1=$(stat -c '%u' $PFX/dir); + group1=$(stat -c '%g' $PFX/dir); + + chown 13:42 $PFX/dir || fail "chown" + + user2=$(stat -c '%u' $PFX/dir); + group2=$(stat -c '%g' $PFX/dir); + + test $user2 == 13 || fail "User comparison after chown" + test $group2 == 42 || fail "Group comparison after chown" + + chown $user1:$group1 $PFX/dir || fail "chown" + + user2=$(stat -c '%u' $PFX/dir); + group2=$(stat -c '%g' $PFX/dir); + + test $user2 == $user1 || fail "User comparison after chown" + test $group2 == $group1 || fail "Group comparison after chown" +} + + +function test_utimes() +{ + local acc0; + local acc1; + local acc2; + local mod0; + local mod1; + local mod2; + + #### file + + acc0=$(stat -c '%X' $PFX/dir/file); + mod0=$(stat -c '%Y' $PFX/dir/file); + + sleep 1; + touch -a $PFX/dir/file || fail "atime change on file" + + acc1=$(stat -c '%X' $PFX/dir/file); + mod1=$(stat -c '%Y' $PFX/dir/file); + + sleep 1; + touch -m $PFX/dir/file || fail "mtime change on file" + + acc2=$(stat -c '%X' $PFX/dir/file); + mod2=$(stat -c '%Y' $PFX/dir/file); + + test $acc0 != $acc1 || fail "atime mismatch comparison on file" + test $acc1 == $acc2 || fail "atime match comparison on file" + test $mod0 == $mod1 || fail "mtime match comparison on file" + test $mod1 != $mod2 || fail "mtime mismatch comparison on file" + + #### dir + + acc0=$(stat -c '%X' $PFX/dir); + mod0=$(stat -c '%Y' $PFX/dir); + + sleep 1; + touch -a $PFX/dir || fail "atime change on directory" + + acc1=$(stat -c '%X' $PFX/dir); + mod1=$(stat -c '%Y' $PFX/dir); + + sleep 1; + touch -m $PFX/dir || fail "mtime change on directory" + + acc2=$(stat -c '%X' $PFX/dir); + mod2=$(stat -c '%Y' $PFX/dir); + + test $acc0 != $acc1 || fail "atime mismatch comparison on directory" + test $acc1 == $acc2 || fail "atime match comparison on directory" + test $mod0 == $mod1 || fail "mtime match comparison on directory" + test $mod1 != $mod2 || fail "mtime mismatch comparison on directory" +} + + +function test_locks() +{ + exec 200>$PFX/dir/lockfile || fail "exec" + + ## exclusive locks test + flock -e 200 || fail "flock -e" + ! flock -n -e $PFX/dir/lockfile -c true || fail "! flock -n -e" + ! flock -n -s $PFX/dir/lockfile -c true || fail "! flock -n -s" + flock -u 200 || fail "flock -u" + + ## shared locks test + flock -s 200 || fail "flock -s" + ! flock -n -e $PFX/dir/lockfile -c true || fail "! flock -n -e" + flock -n -s $PFX/dir/lockfile -c true || fail "! flock -n -s" + flock -u 200 || fail "flock -u" + + exec 200>&- || fail "exec" + +} + + +function test_readdir() +{ + /bin/ls $PFX/dir >/dev/null || fail "ls" +} + + +function test_setxattr() +{ + setfattr -n trusted.testing -v c00k33 $PFX/dir/file || fail "setfattr" +} + + +function test_listxattr() +{ + getfattr -m trusted $PFX/dir/file 2>/dev/null | grep -q trusted.testing || fail "getfattr" +} + + +function test_getxattr() +{ + getfattr -n trusted.testing $PFX/dir/file 2>/dev/null | grep -q c00k33 || fail "getfattr" +} + + +function test_removexattr() +{ + setfattr -x trusted.testing $PFX/dir/file || fail "setfattr remove" + getfattr -n trusted.testing $PFXf/dir/file 2>&1 | grep -q "No such attribute" +} + + +function test_unlink() +{ + rm $PFX/dir/file || fail "rm" +} + + +function test_rmdir() +{ + rm -rf $PFX || fail "rm -rf" +} + + +function run_tests() +{ + test_mkdir; + test_create; + test_statfs; + test_open; + test_write; + test_read; + test_truncate; + test_fstat; + test_mknod; + test_hardlink; + test_symlink; + test_rename; + test_chmod; + test_chown; + test_utimes; + test_locks; + test_readdir; + test_setxattr; + test_listxattr; + test_getxattr; + test_removexattr; + test_unlink; + test_rmdir; +} + + +function _init() +{ + DIR=$(pwd); +} + + +function parse_cmdline() +{ + if [ "x$1" == "x" ] ; then + echo "Usage: $0 /path/mount" + exit 1 + fi + + DIR=$1; + + if [ ! -d "$DIR" ] ; then + echo "$DIR: not a directory" + exit 1 + fi + + PFX="$DIR/coverage"; + rm -rvf $PFX; +} + + +function main() +{ + parse_cmdline "$@"; + + run_tests; + + exit 0; +} + + +_init && main "$@"; diff --git a/tests/basic/rpc-coverage.t b/tests/basic/rpc-coverage.t new file mode 100644 index 000000000..5dfeaa942 --- /dev/null +++ b/tests/basic/rpc-coverage.t @@ -0,0 +1,25 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 stripe 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8}; + +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT '8' brick_count $V0 + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +## Mount FUSE +TEST glusterfs -s $H0 --volfile-id $V0 $M1; + +TEST $(dirname $0)/rpc-coverage.sh $M1 +cleanup; diff --git a/tests/basic/rpm.t b/tests/basic/rpm.t new file mode 100755 index 000000000..a577726a8 --- /dev/null +++ b/tests/basic/rpm.t @@ -0,0 +1,109 @@ +#!/bin/bash +# +# This test will run mock and rebuild the srpm for the latest two EPEL version. +# By default, the results and the chroots are deleted. +# +# When debugging is needed, make sure to set DEBUG=1 in the environment or this +# script. When debugging is enabled, the resulting log files and chroots are +# kept. With debugging enabled, this test will fail the regression test, and +# all output is saved to rpmbuild-mock.log. Tests are run in parallel, so the +# logfile may be difficult to read. +# +# chroots are configured in /etc/mock/*.cfg, with site-defaults.cfg as main +# configuration file. The default for chroots is /var/lib/mock, but this +# depends on the 'basedir' configuration option set in the mentioned files. +# + +. $(dirname $0)/../include.rc + +# enable some extra debugging +if [ -n "${DEBUG}" -a "${DEBUG}" != "0" ] +then + exec &> rpmbuild-mock.log + set -x + MOCK_CLEANUP='--no-cleanup-after' +else + MOCK_CLEANUP='--cleanup-after' +fi + +# detect the branch we're based off +if [ -n "${BRANCH}" ] ; then + # $BRANCH is set in the environment (by Jenkins or other) + GIT_PARENT="origin/${BRANCH}" +else + # get a reference to the latest clean tree + GIT_PARENT=$(git describe --abbrev=0) +fi + +# Filter out everything and what remains needs to be built +BUILD_FILES=$(git diff --name-status ${GIT_PARENT} | grep -Ev '^M.*\.(c|h|py)' | awk {'print $2'}) +SELFTEST=$(grep -e 'tests/basic/rpm.t' <<< "${BUILD_FILES}") +BUILD_FILES=$(grep -Ev '^tests/' <<< "${BUILD_FILES}") +if [ -z "${BUILD_FILES}" -a -z "${SELFTEST}" ] +then + # nothing affecting packaging changed, no need to retest rpmbuild + SKIP_TESTS + cleanup + exit 0 +fi + +# checkout the sources to a new directory to execute ./configure and all +REPO=${PWD} +COMMIT=$(git describe) +mkdir rpmbuild-mock.d +pushd rpmbuild-mock.d 2>/dev/null +git clone -q -s file://${REPO} . +git checkout -q -b rpm-test ${COMMIT} + +# build the glusterfs-*.tar.gz +[ -e configure ] || ./autogen.sh 2>&1 > /dev/null +TEST ./configure --enable-fusermount +TEST make dist + +# build the glusterfs src.rpm +ls extras +TEST make -C extras/LinuxRPM testsrpm + +# build for the last two Fedora EPEL releases (x86_64 only) +for MOCK_CONF in $(ls -x1 /etc/mock/*.cfg | egrep -e 'epel-[0-9]+-x86_64.cfg$' | tail -n2) +do + EPEL_RELEASE=$(basename ${MOCK_CONF} .cfg) + # expand the mock command line + MOCK_CMD="/usr/bin/mock ${MOCK_CLEANUP} \ + -r ${EPEL_RELEASE} --rebuild ${PWD}/*.src.rpm" + + # write the mock command to a file, so that its easier to execute + cat << EOF > mock-${EPEL_RELEASE}.sh +#!/bin/sh +${MOCK_CMD} +EOF + chmod +x mock-${EPEL_RELEASE}.sh + + # root can not run 'mock', it needs to drop priviledges + if (groups | grep -q mock) + then + # the current user is in group 'mock' + ${PWD}/mock-${EPEL_RELEASE}.sh & + else + # "su" might not work, using sudo instead + sudo -u mock -E ${PWD}/mock-${EPEL_RELEASE}.sh & + fi + sleep 5 +done + +# TAP and Prove aren't smart about loops +TESTS_EXPECTED_IN_LOOP=2 +for mockjob in $(jobs -p) +do + TEST_IN_LOOP wait ${mockjob} +done + +# we could build for the last two Fedora releases too, but that is not +# possible on EPEL-5/6 installations, Fedora 17 and newer have unmet +# dependencies on the build-server :-/ + +popd 2>/dev/null +# only remove rpmbuild-mock.d if we're not debugging +[ "${DEBUG}" = "0" ] && rm -rf rpmbuild-mock.d + +cleanup diff --git a/tests/basic/self-heald.t b/tests/basic/self-heald.t new file mode 100644 index 000000000..4468c881b --- /dev/null +++ b/tests/basic/self-heald.t @@ -0,0 +1,48 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1,2,3,4,5} +TEST $CLI volume set $V0 cluster.background-self-heal-count 0 +TEST $CLI volume set $V0 cluster.eager-lock off +TEST $CLI volume start $V0 +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 +TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST kill_brick $V0 $H0 $B0/${V0}2 +TEST kill_brick $V0 $H0 $B0/${V0}4 +cd $M0 +HEAL_FILES=0 +for i in {1..10} +do + dd if=/dev/urandom of=f bs=1M count=10 2>/dev/null + HEAL_FILES=$(($HEAL_FILES+1)) + mkdir a; cd a; + HEAL_FILES=$(($HEAL_FILES+3)) #As many times as distribute subvols +done +HEAL_FILES=$(($HEAL_FILES + 3)) #Count the brick root dir + +cd ~ +EXPECT "$HEAL_FILES" afr_get_pending_heal_count $V0 +TEST ! $CLI volume heal $V0 +TEST $CLI volume set $V0 cluster.self-heal-daemon off +TEST ! $CLI volume heal $V0 info +TEST ! $CLI volume heal $V0 +TEST $CLI volume start $V0 force +TEST $CLI volume set $V0 cluster.self-heal-daemon on +EXPECT_WITHIN 20 "Y" glustershd_up_status +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 2 +EXPECT_WITHIN 20 "1" afr_child_up_status_in_shd $V0 4 +TEST $CLI volume heal $V0 +sleep 5 #Until the heal-statistics command implementation +#check that this heals the contents partially +TEST [ $HEAL_FILES -gt $(afr_get_pending_heal_count $V0) ] + +TEST $CLI volume heal $V0 full +EXPECT_WITHIN 30 "0" afr_get_pending_heal_count $V0 +cleanup diff --git a/tests/basic/volume-snapshot.t b/tests/basic/volume-snapshot.t new file mode 100755 index 000000000..e6c47f0d5 --- /dev/null +++ b/tests/basic/volume-snapshot.t @@ -0,0 +1,96 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc +. $(dirname $0)/../cluster.rc +. $(dirname $0)/../snapshot.rc + + +V1="patchy2" + +function create_volumes() { + $CLI_1 volume create $V0 $H1:$L1 & + PID_1=$! + + $CLI_2 volume create $V1 $H2:$L2 $H3:$L3 & + PID_2=$! + + wait $PID_1 $PID_2 +} + +function create_snapshots() { + $CLI_1 snapshot create ${V0}_snap ${V0}& + PID_1=$! + + $CLI_1 snapshot create ${V1}_snap ${V1}& + PID_2=$! + + wait $PID_1 $PID_2 +} + +function delete_snapshots() { + $CLI_1 snapshot delete ${V0}_snap & + PID_1=$! + + $CLI_1 snapshot delete ${V1}_snap & + PID_2=$! + + wait $PID_1 $PID_2 +} + +function restore_snapshots() { + $CLI_1 snapshot restore ${V0}_snap & + PID_1=$! + + $CLI_1 snapshot restore ${V1}_snap & + PID_2=$! + + wait $PID_1 $PID_2 +} +cleanup; + +TEST verify_lvm_version; +#Create cluster with 3 nodes +TEST launch_cluster 3; +TEST setup_lvm 3 + +TEST $CLI_1 peer probe $H2; +TEST $CLI_1 peer probe $H3; +EXPECT_WITHIN 20 2 peer_count; + +create_volumes +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT 'Created' volinfo_field $V1 'Status'; + +start_volumes 2 +EXPECT 'Started' volinfo_field $V0 'Status'; +EXPECT 'Started' volinfo_field $V1 'Status'; + +#Snapshot Operations +create_snapshots +TEST snapshot_exists 1 ${V0}_snap +TEST snapshot_exists 1 ${V1}_snap +TEST $CLI_1 snapshot config $V0 snap-max-hard-limit 100 +TEST $CLI_1 snapshot config $V1 snap-max-hard-limit 100 + +TEST glusterfs -s $H1 --volfile-id=/snaps/${V0}_snap/${V0} $M0 +sleep 2 +TEST umount -f $M0 +TEST glusterfs -s $H2 --volfile-id=/snaps/${V1}_snap/${V1} $M0 +sleep 2 +TEST umount -f $M0 + +#Clean up +stop_force_volumes 2 +EXPECT 'Stopped' volinfo_field $V0 'Status'; +EXPECT 'Stopped' volinfo_field $V1 'Status'; + +restore_snapshots +TEST ! snapshot_exists 1 ${V0}_snap +TEST ! snapshot_exists 1 ${V1}_snap + +delete_volumes 2 +TEST ! volume_exists $V0 +TEST ! volume_exists $V1 + +cleanup; diff --git a/tests/basic/volume-status.t b/tests/basic/volume-status.t new file mode 100644 index 000000000..f4196ac30 --- /dev/null +++ b/tests/basic/volume-status.t @@ -0,0 +1,66 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 stripe 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8}; + +TEST $CLI volume start $V0; + +sleep 2 + +## Mount FUSE +TEST glusterfs -s $H0 --volfile-id $V0 $M0; + +## Mount NFS +TEST mount -t nfs -o vers=3,nolock,soft,intr $H0:/$V0 $N0; + +TEST $CLI volume status all +TEST $CLI volume status $V0 + +EXPECT_WITHIN 10 'Y' nfs_up_status +EXPECT_WITHIN 10 'Y' glustershd_up_status +function test_nfs_cmds () { + local ret=0 + declare -a nfs_cmds=("clients" "mem" "inode" "callpool") + for cmd in ${nfs_cmds[@]}; do + $CLI volume status $V0 nfs $cmd + (( ret += $? )) + done + return $ret +} + +function test_shd_cmds () { + local ret=0 + declare -a shd_cmds=("mem" "inode" "callpool") + for cmd in ${shd_cmds[@]}; do + $CLI volume status $V0 shd $cmd + (( ret += $? )) + done + return $ret +} + +function test_brick_cmds () { + local ret=0 + declare -a cmds=("detail" "clients" "mem" "inode" "fd" "callpool") + for cmd in ${cmds[@]}; do + for i in {1..2}; do + $CLI volume status $V0 $H0:$B0/${V0}$i $cmd + (( ret += $? )) + done + done + return $ret +} + +TEST test_shd_cmds; +TEST test_nfs_cmds; +TEST test_brick_cmds; + +cleanup; + diff --git a/tests/basic/volume.t b/tests/basic/volume.t new file mode 100755 index 000000000..23b740af1 --- /dev/null +++ b/tests/basic/volume.t @@ -0,0 +1,34 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 stripe 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8}; + + +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT '8' brick_count $V0 + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST $CLI volume add-brick $V0 $H0:$B0/${V0}{9,10,11,12}; +EXPECT '12' brick_count $V0 + +TEST $CLI volume remove-brick $V0 $H0:$B0/${V0}{1,2,3,4} force; +EXPECT '8' brick_count $V0 + +TEST $CLI volume stop $V0; +EXPECT 'Stopped' volinfo_field $V0 'Status'; + +TEST $CLI volume delete $V0; +TEST ! $CLI volume info $V0; + +cleanup; |
