test(abcip): Emulate-tier nested-UDT live-gate smoke + docs (backlog #6)
Add AbCipEmulateNestedUdtTests (skip-gated, AB_SERVER_PROFILE=emulate) to close the live-gate gap for nested-struct UDT discovery via CIP Template Object (class 0x6C) threaded by commits 3d8ce4e8/d203f31c. Compiles + skips cleanly against ab_server (no CIP Template Object service). Update docs/drivers/AbCip.md nested-struct section to record the shipped decode path, the Emulate-only live-gate, and offline unit coverage.
This commit is contained in:
+17
-7
@@ -132,13 +132,23 @@ Variables — in addition to the UDT container tag itself.
|
||||
separate Variable node under the UDT's `Discovered/` sub-folder, addressable by its member
|
||||
path (e.g. `MyUdt.Temperature`, `MyUdt.Flags`). Top-level atomic member discovery is
|
||||
**functional in production**.
|
||||
- **Nested struct members** — when a UDT member is itself a struct, the driver walks into it up
|
||||
to a **depth cap of 8 levels**. Nested-struct expansion is a **documented deferral in
|
||||
production**: the Template Object member block carries no nested template ID, so the
|
||||
sub-shape cannot be re-fetched from the controller at discovery time. Nested struct leaves are
|
||||
never mis-emitted — they are simply dropped (the parent member is omitted from discovery if it
|
||||
is not atomic and its sub-shape is unavailable). Use pre-declared `Members` for nested structs
|
||||
that must be individually addressed.
|
||||
- **Nested struct members** — **shipped** (commits 3d8ce4e8 / d203f31c). When a UDT member is
|
||||
itself a struct, the Template Object member block carries the nested UDT's template instance ID
|
||||
in the low 12 bits of the member `info` field (struct flag `0x8000` set). The driver captures
|
||||
this as `AbCipUdtMember.NestedTemplateId` and threads it into a second `FetchUdtShapeAsync`
|
||||
call (`@udt/{id}`) so the nested struct's atomic leaves are expanded into dot-joined addressable
|
||||
paths (e.g. `Motor1.Status.Code`, `Motor1.Status.Running`). Recursion is bounded by a
|
||||
**depth cap of 8 levels**; members at or beyond the cap are dropped rather than emitted.
|
||||
Nested struct leaves that resolve to no emittable atomic leaf produce no sub-folder (lazy
|
||||
materialisation).
|
||||
|
||||
**Live verification is Emulate-tier only** (`AB_SERVER_PROFILE=emulate` + a Logix Emulate
|
||||
instance): `ab_server` (the default Docker simulator) does not implement the CIP Template
|
||||
Object service (class 0x6C), so the nested-id fetch cannot be exercised against it.
|
||||
See `tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/Emulate/AbCipEmulateNestedUdtTests.cs`
|
||||
for the skip-gated live-gate smoke (backlog #6). Offline unit coverage lives in
|
||||
`AbCipDriverDiscoveryTests.Controller_discovered_UDT_nested_struct_expands_via_nested_template_id_fetch_no_seam`
|
||||
and `CipTemplateObjectDecoderTests`.
|
||||
|
||||
### Bare-container reads
|
||||
|
||||
|
||||
Reference in New Issue
Block a user