#!/bin/bash
#
# Run OpenJDK jtreg tests under Syd.
#
# Copyright 2025 Ali Polatel <alip@chesswob.org>
#
# SPDX-License-Identifier: GPL-3.0

# TEST_LIMIT: Number of tests to run at a time.
# TEST_PATTERN: A Regex (PCRE) for tests to run.
test_pattern_set=false
case "$1" in
    '')
        TEST_LIMIT=40960
        TEST_PATTERN='.*'
        test_pattern_set=true
        ;;
    [0-9]*)
        TEST_LIMIT="${1}"
        TEST_PATTERN='.*'
        ;;
    *)
        TEST_LIMIT=1500
        TEST_PATTERN="${1}"
        test_pattern_set=true
        ;;
esac

# A Regex (PCRE) for tests to skip.
SKIP_PATTERN=''

# Tests that have failed in the past.
FAIL_HISTORY=(
)
# Do not go over history, if user specified a test pattern.
$test_pattern_set && FAIL_HISTORY=()

# Make sure we don't trigger TPE.
umask 077

# Enable coredumps.
ulimit -c unlimited

# Force TTY output.
export SYD_FORCE_TTY=YesPlease

# Enable path hiding and ioctl sandboxing for wider coverage.
# This works because LTP profile includes the PALUDIS profile.
export SYD_PALUDIS_LPATH=1
export SYD_PALUDIS_IOCTL=1

# Timeout is 20 minutes per-test unless otherwise specified.
SYD_TEST_TIMEOUT=${SYD_TEST_TIMEOUT:-20m}

export SYD_LOG=${SYD_LOG:-notice}
SYD="${CARGO_BIN_EXE_syd:-syd}"

# Require Java present.
command -v java >/dev/null 2>&1 || { echo "missing: java" >&2; exit 2; }
JDK_HOME="$(dirname "$(dirname "$(readlink -f "$(command -v java)")")")"

edo() {
    echo >&2 "-- $*"
    "$@"
}

run_test() {
    local name="$1"
    [[ -n "${SYD_TEST_DMESG}" ]] && sudo dmesg -C

    edo timeout -sKILL ${SYD_TEST_TIMEOUT} \
        "${SYD}" -pltp -- jtreg \
            -dir:"${TESTROOT}" \
            -jdk:"${JDK_HOME}" \
            "${name}"
    local r=$?

    if [[ $r == 0 ]]; then
        return 0
    fi

    if [[ -n "${SYD_TEST_DMESG}" ]]; then
        echo '--8<-- KERNEL LOG BEGIN -->8--'
        sudo dmesg
        echo '-->8-- KERNEL LOG END   --8<--'
    fi

    return $r
}

set -ex
DIR="$(mktemp -d syd-jdk.XXXXX)"
mkdir -p "${DIR}/logs"
set +e
pushd "${DIR}"

# Build jtreg from git.
git clone --depth 1 https://github.com/openjdk/jtreg.git jtreg.git || exit 0
pushd jtreg.git
bash make/build.sh --jdk "${JDK_HOME}"
export PATH="${PWD}/build/images/jtreg/bin:${PATH}"
popd

# Get OpenJDK tests.
git clone --depth 1 https://github.com/openjdk/jdk.git jdk.git || exit 0
pushd jdk.git
git rev-parse HEAD

# Determine absolute test root.
TESTROOT="${PWD}/test/jdk"
[[ -d "${TESTROOT}" ]] || { echo "missing test root: ${TESTROOT}" >&2; exit 127; }

set +x

PASS=0
FAIL=0
SKIP=0

# Build candidate list.
if [[ -n "${SKIP_PATTERN}" ]]; then
    TESTS=( $( jtreg -listtests -a -k:'!headful' -jdk:"${JDK_HOME}" "${TESTROOT}" \
        | awk '!/^($|#)/ && /^java\/|^jdk\/|^javax\/|^sun\/|^tools\//' \
        | grep -P "${TEST_PATTERN}" \
        | grep -vP "${SKIP_PATTERN}" \
        | shuf ) )
else
    TESTS=( $( jtreg -listtests -a -k:'!headful' -jdk:"${JDK_HOME}" "${TESTROOT}" \
        | awk '!/^($|#)/ && /^java\/|^jdk\/|^javax\/|^sun\/|^tools\//' \
        | grep -P "${TEST_PATTERN}" \
        | shuf ) )
fi

CTEST=${#TESTS[@]}
NTEST=${TEST_LIMIT}
if [[ ${NTEST} -gt ${CTEST} ]]; then
    NTEST=${CTEST}
fi
TESTS=( "${FAIL_HISTORY[@]}" "${TESTS[@]:0:${NTEST}}" )
NTEST=${#TESTS[@]}

idx=0
for name in "${TESTS[@]}"; do
    : $(( idx++ ))
    echo >&2 -e "\033[92m*** $name ($idx of $NTEST: $PASS ok, $FAIL notok, $SKIP todo) ***\033[0m"
    if [[ -n "${SKIP_PATTERN}" ]] && echo "${name}" | grep -qP "${SKIP_PATTERN}"; then
        echo "ok ${idx} - ${name} # TODO"
        : $(( SKIP++ ))
    elif run_test "${name}"; then
        echo "ok ${idx} - ${name}"
        : $(( PASS++ ))
    else
        echo "not ok ${idx} - ${name} - FAIL: $?"
        : $(( FAIL++ ))
        [[ -z "${SYD_TEST_QUICK}" ]] || break
    fi
done

set -ex
tar -cJpf syd-jdk-test-log.tar.xz JT*
mv *.xz ~
set +ex

echo "# $PASS tests passed."
echo "# $FAIL tests failed."
echo "# $SKIP tests skipped."
exit $FAIL
