Commit Graph

2 Commits

Author SHA1 Message Date
Joseph Doherty
a9b585ac5b Task #253 follow-up — bidirectional + subscribe-sees-change e2e stages
The original three-stage design (probe / driver-loopback / forward-
bridge) only proved driver-write → server-read. It missed:

 - OPC UA write → server → driver → PLC (the reverse direction)
 - server-side data-change notifications actually firing (a stale
   subscription can still let a read-after-the-fact return the new
   value and look fine)

Extend _common.ps1 with two helpers:

 - Test-OpcUaWriteBridge: otopcua-cli write the NodeId -> wait 3s ->
   driver CLI read the PLC side, assert equality.
 - Test-SubscribeSeesChange: Start-Process otopcua-cli subscribe in the
   background with --duration N, settle 2s, driver-side write, wait for
   the subscription window to close, assert captured stdout contains
   the new value.

Wire both into test-modbus / test-abcip / test-ablegacy / test-s7 /
test-focas / test-twincat after the existing forward-bridge stage.
Update README to describe the five-stage design + note that the
published NodeId must be writable for stages 4 + 5.

Also prepend UTF-8 BOM to every script in scripts/e2e so Windows
PowerShell 5.1 parsers agree on em-dash byte sequences the way
PowerShell 7 already does. The scripts still #Requires -Version 7.0 —
the BOM is purely defensive for IDE / CI step parsers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 10:08:52 -04:00
Joseph Doherty
8d92e00e38 Task #253 — E2E CLI test scripts + FOCAS test-client CLI
The driver-layer integration tests confirm the driver sees the PLC, and
the Client.CLI tests confirm the client sees the server. Nothing glued
them end-to-end until this PR.

- scripts/e2e/_common.ps1: shared helpers — CLI invocation (published-
  binary OR `dotnet run` fallback), Test-Probe / Test-DriverLoopback /
  Test-ServerBridge (all return @{Passed;Reason} hashtables).
- scripts/e2e/test-<modbus|abcip|ablegacy|s7|focas|twincat>.ps1: per-
  driver three-stage script (probe → driver-loopback → server-bridge).
  AB Legacy / FOCAS / TwinCAT are gated behind *_TRUST_WIRE env vars
  since they need real hardware (#222) or a licensed runtime (#221).
- scripts/e2e/test-phase7-virtualtags.ps1: writes a Modbus HR, reads
  the server-side VirtualTag (VT = input * 2) back via OPC UA, triggers
  + clears a scripted alarm. Exercises the Phase 7 CachedTagUpstreamSource
  + ScriptedAlarmEngine path.
- scripts/e2e/test-all.ps1: reads e2e-config.json sidecar, runs each
  present driver, prints a FINAL MATRIX (PASS/FAIL/SKIP). Missing
  sections SKIP rather than fail hard.
- scripts/e2e/e2e-config.sample.json: commented sample — each dev's
  NodeIds are local-seed-specific so e2e-config.json is .gitignore-d.
- scripts/e2e/README.md: full walkthrough — prereqs, three-stage design,
  env-var gates, expected matrix, why this is separate from `dotnet test`.

Tasks #249-#251 shipped Modbus/AbCip/AbLegacy/S7/TwinCAT CLIs but left
FOCAS out. Since test-focas.ps1 needs it, the 6th CLI ships here:

- src/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Cli: probe/read/write/subscribe
  commands, AssemblyName `otopcua-focas-cli`. WriteCommand.ParseValue
  handles the full FocasDataType enum (Bit/Byte/Int16/Int32/Float32/
  Float64/String — no UInt variants; the FOCAS protocol exposes signed
  PMC + Fanuc-Float only). Default DataType is Int16 to match the PMC
  register convention.

Full-solution build clean (0 errors). FOCAS CLI wired into
ZB.MOM.WW.OtOpcUa.slnx. No .Tests project for the FOCAS CLI yet —
symmetric with how ProbeCommand has no unit-testable pure logic in the
other 5 CLIs either; WriteCommand.ParseValue parity will land in a
follow-up to keep this PR scoped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 09:51:13 -04:00