summaryrefslogtreecommitdiffstats
path: root/tests/basic
diff options
context:
space:
mode:
Diffstat (limited to 'tests/basic')
-rw-r--r--tests/basic/afr/gfid-mismatch.t26
-rw-r--r--tests/basic/afr/read-subvol-data.t33
-rw-r--r--tests/basic/afr/read-subvol-entry.t35
-rw-r--r--tests/basic/afr/self-heal.t237
-rw-r--r--tests/basic/afr/sparse-file-self-heal.t121
-rw-r--r--tests/basic/afr/stale-file-lookup.t30
-rwxr-xr-xtests/basic/bd.t131
-rwxr-xr-xtests/basic/cdc.t133
-rwxr-xr-xtests/basic/file-snapshot.t56
-rwxr-xr-xtests/basic/four-brick.t85
-rw-r--r--tests/basic/logchecks-messages.h84
-rw-r--r--tests/basic/logchecks.c208
-rw-r--r--tests/basic/mgmt_v3-locks.t121
-rw-r--r--tests/basic/mount-options.disabled140
-rwxr-xr-xtests/basic/mount.t79
-rwxr-xr-xtests/basic/nsr.t47
-rw-r--r--tests/basic/nufa.t32
-rw-r--r--tests/basic/pgfid-feat.t35
-rwxr-xr-xtests/basic/posixonly.t30
-rw-r--r--tests/basic/pump.t44
-rw-r--r--tests/basic/quorum.t64
-rwxr-xr-xtests/basic/quota-anon-fd-nfs.t84
-rwxr-xr-xtests/basic/quota.t195
-rwxr-xr-xtests/basic/recon.t190
-rwxr-xr-xtests/basic/rpc-coverage.sh483
-rw-r--r--tests/basic/rpc-coverage.t25
-rwxr-xr-xtests/basic/rpm.t109
-rw-r--r--tests/basic/self-heald.t48
-rwxr-xr-xtests/basic/volume-snapshot.t96
-rw-r--r--tests/basic/volume-status.t66
-rwxr-xr-xtests/basic/volume.t34
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;