Skip to content

test(hybrid): golden-file end-to-end tests#59

Merged
gilesknap merged 4 commits into
mainfrom
hybrid-e2e-golden-tests
Jun 15, 2026
Merged

test(hybrid): golden-file end-to-end tests#59
gilesknap merged 4 commits into
mainfrom
hybrid-e2e-golden-tests

Conversation

@gilesknap

@gilesknap gilesknap commented Jun 15, 2026

Copy link
Copy Markdown
Member

Hybrid mode golden-file end-to-end tests

Drives the full hybrid pipeline for two real vacuum IOCs and compares against committed baselines:

builder XML --(builder2ibek)--> ioc.yaml --(ibek generate2)--> st.cmd + ioc.subst  [COMPARED]
            --(msi, stubbed)--> ioc.db   --(rsync)--> /ioc_nfs, /ioc_tftp           [placement]
  • Compared artifacts: st.cmd + ioc.subst (what ibek decides about boot + records).
  • Stubbed: msi (its db templates live only under /dls_sw), plus the dbd/proto/binary inputs — for those we assert placement only.
  • requires_dls skips the tests when the internal ibek-support-dls submodule isn't checked out.

Pins (bridge state)

  • ibek-support / ibek-support-dls submodules → the SHAs tested on a real RTEMS crate (parity / Hy8001 / pass-0 autosave present).
  • builder2ibek → CI-only dependency group, temporary git pin at 99108f1 for the unreleased hostlink-interpose fix.
  • Renovate git-submodules enabled so the pins move forward as reviewable PRs.

Docs

docs/hybrid-testing.md explains the golden-file model and the regenerate → review → redeploy loop.

Follow-ups

  • Add the _test.yml submodule-init step (needs a token with workflow permission). Until then the hybrid tests skip in CI — test_cli/test_globals still run.
  • Release builder2ibek → swap the git pin for a PyPI version.
  • Merge the bl19i-va-ioc-01 branch → main in both ibek-support repos → repoint submodules to main and re-run make_samples.sh (expected no-op).

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Documentation

    • Expanded hybrid-mode guidance with a dedicated “Testing” section, golden-file workflow, and regen → review → redeploy instructions.
  • Tests

    • Added new end-to-end hybrid test suite that generates IOC outputs and compares st.cmd / ioc.subst against committed baselines, including expected NFS/TFTP placement.
    • Added new hybrid sample IOCs and baseline artifacts for BL04I-VA and BL19I-VA.
    • Added a script to regenerate approved baselines for review.
  • Chores

    • Updated hybrid test setup guidance and dependency/submodule tracking used by the hybrid test pipeline.

Drive the full hybrid pipeline (builder XML -> builder2ibek -> ibek
generate2 -> /ioc_nfs) for two real vacuum IOCs and compare the generated
st.cmd/ioc.subst against committed baselines, asserting placement for the
stubbed ioc.db/proto/dbd/binary. msi is stubbed (its db templates live only
under /dls_sw) and ibek-support-dls-dependent tests skip when that internal
submodule is absent.

- pin ibek-support / ibek-support-dls submodules to the SHAs tested on a
  real RTEMS crate (parity / Hy8001 / pass-0 autosave present)
- builder2ibek pinned in a CI-only dependency group (temporary git pin at
  99108f1 for the unreleased hostlink-interpose fix)
- Renovate git-submodules enabled so the pins move forward as reviewable PRs
- docs/hybrid-testing.md describes the golden-file regen/review/redeploy loop

NOTE: the matching .github/workflows/_test.yml submodule-init step is omitted
here because the push token lacks workflow permission; until it is added the
hybrid tests will skip in CI (submodules not checked out).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eb99f659-06ae-42d8-995e-9b9f58893d2b

📥 Commits

Reviewing files that changed from the base of the PR and between 2656457 and baaf8d6.

📒 Files selected for processing (1)
  • .pre-commit-config.yaml

📝 Walkthrough

Walkthrough

Introduces golden-file end-to-end testing for the hybrid pipeline. Submodules are redeclared and pinned via .gitmodules, pyproject.toml, and renovate.json. Shared pytest fixtures, two real IOC sample XMLs, committed st.cmd/ioc.subst baselines, a regeneration script, and a parametrized test module are added alongside workflow documentation.

Changes

Hybrid mode golden-file e2e testing

Layer / File(s) Summary
Submodule declarations and CI dependency pinning
.gitmodules, ibek-support, ibek-support-dls, pyproject.toml, renovate.json
Replaces ibek-runtime-support-dls with ibek-support and ibek-support-dls submodule entries (both tracking main), advances both subproject pointers, adds a pinned CI-only builder2ibek==2.1.0 dependency with inline documentation, and enables Renovate git-submodules tracking for ibek-support*.
Shared pytest fixtures and conftest setup
tests/conftest.py
Adds path constants, DLS-support and builder2ibek presence detection with skip markers, samples fixture, fake_msi_bin stub fixture, build_tree directory fixture with symlinks and stubs, run_builder2ibek subprocess helper, and restore_globals teardown.
Real IOC sample XML inputs
tests/samples/BL04I-VA-IOC-01.xml, tests/samples/BL19I-VA-IOC-01.xml
Adds two complete vxWorks EPICS builder XML files (BL04I and BL19I vacuum IOCs) as parametrized test inputs, each fully specifying hardware modules, gauges, relays, vacuum valves, timing, autosave, and sensor wiring.
Committed golden-file baselines
tests/samples/bl04i-va-ioc-01.st.cmd, tests/samples/bl04i-va-ioc-01.ioc.subst, tests/samples/bl19i-va-ioc-01.st.cmd, tests/samples/bl19i-va-ioc-01.ioc.subst
Adds eight baseline artifacts — startup scripts and DB substitution files for both IOC samples — against which generated output is diffed after path normalization.
Baseline regeneration script
tests/samples/make_samples.sh
Adds a bash utility that runs the XML→YAML→st.cmd/ioc.subst pipeline for each sample XML, canonicalizes temp paths to /epics, and writes refreshed baselines to tests/samples/.
Parametrized e2e test and documentation
tests/test_hybrid.py, docs/hybrid-testing.md, docs/hybrid.md, .pre-commit-config.yaml
Adds the parametrized test_hybrid_generate test that runs the full pipeline and asserts baseline match and NFS/TFTP artifact placement. Adds docs/hybrid-testing.md documenting the golden-file model, dependency pinning, regen workflow, and IOC onboarding; adds Testing section to docs/hybrid.md. Adds a pre-commit hook to remind developers about local test requirements.

Sequence Diagram(s)

sequenceDiagram
    participant CI as pytest parametrize
    participant conftest as conftest fixtures
    participant b2i as builder2ibek xml2yaml
    participant hybrid as rtems_proxy.hybrid.hybrid_prepare
    participant fs as tmp NFS/TFTP filesystem
    participant baselines as tests/samples baselines

    CI->>conftest: build_tree (stub IOC dirs + artifacts)
    CI->>conftest: fake_msi_bin (stub msi script)
    CI->>b2i: run_builder2ibek(sample.xml → ioc.yaml)
    b2i-->>CI: ioc.yaml
    CI->>hybrid: hybrid_prepare(tmp EPICS_ROOT, stubbed msi)
    hybrid->>fs: write st.cmd, ioc.subst, ioc.dbd, .req, boot binary
    hybrid-->>CI: done
    CI->>baselines: diff normalized st.cmd / ioc.subst
    CI->>fs: assert NFS runtime files, TFTP binary
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • epics-containers/rtems-proxy#58: Introduced rtems_proxy.hybrid.hybrid_prepare, which is the core function exercised by the test_hybrid_generate parametrized test added in this PR.

Poem

🐇 Hoppity-hop through the vacuum and beam,
Golden files planted like carrots in a dream.
st.cmd and .subst — compared line by line,
Submodules pinned so the baselines align.
Regen, review, redeploy the day —
The rabbit keeps pipeline drift at bay! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'test(hybrid): golden-file end-to-end tests' directly and clearly describes the primary changes: adding golden-file end-to-end tests for hybrid mode validation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hybrid-e2e-golden-tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/conftest.py (1)

1-121: ⚠️ Potential issue | 🟡 Minor

Add timeout to subprocess.run() and run required Python quality checks before commit.

The subprocess.run() call at lines 102-106 lacks a timeout, which could cause tests to hang indefinitely if builder2ibek stalls. Add a reasonable timeout value (e.g., timeout=30).

Also run the mandated Python checks per coding guidelines—all **/*.py files require type checking via uv run pyright src tests or uv run tox -e type-checking, and linting via uv run tox -e pre-commit before committing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/conftest.py` around lines 1 - 121, The subprocess.run() call in the
run_builder2ibek function lacks a timeout parameter, which could cause tests to
hang indefinitely if builder2ibek stalls. Add a timeout parameter (e.g.,
timeout=30) to the subprocess.run() call to prevent indefinite hangs and ensure
tests fail gracefully if the subprocess takes too long. Additionally, before
committing, run type checking via uv run pyright src tests and linting via uv
run tox -e pre-commit as mandated by the project's coding guidelines to ensure
code quality.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/hybrid-testing.md`:
- Around line 71-73: The documentation in the hybrid-testing.md file describes
how Renovate opens PRs that run tests on submodule bumps, but this is misleading
because the required submodule-init step in .github/workflows/_test.yml is still
missing, causing the hybrid tests to skip in CI. Add an explicit caveat or note
immediately after the statement about Renovate running tests to clarify that
this coverage is not yet active in CI due to the missing submodule-init step, so
readers understand the current limitation and don't assume the tests are
actually running.

In `@tests/conftest.py`:
- Around line 102-109: The subprocess.run call in the builder2ibek helper
function lacks a timeout parameter, which can cause test jobs to hang
indefinitely if the builder2ibek process stalls. Add a timeout=120 parameter to
the subprocess.run call to enforce a 120-second limit on the conversion process.
Additionally, wrap the subprocess.run call in a try-except block to catch
subprocess.TimeoutExpired exceptions and handle them appropriately by failing
the assertion with a clear error message indicating that the builder2ibek
process timed out for the given XML file.

In `@tests/samples/BL04I-VA-IOC-01.xml`:
- Line 136: Fix the typo in the DESC attribute of the
interlock.overrideRequestIndividual element where "Overrride" (with three
consecutive r's) should be corrected to "Override" (with a single r). After
fixing the typo in the XML source, regenerate the sample output artifacts to
ensure the corrected text is propagated to all generated files like the
.ioc.subst file.

In `@tests/test_hybrid.py`:
- Around line 46-50: Add an assertion to validate that the expected_subst
baseline file exists before it is read, similar to the existing assertion for
expected_stcmd. The assertion should check expected_subst.exists() with a clear
error message indicating the missing baseline file. This validation needs to be
added at the current location where the expected_stcmd assertion is present, and
also at the other similar location later in the file where the same pattern
applies.

---

Outside diff comments:
In `@tests/conftest.py`:
- Around line 1-121: The subprocess.run() call in the run_builder2ibek function
lacks a timeout parameter, which could cause tests to hang indefinitely if
builder2ibek stalls. Add a timeout parameter (e.g., timeout=30) to the
subprocess.run() call to prevent indefinite hangs and ensure tests fail
gracefully if the subprocess takes too long. Additionally, before committing,
run type checking via uv run pyright src tests and linting via uv run tox -e
pre-commit as mandated by the project's coding guidelines to ensure code
quality.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b9e16c8b-88e0-44a9-b296-96a8a4fb24ee

📥 Commits

Reviewing files that changed from the base of the PR and between 3c3fd3f and 825377c.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • .gitmodules
  • docs/hybrid-testing.md
  • docs/hybrid.md
  • ibek-support
  • ibek-support-dls
  • pyproject.toml
  • renovate.json
  • tests/__init__.py
  • tests/conftest.py
  • tests/samples/BL04I-VA-IOC-01.xml
  • tests/samples/BL19I-VA-IOC-01.xml
  • tests/samples/bl04i-va-ioc-01.ioc.subst
  • tests/samples/bl04i-va-ioc-01.st.cmd
  • tests/samples/bl19i-va-ioc-01.ioc.subst
  • tests/samples/bl19i-va-ioc-01.st.cmd
  • tests/samples/make_samples.sh
  • tests/test_hybrid.py

Comment thread docs/hybrid-testing.md Outdated
Comment thread tests/conftest.py
Comment thread tests/samples/BL04I-VA-IOC-01.xml
Comment thread tests/test_hybrid.py
gilesknap and others added 3 commits June 15, 2026 15:50
The hybrid tests can't run on a public GitHub runner: ibek-support-dls is on
internal GitLab, and the builder2ibek git pin makes uv clone builder2ibek's
*own* vendored ibek-support-dls submodule, which a public runner can't reach.

So make them internal-only and skip cleanly elsewhere:

- builder2ibek moves out of the default install (no [tool.uv] default-groups);
  it stays in the non-default `ci` group, so the default `tox -e tests` never
  installs it and never triggers the transitive submodule clone.
- gate the hybrid tests on `requires_builder2ibek` as well as `requires_dls`,
  so they skip when either is absent. Run them internally with:
    git submodule update --init && uv run --group ci pytest tests/test_hybrid.py
- document where the tests run in docs/hybrid-testing.md.

Net: public CI runs test_cli/test_globals (hybrid skipped); the hybrid canary
runs on a DLS-internal runner / devcontainer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bmodules)

The bl19i-va-ioc-01 work is now merged to main in both ibek-support repos and
builder2ibek 2.1.0 (with the hostlink-interpose fix) is on PyPI, so retire the
bridge pins:

- builder2ibek: git@99108f1 -> ==2.1.0 (a flat wheel, no submodules)
- ibek-support / ibek-support-dls submodules: tested-branch SHAs -> main

Regenerated baselines are byte-identical (main == the tested branch + the
released fix), confirming the steady state. The tests still run only on a
DLS-internal runner / devcontainer because ibek-support-dls is internal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The hybrid IOC tests need DLS-internal GitLab (ibek-support-dls) and are
skipped on public CI, so local runs give real coverage. Add a verbose,
always-passing pre-commit hook that prints a reminder on every commit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gilesknap gilesknap merged commit f5e9d50 into main Jun 15, 2026
7 of 8 checks passed
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