test(abcip): differential stops on first connection failure, paces + caps requests, reserves array/UDT slots, fails vacuous template parity; write tests opt-in (Task 18 review r1)
This commit is contained in:
@@ -118,6 +118,73 @@ fresh Forward Open) per tag: 9+ sessions, which the netstat sampling showed. The
|
||||
on `@tags` for its whole duration, which mirrors the native anchor lease. That leaves the one-session
|
||||
capture above.
|
||||
|
||||
### Review round 1 re-run (press-safety fixes)
|
||||
|
||||
Re-run 2026-10-07 after the review-r1 fixes, with the default pacing. `AB_SERVER_ENDPOINT=127.0.0.1:1`
|
||||
kept the sibling suites' discovery probes off the network:
|
||||
|
||||
```bash
|
||||
AB_SERVER_ENDPOINT=127.0.0.1:1 AB_DIFF_ENDPOINT=10.100.0.35:44818 AB_DIFF_COUNT_OPENS=1 \
|
||||
dotnet test tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests \
|
||||
--filter "FullyQualifiedName~Differential" --logger "console;verbosity=detailed"
|
||||
```
|
||||
|
||||
**Result: 12/12 passed — 7 live tests and 5 offline safety tests — with 0 unexpected and 0 expected divergences.**
|
||||
|
||||
| Check | Result |
|
||||
|---|---|
|
||||
| Settings | pace 20 ms, max tags 200, max templates 50 |
|
||||
| Browse | 9 = 9 |
|
||||
| Selection (array round-robin first) | 1 array + 8 scalars. ab_server has no UDTs, so there were no UDT members and the coverage check had nothing to require |
|
||||
| Reads | 9/9 equal |
|
||||
| Templates | 0 ids, not truncated. Not vacuous by the new rule: ab_server's `STRING` is not a structure, so browse found no structured tags |
|
||||
| Native Forward Opens | **1** |
|
||||
| TCP connections to the target before native | 0 (baseline 0) |
|
||||
|
||||
**Wire capture of this run** (tcpdump in the ab_server container's namespace, decoded with tshark):
|
||||
|
||||
| TCP stream | Session | Forward Open | Forward Close | Requests | Window (s) |
|
||||
|---|---|---|---|---|---|
|
||||
| 0 | libplctag | 1 (Large, 0x5B) | 1 | 1× 0x55, 18× 0x52 | 0.000 → 0.487 |
|
||||
| 1 | native | 1 (0x54) | 1 | 1× 0x55, 18× 0x52 | 0.510 → 0.984 |
|
||||
|
||||
- No discovery probes.
|
||||
- Zero write services: no 0x4D, 0x53, 0x4B or 0x10.
|
||||
- The two sessions are 23 ms apart and do not overlap.
|
||||
|
||||
**The Forward Opens differ between the transports, and that is expected.** libplctag always uses a *Large*
|
||||
Forward Open. Native uses a regular one because the `CompactLogix` profile's connection size (504) is at most 511. Task 21 will
|
||||
see the same split on the press.
|
||||
|
||||
**What changed for press safety (review r1):**
|
||||
|
||||
- **Stop on the first connection-level failure, on either transport.** That covers a refused connect,
|
||||
RegisterSession or Forward Open, a timeout, and a lost session. Any status other than
|
||||
NotFound/NotAllowed/OutOfBounds/TooLarge/TooSmall/Unsupported/TypeMismatch aborts the whole run with the
|
||||
failing operation and status. Nothing is retried.
|
||||
- **The native phase is capped at one open attempt.** It sets the new process-wide
|
||||
`CipConnection.OpenAttemptBudget`, so a reconnect cannot reach the wire at all, even from inside an
|
||||
enumerator that swallows a per-program failure.
|
||||
- **The run also aborts the moment `ForwardOpenCount` passes 1.** This is checked after every browse entry,
|
||||
template and tag.
|
||||
- **Offline pin:** against a loopback listener that accepts and hangs up, the native phase aborts at browse after exactly
|
||||
**one** TCP connect. Removing the harness abort turns the test red. Removing both the abort and the budget
|
||||
turns the connect count red.
|
||||
- **Pacing:** `AB_DIFF_PACE_MS` (default 20) is applied before every harness-issued request: browse,
|
||||
each template read, each tag's create-read and read. Listing *pages* inside the enumerators are not
|
||||
paced.
|
||||
- **Volume caps:** `AB_DIFF_MAX_TEMPLATES` defaults to 50. `AB_DIFF_MAX_TAGS` and `AB_DIFF_MAX_TEMPLATES` must be at most 500;
|
||||
a higher value fails fast instead of being clamped.
|
||||
- **Selection:** the default selection takes arrays (up to 20), UDT members (up to 20) and scalars round-robin, so any cap
|
||||
of 3 or more exercises all three kinds. The reads test fails if browse offered arrays or UDT members
|
||||
but the selection holds none.
|
||||
- **Template parity** fails when browse found structured tags but no template id was compared, and treats an
|
||||
undecodable shape on either side as a mismatch.
|
||||
- **Write-capable integration tests** now require `AB_SERVER_ALLOW_WRITES=1` and refuse while
|
||||
`AB_DIFF_ENDPOINT` is set. Those tests are the Logix Emulate ALMD test and the AbLegacy SLC500 N7:5 round trip.
|
||||
The ab_server controllogix matrix is read-only and unaffected: 15 passed and 11 skipped with
|
||||
`AB_SERVER_COMPOSE_PROFILE=controllogix`.
|
||||
|
||||
## AdminUI /run (T19)
|
||||
|
||||
_(pending)_
|
||||
|
||||
Reference in New Issue
Block a user