Files
cariflex/tools/EVerest-main/tests/run-tests.sh
Eric F d398a6ced2 Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1)
- OpenOCPP extracted (firmware OCPP 1.6J/2.0.1)
- ShapeShifter library installed (pip install -e)
- ShapeShifter specification extracted
- EVerest extracted

TODO updated with progress
2026-06-08 00:38:27 -04:00

231 lines
6.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Unified test runner for E2E tests of EVerest.
#
# Usage: run-tests.sh [OPTIONS] SUITE
#
# Suites:
# all All tests
#
# integration Core, framework, and async API tests
# core Core tests only
# framework Framework tests only
# asyncapi Async API tests only
#
# ocpp All OCPP tests (1.6, 2.0.1, 2.1)
# ocpp16 OCPP 1.6 tests only
# ocpp201 OCPP 2.0.1 tests only
# ocpp21 OCPP 2.1 tests only
#
# Options:
# -j N Parallel workers (default: nproc)
# --serial Run tests serially
# --everest-prefix P EVerest install prefix (default: <repo>/build/dist)
# --junitxml PATH JUnit XML output (default: result.xml)
# --html PATH HTML report output (default: report.html)
# --no-isolation Disable network isolation
# -h, --help Show this help
#
# Environment variables:
# PYTHON_INTERPRETER Python to use (default: python3)
# PARALLEL_TESTS Worker count (overridden by -j)
# NETWORK_ISOLATION true/false (overridden by --no-isolation)
# EVEREST_PREFIX Install prefix (overridden by --everest-prefix)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE:-$0}")" && pwd)"
EVEREST_CORE_DIR="$(dirname "$SCRIPT_DIR")"
PYTHON="${PYTHON_INTERPRETER:-python3}"
# Defaults
WORKERS="${PARALLEL_TESTS:-$(nproc)}"
SERIAL=false
PREFIX="${EVEREST_PREFIX:-${EVEREST_CORE_DIR}/build/dist}"
JUNITXML="result.xml"
HTML="report.html"
ISOLATION="${NETWORK_ISOLATION:-true}"
SUITE=""
usage() {
sed -n '3,/^$/s/^# \?//p' "$0"
exit 0
}
while [[ $# -gt 0 ]]; do
case "$1" in
-j) WORKERS="$2"; shift 2;;
--serial) SERIAL=true; shift;;
--everest-prefix) PREFIX="$2"; shift 2;;
--junitxml) JUNITXML="$2"; shift 2;;
--html) HTML="$2"; shift 2;;
--no-isolation) ISOLATION=false; shift;;
-h|--help) usage;;
-*) echo "Unknown option: $1" >&2; exit 1;;
*) SUITE="$1"; shift;;
esac
done
if [[ -z "$SUITE" ]]; then
echo "Error: no suite specified." >&2
echo "Run '$(basename "$0") --help' for usage." >&2
exit 1
fi
echo "Suite: $SUITE"
echo "Python: $PYTHON"
echo "Prefix: $PREFIX"
# Network isolation
ISOLATION_FLAG=""
if [[ "$ISOLATION" == "true" && "$SERIAL" == "false" ]]; then
SETUP_SCRIPT="$SCRIPT_DIR/setup-network-isolation.sh"
if ip link show ev_test0 >/dev/null 2>&1; then
# Veth pairs already exist (e.g. leftover from a previous run or created by CI).
echo "Network isolation: detected pre-existing veth pairs."
ISOLATION_FLAG="--network-isolation"
elif [[ -x "$SETUP_SCRIPT" ]]; then
echo "Setting up network isolation (veth pairs)..."
# Try without sudo first (for CI).
# CTRL+C at the sudo prompt cancels it and falls back to sequential execution.
if "$SETUP_SCRIPT" setup "$WORKERS" 2>/dev/null; then
ISOLATION_FLAG="--network-isolation"
elif sudo "$SETUP_SCRIPT" setup "$WORKERS"; then
ISOLATION_FLAG="--network-isolation"
else
echo "Warning: Could not set up network isolation (no sudo / CAP_NET_ADMIN)."
echo " ISO 15118 tests will run sequentially via xdist_group markers."
fi
fi
if [[ -n "$ISOLATION_FLAG" ]]; then
# Try without sudo (CI/root), then sudo -n (local NOPASSWD), then warn.
teardown_network_isolation() {
echo "Tearing down network isolation..."
"$SETUP_SCRIPT" teardown "$WORKERS" 2>/dev/null \
|| sudo -n "$SETUP_SCRIPT" teardown "$WORKERS" 2>/dev/null \
|| echo "Warning: Could not tear down network isolation. Run manually: sudo $SETUP_SCRIPT teardown"
}
trap teardown_network_isolation EXIT
fi
fi
# Common pytest arguments
PYTEST_ARGS=(
-rA
--self-contained-html
--max-worker-restart=0
--timeout=300
--everest-prefix "$PREFIX"
--config-file "$SCRIPT_DIR/pytest.ini"
)
if [[ "$SERIAL" == "false" ]]; then
echo "Workers: $WORKERS"
PYTEST_ARGS+=(-n "$WORKERS" --dist=loadgroup)
else
echo "Workers: serial"
fi
[[ -n "$ISOLATION_FLAG" ]] && PYTEST_ARGS+=("$ISOLATION_FLAG")
# OCPP setup (certs + configs)
setup_ocpp() {
local aux_dir="$SCRIPT_DIR/ocpp_tests/test_sets/everest-aux"
if [[ -d "$aux_dir" ]]; then
echo "Installing OCPP test certs and configs..."
(cd "$aux_dir" && ./install_certs.sh "$PREFIX" && ./install_configs.sh "$PREFIX")
fi
}
# Run
case "$SUITE" in
all)
echo "Running all test suites"
cd "$SCRIPT_DIR"
setup_ocpp
"$PYTHON" -m pytest "${PYTEST_ARGS[@]}" \
--junitxml="$JUNITXML" --html="$HTML" \
core_tests/*.py \
framework_tests/*.py \
async_api_tests/*.py \
ocpp_tests/test_sets/ocpp16/*.py \
ocpp_tests/test_sets/ocpp201/*.py \
ocpp_tests/test_sets/ocpp21/*.py
;;
integration)
cd "$SCRIPT_DIR"
"$PYTHON" -m pytest "${PYTEST_ARGS[@]}" \
--junitxml="$JUNITXML" --html="$HTML" \
core_tests/*.py \
framework_tests/*.py \
async_api_tests/*.py
;;
core)
cd "$SCRIPT_DIR"
"$PYTHON" -m pytest "${PYTEST_ARGS[@]}" \
--junitxml="$JUNITXML" --html="$HTML" \
core_tests/*.py
;;
framework)
cd "$SCRIPT_DIR"
"$PYTHON" -m pytest "${PYTEST_ARGS[@]}" \
--junitxml="$JUNITXML" --html="$HTML" \
framework_tests/*.py
;;
asyncapi)
cd "$SCRIPT_DIR"
"$PYTHON" -m pytest "${PYTEST_ARGS[@]}" \
--junitxml="$JUNITXML" --html="$HTML" \
async_api_tests/*.py
;;
ocpp)
setup_ocpp
cd "$SCRIPT_DIR"
"$PYTHON" -m pytest "${PYTEST_ARGS[@]}" \
--junitxml="$JUNITXML" --html="$HTML" \
ocpp_tests/test_sets/ocpp16/*.py \
ocpp_tests/test_sets/ocpp201/*.py \
ocpp_tests/test_sets/ocpp21/*.py
;;
ocpp16)
setup_ocpp
cd "$SCRIPT_DIR"
"$PYTHON" -m pytest "${PYTEST_ARGS[@]}" \
--junitxml="$JUNITXML" --html="$HTML" \
ocpp_tests/test_sets/ocpp16/*.py
;;
ocpp201)
setup_ocpp
cd "$SCRIPT_DIR"
"$PYTHON" -m pytest "${PYTEST_ARGS[@]}" \
--junitxml="$JUNITXML" --html="$HTML" \
ocpp_tests/test_sets/ocpp201/*.py
;;
ocpp21)
setup_ocpp
cd "$SCRIPT_DIR"
"$PYTHON" -m pytest "${PYTEST_ARGS[@]}" \
--junitxml="$JUNITXML" --html="$HTML" \
ocpp_tests/test_sets/ocpp21/*.py
;;
*)
echo "Unknown suite: $SUITE" >&2
echo "Valid suites: all, integration, core, framework, asyncapi, ocpp, ocpp16, ocpp201, ocpp21" >&2
exit 1
;;
esac