Files
lmxopcua/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/LogixProject
Joseph Doherty a25593a9c6 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>
2026-05-17 01:55:28 -04:00
..

Logix Emulate project stub

This folder holds the Studio 5000 project that Logix Emulate loads when running the Emulate-tier integration tests (tests/.../AbCip.IntegrationTests/Emulate/*.cs, gated on AB_SERVER_PROFILE=emulate).

Status today: stub. The actual .L5X export isn't committed yet; once the Emulate PC is running + a project with the required state exists, export to L5X + drop it here as OtOpcUaAbCipFixture.L5X.

Why L5X, not .ACD

Studio 5000 ships two save formats: .ACD (binary, the runtime project) and .L5X (XML export). Ship the L5X because:

  • Text format — reviewable in PR diffs, diffable in git
  • Reproducible import across Studio 5000 versions
  • Doesn't carry per-installation state (license watermarks, revision history)

Reconstruction workflow: Studio 5000 → open project → File → Save As → .L5X. On a fresh Emulate install: File → Open → select the L5X → it rebuilds the ACD from the XML.

Required project state

The Emulate-tier tests rely on this exact tag / UDT set. Missing any of these makes the dependent test fail loudly (TagNotFound, wrong value, wrong type), not skip silently — Emulate is a tier above the Docker simulator; operators who opted into it get opt-in-level coverage expectations.

UDT definitions

UDT name Members Notes
Motor_UDT Speed : DINT, Torque : REAL, Status : DINT Matches AbCipUdtMemberLayoutTests declared-layout golden. Member order fixed — Logix Template Object offsets depend on it

Controller tags

Tag Type Seed value Purpose
Motor1 Motor_UDT {Speed=1800, Torque=42.5, Status=0x0001} AbCipEmulateUdtReadTests.WholeUdt_read_decodes_each_member_at_its_Template_Object_offset
HighTempAlarm ALMD default ALMD config, In tied to SimulateAlarm bit AbCipEmulateAlmdTests.Real_ALMD_raise_fires_OnAlarmEvent_through_the_driver_projection
SimulateAlarm BOOL 0 Operator-writable bit the ladder routes into HighTempAlarm.In — gives the test a clean way to drive the alarm edge without scripting Emulate directly

Program structure

  • One periodic task MainTask @ 100 ms
  • One program MainProgram
  • One routine MainRoutine (Ladder) with a single rung: XIC SimulateAlarm OTE HighTempAlarm.In

That's enough ladder for SimulateAlarm := 1 to raise the alarm + for SimulateAlarm := 0 to clear it.

Tier-level behaviours this project enables

Coverage the existing Dockerized ab_server fixture can't produce — each verified by an Emulate/*Tests.cs class gated on AB_SERVER_PROFILE=emulate:

  • CIP Template Object round-trip — real Logix template bytes, reads produce the same offset layout the CIP Symbol Object decoder + AbCipUdtMemberLayout expect.
  • ALMD rising-edge semantics — real Logix ALMD instruction fires InFaulted / Acked transitions at cycle boundaries, not at our unit-test fake's timer boundaries.
  • Optimized vs unoptimized DB behaviour — Logix 5380/5580 series runs the Studio 5000 project with optimized-DB-equivalent member access; the driver's read path exercises that wire surface.

Not in scope even with Emulate — needs real hardware:

  • EtherNet/IP embedded-switch behaviour (Stratix 5700, 1756-EN4TR)
  • CIP Safety across partitions (Emulate 5580 emulates safety within the chassis but not across nodes)
  • Redundant chassis failover (1756-RM)
  • Motion control timing
  • High-speed discrete-input scheduling

How to run the Emulate-tier tests

On the dev box:

$env:AB_SERVER_PROFILE  = 'emulate'
$env:AB_SERVER_ENDPOINT = '10.0.0.42:44818'   # replace with the Emulate PC IP
dotnet test tests\ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests

With AB_SERVER_PROFILE unset or abserver, the Emulate/*Tests.cs classes skip cleanly; ab_server-backed tests run as usual.

See also