Add PG version test matrix (14-18)
Shell script drives the Dockerfile builder stage across PG versions, capturing pass/fail + timing per version. Makefile targets: test-matrix, test-pg%, test-matrix-clean. Also runs standalone DE reader test in the builder stage to catch compiler-version regressions. Fix pork chop grid test: add ORDER BY to CROSS JOIN (optimizer chooses different join nesting across PG versions, reordering rows).
This commit is contained in:
parent
4f8ad7cea1
commit
b18cded4c2
4
.gitignore
vendored
4
.gitignore
vendored
@ -18,6 +18,10 @@ log/
|
|||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
# Test artifacts
|
||||||
|
test/matrix-logs/
|
||||||
|
test/test_de_reader
|
||||||
|
|
||||||
# Docs site
|
# Docs site
|
||||||
docs/node_modules/
|
docs/node_modules/
|
||||||
docs/dist/
|
docs/dist/
|
||||||
|
|||||||
15
CLAUDE.md
15
CLAUDE.md
@ -257,6 +257,21 @@ All numerical logic is byte-identical to upstream. Verified against 518 Vallado
|
|||||||
| de_ephemeris | DE function fallback to VSOP87, cross-provider consistency, error handling |
|
| de_ephemeris | DE function fallback to VSOP87, cross-provider consistency, error handling |
|
||||||
| vallado_518 | 518 Vallado test vectors (AIAA 2006-6753-Rev1), per-satellite breakdown |
|
| vallado_518 | 518 Vallado test vectors (AIAA 2006-6753-Rev1), per-satellite breakdown |
|
||||||
|
|
||||||
|
### PG Version Matrix
|
||||||
|
|
||||||
|
Test all 13 regression suites + DE reader unit test across PostgreSQL 14-18 using Docker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make test-matrix # Full matrix (PG 14-18)
|
||||||
|
make test-pg18 # Single version
|
||||||
|
PG_TEST_VERSIONS="16 17" make test-matrix # Subset
|
||||||
|
make test-matrix-clean # Remove logs + test images
|
||||||
|
```
|
||||||
|
|
||||||
|
Logs saved to `test/matrix-logs/pg${ver}.log`. The script reuses the Dockerfile `builder` stage as the test engine — no additional test infrastructure.
|
||||||
|
|
||||||
|
**Adding a new PG version:** Update `PG_TEST_VERSIONS` default in `Makefile` and `PG_VERSIONS` default in `test/pg-version-matrix.sh`.
|
||||||
|
|
||||||
## Error Handling Patterns
|
## Error Handling Patterns
|
||||||
|
|
||||||
- `_safe()` variants (`sgp4_propagate_safe`, `observe_safe`, `star_observe_safe`) return NULL on error instead of raising exceptions. Use these for batch queries over potentially invalid data.
|
- `_safe()` variants (`sgp4_propagate_safe`, `observe_safe`, `star_observe_safe`) return NULL on error instead of raising exceptions. Use these for batch queries over potentially invalid data.
|
||||||
|
|||||||
@ -42,6 +42,9 @@ RUN su postgres -c "/usr/lib/postgresql/${PG_MAJOR}/bin/initdb -D /tmp/pgtest" &
|
|||||||
make PG_CONFIG=${PG_CONFIG} installcheck && \
|
make PG_CONFIG=${PG_CONFIG} installcheck && \
|
||||||
su postgres -c "/usr/lib/postgresql/${PG_MAJOR}/bin/pg_ctl -D /tmp/pgtest stop"
|
su postgres -c "/usr/lib/postgresql/${PG_MAJOR}/bin/pg_ctl -D /tmp/pgtest stop"
|
||||||
|
|
||||||
|
# Standalone DE reader unit test (no PostgreSQL dependency)
|
||||||
|
RUN make test-de-reader
|
||||||
|
|
||||||
# Capture artifacts under /pg_orrery prefix for the next stage
|
# Capture artifacts under /pg_orrery prefix for the next stage
|
||||||
RUN make PG_CONFIG=${PG_CONFIG} DESTDIR=/pg_orrery install
|
RUN make PG_CONFIG=${PG_CONFIG} DESTDIR=/pg_orrery install
|
||||||
|
|
||||||
|
|||||||
17
Makefile
17
Makefile
@ -50,6 +50,23 @@ test-de-reader: test/test_de_reader.c src/de_reader.c src/de_reader.h
|
|||||||
|
|
||||||
.PHONY: test-de-reader
|
.PHONY: test-de-reader
|
||||||
|
|
||||||
|
# ── PG version test matrix ─────────────────────────────────
|
||||||
|
PG_TEST_VERSIONS ?= 14 15 16 17 18
|
||||||
|
|
||||||
|
test-matrix:
|
||||||
|
PG_VERSIONS="$(PG_TEST_VERSIONS)" bash test/pg-version-matrix.sh
|
||||||
|
|
||||||
|
test-pg%:
|
||||||
|
PG_VERSIONS="$*" bash test/pg-version-matrix.sh
|
||||||
|
|
||||||
|
test-matrix-clean:
|
||||||
|
rm -rf test/matrix-logs
|
||||||
|
@for v in $(PG_TEST_VERSIONS); do \
|
||||||
|
docker rmi "pg_orrery-test:pg$$v" 2>/dev/null || true; \
|
||||||
|
done
|
||||||
|
|
||||||
|
.PHONY: test-matrix test-matrix-clean
|
||||||
|
|
||||||
# ── Docker packaging ────────────────────────────────────────
|
# ── Docker packaging ────────────────────────────────────────
|
||||||
REGISTRY ?= git.supported.systems/warehack.ing
|
REGISTRY ?= git.supported.systems/warehack.ing
|
||||||
IMAGE ?= pg_orrery
|
IMAGE ?= pg_orrery
|
||||||
|
|||||||
@ -125,14 +125,15 @@ SELECT 'pork_chop_mini' AS test,
|
|||||||
arr_date::date AS arr,
|
arr_date::date AS arr,
|
||||||
round(lambert_c3(3, 4, dep_date, arr_date)::numeric, 1) AS c3
|
round(lambert_c3(3, 4, dep_date, arr_date)::numeric, 1) AS c3
|
||||||
FROM generate_series('2026-04-01'::timestamptz, '2026-06-01'::timestamptz, interval '30 days') dep_date
|
FROM generate_series('2026-04-01'::timestamptz, '2026-06-01'::timestamptz, interval '30 days') dep_date
|
||||||
CROSS JOIN generate_series('2027-01-01'::timestamptz, '2027-03-01'::timestamptz, interval '30 days') arr_date;
|
CROSS JOIN generate_series('2027-01-01'::timestamptz, '2027-03-01'::timestamptz, interval '30 days') arr_date
|
||||||
|
ORDER BY dep_date, arr_date;
|
||||||
test | dep | arr | c3
|
test | dep | arr | c3
|
||||||
----------------+------------+------------+-------
|
----------------+------------+------------+-------
|
||||||
pork_chop_mini | 04-01-2026 | 01-01-2027 | 287.5
|
pork_chop_mini | 04-01-2026 | 01-01-2027 | 287.5
|
||||||
pork_chop_mini | 05-01-2026 | 01-01-2027 | 215.8
|
|
||||||
pork_chop_mini | 05-31-2026 | 01-01-2027 | 203.2
|
|
||||||
pork_chop_mini | 04-01-2026 | 01-31-2027 | 353.9
|
pork_chop_mini | 04-01-2026 | 01-31-2027 | 353.9
|
||||||
|
pork_chop_mini | 05-01-2026 | 01-01-2027 | 215.8
|
||||||
pork_chop_mini | 05-01-2026 | 01-31-2027 | 215.2
|
pork_chop_mini | 05-01-2026 | 01-31-2027 | 215.2
|
||||||
|
pork_chop_mini | 05-31-2026 | 01-01-2027 | 203.2
|
||||||
pork_chop_mini | 05-31-2026 | 01-31-2027 | 172.0
|
pork_chop_mini | 05-31-2026 | 01-31-2027 | 172.0
|
||||||
(6 rows)
|
(6 rows)
|
||||||
|
|
||||||
|
|||||||
92
test/pg-version-matrix.sh
Executable file
92
test/pg-version-matrix.sh
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# test/pg-version-matrix.sh — Test pg_orrery across PostgreSQL versions
|
||||||
|
#
|
||||||
|
# Uses the Dockerfile builder stage as the test engine: compile, install,
|
||||||
|
# initdb, installcheck, and standalone DE reader test for each PG version.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./test/pg-version-matrix.sh # Test PG 14-18
|
||||||
|
# PG_VERSIONS="16 17" ./test/pg-version-matrix.sh # Subset
|
||||||
|
# ./test/pg-version-matrix.sh --no-cache # Force fresh builds
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
LOG_DIR="$SCRIPT_DIR/matrix-logs"
|
||||||
|
|
||||||
|
PG_VERSIONS="${PG_VERSIONS:-14 15 16 17 18}"
|
||||||
|
|
||||||
|
# Parse flags
|
||||||
|
DOCKER_EXTRA_ARGS=()
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--no-cache) DOCKER_EXTRA_ARGS+=(--no-cache) ;;
|
||||||
|
*) echo "Unknown flag: $arg" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
|
||||||
|
# Track results: "version status seconds"
|
||||||
|
declare -a RESULTS=()
|
||||||
|
FAILURES=0
|
||||||
|
|
||||||
|
echo "pg_orrery version matrix"
|
||||||
|
echo "========================"
|
||||||
|
echo "Versions: $PG_VERSIONS"
|
||||||
|
echo "Logs: $LOG_DIR/"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
for ver in $PG_VERSIONS; do
|
||||||
|
log="$LOG_DIR/pg${ver}.log"
|
||||||
|
printf "Testing PG %-4s... " "$ver"
|
||||||
|
|
||||||
|
start=$(date +%s)
|
||||||
|
|
||||||
|
if docker build \
|
||||||
|
--build-arg PG_MAJOR="$ver" \
|
||||||
|
--target builder \
|
||||||
|
"${DOCKER_EXTRA_ARGS[@]}" \
|
||||||
|
-t "pg_orrery-test:pg${ver}" \
|
||||||
|
"$PROJECT_DIR" \
|
||||||
|
> "$log" 2>&1; then
|
||||||
|
end=$(date +%s)
|
||||||
|
elapsed=$((end - start))
|
||||||
|
printf "PASS (%ds)\n" "$elapsed"
|
||||||
|
RESULTS+=("$ver PASS $elapsed")
|
||||||
|
else
|
||||||
|
end=$(date +%s)
|
||||||
|
elapsed=$((end - start))
|
||||||
|
printf "FAIL (%ds) -> %s\n" "$elapsed" "$log"
|
||||||
|
RESULTS+=("$ver FAIL $elapsed")
|
||||||
|
FAILURES=$((FAILURES + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Summary table
|
||||||
|
echo ""
|
||||||
|
echo "Summary"
|
||||||
|
echo "-------"
|
||||||
|
printf "%-6s %-6s %s\n" "PG" "Result" "Time"
|
||||||
|
printf "%-6s %-6s %s\n" "---" "------" "----"
|
||||||
|
for entry in "${RESULTS[@]}"; do
|
||||||
|
read -r ver status secs <<< "$entry"
|
||||||
|
printf "%-6s %-6s %ds\n" "$ver" "$status" "$secs"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Cleanup test images
|
||||||
|
echo ""
|
||||||
|
echo "Cleaning test images..."
|
||||||
|
for ver in $PG_VERSIONS; do
|
||||||
|
docker rmi "pg_orrery-test:pg${ver}" >/dev/null 2>&1 || true
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$FAILURES" -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "$FAILURES version(s) failed. Check logs in $LOG_DIR/"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "All versions passed."
|
||||||
@ -98,4 +98,5 @@ SELECT 'pork_chop_mini' AS test,
|
|||||||
arr_date::date AS arr,
|
arr_date::date AS arr,
|
||||||
round(lambert_c3(3, 4, dep_date, arr_date)::numeric, 1) AS c3
|
round(lambert_c3(3, 4, dep_date, arr_date)::numeric, 1) AS c3
|
||||||
FROM generate_series('2026-04-01'::timestamptz, '2026-06-01'::timestamptz, interval '30 days') dep_date
|
FROM generate_series('2026-04-01'::timestamptz, '2026-06-01'::timestamptz, interval '30 days') dep_date
|
||||||
CROSS JOIN generate_series('2027-01-01'::timestamptz, '2027-03-01'::timestamptz, interval '30 days') arr_date;
|
CROSS JOIN generate_series('2027-01-01'::timestamptz, '2027-03-01'::timestamptz, interval '30 days') arr_date
|
||||||
|
ORDER BY dep_date, arr_date;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user