Files
lmxopcua/scripts/validation/opcua-lifecycle-memory/sdk1-comparator
Joseph Doherty fea7de0aef
v2-ci / unit-tests (push) Waiting to run
docs(evidence): #799 acceptance runs on master aa60b3e3 - Windows x64 and Linux both fail the unchanged cold RSS cap
Owner scope 2026-11-12 (Windows x64 + Linux, unchanged cycle-3 caps, >=7200 s, SDK 1.5 comparator).

- Linux ARM64 (late-slope, 7200.12 s, 1964 cycles / 491 restarts, shutdown verified, analyzer-validated):
  first rejection RSS at cycle 247 / 900.73 s, 358,682,624 > 358,678,528 (+4 KiB); peak 382.98 MiB vs
  limit 342.06 MiB; late plateau medians 344.4/341.1/341.9 MiB, OLS -1.90 MiB/h. FAIL.
- Windows x64 on windev (same workload, working set as RSS, handle table as descriptors): first rejection RSS
  at cycle 285 / 1130.76 s, 303,505,408 > 302,174,208; peak 319.49 vs limit 288.18 MiB; plateau ~314-315 MiB,
  +0.93 MiB/h. FAIL. Also incomplete: the launcher's wall-clock outer deadline fired early after a +552 s
  w32time step and ended the run at test-phase 7014 s (rejection had already latched); launchers now use a
  Stopwatch.
- SDK 1.5.378.182 comparator (efb9197a publication, Windows, 7201 s): RSS peak +65.8 MiB (never over its cap),
  plateau ~+48 MiB, but the +32 handle cap tripped at cycle 17 (max 674 vs 642).
- Managed flat on both SDK2 runs; growth is the generated-factory JIT burst (+40k/+44k methods) - Linux JIT
  doublemapper ~180 MiB; Windows private bytes grew ~25 MiB of a ~132 MiB working-set rise.
- Retained: b61f3e05 cycle-1 fixture failure (#808 unplaced UNS folder), Windows/SDK1 smoke diagnostics.

No cap raised, no warm baseline, no failed run counted as passing.

Claude-Session: https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi
2026-11-12 14:51:31 -05:00
..

SDK 1.5.378.182 comparator (lmxopcua#799)

The owner's #799 scope asks for the matched SDK 1.5 comparator numbers next to the SDK2 acceptance runs. This comparator drives the canonical workload against the immutable repaired SDK1 baseline efb9197a (includes the #807 terminal-disposal fix), published RID-specific (win-x64, framework-dependent) from that commit and referenced, never rebuilt. It is acceptance=false by construction; it is evidence for comparison only.

Sources: BaselineRig.cs, BaselineMetrics.cs, CanonicalOperations.cs, Program.cs are copies of ../baseline-canonical/ (the reviewed SDK1 port of the canonical operations, ported from the SDK2 soak at 75057d8c), with exactly these changes:

Change Why
Program.cs: the 1..4-cycle / 120 s short-smoke entry is replaced by ComparatorAsync, the late-slope loop: same cycle body, quiescent sample after every cycle, active restart every fourth cycle (25 s bound), 30 s cycle bound, 120 s startup bound, 7,200 s phase, cycle-3 cold baseline with the unchanged +64 MiB managed / +128 MiB RSS / +32 descriptor caps and a latched first rejection, then bounded shutdown checks. The canonical late-slope protocol applied to SDK1.
CanonicalOperations.cs: the held-reference zero closed-session continuation-list assertion is recorded per cycle (closedSessionPointsWhileHeld) instead of asserted; the 250 ms observation delay is removed. SDK 1.5 Session.Close keeps the lists until Dispose; the baseline-canonical README/OWNERSHIP.md show this is not the SDK1 close contract and the objects are collected once harness roots drop. Asserting it would end the comparator at cycle 1.
The 24-sample managed-monotonic guard is latched (recorded) rather than fatal. So the comparator yields numbers for the full phase even if the old SDK grows; it is not a pass/fail gate.
Steady inventories use SDK1 observables: Server/ClientCachedStoreReferences (validator cached store references) in place of SDK2 manager cached stores; no ApplicationInstance.DisposeAsync / manager-disposed checks. Not present in SDK 1.5 (reported unsupported, never as zero).
WindowsDescriptors.cs: byte-for-byte the SDK2 test's Windows descriptor observer. Same descriptor/PKI semantics as the SDK2 Windows run.
Samples also carry PrivateBytes. Descriptive.

Known non-matched elements: the comparator is a standalone self-contained executable, while the SDK2 workload runs inside the VSTest testhost (xUnit v3), so absolute RSS includes different host overhead; compare growth relative to each run's own cycle-3 baseline. OPCUA_CERTIFICATE_LEAK_TRACKING has no SDK1 equivalent.

python3 build.py --host "$sdk1HostWinX64" --client "$sdk1ClientWinX64" --assertions "$dirWithShouldly" --output "$build"
# on Windows:
powershell -NoProfile -ExecutionPolicy Bypass -File launch.ps1 -Bin "$build\publish" -Output "$run" -SourceRevision "$rev"