[architect] refactor: enforce behave suite environment quarantine-gate contract (new tests/unit/test_suite_environment_contract.py) - #765
Open
kubestellar-hive[bot] wants to merge 1 commit into
Conversation
…-gate contract Every behave suite ships its own tests/<suite>/features/environment.py. The cross-cutting hooks they are all expected to honour are copy-pasted rather than inherited from a shared base, so nothing detects a suite that silently drops one. tests/shared/quarantine.py is the gate that keeps @quarantine, @future, @pending and @hardware_blocked scenarios from executing. tests/unit/test_quarantine.py covers that helper's own logic thoroughly, but nothing asserts a suite calls it. A suite that omits the call runs its known-failing scenarios for real, which surfaces later as a red E2E gate that reads like a product regression. Adds tests/unit/test_suite_environment_contract.py, which parses each tests/*/features/environment.py with ast -- no imports, no behave runtime, no VM -- and asserts that the suite defines before_scenario, calls skip_quarantine from it, and imports that helper from tests.shared.quarantine rather than redefining it locally. A guard test fails if the discovery glob ever collects nothing, so the parametrised assertions cannot become vacuous. No runtime behaviour changes: this adds a test file only and turns an existing unenforced convention into an enforced contract. All 14 current suites already satisfy it (43 passed). Refs #763 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: kubestellar-hive[bot] <280983584+kubestellar-hive[bot]@users.noreply.github.com>
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This was referenced Aug 28, 2026
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.
Refactor
Claimed ground — exact files/functions/cluster this PR occupies:
tests/unit/test_suite_environment_contract.pytests/*/features/environment.py(all 14 suites),tests/shared/quarantine.pyNo existing file is touched.
git show --staton this branch is one added file.What this changes structurally
Every behave suite ships its own
tests/<suite>/features/environment.py— 14 ofthem, from 26 lines (
nvidia) to 469 lines (smoke). There is no shared base andno mixin, so the cross-cutting hooks they are all expected to honour are copy-pasted
rather than inherited, and nothing detects a suite that silently drops one.
tests/shared/quarantine.pyis the gate that keeps@quarantine,@future,@pendingand@hardware_blockedscenarios from executing.tests/unit/test_quarantine.pycovers that helper thoroughly in isolation, but itsays nothing about whether any suite calls it. A suite that omits the call runs its
known-failing scenarios for real — and because those tags exist precisely because
those scenarios are known-failing, the omission does not fail at authoring time. It
surfaces later as a red E2E gate that looks like a product regression.
That drift is not hypothetical: the same copy-paste shape already produced a gap in
the sibling concern.
record_start/record_endfromtests/shared/timing.pyiswired in only 10 of the 14 suites —
bazzite,flatcar,nvidiaandsecuritysilently record nothing. See #763 for the full matrix.
This PR converts the quarantine convention into an enforced contract. The new module
parses each
tests/*/features/environment.pywithast— no imports, no behaveruntime, no VM, no selenium — and asserts three things per suite:
before_scenariois defined.before_scenariocallsskip_quarantine.skip_quarantineis imported fromtests.shared.quarantineand not redefinedlocally, so the skip-tag precedence stays in exactly one place.
A fourth non-parametrised guard fails if the discovery glob ever collects zero
suites, so the parametrised assertions cannot quietly become vacuous.
Scope discipline
This is enforcement only — no runtime behaviour change, no production code
touched, no suite rewired. Deliberately excluded from this PR:
tests/shared/suite_env.py(proposed as step 1 in [architect] behave suite environment contract is unenforced convention: 14 hand-wired environment.py, quarantine gate copy-pasted, timing wired in only 10/14 #763) — that is a 14-file behaviour-sensitive refactor that
needs a real E2E run behind it.
cover timing — that first needs the [architect] tests/shared/timing.py is an orphaned subsystem: timings.jsonl has no consumer, DEFAULT_SLA and SLA_STRICT are never read outside their own tests #764 decision on whether timing is mandatory
at all, given nothing currently consumes
timings.jsonl._first_valuedefinitions(
tests/common/features/environment.py:23,tests/kde-smoke/features/environment.py:35,tests/shared/ssh_config.py:28).Verification
All 14 existing suites already satisfy the contract, so this is green on arrival.
Mutation-checked that the test is not tautological — replacing the gate in
tests/nvidia/features/environment.pywithif False:produces:The mutation was reverted; the diff contains only the new file.
Disjointness from open hold-gated PRs
Checked against the open snapshot for this repo via
gh pr view --json title,files:[quality] test: add unit tests for screenshot_steps.py behave wrapperstouches only
tests/unit/test_screenshot_steps.py.[scanner] fix: ignore input-remapper in QEMUtouches onlytests/smoke/features/steps/system_health_steps.pyandtests/unit/test_system_health_steps.py.Neither touches
tests/*/features/environment.py,tests/shared/quarantine.py, orthe new file. No overlap.
Refs #763
Filed by architect agent (ACMM L5 — hold-gated mode). Hold-gated: human review required.
— hive: agent=architect backend=copilot model=claude-opus-5