timeout_set 2 minutes

# Create a config file with a limit of 1 MB/s for all processes
iolimits="$TEMP_DIR/iolimits.cfg"
echo "limit unclassified 1024" > "$iolimits"

# Create a second config file with a limit of 2 MB/s for all processes
iolimits2="$TEMP_DIR/iolimits2.cfg"
echo "limit unclassified 2048" > "$iolimits2"

run_io_test() {
	local limit_mbps=$1
	local expected_time_divisor=$2

	time=$(which time) # We need /usr/bin/time or something like this in this test, not a bash built-in
	head -c 1M /dev/zero > warmup

	for mb in 9 5 3 1; do
		export FILE_SIZE="${mb}M"
		expected_time_ms=$(( mb * 1000 / expected_time_divisor ))

		export MESSAGE="Writing $mb MB at $limit_mbps MB/s"
		echo "$MESSAGE"
		seconds=$("$time" -f %e file-generate "file_${mb}" 2>&1)
		actual_time_ms=$(bc <<< "scale=0; $seconds * 1000 / 1")
		assert_near "${expected_time_ms}" "${actual_time_ms}" "$(rescale_value 250)"

		export MESSAGE="Reading $mb MB at $limit_mbps MB/s"
		echo "$MESSAGE"
		seconds=$("$time" -f %e file-validate "file_${mb}" 2>&1)
		actual_time_ms=$(bc <<< "scale=0; $seconds * 1000 / 1")
		assert_near "${expected_time_ms}" "${actual_time_ms}" "$(rescale_value 250)"

		export MESSAGE="Reading + writing $mb MB at $limit_mbps MB/s"
		echo "$MESSAGE"
		seconds=$("$time" -f %e bash -c "file-validate file_${mb} & file-generate garbage & wait" 2>&1)
		actual_time_ms=$(bc <<< "scale=0; $seconds * 1000 / 1")
		assert_near "$((2 * expected_time_ms))" "${actual_time_ms}" "$(rescale_value 250)"
	done
}

CHUNKSERVERS=3 \
	USE_RAMDISK=YES \
	MOUNT_EXTRA_CONFIG="sfscachemode=NEVER|sfsiolimits=$iolimits" \
	setup_local_empty_saunafs info

cd "${info[mount0]}"

rescale_value() {
	if valgrind_enabled || [[ ${info[is_windows_system]} -eq 1 ]]; then
		echo $((4 * $1))
	else
		echo "$1"
	fi
}


run_io_test 1 1

# check that iolimits could be changed at runtime using .saunafs_tweaks file
echo "IOLimitsFilePath=${iolimits2}" | sudo tee "${info[mount0]}/.saunafs_tweaks"
sleep 1 # wait a bit for the change to be reloaded on client

run_io_test 2 2
