Skip to content

Contract test suite (3/5): UDA tier - #97

Open
olivhoenen wants to merge 17 commits into
split85/2-contract-mdsplusfrom
split85/3-contract-uda
Open

olivhoenen wants to merge 17 commits into
split85/2-contract-mdsplusfrom
split85/3-contract-uda

Conversation

@olivhoenen

Copy link
Copy Markdown
Collaborator

Part of the split of #85 (Tests and Benchmarks for regression) into smaller, single-purpose PRs that are easier to review.

Adds the UDA contract-test tier against a Docker reference stack (docker/uda): smoke round trip, read-only parity over the equilibrium seed, parity breadth, and the UDA-specific surface (cache modes, runtime DD loading, datapath, fetch mode, remote write/delete). It also adds the non-blocking uda-contract CI workflow and the ./test dispatcher with its make targets. Tests, tooling and CI only.

Fork history: issues yohannmarguier#20 – yohannmarguier#29, fork PR yohannmarguier#30.

Stack position: 3/9; depends on #96.

Authorship: these commits are @yohannmarguier's, cherry-picked unchanged from his fork with git cherry-pick -x, so each one keeps its original author, date and message plus a (cherry picked from commit …) link back to the fork. Only conflicts with current develop and with the new commit order were resolved.

⚠️ Please merge with "Create a merge commit" or "Rebase and merge", not "Squash and merge": squashing would attribute Yohann's commits to the person who merges.

🤖 Generated with Claude Code

)

Subtask 1 of the UDA characterization baseline (PRD #21): the time-boxed
feasibility spike. Stands up the pinned UDA reference stack and proves one
end-to-end smoke round trip through the public C ABI.

- docker/uda/: aarch64 image (UDA server 2.9.3 + IDSDef.xml DD 4.1.1 +
  UDA-Plugins 1.8.0 source + xinetd) plus run.sh, which builds IMAS-Core
  (HDF5 + UDA backends) from the mounted workspace, builds + registers the
  IMAS server plugin against that core (failing loudly on the NO_IMAS
  mapping-only degradation), starts uda_server, and runs the UDA tier.
  Mirrors the MDSplus leg's toolchain-image + build-workspace-at-runtime
  pattern so tests exercise the source under review.
- tests/contract/test_uda.cpp: read-only tracer bullet -- a scalar seeded
  via the plain HDF5 backend reads back byte-identical through the UDA
  backend in remote mode. Build-gated (AL_CONTRACT_HAVE_UDA) and
  runtime-skipped when UDA_HOST is unset -- absent/skipped, never failed.
- CMake gate + dedicated 'uda' ctest label; UDA runtime-skip macro and
  remote-URI helper in al_contract.h.

Gate: FULL-STACK TIER CONFIRMED (smoke passes; fallback not invoked).
Open items answered empirically and recorded in docker/uda/README.md
(IDSDef.xml lookup + absent/missing errors, remote-write 'Unknown function
requested!' surface, plugin version 1.8.0, pinned stack identifiers;
fetch-mode cache semantics documented from source with deferral rationale).

(cherry picked from commit 82e03aa)
One verb over the three tiers: ./test common (host-native HDF5/memory/ASCII/
flexbuffers), ./test mdsplus and ./test uda (their Docker legs), and ./test all.
Makefile targets (test-common/test-mdsplus/test-uda/test) delegate to it.

Coherent reporting: every tier prints the same section header + PASS/FAIL(elapsed)
line; ./test all runs all tiers even if one fails, prints a summary table, and
exits non-zero if any failed. TTY-aware colour, stripped when piped. Auto-builds
the Docker images on first use; both legs bind-mount the repo so tests exercise
the working copy. PLATFORM overridable for x86 clusters.

(cherry picked from commit 7e0ee7c)
Broadens the scalar tracer bullet (#23) to the full equilibrium-seed
composite (scalar + timebase-carrying 2-D array + constraints AOS),
reusing the seed's own generator and FNV-1a hash oracle unchanged.

Run against the docker/uda/ reference stack (UDA server 2.9.3, IMAS
plugin 1.8.0, DD 4.1.1): the composite is a genuine divergence, the
same wall MDSplus hits on EquilibriumSeedMatrix/Mdsplus -- UDA
resolves every remote path against the DD schema, and the seed's flat
profiles_1d/psi leaf + generic constraints AOS have no counterpart in
equilibrium's real DD-4.1.1 layout. The test still runs the
seed-then-reopen attempt every time and asserts the specific failure
signature before GTEST_SKIP()'ing, so a future fix would fail loudly
rather than the row silently going stale.

Adds TRACEABILITY.md Part 5 with the pinned reference-stack header
and the tracer-bullet + parity-fixture verdict rows.

(cherry picked from commit edb1938)
…_paths/pulse-modes/slice-timerange (issue #25)

Extends the UDA read-only parity fixture (issue #24) until every C-ABI-reachable
read-side capability from FUNCTIONALITY_INVENTORY Part 1 has a UDA verdict,
closing TRACEABILITY.md Part 5 to zero blank rows:

- test_uda_real_paths.cpp: reuses issue #15's curated real-DD-4.1.1
  {CHAR,INTEGER,DOUBLE,COMPLEX} x rank path set as-is, adapted to UDA's
  seed(HDF5)-then-reopen(UDA) shape. 15 cells covered, 13 terminal-gap
  (unchanged DD facts), 1 divergence (CHAR r0 reproduces the pre-existing
  HDF5 CHAR-scalar crash during fixture seeding, not a new UDA finding).

- test_uda_breadth.cpp: AOS traversal, al_get_occurrences, al_list_filled_paths,
  pulse open-mode/error-behavior parity, and slice/time-range reads, all
  seed(HDF5)-then-reopen(UDA).

Two genuine new defects found and pinned (xfail: correct-contract DISABLED_ +
current-behavior tripwire, never fixed per D2):
  1. A *dynamic* (time-varying) DD leaf nested inside a struct_array comes
     back empty/absent through UDA remote mode + backend=hdf5 instead of
     what was written (UdaAosKnownDefects; also affects real-path matrix
     cells COMPLEX_r1/r3/r5, which cite the same pin via known_defect_reason
     rather than duplicating it).
  2. al_begin_timerange_action's OperationContext constructor never
     initializes the base interpmode member (only time_range.interpolation_method),
     silently harmless on every backend that ignores getInterpmode() for
     TIMERANGE_OP -- except UDA's remote readData() directive-builder, which
     reads it unconditionally and throws "unknown interp mode: <garbage>"
     (UdaSliceAndTimeRange).

Also corrected two working assumptions once run against the real reference
stack: UDA's OPEN_PULSE genuinely round-trips to the server at open time
(fails cleanly on an absent remote pulse, matching on-disk-backend parity),
and reading an unwritten leaf on a seeded IDS returns the HDF5 absent-scalar
sentinel with code==0, transparently forwarded, not an error.

Verified: ctest -L uda -> 42/42 (2 intentionally Disabled correct-contract
pairs, rest covered/skipped as designed); full ctest -> 291/291 passing
against docker/uda/'s pinned reference stack (UDA 2.9.3, IMAS plugin 1.8.0,
DD 4.1.1).

(cherry picked from commit 2314b2a)
Code review of issue #25's commit found the real-path matrix section
mis-stated the cell count as 34; test_uda_real_paths.cpp and
test_mdsplus_real_paths.cpp both actually carry 32 cells (4 types x 8
ranks), which the path/rank/aos_chain values already matched field-for-
field. Fixing the count keeps the traceability doc accurate as an audit
trail.

(cherry picked from commit b4282ff)
… negotiation (issue #26)

Adds test_uda_unique_surface.cpp characterizing six areas through the
public C ABI against the docker/uda/ reference stack: URI option surface
(cache_mode/verbose/plugin/init_args/dd_version/host-port), cache-mode
invisibility (none/ids/struct), runtime DD loading (present/absent/
wrong-version, backed by a second pinned DD 3.42.0 in the Docker image),
datapath partial-get via cache_mode=ids, version-drift check inertness,
and the server-version-gated supportsTimeRangeOperation(). Found and
pinned (xfail, not fixed) a genuine server-side pulse-handle leak on
close, caused by readData/populate_cache building their IMAS::get() uri
without stripping cache_mode/verbose the way open/close do.

TRACEABILITY.md Part 5 gains a terminal-status row for every area.

(cherry picked from commit ef1e973)
…, remote write/delete pins (issue #27)

Second half of the UDA-unique-surface tier (sibling of #26): fetch mode's
download/handoff/cache-reuse, local_cache override, the stale-cache
write-divergence pin, and remote write/delete pinned behavior, all driven
against the real reference stack (docker/uda/). One new genuine defect
discovered and pinned (DISABLED_/tripwire): remote write silently reports
success without persisting, unlike remote delete's clean refusal. Also
corrects docker/uda/README.md's unverified spike assumption that the BYTES
plugin wasn't registered on the reference image -- it is, by default.

(cherry picked from commit 623cf17)
…ssue #28)

Audited Part 5 against issue #28's acceptance criteria: zero blank rows,
every row at a terminal status, every xfail's DISABLED_/tripwire pair
present in test_uda_breadth.cpp/test_uda_unique_surface.cpp, every
divergence explained in prose, and the pinned reference stack matching
docker/uda/ verbatim — all already true from issues #25/#26/#27. The one
gap: Part 1/Part 2's shared always-on rows had no "UDA: see Part 5" note
mirroring their existing "MDSplus: see Part 4" convention (added by issue
mirroring Part 4's own issue-#18 closure paragraph.

(cherry picked from commit c00552d)
Mirrors mdsplus-contract.yml: caches the docker/uda/ reference-stack
image across pushes, verifies its pinned stack identifiers against
TRACEABILITY.md Part 5's header, then runs the UDA contract tier via
run.sh. continue-on-error keeps it informational now that issue #28
has triaged the whole baseline to terminal statuses.

(cherry picked from commit d73f134)
(cherry picked from commit e4911ec)
(cherry picked from commit 5165a13)
(cherry picked from commit 09bb450)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants