Task #253 — E2E CLI test scripts + FOCAS test-client CLI #207

Merged
dohertj2 merged 1 commits from task-253-e2e-cli-test-scripts into v2 2026-04-21 09:58:36 -04:00
Owner

Summary

  • scripts/e2e/ — PowerShell 7 e2e test suite that drives each protocol through its driver CLI + verifies the OPC UA server republishes the change via otopcua-cli
  • src/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Cli — sixth driver CLI (completes the symmetric set; #249-#251 landed the other five)

Design

Per-driver script runs three stages:

  1. probe — driver CLI confirms the PLC/simulator is reachable
  2. driver loopback — write random value, read back, assert equality (driver-only path)
  3. server bridge — write via driver CLI, wait 3s, read the OPC UA NodeId via otopcua-cli (full path: driver → PLC → server → client)

Modbus / AB CIP / S7 / Phase 7 run on public simulators. AB Legacy / FOCAS / TwinCAT are gated behind *_TRUST_WIRE=1 env vars since they need real hardware (#222) or a licensed runtime (#221).

The runner reads a sidecar e2e-config.json (gitignored — per-dev NodeIds). Sample + README included.

FOCAS CLI

Mirrors the other 5 driver CLIs. WriteCommand.ParseValue covers the full FocasDataType enum (Bit / Byte / Int16 / Int32 / Float32 / Float64 / String — FOCAS PMC + Fanuc-Float are signed-only, no UInt variants). Wired into ZB.MOM.WW.OtOpcUa.slnx.

Test plan

  • dotnet build ZB.MOM.WW.OtOpcUa.slnx — 0 errors (warnings only — pre-existing xUnit1051 noise)
  • End-to-end run with Modbus + AB CIP simulators up (manual — dev-box-local)
  • Phase 7 bridge run against a server with VT_DoubledHR100 seeded
## Summary - `scripts/e2e/` — PowerShell 7 e2e test suite that drives each protocol through its driver CLI + verifies the OPC UA server republishes the change via `otopcua-cli` - `src/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Cli` — sixth driver CLI (completes the symmetric set; #249-#251 landed the other five) ## Design Per-driver script runs three stages: 1. `probe` — driver CLI confirms the PLC/simulator is reachable 2. driver loopback — write random value, read back, assert equality (driver-only path) 3. server bridge — write via driver CLI, wait 3s, read the OPC UA NodeId via `otopcua-cli` (full path: driver → PLC → server → client) Modbus / AB CIP / S7 / Phase 7 run on public simulators. AB Legacy / FOCAS / TwinCAT are gated behind `*_TRUST_WIRE=1` env vars since they need real hardware (#222) or a licensed runtime (#221). The runner reads a sidecar `e2e-config.json` (gitignored — per-dev NodeIds). Sample + README included. ## FOCAS CLI Mirrors the other 5 driver CLIs. `WriteCommand.ParseValue` covers the full `FocasDataType` enum (Bit / Byte / Int16 / Int32 / Float32 / Float64 / String — FOCAS PMC + Fanuc-Float are signed-only, no UInt variants). Wired into `ZB.MOM.WW.OtOpcUa.slnx`. ## Test plan - [x] `dotnet build ZB.MOM.WW.OtOpcUa.slnx` — 0 errors (warnings only — pre-existing xUnit1051 noise) - [ ] End-to-end run with Modbus + AB CIP simulators up (manual — dev-box-local) - [ ] Phase 7 bridge run against a server with VT_DoubledHR100 seeded
dohertj2 added 1 commit 2026-04-21 09:58:25 -04:00
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>
dohertj2 merged commit 097f92fdb8 into v2 2026-04-21 09:58:36 -04:00
dohertj2 deleted branch task-253-e2e-cli-test-scripts 2026-04-21 09:58:37 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#207