Closes out the field report that prompted 2026.05.08.2. Full integration suite, same commit, all green: Informix 15.0.1.0.3DE 241 / 241 Informix 14.10.FC7W1DE 241 / 241 Informix 12.10.FC12W1DE 241 / 241 Including smart-LOB. The 28-type round-trip produces byte-identical wire output on all three — same type codes, same encoded lengths, same values. There is no 12-vs-14-vs-15 wire difference for anything we support. Testing three versions by hand was tedious and undocumented, which is part of why it never happened. Now: make ifx-legacy-up 12.10 on 9089, 14.10 on 9090, alongside 15 on 9088 make ifx-legacy-setup blobspace1 + sbspace1 in both make test-matrix the suite against all three tests/setup-spaces.sh absorbs the per-image differences that made this annoying: 12.10/14.10 use a flat INFORMIXDIR while 15 nests a versioned subdirectory; ONCONFIG is named differently across images; `bash -lc` wipes INFORMIXDIR and makes every utility fail with a misleading "Unable to read $INFORMIXDIR (/usr/informix)"; and 12.10 DE ships no ontape at all (the level-0 archive turns out to be unnecessary anyway). Without blobspace1/sbspace1, ~21 tests fail with errors that look like driver bugs and aren't. The documented workflow was validated from scratch — containers removed, recreated via compose, spaces created via the script, matrix run — rather than written up afterward from whichever commands happened to work. The README claim this replaces was wrong precisely because nobody did that.
138 lines
5.6 KiB
Makefile
138 lines
5.6 KiB
Makefile
# informix-db — common dev commands
|
|
#
|
|
# uv-managed; run `make help` for the full target list.
|
|
|
|
# Image digest pinned in tests/docker-compose.yml; mirrored here for
|
|
# tab-complete-able commands like `make ifx-logs` that don't go through
|
|
# docker-compose.
|
|
IFX_CONTAINER ?= informix-db-test
|
|
|
|
.PHONY: help install lint format test test-integration test-all test-pdu \
|
|
ifx-up ifx-down ifx-logs ifx-shell ifx-status \
|
|
capture clean
|
|
|
|
help: ## Show this help
|
|
@grep -E '^[a-zA-Z_-]+:.*## ' $(MAKEFILE_LIST) \
|
|
| awk -F':.*## ' '{printf " %-20s %s\n", $$1, $$2}'
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# Python / dev workflow
|
|
# ----------------------------------------------------------------------------
|
|
|
|
install: ## Sync dev dependencies (uv sync --extra dev)
|
|
uv sync --extra dev
|
|
|
|
lint: ## Run ruff
|
|
uv run ruff check src/ tests/
|
|
|
|
format: ## Auto-format with ruff
|
|
uv run ruff format src/ tests/
|
|
uv run ruff check src/ tests/ --fix
|
|
|
|
test: ## Run unit tests (no Docker required)
|
|
uv run pytest
|
|
|
|
test-integration: ## Run integration tests (needs Informix container; see `make ifx-up`). Excludes benchmarks; use `make bench` for those.
|
|
uv run pytest -m "integration and not benchmark"
|
|
|
|
test-all: ## Run unit + integration tests (no benchmarks; use `make bench` for those)
|
|
uv run pytest -m "not benchmark"
|
|
|
|
test-pdu: ## Run only the JDBC-vs-Python PDU regression test
|
|
uv run pytest tests/test_pdu_match.py -v
|
|
|
|
bench: ## Run all benchmarks (needs container for end-to-end; codec works standalone)
|
|
uv run pytest tests/benchmarks/ -m benchmark --benchmark-only \
|
|
--benchmark-columns=median,iqr,mean,stddev,ops,rounds \
|
|
--benchmark-sort=mean
|
|
|
|
bench-codec: ## Run codec micro-benchmarks only (no container required)
|
|
uv run pytest tests/benchmarks/test_codec_perf.py -m benchmark --benchmark-only \
|
|
--benchmark-columns=median,iqr,mean,stddev,ops,rounds \
|
|
--benchmark-sort=mean
|
|
|
|
bench-save: ## Save current bench run under .results/ (manual: copy to baseline.json)
|
|
uv run pytest tests/benchmarks/ -m benchmark --benchmark-only \
|
|
--benchmark-storage=tests/benchmarks/.results \
|
|
--benchmark-save=run
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# Informix dev container
|
|
# ----------------------------------------------------------------------------
|
|
|
|
ifx-up: ## Start the Informix dev container (pinned by digest)
|
|
docker compose -f tests/docker-compose.yml up -d
|
|
@echo " Container: $(IFX_CONTAINER)"
|
|
@echo " Listener: 127.0.0.1:9088 (SQLI native)"
|
|
@echo " Login: informix / in4mix on database sysmaster"
|
|
|
|
ifx-down: ## Stop and remove the Informix container
|
|
docker compose -f tests/docker-compose.yml down
|
|
|
|
ifx-logs: ## Tail the container logs
|
|
docker logs -f $(IFX_CONTAINER)
|
|
|
|
ifx-shell: ## Drop into a shell inside the container
|
|
docker exec -it $(IFX_CONTAINER) bash
|
|
|
|
ifx-status: ## Check container health and listener readiness
|
|
@docker ps --filter name=$(IFX_CONTAINER) --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
|
|
@nc -zv 127.0.0.1 9088 2>&1 | head -1
|
|
|
|
ifx-spaces: ## Create blobspace1 + sbspace1 in the Informix 15 container (needed for LOB tests)
|
|
tests/setup-spaces.sh $(IFX_CONTAINER)
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# Server-compatibility matrix: Informix 12.10 / 14.10 alongside 15
|
|
# ----------------------------------------------------------------------------
|
|
# The legacy containers run on 9089 / 9090 so they coexist with the primary
|
|
# 15 container on 9088. The integration suite targets whichever server
|
|
# IFX_PORT names, so the matrix is just the same suite three times.
|
|
|
|
ifx-legacy-up: ## Start Informix 12.10 (9089) and 14.10 (9090) alongside 15
|
|
docker compose -f tests/docker-compose.legacy.yml up -d
|
|
@echo " 12.10 -> 127.0.0.1:9089"
|
|
@echo " 14.10 -> 127.0.0.1:9090"
|
|
@echo " Engine init takes ~1-3 min on first start; then: make ifx-legacy-setup"
|
|
|
|
ifx-legacy-setup: ## Create blobspace1 + sbspace1 in both legacy containers
|
|
tests/setup-spaces.sh informix-db-test-1210
|
|
tests/setup-spaces.sh informix-db-test-1410
|
|
|
|
ifx-legacy-down: ## Stop and remove the legacy containers
|
|
docker compose -f tests/docker-compose.legacy.yml down
|
|
|
|
test-matrix: ## Run the integration suite against 15 (9088), 14.10 (9090), and 12.10 (9089)
|
|
@echo "=== Informix 15 (9088) ==="
|
|
@IFX_PORT=9088 uv run pytest -m "integration and not benchmark" -q --no-header
|
|
@echo "=== Informix 14.10 (9090) ==="
|
|
@IFX_PORT=9090 uv run pytest -m "integration and not benchmark" -q --no-header
|
|
@echo "=== Informix 12.10 (9089) ==="
|
|
@IFX_PORT=9089 uv run pytest -m "integration and not benchmark" -q --no-header
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# Phase 0 spike: re-capture wire traffic against the dev container
|
|
# ----------------------------------------------------------------------------
|
|
|
|
capture: ## Re-capture all three reference scenarios (JDBC) under socat
|
|
@for s in connect-only select-1 dml-cycle; do \
|
|
echo "=== $$s ==="; \
|
|
socat -d -d -x TCP-LISTEN:9090,reuseaddr TCP:127.0.0.1:9088 \
|
|
2>"docs/CAPTURES/$$s.socat.log" & \
|
|
SOCAT_PID=$$!; \
|
|
sleep 0.4; \
|
|
IFX_PORT=9090 java -cp "build/ifxjdbc.jar:build/" tests.reference.RefClient $$s; \
|
|
sleep 0.3; \
|
|
kill $$SOCAT_PID 2>/dev/null; \
|
|
wait 2>/dev/null; \
|
|
echo " → docs/CAPTURES/$$s.socat.log"; \
|
|
done
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# Cleanup
|
|
# ----------------------------------------------------------------------------
|
|
|
|
clean: ## Remove build artifacts and caches (keeps captures and decompiled JDBC source)
|
|
rm -rf dist/ .pytest_cache/ .ruff_cache/ .mypy_cache/
|
|
find src tests -name __pycache__ -type d -exec rm -rf {} +
|