#!/bin/sh -ef
# NAME=HDD array stress
# DESCRIPTION=HDD array is a stress test that causes high load on HDD array subsystem. First of all it creates a filesystem on each array and unpacks and compiles there a large source tree for a specified time. Test distributes specified test duration among created arrays equally. Compilation, as in hdd-passthrough test, goes with 16 simultaneous jobs (by default). Test will finish successfully if there won't be any errors in filesystem creation and source code compilation runs. Usually this test starts after the CPU burning, memory and hdd-passthrough ones, and thus failing of this test (considering successful previous tests) usually identifies a broken RAID controller.
# DESTROYS_HDD=true
# IS_INTERACTIVE=false
# POWEROFF_DURING_TEST=false
# VERSION=0.1
# TAGS=hdd,stress
# DEPENDS=CPU,HDD,Memory,Mainboard,Disk Controller
# VAR=TESTTIME:int:3600:Total time of HDD array testing, sec
# VAR=LOGTIME:int:120:Time between progress updates, sec
# VAR=JOBS:int:16:Number of parallely running jobs during compile
# VAR=STRESS_TREE:string:linux-stress.tar.gz:Tarball file containing stress test tree
# VAR=MINIMAL_DRIVE_SIZE:int:2048:That is less than this amount is an flash device, MiB

. _inq-config-global; . $SHARE_DIR/functions-test

clear_testing_environment()
{
	cd $HOME
	umount -f $MOUNTPOINT >$DEBUG_TTY 2>&1 || true
}

exit_handler()
{
	clear_testing_environment
	[ -d "$MOUNTPOINT" ] && rmdir $MOUNTPOINT
}

MOUNTPOINT=`mktemp -d`

array_stress_check()
{
	local array=$1

	echo -n "Preparing array $array..."
	prepare_array_for_test $array
	echo_success

	echo "Testing $array..."
	START=`date "+%s"`
	LAST_LOGTIME=$TOTAL_START

	while true; do
		TIME=`date "+%s"`
		if [ $(($TIME - $START)) -gt $TIME_PER_ARRAY ]; then
			clear_testing_environment
			break
		else
			make clean >$DEBUG_TTY 2>&1 &&
			make -j $JOBS >$DEBUG_TTY 2>&1 ||
			test_failed "Make error"
		fi

		if [ $(($TIME - $LAST_LOGTIME)) -gt $LOGTIME ]; then
			test_progress $(( $TIME - $START )) $TESTTIME
			LAST_LOGTIME=$TIME
		fi
	done
}

prepare_array_for_test()
{
	local array=$1

	# Create and mount filesystem on which we will work
	mkfs.$DEFAULT_FILESYSTEM $DEFAULT_FILESYSTEM_FORCE $array >$DEBUG_TTY 2>&1 || test_failed "Disk write error"
	mount -t $DEFAULT_FILESYSTEM $array $MOUNTPOINT

	# Extract sources for compilation
	cd "$SHARE_DIR"
	tar xvf "$STRESS_TREE" -C "$MOUNTPOINT" >$DEBUG_TTY 2>&1 || test_failed "Untaring error"

	cd $MOUNTPOINT
	tree_name=`basename "$STRESS_TREE" .tar.gz`
	cd $tree_name

	# Is it linux source? We have to touch some files for proper
	# Makefile working.
	if echo "$tree_name" | grep '^linux' ; then
		find . -print | xargs touch >/dev/null 2>&1 || true
		touch .config include/linux/autoconf.h >/dev/null 2>&1 || true
	fi
}

HDD_QUANTITY=`get_hdds_list | wc -l`
test_succeed_if_no hdds
TIME_PER_ARRAY=$(( $TESTTIME / $HDD_QUANTITY ))

# Temporary checking for correct number of JOBS
# This need caused by small memory amount computers
[ "`memory_amount`" -lt 600 ] && JOBS=4 || true

TOTAL_START=`date "+%s"`
test_promise_time $TESTTIME

for i in `get_hdds_list`; do
	drivename=`echo $i | sed 's/\/dev\///'`
	drive_size=`cat /sys/block/$drivename/size`
	[ "$drive_size" -lt "$MINIMAL_DRIVE_SIZE" ] && continue
	array_stress_check $i
done

test_succeeded
