Files
secs-gem/interop/secs4j_validate.sh
T
raphael b30443089f
tests / build-and-test (push) Successful in 2m54s
tests / thread-sanitizer (push) Successful in 3m48s
tests / tshark-dissector (push) Successful in 2m24s
tests / secs4j-interop (push) Successful in 1m44s
tests / python-interop (push) Successful in 3m10s
tests / libfuzzer (push) Successful in 3m38s
feat(clients)+test(interop): C++ client + Java validation of the daemon (B7)
B7 — the daemon's HSMS face under the Java reference: Dockerfile.server now
bakes secs_gemd alongside secs_server (grpc deps in both stages), and
secs4j_validate.sh gains TARGET=gemd to point the 55-check secs4java8 suite
at the daemon instead. Result: 55/55 green. With secsgem-py already
validating both faces, byte-identical GEM between secs_server and secs_gemd
is now proven by both reference implementations, not inferred from shared
code. CI runs the daemon target as an extra step (image layers shared).

Second client — clients/cpp: a header-only C++ twin of the Python client
over the same proto. eq.set("ChamberPressure", 2.5) with bare literals
(integral/floating dispatch avoids variant ambiguity), get/fire/alarm/
clear, control_state/request_control_state/health, on("START", fn) +
listen()/listen_async()/stop() with auto-CompleteCommand, SecsGemError
carrying the daemon's message. cpp_mini_tool (~30 lines) mirrors the
Python mini_tool. Tested end-to-end over real loopback TCP against the
service inside secs_gemd_tests — now 4 cases / 141 assertions — including
set/get round-trips, error text, alarm-by-name into the model, health,
and the full HCACK-4 command loop with parameters.

(Build note: two grpc-heavy TUs at -O3 OOM even at -j2 on Docker Desktop;
built -j1. Known environment limitation, roadmap-documented.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 23:37:14 +02:00

76 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Orchestrate the secs4java8 interop harness against our C++ server.
#
# Builds a self-contained C++ server image (interop/Dockerfile.server)
# and the Java harness image (interop/secs4j/Dockerfile), spins both
# up on a dedicated docker network, and runs the harness against the
# server. No bind mounts — important under docker-in-docker (gitea-
# act / GitHub Actions runners with a mounted /var/run/docker.sock),
# where bind-mount sources don't resolve against the daemon's host
# filesystem. Wired into CI via .gitea/workflows/ci.yml.
#
# Usage: bash interop/secs4j_validate.sh
# TARGET=gemd bash interop/secs4j_validate.sh
# -> runs the same 55 checks against secs_gemd's HSMS face
# (the daemon must be byte-identical GEM to secs_server,
# since both sit on register_default_handlers).
# Exit codes:
# 0 — every check the harness defines passed
# 1 — one or more checks failed
# 2 — script / orchestration error
set -euo pipefail
cd "$(dirname "$0")/.."
NET=secs4j-interop-net
SERVER_NAME=secs4j-interop-server
cleanup() {
docker rm -f "$SERVER_NAME" >/dev/null 2>&1 || true
docker network rm "$NET" >/dev/null 2>&1 || true
}
trap cleanup EXIT
# Build both images (idempotent — docker reuses layers). Errors are
# NOT swallowed: an early failure here is the most informative signal
# we get when something breaks in CI.
echo "building secs_server image..."
docker build -t secsgem-secs4j-server -f interop/Dockerfile.server .
echo "building secs4j harness image..."
docker build -t secsgem-secs4j-interop -f interop/secs4j/Dockerfile interop/secs4j
# Fresh network each run so we don't collide with a leftover from a
# previous failed invocation.
docker network rm "$NET" >/dev/null 2>&1 || true
docker network create "$NET" >/dev/null
echo "starting ${TARGET:-server} (secs4j peer)..."
# --name doubles as the DNS hostname on the user-defined network, so
# the harness reaches it as "secs4j-interop-server:5000".
if [ "${TARGET:-server}" = "gemd" ]; then
docker run -d --rm \
--name "$SERVER_NAME" \
--network "$NET" \
--entrypoint /usr/local/bin/secs_gemd \
secsgem-secs4j-server \
--port 5000 --grpc 0.0.0.0:50051 --config-dir /app/data >/dev/null
else
docker run -d --rm \
--name "$SERVER_NAME" \
--network "$NET" \
secsgem-secs4j-server >/dev/null
fi
# Give the server a moment to bind.
sleep 1
echo "running Secs4jHostHarness..."
docker run --rm \
--network "$NET" \
secsgem-secs4j-interop \
java -cp /opt/secs4java8/Export.jar:/work Secs4jHostHarness \
"$SERVER_NAME" 5000
# trap handles teardown.