Add tests for (3006,004C) and a CI workflow #3
No reviewers
Labels
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
IHE-RO-Tooling/virtual-ct!3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "test/hdss-source-series-tests-and-ci"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds tests for the (3006,004C) fix in #2, and a CI workflow.
Now green on your runner — run #3,
linux-amd64. The first two runs failed and the reason isworth writing down, because it was in your own workflow and I did not read far enough.
I read
dicom-gateway/.forgejo/workflows/ci.yamlto follow your conventions and took four thingsfrom it —
.forgejo/workflows,runs-on: linux-amd64, container-based,workflow_dispatchfirst,paths-ignorerather than apathsinclude-list. I did not read its steps, so I missed the onethat makes container jobs run at all under
rust:latestfor exactly the same reason. Your file hadthe answer before I had the problem.
One incidental finding, in case it is useful: a push touching only
.forgejo/workflows/**still triggered the
pull_requestrun, even though that path is inpaths-ignore. The filter isevaluated against the pull request's whole changeset rather than the individual push, which matches
GitHub's semantics.
Tests
Layered, because the layers catch different failures and only the middle one catches the defect
#2 fixed:
_build_structure_set_tagspopulates all six Type 1 sub-attributes, and refuses rather than emitting a partial item when one is absentDicomExporter.exportreturns carries whatRtssHdExporterreadsThe missing-value case is parametrised per key — a single "it raises" test would pass while five of
six branches were dead.
The integration test is the regression guard. The original defect wasn't a wrong value, it was
a value that existed in one component and couldn't be reached from the other. A unit test on either
side passes equally before and after the fix.
Mutation-proved rather than asserted: renaming
series_descriptionon the producing side withoutupdating the consumer fails exactly the integration test, with all 9 unit tests still passing.
Green before, injection verified present, restored byte-identical, green after.
An e2e check — write a phantom, read both objects back, confirm 004C describes the CT series on
disk — is deliberately not here. It costs a phantom generation and belongs on a release gate
rather than per-push CI. Happy to add it to a
release.yamlif you'd like one.CI — two departures, offered rather than assumed. Say the word and either reverts.
concurrency+cancel-in-progress. With a single shared runner, three quick pushes to abranch queue three full builds and the first two are already obsolete. Costs nothing, changes
nothing about what is tested.
pull_request+pushtomain, instead of push to every branch. Same protection where itmatters — the merge — without every work-in-progress push consuming the runner. If you build
every branch on purpose, this is the one to revert.
One thing stated plainly rather than buried
Dependencies are installed directly, not via
poetry install. The domain layer is Qt-free(measured: PySide6 appears only under
gui/andmain.py), so the tests need numpy, pydicom andmatplotlib.
poetry installwould also pull pyside6 and nuitka — minutes per run, and pyside6 on aslim image is a plausible failure with nothing to do with the code under test. The cost: CI is
then not exercising the locked dependency set. The clean fix is upstream of CI — GUI dependencies
as an optional extra, so
poetry installwithout extras gives exactly the domain layer. That's achange to your dependency structure, so it's a question rather than something done here.
Written by River (
river-2fc1630e), collaborating with @sjswerdloff and posting through hisaccount. The commits carry
river-2fc1630eas author.Stacked on the 004C fix, so this branch targets that branch rather than main. TESTS -- layered, because the layers catch different failures and only the middle one catches the defect being fixed: unit _build_structure_set_tags populates all six Type 1 sub-attributes, and refuses rather than emitting a partial item when one is absent. The missing-value case is parametrised per key: a single "it raises" test would pass while five of six branches were dead. integration the dict DicomExporter.export RETURNS carries what RtssHdExporter READS. This is the regression guard. The original defect was not a wrong value, it was a value that existed in one component and could not be reached from the other, so a unit test on either side passed both before and after the fix. Mutation-proved rather than asserted. Renaming series_description on the producing side without updating the consumer fails EXACTLY the integration test, 9 unit tests still passing -- which demonstrates that the seam guard works and that unit coverage structurally cannot replace it. Green before, injection verified, restored byte-identical, green after. An end-to-end check -- write a phantom, read both objects back, confirm 004C describes the CT series on disk -- is deliberately NOT here. It costs a phantom generation and belongs on a release gate rather than per-push CI. CI -- follows the dicom-gateway house style: .forgejo/workflows, runs-on: linux-amd64, container-based, workflow_dispatch first, paths-ignore rather than a paths include-list (the right polarity -- an exclusion list covers a new source directory by default, an include-list leaves it silently untested). Two departures, offered rather than assumed, both reverted on request: concurrency + cancel-in-progress with one shared runner, three quick pushes queue three builds and the first two are already obsolete pull_request + push to main instead of push to every branch: same protection at the merge, without every WIP push consuming the runner Dependencies are installed directly rather than via `poetry install`, because the domain layer is Qt-free (measured: PySide6 appears only under gui/ and main.py) and pulling pyside6 plus nuitka costs minutes per run and can fail on a slim image for reasons unrelated to the code. The cost of that choice is stated in the workflow: CI is then not exercising the locked dependency set. The clean fix is upstream -- GUI dependencies as an optional extra -- which is a change to the project's dependency structure and is left as a question. NOT VERIFIED ON A RUNNER. The YAML parses and the tests pass locally, but neither of us has a linux-amd64 runner to execute this on, so the first real run is the first evidence.Add tests for (3006,004C) and a CI workflow (stacked on #2)to WIP: Add tests for (3006,004C) and a CI workflow (stacked on #2)WIP: Add tests for (3006,004C) and a CI workflow (stacked on #2)to WIP: Add tests for (3006,004C) and a CI workflowWIP: Add tests for (3006,004C) and a CI workflowto Add tests for (3006,004C) and a CI workflow