# FOCAS test fixture Coverage map + gap inventory for the FANUC FOCAS2 CNC driver. **TL;DR: there is no integration fixture.** Every test uses a `FakeFocasClient` injected via `IFocasClientFactory`. Fanuc's FOCAS library (`Fwlib32.dll`) is closed-source proprietary with no public simulator; CNC-side behavior is trusted from field deployments. ## What the fixture is Nothing at the integration layer. `tests/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/` is unit-only. The driver ships as Tier C (process-isolated) per `docs/v2/driver-stability.md` because the FANUC DLL has known crash modes; tests can't replicate those in-process. ## What it actually covers (unit only) - `FocasCapabilityTests` — data-type mapping (PMC bit / word / float, macro variable types, parameter types) - `FocasCapabilityMatrixTests` — per-CNC-series range validation (macro / parameter / PMC letter + number) across 16i / 0i-D / 0i-F / 30i / PowerMotion. See [`docs/v2/focas-version-matrix.md`](../v2/focas-version-matrix.md) for the authoritative matrix. 46 theory cases lock every documented range boundary — widening a range without updating the doc fails a test. - `FocasReadWriteTests` — read + write against the fake, FOCAS native status → OPC UA StatusCode mapping - `FocasScaffoldingTests` — `IDriver` lifecycle + multi-device routing - `FocasPmcBitRmwTests` — PMC bit read-modify-write synchronization (per-byte `SemaphoreSlim`, mirrors the AB / Modbus pattern from #181) - `FwlibNativeHelperTests` — `Focas32.dll` → `Fwlib32.dll` bridge validation + P/Invoke signature validation Capability surfaces whose contract is verified: `IDriver`, `IReadable`, `IWritable`, `ITagDiscovery`, `ISubscribable`, `IHostConnectivityProbe`, `IPerCallHostResolver`. Pre-flight validation runs in `FocasDriver.InitializeAsync` — configs referencing out-of-range addresses fail at load time with a diagnostic message naming the CNC series + documented limit. This closes the cheap half of the hardware-free stability gap; Tier-C process isolation (task #220) closes the expensive half — see [`docs/v2/implementation/focas-isolation-plan.md`](../v2/implementation/focas-isolation-plan.md). ## What it does NOT cover ### 1. FOCAS wire traffic No FOCAS TCP frame is sent. `Fwlib32.dll`'s TCP-to-FANUC-gateway exchange is closed-source; the driver trusts the P/Invoke layer per #193. Real CNC correctness is trusted from field deployments. ### 2. Alarm / parameter-change callbacks FOCAS has no push model — the driver polls via the shared `PollGroupEngine`. There are no CNC-initiated callbacks to test; the absence is by design. ### 3. Macro / ladder variable types FANUC has CNC-specific extensions (macro variables `#100-#999`, system variables `#1000-#5000`, PMC timers / counters / keep-relays) whose per-address semantics differ across 0i-F / 30i / 31i / 32i Series. Driver covers the common address shapes; per-model quirks are not stressed. ### 4. Model-specific behavior - Alarm retention across power cycles (model-specific CNC behavior) - Parameter range enforcement (CNC rejects out-of-range writes) - MTB (machine tool builder) custom screens that expose non-standard data ### 5. Tier-C process isolation — architecture shipped, Fwlib32 integration hardware-gated The Tier-C architecture is now in place as of PRs #169–#173 (FOCAS PR A–E, task #220): - `Driver.FOCAS.Shared` carries MessagePack IPC contracts - `Driver.FOCAS.Host` (.NET 4.8 x86 Windows service via NSSM) accepts a connection on a strictly-ACL'd named pipe + dispatches frames to an `IFocasBackend` - `Driver.FOCAS.Ipc.IpcFocasClient` implements the `IFocasClient` DI seam by forwarding over IPC — swap the DI registration and the driver runs Tier-C with zero other changes - `Driver.FOCAS.Supervisor.FocasHostSupervisor` owns the spawn + heartbeat + respawn + 3-in-5min crash-loop breaker + sticky alert - `Driver.FOCAS.Host.Stability.PostMortemMmf` ↔ `Driver.FOCAS.Supervisor.PostMortemReader` — ring-buffer of the last ~1000 IPC operations survives a Host crash The one remaining gap is the production `FwlibHostedBackend`: an `IFocasBackend` implementation that wraps the licensed `Fwlib32.dll` P/Invoke. That's hardware-gated on task #222 — we need a CNC on the bench (or the licensed FANUC developer kit DLL with a test harness) to validate it. Until then, the Host ships `FakeFocasBackend` + `UnconfiguredFocasBackend`. Setting `OTOPCUA_FOCAS_BACKEND=fake` lets operators smoke-test the whole Tier-C pipeline end-to-end without any CNC. ## When to trust FOCAS tests, when to reach for a rig | Question | Unit tests | Real CNC | | --- | --- | --- | | "Does PMC address `R100.3` route to the right bit?" | yes | yes | | "Does the FANUC status → OPC UA StatusCode map cover every documented code?" | yes (contract) | yes | | "Does a real read against a 30i Series return correct bytes?" | no | yes (required) | | "Does `Fwlib32.dll` crash on concurrent reads?" | no | yes (stress) | | "Do macro variables round-trip across power cycles?" | no | yes (required) | ## Follow-up candidates 1. **Nothing public** — Fanuc's FOCAS Developer Kit ships an emulator DLL but it's under NDA + tied to licensed dev-kit installations; can't redistribute for CI. 2. **Lab rig** — used FANUC 0i-F simulator controller (or a retired machine tool) on a dedicated network; only path that covers real CNC behavior. 3. **Process isolation first** — before trusting FOCAS in production at scale, shipping the Tier-C out-of-process Host architecture (similar to Galaxy) is higher value than a CI simulator. ## Key fixture / config files - `tests/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FakeFocasClient.cs` — in-process fake implementing `IFocasClient` - `tests/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasCapabilityMatrixTests.cs` — parameterized theories locking the per-series matrix - `src/ZB.MOM.WW.OtOpcUa.Driver.FOCAS/FocasDriver.cs` — ctor takes `IFocasClientFactory` - `src/ZB.MOM.WW.OtOpcUa.Driver.FOCAS/FocasCapabilityMatrix.cs` — per-CNC-series range validator (the matrix the doc describes) - `docs/v2/focas-version-matrix.md` — authoritative range reference - `docs/v2/implementation/focas-isolation-plan.md` — Tier-C isolation plan (task #220) - `docs/v2/driver-stability.md` — Tier C scope + process-isolation rationale