chore: organize solution into module folders (Core/Server/Drivers/Client/Tooling)
Group all 69 projects into category subfolders under src/ and tests/ so the Rider Solution Explorer mirrors the module structure. Folders: Core, Server, Drivers (with a nested Driver CLIs subfolder), Client, Tooling. - Move every project folder on disk with git mv (history preserved as renames). - Recompute relative paths in 57 .csproj files: cross-category ProjectReferences, the lib/ HintPath+None refs in Driver.Historian.Wonderware, and the external mxaccessgw refs in Driver.Galaxy and its test project. - Rebuild ZB.MOM.WW.OtOpcUa.slnx with nested solution folders. - Re-prefix project paths in functional scripts (e2e, compliance, smoke SQL, integration, install). Build green (0 errors); unit tests pass. Docs left for a separate pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
# FOCAS Docker simulator — focas-mock + shim DLL
|
||||
|
||||
Hardware-free FOCAS fixture for OtOpcUa's integration test matrix. Runs
|
||||
the vendored [`focas-mock`](focas-mock/VENDORED.md) Python server under
|
||||
Docker and pairs it with the [shim DLL](../Shim/VENDORED.md) that
|
||||
masquerades as `Fwlib64.dll` inside the .NET test process.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌────────────────────────────┐ cnc_allclibhndl3 / cnc_rdparam / ...
|
||||
│ xunit test process │ (P/Invoke, __stdcall)
|
||||
│ ├── Driver.FOCAS │
|
||||
│ │ └── FwlibNative.cs ─┼─┐
|
||||
│ └── FocasSimFixture │ │ resolves to...
|
||||
└────────────────────────────┘ │
|
||||
▼
|
||||
┌────────────────────────────┐
|
||||
│ Fwlib64.dll (shim) │ JSON over TCP
|
||||
│ tests/.../Shim/focas_ │──────────────────────┐
|
||||
│ shim.c compiled here │ │
|
||||
└────────────────────────────┘ │
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ focas-mock (Docker) │
|
||||
│ python:3.11-slim │
|
||||
│ profile-aware responses │
|
||||
│ mock_load_profile / │
|
||||
│ mock_patch admin methods │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
The shim bridges the binary ABI (C `__stdcall` exports with FOCAS struct
|
||||
shapes) to the mock's newline-delimited JSON protocol. OtOpcUa's
|
||||
`FocasSimFixture` seeds per-test state by sending `mock_load_profile` +
|
||||
`mock_patch` admin calls on the same socket. Tests assert the managed
|
||||
driver sees the seeded values through its normal P/Invoke path.
|
||||
|
||||
## Running
|
||||
|
||||
Pick one compose profile (they all publish 8193 — only one at a time):
|
||||
|
||||
```powershell
|
||||
docker compose -f Docker/docker-compose.yml --profile thirtyone up -d
|
||||
dotnet test tests/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests
|
||||
docker compose -f Docker/docker-compose.yml --profile thirtyone down
|
||||
```
|
||||
|
||||
Available profiles + their focas-mock target:
|
||||
|
||||
| compose --profile | focas-mock profile | Covers |
|
||||
|---|---|---|
|
||||
| `thirtyone` / `thirty` / `thirtytwo` | `fwlib30i64` | 30i / 31i / 32i series |
|
||||
| `sixteen` | `FWLIB64` | 16i / 18i / 21i legacy family |
|
||||
| `zerod` / `zerof` / `zeromf` / `zerotf` | `fwlib0iD64` | 0i-D / 0i-F / 0i-MF / 0i-TF |
|
||||
| `powermotion` | `fwlib0DN64` | Power Motion i |
|
||||
| `ethernet` | `fwlibe64` | Ethernet-variant DLL |
|
||||
| `ncguide` | `fwlibNCG64` | NC Guide PC simulator |
|
||||
|
||||
## What this covers — and what it doesn't
|
||||
|
||||
**Covered:**
|
||||
|
||||
- All 10 FOCAS functions `FwlibNative.cs` P/Invokes
|
||||
- Read-after-write round-trip for parameters, macros, PMC ranges
|
||||
- PMC bit read-modify-write path (via the `pmc_wrpmcrng` seam)
|
||||
- `IAlarmSource` raise + clear transitions (via `mock_schedule_alarms`)
|
||||
- Per-series profile selection — tests can pin one and assert series-gated
|
||||
behaviour
|
||||
|
||||
**Not covered** (still hardware-gated):
|
||||
|
||||
- Real FOCAS2 TCP wire protocol (this is a JSON mock; the shim hides
|
||||
the real protocol entirely)
|
||||
- CNC-specific firmware quirks (position scaling across power cycles,
|
||||
edit-mode session locks, MTB custom screens)
|
||||
- Concurrent-read behaviour on the real `Fwlib64.dll` — the shim is
|
||||
single-threaded per connection
|
||||
|
||||
See [`docs/drivers/FOCAS-Test-Fixture.md`](../../../docs/drivers/FOCAS-Test-Fixture.md)
|
||||
for the full coverage map.
|
||||
|
||||
## Skip behaviour
|
||||
|
||||
`FocasSimFixture` probes the mock at collection init time:
|
||||
|
||||
- Mock unreachable → tests skip with the compose-up command to run
|
||||
- Mock reachable but shim DLL not loaded → tests skip with a pointer
|
||||
at `Shim/build.ps1`
|
||||
- Both available → tests run
|
||||
|
||||
This lets the same test assembly be green on a fresh CI box without
|
||||
docker, green on a dev box with just the docker compose up, and
|
||||
exercise the full wire path when the shim is built.
|
||||
Reference in New Issue
Block a user