sots-engine/tests/mars_vfs/build_and_run.sh

88 lines
3.9 KiB
Bash
Executable file

#!/usr/bin/env bash
# Self-contained build + test for src/mars/vfs (plain g++, no CMake needed).
#
# tests/mars_vfs/build_and_run.sh
#
# Always runs the unit tests (the deflated fixture is generated with Python's
# zipfile if python3 is available). When SOTS_GOB_DIR points at a directory
# holding sots.gob + sots_local_en.gob it also runs the oracle-backed
# real-data test and byte-compares a few entries against `unzip -p`.
#
# Env: CXX (g++), CC (gcc), PYTHON (python3), BUILD_DIR (tests/mars_vfs/build),
# SOTS_GOB_DIR, SOTS_GOB_ORACLE_DIR (defaults to SOTS_GOB_DIR), SOTS_GOB_FULL=1.
set -euo pipefail
HERE=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
ROOT=$(cd "$HERE/../.." && pwd)
BUILD=${BUILD_DIR:-$HERE/build}
CXX=${CXX:-g++}
CC=${CC:-gcc}
PYTHON=${PYTHON:-python3}
MINIZ="$ROOT/third_party/miniz"
MINIZ_DEFS=(-DMINIZ_NO_ARCHIVE_APIS -DMINIZ_NO_ARCHIVE_WRITING_APIS -DMINIZ_NO_STDIO -DMINIZ_NO_TIME -DMINIZ_NO_ZLIB_COMPATIBLE_NAMES)
FLAGS=(-std=c++17 -O2 -Wall -Wextra -Werror -I"$ROOT/src" -I"$HERE" -I"$MINIZ" "${MINIZ_DEFS[@]}")
VFS=("$ROOT/src/mars/vfs/path.cpp" "$ROOT/src/mars/vfs/zip_archive.cpp" "$ROOT/src/mars/vfs/vfs.cpp")
PARSE=("$ROOT/src/mars/parse/blocks.cpp" "$ROOT/src/mars/parse/effect.cpp" "$ROOT/src/mars/parse/value.cpp")
TEXT=("$ROOT/src/mars/text/value.cpp" "$ROOT/src/mars/text/flat_kv.cpp" "$ROOT/src/mars/text/manifest.cpp" "$ROOT/src/mars/text/csv.cpp")
mkdir -p "$BUILD"
echo "== building (miniz as C, module + tests as C++17 -Werror)"
"$CC" -std=c11 -O2 -w "${MINIZ_DEFS[@]}" -c "$MINIZ/miniz.c" -o "$BUILD/miniz.o"
"$CXX" "${FLAGS[@]}" "${VFS[@]}" "$BUILD/miniz.o" "$HERE/test_main.cpp" "$HERE/unit_tests.cpp" -o "$BUILD/unit_tests"
"$CXX" "${FLAGS[@]}" "${VFS[@]}" "$BUILD/miniz.o" "$HERE/vfs_cat.cpp" -o "$BUILD/vfs_cat"
"$CXX" "${FLAGS[@]}" "${VFS[@]}" "${PARSE[@]}" "${TEXT[@]}" "$BUILD/miniz.o" "$HERE/realdata_test.cpp" -o "$BUILD/realdata_test"
echo "== deflated fixture"
FIXTURE="$BUILD/deflated.zip"
if command -v "$PYTHON" >/dev/null 2>&1 && "$PYTHON" "$HERE/make_fixture.py" "$FIXTURE"; then
export MARS_VFS_FIXTURE="$FIXTURE"
echo "generated $FIXTURE"
else
echo "python3 unavailable: deflate test will SKIP"
unset MARS_VFS_FIXTURE
fi
echo "== unit tests"
"$BUILD/unit_tests"
if [ -z "${SOTS_GOB_DIR:-}" ]; then
echo "== SOTS_GOB_DIR not set: skipping real-data tests"
exit 0
fi
if [ ! -f "$SOTS_GOB_DIR/sots.gob" ] || [ ! -f "$SOTS_GOB_DIR/sots_local_en.gob" ]; then
echo "== SOTS_GOB_DIR=$SOTS_GOB_DIR does not hold sots.gob + sots_local_en.gob" >&2
exit 1
fi
echo "== real-data test"
"$BUILD/realdata_test"
echo "== byte-equality spot check against unzip -p"
if ! command -v unzip >/dev/null 2>&1; then
echo "unzip not installed: SKIP"
exit 0
fi
check() { # archive rel -- unzip is the oracle; the VFS is asked with a different spelling
local gob="$1" rel="$2" exp="$BUILD/spot.expected" got="$BUILD/spot.got"
local spelled
spelled=$(echo "$rel" | tr '/a-z' '\\A-Z') # backslashes + upper case
unzip -p "$gob" "$rel" > "$exp" || { echo "unzip cannot extract $rel" >&2; return 1; }
[ -s "$exp" ] || { echo "empty oracle output for $rel" >&2; return 1; }
"$BUILD/vfs_cat" --zip "$SOTS_GOB_DIR/sots.gob" --zip "$SOTS_GOB_DIR/sots_local_en.gob" "$spelled" > "$got" \
|| { echo "vfs_cat cannot read $spelled" >&2; return 1; }
if cmp -s "$exp" "$got"; then
echo "same: $rel ($(wc -c < "$exp") bytes)"
else
echo "DIFFER: $rel" >&2
return 1
fi
}
check "$SOTS_GOB_DIR/sots.gob" "TechTree/MasterTechList.tech"
check "$SOTS_GOB_DIR/sots.gob" "Weapons/_weapons.txt"
check "$SOTS_GOB_DIR/sots.gob" "Data/globals.txt"
check "$SOTS_GOB_DIR/sots.gob" "Avatars/AI_AV.tga"
check "$SOTS_GOB_DIR/sots.gob" "Species/Human/sections/CRAIC.shipsection"
check "$SOTS_GOB_DIR/sots_local_en.gob" "Locale/EN/Strings.csv"
rm -f "$BUILD/spot.expected" "$BUILD/spot.got"
echo "== all good"