#!/bin/sh
# Helpers shared by the ikvswitch-setup unit tests. This file is not
# named test_*, so run_tests never executes it directly. It must be
# sourced from a test file, which is started by run_tests with the
# working directory set to the test's folder.

set -e

TESTDIR=$(pwd)
IKVROOT=$(readlink -f "${TESTDIR}/../..")
SCRIPT_SRC=$(readlink -f "${IKVROOT}/usr/bin/ikvswitch-setup")
CONF_SRC=$(readlink -f "${IKVROOT}/etc/ikvswitch/ikvswitch.conf")

SANDBOX=$(mktemp -d /tmp/ikvswitch-test.XXXXXX)

cleanup () {
	rm -rf "${SANDBOX}"
}
trap cleanup EXIT

# ikvswitch-setup hardcodes /etc/ikvswitch/ikvswitch.conf,
# /root/.ssh/authorized_keys and /var/lib/ikvswitch: the tests run a
# patched copy of the script, with all three redirected inside a
# mktemp sandbox, so that the suite is hermetic (it never needs root,
# and never touches the real paths). The mock binaries of bin/ are
# prepended to the PATH, and the fake umount copies what the script
# wrote into each "mounted" VM rootfs into ${SANDBOX}/out/<vm-name>/.
setup_sandbox () {
	mkdir -p "${SANDBOX}/etc" \
		"${SANDBOX}/var/lib/ikvswitch/templates" \
		"${SANDBOX}/var/lib/ikvswitch/runtime" \
		"${SANDBOX}/rootfs/etc/frr" \
		"${SANDBOX}/rootfs/etc/sysctl.d" \
		"${SANDBOX}/rootfs/etc/network" \
		"${SANDBOX}/rootfs/etc/dhcp" \
		"${SANDBOX}/rootfs/etc/dnsmasq.d"
	touch "${SANDBOX}/authorized_keys"
	touch "${SANDBOX}/var/lib/ikvswitch/templates/ikvswitch-template.raw"
	echo "bgpd=no" >"${SANDBOX}/rootfs/etc/frr/daemons"
	reset_conf
	sed -e "s|/etc/ikvswitch/ikvswitch.conf|${SANDBOX}/etc/ikvswitch.conf|g" \
		-e "s|/root/.ssh/authorized_keys|${SANDBOX}/authorized_keys|g" \
		-e "s|/var/lib/ikvswitch|${SANDBOX}/var/lib/ikvswitch|g" \
		"${SCRIPT_SRC}" >"${SANDBOX}/ikvswitch-setup"
	chmod +x "${SANDBOX}/ikvswitch-setup"
}

# Restores the pristine configuration file from the repository.
reset_conf () {
	cp "${CONF_SRC}" "${SANDBOX}/etc/ikvswitch.conf"
}

# Runs the patched ikvswitch-setup with the given arguments, capturing
# its output in OUT and its return code in SETUP_RC.
run_setup () {
	IKV_MOCK_ROOTFS=${SANDBOX}/rootfs
	IKV_MOCK_OUTPUT=${SANDBOX}/out
	IKV_MOCK_CURRENT=${SANDBOX}/current-vm
	IKV_MOCK_SSD_LOG=${SANDBOX}/start-stop-daemon.log
	export IKV_MOCK_ROOTFS IKV_MOCK_OUTPUT IKV_MOCK_CURRENT IKV_MOCK_SSD_LOG
	rm -rf "${SANDBOX}/out"
	set +e
	OUT=$(PATH=${TESTDIR}/bin:${PATH} sh "${SANDBOX}/ikvswitch-setup" "$@" 2>&1)
	SETUP_RC=$?
	set -e
}

assert_eq () {
	if [ "${2}" != "${3}" ] ; then
		echo "assert_eq ${1}: got [${2}], expected [${3}]"
		exit 1
	fi
}

assert_contains () {
	case "${2}" in
	*"${3}"*) ;;
	*)
		echo "assert_contains ${1}: [${2}] does not contain [${3}]"
		exit 1
	;;
	esac
}

assert_not_contains () {
	case "${2}" in
	*"${3}"*)
		echo "assert_not_contains ${1}: [${2}] must not contain [${3}]"
		exit 1
	;;
	esac
}

assert_file_contains () {
	if ! grep -Fq -- "${3}" "${2}" ; then
		echo "assert_file_contains ${1}: ${2} does not contain [${3}]"
		exit 1
	fi
}

assert_file_not_contains () {
	if grep -Fq -- "${3}" "${2}" ; then
		echo "assert_file_not_contains ${1}: ${2} must not contain [${3}]"
		exit 1
	fi
}

assert_file_absent () {
	if [ -r "${2}" ] ; then
		echo "assert_file_absent ${1}: ${2} must not exist"
		exit 1
	fi
}
