fix: migrate PaperMC to v3 API, fix NeoForge beta fallback, add test suite
- Migrate Paper loader from sunset v2 API to v3 (fill.papermc.io) - Fix NeoForge: fall back to beta versions when no stable exists (set -e + grep) - Fix setEula/setperms ordering (was writing eula.txt before /data was writable) - Fix setEula/serverInfoWrite to use absolute paths (/data/server/) - Add VOLUME directive removal (was shadowing bind mounts) - Add comprehensive API test suite (110 tests across 6 suites) - Move test.sh to tests/integration.sh, switch to named volumes - Add Docker build cache to CI workflows - Add .editorconfig, expand .gitignore, improve README docs
This commit is contained in:
Executable
+175
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") [options]
|
||||
|
||||
Test Minecraft server loader integrations in isolated Docker containers.
|
||||
|
||||
Options:
|
||||
-m, --mc-version <ver> Minecraft version (default: auto-detect latest)
|
||||
-l, --loader <name> Loader to test (default: all)
|
||||
-v, --loader-version <v> Loader version (default: auto-detect latest)
|
||||
-t, --timeout <sec> Max wait for server jar (default: 180)
|
||||
-h, --help Show this help
|
||||
|
||||
Examples:
|
||||
$(basename "$0") Test all loaders (latest MC)
|
||||
$(basename "$0") -m 1.21.1 Test all loaders on MC 1.21.1
|
||||
$(basename "$0") -m 1.21.1 -l fabric Test Fabric on MC 1.21.1
|
||||
$(basename "$0") -m 1.21.1 -l fabric -v 0.19.3 Test Fabric 0.19.3 on MC 1.21.1
|
||||
|
||||
Loaders: vanilla paper fabric forge neoforge bedrock
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
detect_mc_version() {
|
||||
curl -sf --connect-timeout 10 --max-time 30 \
|
||||
"https://launchermeta.mojang.com/mc/game/version_manifest.json" |
|
||||
jq -r '.latest.release'
|
||||
}
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
|
||||
IMAGE="dockercraft-test:latest"
|
||||
MC_VERSION=""
|
||||
LOADER=""
|
||||
LOADER_VERSION=""
|
||||
TIMEOUT=180
|
||||
PASS=0
|
||||
FAIL=0
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-h|--help) usage ;;
|
||||
-m|--mc-version) MC_VERSION="$2"; shift 2 ;;
|
||||
-l|--loader) LOADER="$2"; shift 2 ;;
|
||||
-v|--loader-version) LOADER_VERSION="$2"; shift 2 ;;
|
||||
-t|--timeout) TIMEOUT="$2"; shift 2 ;;
|
||||
*) echo "Unknown option: $1"; usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$MC_VERSION" ]]; then
|
||||
echo "Detecting latest Minecraft version..."
|
||||
MC_VERSION=$(detect_mc_version)
|
||||
echo " -> ${MC_VERSION}"
|
||||
fi
|
||||
|
||||
if [[ -z "$LOADER" ]]; then
|
||||
tests=("vanilla" "paper" "fabric" "forge" "neoforge" "bedrock")
|
||||
else
|
||||
tests=("$LOADER")
|
||||
fi
|
||||
|
||||
cleanup() {
|
||||
local name="$1"
|
||||
docker kill "dc-test-${name}" 2>/dev/null || true
|
||||
docker rm "dc-test-${name}" 2>/dev/null || true
|
||||
docker volume rm "dc-test-vol-${name}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
run_test() {
|
||||
local name="$1"
|
||||
shift
|
||||
|
||||
echo "=== Testing: ${name} ==="
|
||||
cleanup "$name"
|
||||
|
||||
# Use a named volume instead of a bind mount (avoids host filesystem quirks)
|
||||
docker volume create "dc-test-vol-${name}" >/dev/null
|
||||
|
||||
local CONTAINER_ID
|
||||
if CONTAINER_ID=$(docker run -d --name "dc-test-${name}" \
|
||||
-e EULA=true \
|
||||
-e MC_VERSION="${MC_VERSION}" \
|
||||
"$@" \
|
||||
-v "dc-test-vol-${name}:/data" \
|
||||
"${IMAGE}" 2>&1); then
|
||||
|
||||
local waited=0
|
||||
local jar_found=false
|
||||
while [[ $waited -lt $TIMEOUT ]]; do
|
||||
# Check inside the container for the server binary
|
||||
if docker exec "dc-test-${name}" test -f /data/server/server.jar 2>/dev/null || \
|
||||
docker exec "dc-test-${name}" find /data/server -name 'forge-*-server.jar' 2>/dev/null | grep -q . || \
|
||||
docker exec "dc-test-${name}" test -f /data/server/bedrock_server 2>/dev/null; then
|
||||
jar_found=true
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
waited=$((waited + 3))
|
||||
echo -n "."
|
||||
done
|
||||
echo ""
|
||||
|
||||
if $jar_found; then
|
||||
if docker exec "dc-test-${name}" test -f /data/server/bedrock_server 2>/dev/null; then
|
||||
echo " PASS (bedrock_server found in ~${waited}s)"
|
||||
else
|
||||
echo " PASS (server jar found in ~${waited}s)"
|
||||
fi
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
echo ""
|
||||
echo " FAIL: server binary not found after ${TIMEOUT}s"
|
||||
echo " --- container logs ---"
|
||||
docker logs "dc-test-${name}" 2>&1 | tail -50 || true
|
||||
echo " ---------------------"
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo " FAIL: container failed to start"
|
||||
echo " ${CONTAINER_ID}"
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
||||
cleanup "$name"
|
||||
}
|
||||
|
||||
echo "Building image..."
|
||||
DOCKER_BUILDKIT=0 docker build -t "${IMAGE}" "${PROJECT_ROOT}"
|
||||
|
||||
for t in "${tests[@]}"; do
|
||||
case $t in
|
||||
vanilla)
|
||||
run_test "vanilla" -e MC_LOADER=vanilla
|
||||
;;
|
||||
paper)
|
||||
run_test "paper" -e MC_LOADER=paper
|
||||
;;
|
||||
fabric)
|
||||
run_test "fabric" \
|
||||
-e MC_LOADER=fabric \
|
||||
-e FABRIC_LOADER_VERSION="${LOADER_VERSION}"
|
||||
;;
|
||||
forge)
|
||||
run_test "forge" \
|
||||
-e MC_LOADER=forge \
|
||||
-e FORGE_VERSION="${LOADER_VERSION}"
|
||||
;;
|
||||
neoforge)
|
||||
run_test "neoforge" \
|
||||
-e MC_LOADER=neoforge \
|
||||
-e NEOFORGE_VERSION="${LOADER_VERSION}"
|
||||
;;
|
||||
bedrock)
|
||||
run_test "bedrock" \
|
||||
-e MC_LOADER=bedrock \
|
||||
-e MC_VERSION=
|
||||
;;
|
||||
*)
|
||||
echo "Unknown loader: ${t}"
|
||||
echo "Valid: vanilla paper fabric forge neoforge bedrock"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Results: ${PASS} passed, ${FAIL} failed"
|
||||
[[ $FAIL -eq 0 ]]
|
||||
Reference in New Issue
Block a user