#
# Test case for operation when network interface of two gfsd node is down
#
load "gfarm_v2::generate_testdata"
load "gfarm2fs::wait_for_gfsd_connect"
load "gfarm2fs::wait_for_gfsd_disconnect"
load "gfarm_v2::check_replica_num"

#
# Test parameters
#
# GFARM_HOME:	A directory path of Gfarm which this test will be executed
# FILE_SIZE:	Size of a file to be created
# RETRY_COUNT:	Retry number to check number of replicas
#
setup_operation_in_two_gfsd_ifdown()
{
	# define mount point
	MOUNT_POINT=mnt_$TEST_EXEC_ID

	# default parameter
	GFARM_HOME=${GFARM_HOME-"/"}
	FILE_SIZE=${FILE_SIZE-"100M"}
	RETRY_COUNT=${RETRY_COUNT-"20"}
	RETRY_INTERVAL=${RETRY_INTERVAL-"30"}

	# miscellaneous parameters
	GFARM_PATH1=$GFARM_HOME/${TEST_EXEC_ID}_1
	GFARM_PATH2=$GFARM_HOME/${TEST_EXEC_ID}_2
	GFARM_PATH3=$GFARM_HOME/${TEST_EXEC_ID}_3

	READ_GFARM_PATH1=$GFARM_PATH3/${TEST_EXEC_ID}_1
	READ_GFARM_PATH2=$GFARM_PATH3/${TEST_EXEC_ID}_2

	WRITE_GFARM_PATH1=$GFARM_PATH1/$TEST_EXEC_ID
	WRITE_GFARM_PATH2=$GFARM_PATH2/$TEST_EXEC_ID
	WRITE_GFARM_PATH3=$GFARM_PATH3/${TEST_EXEC_ID}_3

	# prepare: check whether required hosts are defined
	$GFSERVICE systest::gfarm_v2::check_hostids_defined - \
		"gfmd1 gfsd1 gfsd2 gfsd3 client1"
	[ $? -ne 0 ] && return $RESULT_UNSUPPORTED

	# prepare: wait until gfsd get connected
	wait_for_gfsd_connect gfsd1 client1 $RETRY_COUNT $RETRY_INTERVAL
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: gfsd1 is unavailable"
		return $RESULT_FATAL
	fi

	wait_for_gfsd_connect gfsd2 client1 $RETRY_COUNT $RETRY_INTERVAL
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: gfsd2 is unavailable"
		return $RESULT_FATAL
	fi

	wait_for_gfsd_connect gfsd3 client1 $RETRY_COUNT $RETRY_INTERVAL
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: gfsd3 is unavailable"
		return $RESULT_FATAL
	fi

	# prepare: make directory
	$GFSERVICE gfcmd client1 gfmkdir $GFARM_PATH1 $GFARM_PATH2 \
		$GFARM_PATH3

	# prepare: set number of replica to be created
	$GFSERVICE gfcmd client1 gfncopy -s 2 $GFARM_PATH1
	$GFSERVICE gfcmd client1 gfncopy -s 2 $GFARM_PATH2

	# prepare: make a file
	generate_testdata $FILE_SIZE | $GFSERVICE systest::gfarm_v2::read_and_register \
		client1 $READ_GFARM_PATH1 gfmd1 gfsd1
	generate_testdata $FILE_SIZE | $GFSERVICE systest::gfarm_v2::read_and_register \
		client1 $READ_GFARM_PATH2 gfmd1 gfsd3

	# prepare: mount
	$GFSERVICE systest::gfarm2fs::exec_ssh client1 mkdir $MOUNT_POINT
	$GFSERVICE mount client1 $MOUNT_POINT -o modules=subdir \
		-o subdir=$GFARM_HOME

	# prepare: make network interface down
	$GFSERVICE systest::gfarm2fs::ifdown gfsd1
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: failed to execute ifdown on gfsd1"
		return $RESULT_FATAL
	fi

	$GFSERVICE systest::gfarm2fs::ifdown gfsd2
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: failed to execute ifdown on gfsd2"
		return $RESULT_FATAL
	fi

	return $RESULT_PASS
}

test_operation_in_two_gfsd_ifdown()
{
	RESULT=$RESULT_PASS

	# step: wait until gfsd get disconnected
	wait_for_gfsd_disconnect gfsd1 client1 $RETRY_COUNT $RETRY_INTERVAL
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: gfsd1 is available unexpectedly"
		return $RESULT_FATAL
	fi

	wait_for_gfsd_disconnect gfsd2 client1 $RETRY_COUNT $RETRY_INTERVAL
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: gfsd2 is available unexpectedly"
		return $RESULT_FATAL
	fi

	# step: write file
	WRITE_PATH1=$MOUNT_POINT/${TEST_EXEC_ID}_1/$TEST_EXEC_ID
	WRITE_PATH2=$MOUNT_POINT/${TEST_EXEC_ID}_2/$TEST_EXEC_ID
	$GFSERVICE systest::gfarm2fs::exec_ssh client1 "echo $TEST_EXEC_ID > $WRITE_PATH1"
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: failed to write a file $WRITE_PATH1"
		set_result RESULT $RESULT_FAIL
	fi

	$GFSERVICE systest::gfarm2fs::exec_ssh client1 "echo $TEST_EXEC_ID > $WRITE_PATH2"
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: failed to write a file $WRITE_PATH2"
		set_result RESULT $RESULT_FAIL
	fi

	# step: check number of replicas
	check_replica_num client1 $WRITE_GFARM_PATH1 2 $RETRY_COUNT
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: number of file replica is not enough"
		set_result RESULT $RESULT_FAIL
	fi

	check_replica_num client1 $WRITE_GFARM_PATH2 2 $RETRY_COUNT
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: number of file replica is not enough"
		set_result RESULT $RESULT_FAIL
	fi

	# step: compare check sum of spool file
	CHECKSUM=`echo $TEST_EXEC_ID | openssl md5 | awk '{ print $2 }'`
	SPOOL_PATH1=`$GFSERVICE gfcmd client1 gfspoolpath \
		$WRITE_GFARM_PATH1`
	if [ X$SPOOL_PATH1 = X ]; then
		log_warn "$TESTNAME: failed to get spool path"
		set_result RESULT $RESULT_FAIL
	fi

	for HOST in `$GFSERVICE gfcmd client1 gfwhere \
		$WRITE_GFARM_PATH1`; do
		HOSTID=`$GFSERVICE systest::gfarm_v2::get_gfsd_hostid_by_name $HOST`
		CHECKSUM_SPOOL=`$GFSERVICE systest::gfarm2fs::spool_file_checksum \
			$HOSTID $SPOOL_PATH1`
		if [ X$CHECKSUM_SPOOL != X$CHECKSUM ]; then
			log_warn "$TESTNAME: checksum of a file is different" \
				"from original one"
			set_result RESULT $RESULT_FAIL
			break
		fi
	done

	SPOOL_PATH2=`$GFSERVICE gfcmd client1 gfspoolpath \
		$WRITE_GFARM_PATH2`
	if [ X$SPOOL_PATH2 = X ]; then
		log_warn "$TESTNAME: failed to get spool path"
		set_result RESULT $RESULT_FAIL
	fi

	for HOST in `$GFSERVICE gfcmd client1 gfwhere \
		$WRITE_GFARM_PATH2`; do
		HOSTID=`$GFSERVICE systest::gfarm_v2::get_gfsd_hostid_by_name $HOST`
		CHECKSUM_SPOOL=`$GFSERVICE systest::gfarm2fs::spool_file_checksum \
			$HOSTID $SPOOL_PATH2`
		if [ X$CHECKSUM_SPOOL != X$CHECKSUM ]; then
			log_warn "$TESTNAME: checksum of a file is different" \
				"from original one"
			set_result RESULT $RESULT_FAIL
			break
		fi
	done

	# step: read file
	$GFSERVICE systest::gfarm2fs::export_file client1 $READ_GFARM_PATH2 gfmd1 \
		> /dev/null
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: failed to read a file from gfsd3"
		set_result RESULT $RESULT_FAIL
	fi

	# step: write file
	generate_testdata $FILE_SIZE | $GFSERVICE systest::gfarm_v2::read_and_register \
		client1 $GFARM_FILE4 $WRITE_GFARM_PATH3 gfmd1 gfsd1
	if [ $? -eq 0 ]; then
		log_warn "$TESTNAME: wrote file unexpectedly to gfsd1"
		set_result RESULT $RESULT_XPASS
	fi

	# step: read file
	$GFSERVICE systest::gfarm2fs::export_file client1 $READ_GFARM_PATH1 gfmd1 \
		> /dev/null
	if [ $? -eq 0 ]; then
		log_warn "$TESTNAME: read a file unexpectedly from gfsd1"
		set_result RESULT $RESULT_XPASS
	fi

	return $RESULT
}

teardown_operation_in_two_gfsd_ifdown()
{
	# cleanup: make network interface up
	$GFSERVICE systest::gfarm2fs::ifup gfsd1
	$GFSERVICE systest::gfarm2fs::ifup gfsd2

	# cleanup: remove files
	$GFSERVICE gfcmd client1 gfrm -f $READ_GFARM_PATH1 \
		$READ_GFARM_PATH2 $WRITE_GFARM_PATH1 $WRITE_GFARM_PATH2 \
		$WRITE_GFARM_PATH3

	# cleanup: remove dir
	$GFSERVICE gfcmd client1 gfrmdir $GFARM_PATH1 $GFARM_PATH2 \
		$GFARM_PATH3

	# cleanup: unmount
	$GFSERVICE umount client1 $MOUNT_POINT
	$GFSERVICE systest::gfarm2fs::exec_ssh client1 rmdir $MOUNT_POINT

	return $RESULT_PASS
}
