Seven-stage e2e script covering every Galaxy-specific capability surface:
IReadable + IWritable + ISubscribable + IAlarmSource + IHistoryProvider.
Unlike the other drivers there is no per-protocol CLI — Galaxy's proxy
lives in-process with the server + talks to OtOpcUaGalaxyHost over a
named pipe (MXAccess COM is 32-bit-only), so every stage runs through
`otopcua-cli` against the published OPC UA address space.
## Stages
1. Probe — otopcua-cli read on the source NodeId
2. Source read — capture value for downstream comparison
3. Virtual-tag bridge — Phase 7 VirtualTag (source × 2) through
CachedTagUpstreamSource
4. Subscribe-sees-change — data-change events propagate
5. Reverse bridge — opc-ua write → Galaxy; soft-passes if the
attribute's Galaxy-side ACL forbids writes
(`BadUserAccessDenied` / `BadNotWritable`)
6. Alarm fires — scripted-alarm Condition fires with Active
state when source crosses threshold
7. History read — historyread returns samples from the Aveva
Historian → IHistoryProvider path
## Two new helpers in _common.ps1
- `Test-AlarmFiresOnThreshold` — start `otopcua-cli alarms --refresh`
in the background on a Condition NodeId, drive the source change,
assert captured stdout contains `ALARM` + `Active`. Uses the same
Start-Process + temp-file pattern as `Test-SubscribeSeesChange` since
the alarms command runs until Ctrl+C (no built-in --duration).
- `Test-HistoryHasSamples` — call `otopcua-cli historyread` over a
configurable lookback window, parse `N values returned.` marker, fail
if below MinSamples. Works for driver-sourced, virtual, or scripted-
alarm historized nodes.
## Wiring
- `test-all.ps1` picks up the optional `galaxy` sidecar section and
runs the script with the configured NodeIds + wait windows.
- `e2e-config.sample.json` adds a `galaxy` section seeded with the
Phase 7 defaults (`p7-smoke-tag-source` / `-vt-derived` /
`-al-overtemp`) — matches `scripts/smoke/seed-phase-7-smoke.sql`.
- `scripts/e2e/README.md` expected-matrix gains a Galaxy row.
## Prereqs
- OtOpcUaGalaxyHost running (NSSM-wrapped) with the Galaxy + MXAccess
runtime available
- `seed-phase-7-smoke.sql` applied with a live Galaxy attribute
substituted into `dbo.Tag.TagConfig`
- OtOpcUa server running against the `p7-smoke` cluster
- Non-elevated shell (Galaxy.Host pipe ACL denies Admins)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
71 lines
3.4 KiB
JSON
71 lines
3.4 KiB
JSON
{
|
|
"$comment": "Copy this file to e2e-config.json and replace the NodeIds with the ones your Config DB publishes. Fields named `opcUaUrl` override the -OpcUaUrl parameter on test-all.ps1 per-driver. Omit a top-level key to skip that driver.",
|
|
|
|
"modbus": {
|
|
"$comment": "Port 5020 matches tests/.../Modbus.IntegrationTests/Docker/docker-compose.yml — `docker compose --profile standard up -d`.",
|
|
"endpoint": "127.0.0.1:5020",
|
|
"bridgeNodeId": "ns=2;s=Modbus/HR200",
|
|
"opcUaUrl": "opc.tcp://localhost:4840"
|
|
},
|
|
|
|
"abcip": {
|
|
"$comment": "ab_server listens on port 44818 (default CIP/EIP). `docker compose --profile controllogix up -d`.",
|
|
"gateway": "ab://127.0.0.1:44818/1,0",
|
|
"family": "ControlLogix",
|
|
"tagPath": "TestDINT",
|
|
"bridgeNodeId": "ns=2;s=AbCip/TestDINT"
|
|
},
|
|
|
|
"ablegacy": {
|
|
"$comment": "Works against ab_server --profile slc500 (Docker fixture) or real SLC/MicroLogix/PLC-5 hardware. `/1,0` cip-path is required for the Docker fixture; real hardware accepts an empty path — e.g. `ab://10.0.1.50:44818/`.",
|
|
"gateway": "ab://127.0.0.1/1,0",
|
|
"plcType": "Slc500",
|
|
"address": "N7:5",
|
|
"bridgeNodeId": "ns=2;s=AbLegacy/N7_5"
|
|
},
|
|
|
|
"s7": {
|
|
"$comment": "Port 1102 matches tests/.../S7.IntegrationTests/Docker/docker-compose.yml (python-snap7 needs non-priv port). `docker compose --profile s7_1500 up -d`. Real S7 PLCs listen on 102.",
|
|
"endpoint": "127.0.0.1:1102",
|
|
"cpu": "S71500",
|
|
"slot": 0,
|
|
"address": "DB1.DBW0",
|
|
"bridgeNodeId": "ns=2;s=S7/DB1_DBW0"
|
|
},
|
|
|
|
"focas": {
|
|
"$comment": "Gated behind FOCAS_TRUST_WIRE=1 — no public simulator. Point at a real CNC + ensure Fwlib32.dll is on PATH.",
|
|
"host": "192.168.1.20",
|
|
"port": 8193,
|
|
"address": "R100",
|
|
"bridgeNodeId": "ns=2;s=Focas/R100"
|
|
},
|
|
|
|
"twincat": {
|
|
"$comment": "Gated behind TWINCAT_TRUST_WIRE=1 — needs XAR or standalone TwinCAT Router NuGet reachable at -AmsNetId.",
|
|
"amsNetId": "127.0.0.1.1.1",
|
|
"amsPort": 851,
|
|
"symbolPath": "MAIN.iCounter",
|
|
"bridgeNodeId": "ns=2;s=TwinCAT/MAIN_iCounter"
|
|
},
|
|
|
|
"galaxy": {
|
|
"$comment": "Galaxy (MXAccess) driver. Has no per-driver CLI — all stages go through otopcua-cli against the published NodeIds. Seven stages: probe / source read / virtual-tag bridge / subscribe-sees-change / reverse write / alarm fires / history read. Requires OtOpcUaGalaxyHost running + seed-phase-7-smoke.sql applied with a real Galaxy attribute substituted into dbo.Tag.TagConfig.",
|
|
"sourceNodeId": "ns=2;s=p7-smoke-tag-source",
|
|
"virtualNodeId": "ns=2;s=p7-smoke-vt-derived",
|
|
"alarmNodeId": "ns=2;s=p7-smoke-al-overtemp",
|
|
"alarmTriggerValue": "75",
|
|
"changeWaitSec": 10,
|
|
"alarmWaitSec": 10,
|
|
"historyLookbackSec": 3600
|
|
},
|
|
|
|
"phase7": {
|
|
"$comment": "Virtual tags + scripted alarms. The VirtualNodeId must resolve to a server-side virtual tag whose script reads the modbus InputNodeId and writes VT = input * 2. The AlarmNodeId is the ConditionId of a scripted alarm that fires when VT > 100.",
|
|
"modbusEndpoint": "127.0.0.1:5502",
|
|
"inputNodeId": "ns=2;s=Modbus/HR100",
|
|
"virtualNodeId": "ns=2;s=Virtual/VT_DoubledHR100",
|
|
"alarmNodeId": "ns=2;s=Alarm/HR100_High"
|
|
}
|
|
}
|