#!/bin/bash
set -euo pipefail
#
# Run a scheduler for TIMEOUT seconds inside virtme-ng and catch potential
# errors, then unload the scheduler and return the exit status.

# Maximum time for each scheduler run.
TEST_TIMEOUT=30

# Maximum timeout for the guest used for each scheduler run (this is used to
# hard-shutdown the guest in case of system hangs).
GUEST_TIMEOUT=60

# List of schedulers to test
#
# TODO:
#   - scx_mitosis: not ready yet
#
declare -A SCHEDS

VNG_RW=''

# Enable vng rw for when on ci.
if [ $# -ge 3 ] ; then
  if [ "$3" == "VNG_RW=true" ]; then
    echo 'setting vng to mount rw'
    VNG_RW=' --rw '
  fi
fi

# enable running tests on individual schedulers
export RUST_LOG=debug

if [ ! -x `which vng` ]; then
    echo "vng not found, please install virtme-ng to enable testing"
    exit 1
fi
if [ $# -lt 2 ]; then
    echo "Usage: $0 VMLINUZ SCHED_PATH"
    exit 1
fi
kernel=$1
sched_path=$2

if [ ! -f "${sched_path}" ]; then
    echo "Scheduler binary not found at ${sched_path}"
    echo "FAIL: ${sched_path}"
    exit 1
fi

sched_name=$(basename "$sched_path")
echo "Testing ${sched_name} at ${sched_path}"

# Set default args based on scheduler name
if [[ "$sched_name" == "scx_layered" ]]; then
    args="--run-example -v --stats 1"
elif [[ "$sched_name" == "scx_p2dq" ]]; then
    args=""
else
    args="-v"
fi

rm -f /tmp/output
timeout --preserve-status ${GUEST_TIMEOUT} \
    vng --user root -m 10G --cpu 8 $VNG_RW -v -r ${kernel} -- \
        "timeout --foreground --preserve-status ${TEST_TIMEOUT} ${sched_path} ${args}" \
            2> >(tee /tmp/output) </dev/null
    grep -v \
        -e " Speculative Return Stack Overflow" \
        -e " RETBleed: " \
        /tmp/output | \
        sed -n -e '/\bBUG:/q1' \
               -e '/\bWARNING:/q1' \
               -e '/\berror\b/Iq1' \
               -e '/\bstall/Iq1' \
               -e '/\btimeout\b/Iq1'
res=$?
if [ ${res} -ne 0 ]; then
    echo "FAIL: ${sched_name}"
    exit 1
else
    echo "OK: ${sched_name}"
fi
cp /tmp/output test_log.ci.log
