ci(questdb): CI keeps its throwaway QuestDB but reads the image pin from the shared fixture's compose file (#841)

Decision: CI stays hermetic (no dependency on the 10.100.0.35 box or its
state), but must run the same engine. integration-fixtures.sh now takes the
questdb/questdb:<tag> line from the #822 fixture compose file (10.0.1 today,
same as the docker-dev overlay) and fails 'up' if it is missing;
CI_QDB_IMAGE overrides for a trial. Documented in scripts/ci/README.md.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-11-11 03:50:12 -05:00
parent 7095e128e3
commit c3cf11c5e4
2 changed files with 23 additions and 2 deletions
+9 -1
View File
@@ -70,7 +70,15 @@ Neither touches `v2-ci.yml`; each has its own concurrency group (`lmxopcua-v2-in
QuestDB and opc-plc — plus a port-NAT opc-plc (`otopcua-ci-opcplc-nat`, host 50110 → 50000, private `.invalid`
advertised host, `OPCUA_NAT_ENDPOINT`, #813) — (`otopcua-ci-*`, non-default host ports), exports the env vars the fixtures read, and
`down` removes them. It uses plain `docker run`, not `services:` (act_runner support is undocumented and
Postgres needs a seed step); the only runner requirement is a docker daemon. Runs the Sql, Historian.SqlServer,
Postgres needs a seed step); the only runner requirement is a docker daemon.
**QuestDB is a throwaway container by decision (#841), not the shared `/opt/otopcua-questdb` fixture (#822):** CI stays
hermetic — no dependency on the 10.100.0.35 box, no state left by a developer's runs, nothing a concurrent CI job can
share. What must not differ is the engine, so `integration-fixtures.sh` reads the image tag from the shared fixture's
compose file (`tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.IntegrationTests/Docker/docker-compose.yml`,
currently `questdb/questdb:10.0.1`, the same pin as `docker-dev/docker-compose.questdb.yml`) instead of hard-coding
one, and fails `up` if that line is missing. Upgrade QuestDB by bumping the compose file (and the docker-dev overlay);
`CI_QDB_IMAGE` overrides the image for a one-off trial. Both run QuestDB's defaults (incl.
`cairo.ttl.use.wall.clock=true`, which the historian relies on). Runs the Sql, Historian.SqlServer,
Historian.QuestDb, OpcUaClient and OpcUaClient.Browser `*.IntegrationTests` with `MIN_EXECUTED=440`.
Local run: 468 executed / 8 skipped (Oracle x2, the blackhole `docker pause` gate, one QuestDB stress test,
4 others), about 4.5 min of test time, QuestDB the longest (~3.3 min). Not covered (no pullable image or
+14 -1
View File
@@ -29,6 +29,18 @@ SA_PASSWORD="${CI_SA_PASSWORD:-Ci_throwaway_Pw1}"
PG_PASSWORD="${CI_PG_PASSWORD:-Ci_throwaway_pg1}"
NAMES=(otopcua-ci-mssql otopcua-ci-pg otopcua-ci-questdb otopcua-ci-opcplc otopcua-ci-opcplc-nat)
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# #841: CI keeps its OWN throwaway QuestDB (hermetic — never the shared /opt/otopcua-questdb fixture), but runs the
# SAME image the shared fixture's compose file pins, read from that file so the two cannot drift. CI_QDB_IMAGE
# overrides it only to trial an upgrade.
QDB_COMPOSE="$ROOT/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.IntegrationTests/Docker/docker-compose.yml"
questdb_image() {
if [ -n "${CI_QDB_IMAGE:-}" ]; then echo "$CI_QDB_IMAGE"; return; fi
local img
img="$(sed -n 's/^[[:space:]]*image:[[:space:]]*\(questdb\/questdb:[^[:space:]]*\).*/\1/p' "$QDB_COMPOSE" | head -n 1)"
if [ -z "$img" ]; then echo "no questdb/questdb:<tag> image line in $QDB_COMPOSE" >&2; return 1; fi
echo "$img"
}
fixture_host() {
if [ -n "${FIXTURE_HOST:-}" ]; then echo "$FIXTURE_HOST"; return; fi
@@ -52,6 +64,7 @@ wait_for() { # <description> <timeout-seconds> <command...>
up() {
command -v docker >/dev/null || { echo "docker not available" >&2; exit 1; }
local qdb_image; qdb_image="$(questdb_image)"
down
docker run -d --name otopcua-ci-mssql -e ACCEPT_EULA=Y -e MSSQL_PID=Developer \
-e "MSSQL_SA_PASSWORD=$SA_PASSWORD" -p "$SQL_PORT:1433" \
@@ -59,7 +72,7 @@ up() {
docker run -d --name otopcua-ci-pg -e "POSTGRES_PASSWORD=$PG_PASSWORD" -e POSTGRES_DB=sqlpollfixture \
-p "$PG_PORT:5432" postgres:17-alpine >/dev/null
docker run -d --name otopcua-ci-questdb -p "$QDB_PORT:8812" -p "$QDB_HTTP_PORT:9000" \
questdb/questdb:10.0.1 >/dev/null
"$qdb_image" >/dev/null
docker run -d --name otopcua-ci-opcplc -p "$OPC_PORT:$OPC_PORT" \
mcr.microsoft.com/iotedge/opc-plc:2.14.10 --pn="$OPC_PORT" --ut --aa --alm >/dev/null
# Mirrors tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/Docker/nat/docker-compose.yml.