feat(hw-ci): migrate hardware-test workflow to hw-matrix.yml@v2 - #749
Draft
tfcollins wants to merge 24 commits into
Draft
feat(hw-ci): migrate hardware-test workflow to hw-matrix.yml@v2#749tfcollins wants to merge 24 commits into
tfcollins wants to merge 24 commits into
Conversation
Net-new GH Actions HW pipeline calling the shared hw-matrix reusable
workflow in tfcollins/labgrid-plugins. Runs alongside the existing
JenkinsfileHW for at least two weeks during the migration period; do
not delete the Jenkins config until result delta is understood.
Initial scope: 2 places (pluto, fmcomms2-zcu102), coord leg only,
labeled-PR + nightly cron + manual triggers. Add boards by extending
.github/hw-nodes.json and writing test/hw/test_<board>_smoke.py.
New artifacts:
- .github/workflows/hardware-test.yml: thin caller of
tfcollins/labgrid-plugins/.github/workflows/hw-matrix.yml@v1.
- .github/hw-nodes.json: per-place manifest consumed by hw-matrix.
- test/hw/conftest.py: 'iio_uri' session fixture that resolves a
libiio URI from either --iio-uri-override (laptop runs) or
LG_COORDINATOR + LG_PLACE (set by the workflow before pytest).
- test/hw/test_pluto_smoke.py, test/hw/test_ad9361_smoke.py:
minimal smoke tests that open a context and capture a buffer.
Independent of test/conftest.py and its pytest-libiio fixtures.
- test/hw/env/{pluto,fmcomms2_zcu102}.yaml: coord-mode env stubs.
- test/hw/README.md: onboarding for adding boards.
The existing JenkinsfileHW and test/test_*.py are untouched.
The subprocess argument list in _labgrid_show was a single 96-char line; the repo's pinned black==19.10b0 (via pre-commit) splits long literal lists one element per line. No behavior change.
Replace placeholder pluto / fmcomms2-zcu102 manifest entries (which don't exist on coordinator 10.0.0.41) with the actual hardware behind the lab: - mini2 (ZCU102 + AD9081) -> adi.ad9081 smoke - bq (ZC706 + ADRV9371) -> adi.ad9371 smoke - nemo (ZC706 + ADRV9009) -> adi.adrv9009 smoke Each smoke instantiates the device class via the iio_uri fixture (which extracts the labgrid place's NetworkService address) and runs two assertions: - ctx.attrs is populated (real libiio context handshake) - rx() returns a non-empty buffer (real DMA roundtrip) No fmcdaq3 class in adi/ yet, so nuc/fmcdaq3 is deferred. Tests deliberately don't .skip() on connection failure — if a DUT is offline the test FAILS (which is the right signal, not silent).
Two changes:
* Replace 'python -m labgrid.remote.client' with the venv's
labgrid-client script. The module-style invocation against the
pinned tfcollins/labgrid SHA swallows stdout in some paths, which
made every test silently skip with "Place" not found.
* Drop the silent skip — pytest.fail instead, so missing places or
missing addresses are loud red. The reusable workflow's
acquire-place composite has already acquired the place; if show
can't find it now, something is genuinely wrong.
Also always echo the raw 'labgrid-client show' stdout/stderr to
test-stderr so a CI re-run doesn't require another debug roundtrip.
The tfcollins/labgrid fork prints NetworkService params as Python repr
('address': '10.0.0.23'), not flat key-value (address: 10.0.0.23).
The line-prefix matcher missed both; regex now captures either form.
Stacks on PR #747 (feature/gha-hw-workflow). Once that merges, this PR rebases onto main and lands the v2 migration. Discovery-driven flow lives entirely in labgrid-plugins (PR #16). On the consumer side this PR is a deletion-heavy diff: * Delete .github/hw-nodes.json (the v1 static per-place manifest). * Delete test/hw/env/{mini2,bq,nemo}.yaml (v1 per-place labgrid env files). The reusable workflow renders the env yaml on the fly from the place's `boot-strategy` tag. * Drop the !test/hw/env/ exception line in .gitignore. * Update .github/workflows/hardware-test.yml: switch the `uses:` ref to hw-matrix-v2.yml; drop manifest_path + legs inputs; add marker_filter=iio_hardware + test_root=test/hw; install adi-labgrid-plugins in the venv (it provides both the marker plugin and the adi-lg-hw-ci CLI the workflow shells out to). * Add @pytest.mark.iio_hardware(["..."]) decorators to the three smoke tests so the v2 matrix discovers them. Carrier-narrowing not used yet — these tests don't depend on a specific carrier. * Rewrite test/hw/README.md to describe the v2 model (no manifest, no env yaml, marker-driven, lab-admin sets tags). Workflow ref pinned to labgrid-plugins@feature/hw-matrix-v2-discovery until that PR merges and the v2 tag is cut. Flip to @v2 in a follow-up commit before this PR merges. Test plan: * actionlint .github/workflows/hardware-test.yml → clean. * pytest --collect-only -m iio_hardware against test/hw/ in a venv with adi-labgrid-plugins installed → 6 tests collected; the --hw-ci-export-markers JSON correctly shapes each entry as {iio_hardware: [...], iio_carrier: []}. * Once the lab admin tags mini2 / bq / nemo on the live 10.0.0.41:20408 coordinator, dispatching this workflow should produce one matrix shard per (place, daughter-board) pair and skip-with-annotation any board that isn't live. Migration status: * v1 (hw-matrix.yml@v1) stays in labgrid-plugins indefinitely for any consumer that hasn't migrated yet. * The legacy JenkinsfileHW pipeline is untouched.
No code change. The labgrid-plugins reusable workflow at @feature/hw-matrix-v2-discovery has been updated (PR #16) so the `discover` job pins to `hw-coordinator` and each `hw` shard pins to `hw-<place>` — matching the lab's real self-hosted runner labels. The prior run (25865035443) sat in `queued` indefinitely because the old default `hw-coord` matched no runner. This commit re-fires the workflow against the fixed reusable workflow.
labgrid's pytest plugin registers --lg-env. The v2 caller had a typo that pytest rejected with 'unrecognized arguments: --lg-config' before any test ran.
BootFPGASoC.__attrs_post_init__ unconditionally calls KuiperDLDriver.get_boot_files_from_release() which imports pytsk3. pytsk3 is declared as an optional extra in adi-labgrid-plugins (see pyproject.toml [kuiper]); without it, every shard's boot step crashes with ModuleNotFoundError before pytest runs. Tack [kuiper] on the install line so uv pulls pytsk3 in.
…covery Previously the conftest fell back to a labgrid-show lookup whenever --iio-uri-override wasn't passed. That meant the test could end up poking whichever board the coordinator advertised — and we just learned the hard way (mini2 ran into this) that NetworkService.address goes stale across DHCP renewals. Make the URI an explicit pytest CLI argument: * hardware-test.yml's pytest_cmd_template adds `--iio-uri-override "$IIO_URI_OVERRIDE"`. The hw-matrix-v2 workflow resolves the IP from the live board's serial console and exports IIO_URI_OVERRIDE before pytest runs. * test/hw/conftest.py drops the labgrid auto-discovery path entirely. If no URI was provided, the fixture skips with a clear message instead of silently connecting to whatever the coordinator says. This eliminates the "what if I'm testing a random board on the LAN?" class of failure. The workflow IS the contract.
tfcollins
force-pushed
the
feature/gha-hw-workflow
branch
3 times, most recently
from
May 20, 2026 20:28
170cee3 to
a8698c8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrate
pyadi-iioHW-CI off the manifest-drivenhw-matrix.yml@v1andonto the new discovery-driven
hw-matrix-v2.ymlshipped intfcollins/labgrid-plugins#16.
This PR is stacked on #747 (
feature/gha-hw-workflow). It will moveto base
mainafter #747 merges. Keep #747 as the v1 landing pad so thenew workflow has a working consumer to diff against during review.
What changes
.github/workflows/hardware-test.yml— now callstfcollins/labgrid-plugins/.github/workflows/hw-matrix-v2.yml. Nomanifest_path;marker_filter: iio_hardwareinstead..github/hw-nodes.json,test/hw/env/{bq,mini2,nemo}.yaml.The reusable workflow renders the per-shard labgrid env yaml on the
fly from each place's
boot-strategytag..gitignore— drop the!test/hw/env/exception line (no longerneeded; the dir is gone).
test/hw/test_*_smoke.py— every test now wears@pytest.mark.iio_hardware([<daughter>...]). AD9371 uses the["adrv9371", "ad9371"]alias list. Matchback against the livecoordinator's
daughter-board=tag.test/hw/README.md— rewritten to describe the discovery model anddrop the manifest/env-yaml story.
Tag contract the lab needs
For each live place (mini2 / bq / nemo / …) the coordinator admin sets:
Concrete current contract per #16's docs:
The workflow validates these on every run; an unknown
boot-strategy=value fails thediscoverjob with a clear errorlisting the legal class names.
Empty-intersection behavior
If no live place advertises a
daughter-boardthat any marker'd testasks for, the workflow emits a
::warning::annotation anddiscoversucceeds with an empty matrix — no jobs are spawned and the run is
green. Concrete example: if all three lab boards are offline, the run
finishes with a single annotation rather than a wall of failed shards.
Stacking / merge order
tfcollins/labgrid-plugins#16merges → tagv2on that repo.uses:ref flips from@feature/hw-matrix-v2-discoveryto@v2, and thepip installline for
adi-labgrid-pluginsflips from@feature/...to@v2.main, gets reviewed, merges.Test plan
hardware-test.ymlskip path stays SKIPPEDwhen the
hw-testlabel is absent (matches today's behaviour).hw-testlabel,discoverjob emits a non-emptymatrix and
hwshards run on the live coordinator. Tag the livecoordinator places with the contract above before adding the
label.
Tests (hw-coord bq)/Tests (hw-coord mini2)checksremain green and independent.
pytest --collect-only -m iio_hardwarelocally inside a fresh venv:
pip install -e .[dev] git+https://github.com/tfcollins/labgrid-plugins@feature/hw-matrix-v2-discovery.