docs(reviews): record driver fixture + H1 gates (lmxopcua#761)
v2-ci / unit-tests (push) Has been cancelled
v2-ci / unit-tests (push) Has been cancelled
Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
@@ -212,3 +212,52 @@ hold.
|
|||||||
- Every gate edit was reverted in the ConfigDb: `HR101` deleted; `e1` name restored; `gateE-spin`/`spinvt` deleted;
|
- Every gate edit was reverted in the ConfigDb: `HR101` deleted; `e1` name restored; `gateE-spin`/`spinvt` deleted;
|
||||||
both driver configs restored. A clean-up deploy, `cd41a890`, sealed 6 of 6.
|
both driver configs restored. A clean-up deploy, `cd41a890`, sealed 6 of 6.
|
||||||
- Both centrals were restarted afterwards to clear the gate-E orphan thread.
|
- Both centrals were restarted afterwards to clear the gate-E orphan thread.
|
||||||
|
|
||||||
|
## Driver fixture gates + H1 (2026-11-09, commit 1b9c36f3, fixture host 10.100.0.35)
|
||||||
|
|
||||||
|
### Fixture gates, lmxopcua#761 (driver fixtures + H1)
|
||||||
|
|
||||||
|
Date: 2026-11-09. Commit tested: `1b9c36f3` (origin/master), worktree `scratchpad/wt/otopc-fix` (branch w18/fixtures, nothing committed). Release builds, 0 errors. Nothing posted to Gitea.
|
||||||
|
|
||||||
|
Fixture host 10.100.0.35: `lmxopcua-fix` does not exist on macOS (CLAUDE.md says to use ssh). Every needed fixture was already running, so nothing was started or stopped there. State before and after was identical (modbus-standard, ab-server-controllogix, python-snap7-s7_1500, opc-plc, mosquitto + sparkplug-sim + mqtt-publisher, sql-pg/oracle/blackhole, otopcua-mssql). Pre-existing: `otopcua-opc-plc` reports "unhealthy" (before and after; the opcuaclient suite still passed). `otopcua-sql-blackhole` showed "unhealthy" briefly right after the blackhole pause/unpause test, then "healthy" again.
|
||||||
|
|
||||||
|
## Driver fixture gates
|
||||||
|
|
||||||
|
| Gate | Command (from worktree) | Result |
|
||||||
|
|---|---|---|
|
||||||
|
| modbus standard | `dotnet test tests/Drivers/*Modbus.IntegrationTests -c Release` (default endpoint 10.100.0.35:5020, profile standard) | PASS: 12 passed, 0 failed, 32 skipped. Skips are the other profiles only (exception_injection 11, mitsubishi 7, dl205 ~11, s7_1500 4). They are not valid on the standard profile. Standard round-trip and AddressingGrammar ran. |
|
||||||
|
| s7 s7_1500 | `S7_SIM_ALLOW_WRITES=1 dotnet test tests/Drivers/*S7.IntegrationTests` | PASS: 23 passed, 0 failed, 3 skipped. Without the writes env var: 20 passed and 6 skipped. The 3 remaining skips: TM/CT address limit of python-snap7, and two destructive tests (`S7_RECONNECT_BOUNCE_CMD`, `S7_TIMEOUT_OUTAGE_*_CMD`) not run so the shared sim is not bounced. |
|
||||||
|
| abcip controllogix | `AB_SERVER_ALLOW_WRITES=1 AB_DIFF_ENDPOINT=10.100.0.35:44818 dotnet test tests/Drivers/*AbCip.IntegrationTests` | PASS with one flake: 33 passed, 1 failed, 22 skipped (about 2 min). Failure: `PollLatencyComparisonTests.Native_poll_p95_is_within_ten_percent_of_libplctag` raised `DifferentialAbortedException` ("Connection reset by peer" on tag UdtSeg.Ready). Rerun of that class: 2/2 passed. Verdict: flake (ab_server connection reset, aborts on first connection-level failure by design). Skips: 6 need `AB_SERVER_PROFILE=emulate` (Logix Emulate), 1 needs `AB_HW_WRITE_GATEWAY` (hardware), 15 are the remaining differential and write tests. Without writes env: 28 passed, 0 failed, 28 skipped. |
|
||||||
|
| opcuaclient opc-plc | `dotnet test tests/Drivers/*OpcUaClient.IntegrationTests` (opc.tcp://10.100.0.35:50000) | PASS: 5 passed, 0 skipped. |
|
||||||
|
| mqtt + sparkplug | `MQTT_FIXTURE_ENDPOINT=10.100.0.35:8883 MQTT_FIXTURE_PLAIN_ENDPOINT=10.100.0.35:1883 MQTT_FIXTURE_USERNAME=otopcua MQTT_FIXTURE_PASSWORD=<from publisher container env> MQTT_FIXTURE_CA_CERT=<scp'd ca.crt> dotnet test tests/Drivers/*Mqtt.IntegrationTests` | PASS: 30 passed, 0 skipped (includes Sparkplug, simulator running). |
|
||||||
|
| sql | `SQL_TEST_ENDPOINT=10.100.0.35,14330 SQL_TEST_PASSWORD=.. SQL_PG_ENDPOINT=10.100.0.35:15432 SQL_PG_PASSWORD=.. SQL_ORACLE_ENDPOINT=10.100.0.35:11521 SQL_ORACLE_PASSWORD=.. SQL_BLACKHOLE_ENDPOINT=10.100.0.35,14333 SQL_BLACKHOLE_PASSWORD=.. SQL_BLACKHOLE_DOCKER_SSH=dohertj2@10.100.0.35 dotnet test tests/Drivers/*Sql.IntegrationTests` | PASS: 37 passed, 0 failed, 17 skipped. SQL Server, Postgres, Oracle and the blackhole timeout test ran. Skips: 14 MySQL (no MySQL fixture on the host) and 3 ODBC (no `SQL_ODBC_CONNECTION_STRING`). |
|
||||||
|
|
||||||
|
Side effect: the SQL suite creates (and never drops, by design) database `SqlPollFixture` on `otopcua-mssql`. It was already there before (listed in sys.databases).
|
||||||
|
|
||||||
|
## H1 (#736) historian year-window gate
|
||||||
|
|
||||||
|
There was no pre-existing year-window fixture test. The existing fixture suites test the cap at 3 rows, and the 10k fuzz is offline in `OpcUaServer.Tests`. I added an uncommitted probe, `tests/Drivers/Historian.Conformance/YearWindowGateProbe.cs`, with a subclass in each backend's integration project (edits are only in the throwaway worktree). It seeds one tag with 52,560 samples spanning 365 days, with `maxRawValuesPerRead` = 10,000.
|
||||||
|
|
||||||
|
- It checks that an N=0 read of the whole year is refused with `HistoryReadLimitExceededException` (Limit=10000), not returned unbounded and not truncated.
|
||||||
|
- It walks the window in 10k-capped pages, resuming after the last timestamp, and checks every page is at most 10000.
|
||||||
|
- It checks the concatenated pages equal the seeded set (no loss, no duplicates, ordered), and that peak process working set stays under 500 MB.
|
||||||
|
|
||||||
|
| Backend | Where | Result |
|
||||||
|
|---|---|---|
|
||||||
|
| QuestDb | local throwaway container `h1-gate-questdb` (`questdb/questdb:10.0.1`, ports 28812/29000; removed afterwards) | PASS: N=0 refused, limit 10000; 6 pages, max page 10000, 52,560 rows walked, no loss or duplicates; peak working set 122 MB (managed 27 MB). Full QuestDb integration project: 234 passed, 0 failed, 1 skipped (opt-in `HISTORIAN_QUESTDB_STRESS_SECONDS` stress test). |
|
||||||
|
| SqlServer | throwaway DB `OtOpcUaHistorian_T_*` on `otopcua-mssql` (the fixture creates and drops it; no orphan left) | PASS: same numbers. 6 pages, max 10000, 52,560 rows walked; peak working set 114 MB (managed 18 MB). Full SqlServer integration project: 196 passed, 0 failed, 0 skipped. |
|
||||||
|
| Server half: continuation point at N=0 | offline: `dotnet test tests/Server/*OpcUaServer.Tests --filter RawPageLimit/HistoryRead/MaxReturnDataValues/HistoryServerCapabilities` | PASS: 431 passed, 0 failed (includes the paged-vs-unpaged raw cap fuzz and the MaxReturnDataValues advertisement). |
|
||||||
|
|
||||||
|
Scope caveat: the probe drives the backend `IHistorianDataSource` directly, not a live OPC UA HistoryRead through the server node manager. The backend side is proven live: bounded at 10k, N=0 refused, pages complete. The continuation point itself is the server's `RawPageLimit` planning, covered by the offline tests above, not by a live OPC UA session. A true end-to-end gate (OPC UA client reading a year at N=0 against a server on the SqlServer/QuestDb backend) needs the docker-dev rig, which I was told not to use.
|
||||||
|
|
||||||
|
Mishap: two aborted SQL Server probe attempts (row-by-row seeding was too slow, so I killed them) each left a throwaway `OtOpcUaHistorian_T_*` database on `otopcua-mssql`. Both were dropped manually. The final check shows no `OtOpcUaHistorian*` databases remain.
|
||||||
|
|
||||||
|
## NOT RUN
|
||||||
|
|
||||||
|
- Hardware userGates (real PLCs): AbCip / AbLegacy / TwinCAT array writes, FOCAS `MACRO:` > 32767, AbCip probe-typo recovery.
|
||||||
|
- docker-dev gates A, B, C, D, E, and the Galaxy gate F: not in scope. The otopcua-dev rig is off-limits, and F needs mxaccessgw.
|
||||||
|
- Modbus exception_injection / dl205 / mitsubishi / s7_1500 profiles (only `standard` requested); S7 reconnect-bounce and connect-timeout-outage destructive tests; AbCip Logix Emulate profile; Sql MySQL and ODBC (no fixture).
|
||||||
|
|
||||||
|
## Cleanup
|
||||||
|
|
||||||
|
Container `h1-gate-questdb` removed. The fixture host is unchanged. The worktree `scratchpad/wt/otopc-fix` (branch w18/fixtures) is left in place with uncommitted probe edits. Remove it with `git worktree remove --force` if not wanted.
|
||||||
|
|||||||
Reference in New Issue
Block a user