Skip to content

test(interop): required cross-vendor typed-data CI gate (Cyclone + Fast DDS) - #36

Closed
SandraK82 wants to merge 4 commits into
mainfrom
codex/issue28-interop-ci
Closed

test(interop): required cross-vendor typed-data CI gate (Cyclone + Fast DDS)#36
SandraK82 wants to merge 4 commits into
mainfrom
codex/issue28-interop-ci

Conversation

@SandraK82

Copy link
Copy Markdown
Contributor

Draft toward closing #28. Builds on #29 (interop/cyclone-xtypes-27/) as prior foundation.

Base

main @ 80663c06a87b629dfdcee8b5ba42201a971e104d (Merge PR #35 — the #27 multi-locator work; verified present: Vec<Locator> participant locators, if-addrs).

Missing gate this addresses

The repo's cross-vendor interop is manual/gated (#29 is opt-in and Cyclone-only) or SPDP-discovery-only with floating latest images. There is no required public CI cell that exchanges typed user data with the open-source vendors in both directions.

What this adds — tests/interop/ci/

A vendor-agnostic runner that, per vendor and per direction, exchanges typed Robot samples over live DDS/RTPS and asserts endpoint match AND decoded sample delivery (SPDP discovery alone is never a pass).

  • interop_result.py — pure classifier: counts → PASS / EXPECTED_NEGATIVE / PRODUCT_FAIL / TIMEOUT / SETUP_FAIL (distinguishes an expected-negative from a product bug, a timeout and a setup failure).
  • run_vendor.sh — orchestrates every cell: unique DDS domain per cell, exact-PID cleanup trap (never a broad pkill), bounded timeouts, <vendor>-result.json + human summary.
  • lib.sh — shared exact-PID cleanup (unit tested).
  • install_cyclone.sh / install_fastdds.shpinned vendor installs (no latest); official packages/releases.
  • fastdds/ — Fast DDS Robot pub/sub client, type generated by Fast-DDS-Gen from robot.idl.
  • .github/workflows/ci.yml — two jobs: interop-harness (vendor-free classifier/cleanup/shellcheck) and interop (matrix cyclone,fastdds, fail-fast: false, artifacts if: always()).

The ZeroDDS reader/writer and Cyclone Python client are reused from #29, parameterised by ZERODDS_DOMAIN for per-cell isolation (default 100 keeps the #29 matrix intact).

Required matrix

CycloneDDS and Fast DDS, both directions, typed samples > 0, decode errors = 0 on the forward leg. CycloneDDS retains the #29 XTypes cases including the visible final-vs-appendable XCDR2 negative case (matched + zero decoded + decode errors surfaced via take()), not a silent timeout.

Validation

Portable layers, run locally on macOS (green):

  • python -m pytest tests/interop/ci/tests/test_interop_result.py -q → 16 passed.
  • bash tests/interop/ci/tests/test_cleanup.sh → exact-PID cleanup spares an unrelated process.
  • bash tests/interop/ci/run_vendor.sh fastdds <out> with the client absent → single SETUP_FAIL cell, result.json, exit 1.
  • shellcheck -S warning clean; rustfmt --check clean; yaml.safe_load OK.

Vendor-live cells (CycloneDDS + Fast DDS typed exchange, both directions) run on the hosted Linux CI in this PR — this host is macOS and cannot run the Linux vendor stacks, so per the contribution rules the public CI run is the evidence. This PR is a draft until those cells are green; the deliberate zero-sample mutation check will be exercised before it is marked ready.

Non-goals

RTI Connext in required CI, the full vendor×vendor matrix, DDS Security / SHM / TCP / TSN / WAN / soak / latency benchmarking, and fixing unrelated interop defects found while building the gate (filed separately).

Compatibility

No production/library code changes. The only edits outside tests/interop/ci/ make the #29 interop reader/writer and Cyclone client honour ZERODDS_DOMAIN (default 100) — behaviour-preserving.

Refs #28. Prior foundation: #29.

Adds tests/interop/ci/: a vendor-agnostic runner that exchanges typed
Robot samples over live DDS/RTPS between ZeroDDS and CycloneDDS / Fast DDS
in both directions, asserting endpoint match AND decoded delivery (SPDP
discovery alone is never a pass). The classifier distinguishes PASS,
EXPECTED_NEGATIVE, PRODUCT_FAIL, TIMEOUT and SETUP_FAIL; machine-readable
JSON + human summary + always-uploaded per-cell logs.

- Pinned vendor installs (install_cyclone.sh / install_fastdds.sh); no
  floating latest images.
- CycloneDDS cells retain the #29 XTypes semantics incl. the visible
  final-vs-appendable negative case.
- Fast DDS client (fastdds_robot) generated from robot.idl by Fast-DDS-Gen.
- Harness self-tests (classifier, exact-PID cleanup) run vendor-free in
  the interop-harness job.
- ZeroDDS reader/writer + Cyclone client reused from #29, domain
  parameterised via ZERODDS_DOMAIN for per-cell isolation.

Base main 80663c0. Vendor-live cells are validated by the public Linux CI
in this PR.
Neither vendor is apt-installable on the hosted ubuntu-24.04 runner
("Unable to locate package libcyclonedds-dev") and eProsima publishes no
binary GitHub release asset, so both are now built from pinned git tags:
CycloneDDS 0.10.5 (+ matching cyclonedds-python 0.10.5), Fast CDR v2.2.4 +
Fast DDS v3.1.0 (bundled foonathan_memory) + Fast-DDS-Gen v4.0.1.
Deterministic, no floating latest, no unverified installer.
…y for Fast DDS (Refs #28)

- The ZeroDDS interop reader/writer domain must be i32 (DomainParticipantFactory::create_participant takes DomainId = i32); the ZERODDS_DOMAIN parse used u32 and failed to compile (E0308), turning every Cyclone cell into SETUP_FAIL.
- Fast DDS: build foonathan_memory_vendor + Fast CDR as separate pinned installs instead of -DTHIRDPARTY (a --depth 1 clone has no submodules, so find_package(foonathan_memory) failed).
…#28)

The all-core Fast DDS source build (XTypes/TypeObject TUs are memory-heavy)
peaked past the hosted-runner limit and the runner was SIGTERM'd twice at
~54% (exit 143) on the unchanged SHA — a resource limit, not transient infra.
Cap the build to 2 jobs (CMAKE_BUILD_PARALLEL_LEVEL + gradle --max-workers)
so the peak fits, add actions/cache keyed on the pinned versions so the stack
builds once, and set a 60-minute job timeout for a clean failure mode.
Cyclone cell is already green (both directions + the #29 XTypes cases).
@SandraK82 SandraK82 closed this Aug 3, 2026
@SandraK82
SandraK82 deleted the codex/issue28-interop-ci branch August 3, 2026 20:49
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.

1 participant