#
# Test case for check behavior when network interface of two gfsd node is
# down in replicating files
#
load "gfarm2fs::calc_checksum"
load "gfarm2fs::wait_for_gfsd_connect"
load "gfarm_v2::generate_testdata"
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
# SLEEP_SEC:	Second to sleep before make network interface down
# RETRY_COUNT:	Retry number to check number of replicas
#
setup_two_gfsd_ifdown_in_rep()
{
	# default parameter
	GFARM_HOME=${GFARM_HOME-"/"}
	FILE_SIZE=${FILE_SIZE-"100M"}
	SLEEP_SEC=${SLEEP_SEC-"3"}
	RETRY_COUNT=${RETRY_COUNT-"20"}
	RETRY_INTERVAL=${RETRY_INTERVAL-"30"}

	# miscellaneous parameters
	GFARM_FILE=$GFARM_HOME/$TEST_EXEC_ID

	# prepare: check whether required host is 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: calc checksum
	CHECKSUM=`calc_checksum $FILE_SIZE`

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

	return $RESULT_PASS
}

test_two_gfsd_ifdown_in_rep()
{
	RESULT=$RESULT_PASS

	# step: replicate a file in background
	$GFSERVICE systest::gfarm2fs::replicate_file client1 $GFARM_FILE gfsd2 &
	REP_PID1=$!

	$GFSERVICE systest::gfarm2fs::replicate_file client1 $GFARM_FILE gfsd3 &
	REP_PID2=$!

	# wait a bit for a process starts replicating a file
	sleep $SLEEP_SEC

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

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

	wait $REP_PID1
	if [ $? -eq 0 ]; then
		log_warn "$TESTNAME: unexpectedly suceeded to replicate a" \
			"file to gfsd2"
		set_result RESULT $RESULT_XPASS
	fi

	wait $REP_PID2
	if [ $? -eq 0 ]; then
		log_warn "$TESTNAME: unexpectedly suceeded to replicate a" \
			"file to gfsd3"
		set_result RESULT $RESULT_XPASS
	fi

	# step: replicate a file
	$GFSERVICE gfcmd client1 gfrep -N 2 $GFARM_FILE
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: failed to execute gfrep"
		set_result RESULT $RESULT_FAIL
	fi

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

	# step: make network interface up
	$GFSERVICE systest::gfarm2fs::ifup gfsd2
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: failed to execute ifup on gfsd2"
		return $RESULT_FATAL
	fi

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

	# prepare: wait until gfsd get connected
	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

	# step: replicate a file
	$GFSERVICE systest::gfarm2fs::replicate_file client1 $GFARM_FILE gfsd2
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: failed to replicate a file to gfsd2"
		set_result RESULT $RESULT_FAIL
	fi

	$GFSERVICE systest::gfarm2fs::replicate_file client1 $GFARM_FILE gfsd3
	if [ $? -ne 0 ]; then
		log_warn "$TESTNAME: failed to replicate a file to gfsd3"
		set_result RESULT $RESULT_FAIL
	fi

	# step: compare check sum of spool file
	SPOOL_PATH=`$GFSERVICE gfcmd client1 gfspoolpath $GFARM_FILE`
	if [ X$SPOOL_PATH = X ]; then
		log_warn "$TESTNAME: failed to get spool path"
		set_result RESULT $RESULT_FAIL
	fi

	CHECKSUM_GFSD2=`$GFSERVICE systest::gfarm2fs::spool_file_checksum gfsd2 \
		$SPOOL_PATH`

	if [ X$CHECKSUM_GFSD2 != X$CHECKSUM ]; then
		log_warn "$TESTNAME: checksum of a file is different from" \
			"original one"
		set_result RESULT $RESULT_FAIL
	fi

	CHECKSUM_GFSD3=`$GFSERVICE systest::gfarm2fs::spool_file_checksum gfsd3 \
		$SPOOL_PATH`

	if [ X$CHECKSUM_GFSD3 != X$CHECKSUM ]; then
		log_warn "$TESTNAME: checksum of a file is different from" \
			"original one"
		set_result RESULT $RESULT_FAIL
	fi

	return $RESULT
}

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

	# cleanup: remove a file
	$GFSERVICE gfcmd client1 gfrm -r $GFARM_FILE

	return $RESULT_PASS
}
