#!/bin/sh
set -u

jdwp_option=
if [ -n "${JEPSEN_JDWP_PORT:-}" ]; then
	case "$JEPSEN_JDWP_PORT" in
	*[!0-9]*)
		echo "JEPSEN_JDWP_PORT must be a number" >&2
		exit 2
		;;
	esac
	if [ "$JEPSEN_JDWP_PORT" -lt 1 ] || [ "$JEPSEN_JDWP_PORT" -gt 65535 ]; then
		echo "JEPSEN_JDWP_PORT must be between 1 and 65535" >&2
		exit 2
	fi
	jdwp_option="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=127.0.0.1:${JEPSEN_JDWP_PORT}"
fi

(
	if [ -n "${JEPSEN_SUPPRESS_STDOUT:-}" ]; then
		exec >/dev/null
	fi

	set -x
	java \
		-ea -cp "/opt/jepsen/*" \
		${jdwp_option:+"$jdwp_option"} \
		-Djava.awt.headless=true \
		-server \
		jepsen.postgres.cli \
		test-all \
		--test-count 1 \
		--no-ssh \
		--workload "$JEPSEN_WORKLOAD" \
		--isolation "$JEPSEN_ISOLATION" \
		--expected-consistency-model "$JEPSEN_EXPECTED_CONSISTENCY_MODEL" \
		--concurrency "$JEPSEN_CONCURRENCY" \
		--max-writes-per-key "$JEPSEN_MAX_WRITES_PER_KEY" \
		--rate "$JEPSEN_RATE" \
		--time-limit "$JEPSEN_TIME_LIMIT" \
		--nemesis "$JEPSEN_NEMESIS" \
		--node "$JEPSEN_NODE" \
		--existing-postgres \
		--postgres-user "$JEPSEN_POSTGRES_USER" \
		--postgres-password "$JEPSEN_POSTGRES_PASSWORD" \
		--postgres-port "$JEPSEN_POSTGRES_PORT" \
		"$@"
)
rc=$?

# jepsen.postgres.cli/test-all exit codes:
#
#   0 all passed
#   1 some test invalid,
#   2 some test :unknown
#   254 usage errors
#   255 crashed.
#
# NB invalid results (1) are model failures.
# Those are reported per-anomaly by finally_jepsen-results,
# unknown is also handled in finally_jepsen-results.
# So we return 0 for cases 0, 1 and 2
#
# For 255
#
# When there are network partitions during setup, jepsen hard fails
# resulting in a false-positive property failure.
#
# Ideally, there would be a way to run the jepsen setup before fault
# injection starts. The jepsen workload could emit the setup_complete signal,
# but that would mean we couldn't use the test template harness and need
# to build a container entry point that provides similar functionality.
#
# Ideally jepsen would have Client/setup! separated from core/run-case!
# Were setup and execution separated, we would ideally make
# two java calls, one to setup the db run during "first_" to initialize the
# db, and a second to run the tests.
# But, calling Client/setup! is baked into the with-client+nemesis-setup-teardown macro.
# Separating setup from test execution is a bit of a refactor that is only
# needed when executed under Antithesis.
# For now, we explicitly ignore crashed jepsen processes as the only observed
# crash is during a startup network partition.
case "$rc" in
0 | 1 | 2 | 255) exit 0 ;;
*) exit "$rc" ;;
esac
