Skip to content

test: expand test coverage - #29

Merged
aldbr merged 58 commits into
DIRACGrid:mainfrom
Alexander-Auer:stack/test-expansion
Oct 27, 2026
Merged

aldbr merged 58 commits into
DIRACGrid:mainfrom
Alexander-Auer:stack/test-expansion

Conversation

@Alexander-Auer

@Alexander-Auer Alexander-Auer commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

test: unit tests for the fake's hooks and the model rules, and coverage measurement

Follows #28 (merged). Tests and tooling only; no library code changes.

What is added

The fake backend (test_fake_backend.py), for what the conformance suite cannot reach without the fake's test hooks:

  • refused copies keep their indexes; an injected failure is reported per job by every per-job operation; an unavailable resource fails the whole operation;
  • what a resource cannot do (URL inputs or outputs, container images) is refused at submit, before anything is stored;
  • a copy's environment wins over the spec's, and job IDs stay unique across submissions;
  • kill aborts an active job and leaves a finished one alone;
  • output can be collected again, is refused while the job runs, and an escaping member writes nothing at all;
  • a purged job is gone for every operation; diagnostics read a running job's file by name.

Two of these read the fake's private job table, because the fake has no public way to show which environment a copy got or that nothing was stored.

Models, configuration and smoke tests:

  • JobHandle.key escapes separators, so different handles never share a key;
  • the JobStatus values stay stable, since stored statuses are compared by value;
  • a configuration that is not a mapping is refused with a clear message;
  • the version falls back when the package is not installed.

Tooling

  • pytest-cov in the testing extras.

  • [tool.coverage]: branch coverage, subprocesses measured too, protocol ... bodies and TYPE_CHECKING blocks excluded.

    pixi run -e py313 pytest --cov

Coverage of src/intercede is 99%; the two uncovered lines cannot be reached through the API.

109 tests pass on Python 3.11 and 3.13, and pre-commit passes.

alexander and others added 30 commits October 2, 2026 16:54
* feat: Models the core contract needs

* Feat: Protocols and Exceptions added for the core contract

* Feat: Private protocols for the BatchBackend

* feat: a fake backend to run unit tests against

* fix: some code cleanup in the helper functions

* feat: setup for the unit test suite

* chore: style fix

* chore: styling, unit test fixture

* chore: single letter var `h` refering to hanlde changed to `handle`

* fix: unused parameter in `test_injected_failure_is_reported_per_job()` removed

* feat: Models the core contract needs

* Feat: Protocols and Exceptions added for the core contract

* Feat: Private protocols for the BatchBackend

* feat: a fake backend to run unit tests against

* fix: some code cleanup in the helper functions

* feat: setup for the unit test suite

* chore: style fix

* chore: styling, unit test fixture

* chore: single letter var `h` refering to hanlde changed to `handle`

* fix: unused parameter in `test_injected_failure_is_reported_per_job()` removed

* fix: made the OutputSpec optional as it is not suppoerted by all and a consumer should choose to use it or not

---------

Co-authored-by: alexander <alexander.auer@cern.ch>
@Alexander-Auer Alexander-Auer self-assigned this Oct 20, 2026
Alexander-Auer and others added 23 commits October 23, 2026 15:16
Drop tests of pydantic and Python behaviour (immutability, defaults, hashing) and keep the rules interCEde itself adds.
One test per rule, no tests of what pydantic or a closed table already guarantees.
# Conflicts:
#	tests/unit/test_config.py
Keep the every-field-for-every-kind table, one test per configuration rule, and the fake's hooks; drop what the table, the conformance suite or pydantic already cover.
Move the API reference to docs/user/reference/api.md, link the user and developer documentation from the index, and stop referring to the ADRs there.
- Google-style docstrings for the public and batch protocols, with arguments, returns and raises.
- get_diagnostics takes a filename (a file in the job's working directory; None reads stdout) instead of a generic name; Diagnostics.filename matches.
- An input name may appear once in a SubmissionSpec: two sources for one file are refused when the spec is built.
- A copy with a secret named like an input is refused at submit with SpecificationRejectedError; SubmissionSpec.clashes_with() lets every backend apply the same rule.
- No references to the ADRs in code or docstrings: they are not part of the source and can be superseded.
Follows the review of the core contract: the ADRs are not part of the source and can be superseded. The registry's docstrings also say what they return.
# Conflicts:
#	tests/unit/test_fake_backend.py
#	tests/unit/test_models.py
- Google-style docstrings with Args, Returns and Raises for resolve() and every registry and configuration helper, and docstrings for the settings classes; ruff now checks docstrings against the Google convention.
- Remove vm_max_lifetime_s: removing VMs after a lifetime is the consumer's policy, not interCEde's.
- Import Callable from collections.abc, like the rest of the code.
A verb says that the call builds something, and get_backend() no longer reads like the backend itself.
ARCConfig, HTCondorCEConfig, CloudConfig, BatchLocalConfig and BatchSSHConfig
replace the flat BackendConfig, which is now their union, chosen by kind (and
by transport for batch). A consumer can still pass a plain mapping, such as a
TOML table.

- Every field is declared once, on the model of its kind: the internal
  settings classes, the hand-kept field lists and resolve() are gone, so a
  configuration is validated once instead of twice.
- validate_config() checks a configuration and returns its model;
  registry.get_backend() uses it. A model is checked again, so one changed
  with model_copy() cannot carry fields of another transport to a backend.
- Errors never repeat a value they were given, since it may be a secret, and
  name the expected fields when a field does not belong to the kind.
- The configuration tests use the public API only.

The SSH auth mode is now one value (auth = "key") instead of a list.
griffe-pydantic renders every field of each configuration model, inherited
ones included, with its type, default and description, so the reference cannot
drift from the code like the hand-written table could.
The merge of stack/registry kept a helper and a section header from the old test_config.py; the helper referred to resolve() and BackendConfig.model_validate(), which no longer exist.
Two tests had moved without changing, which only made the diff harder to read.
@Alexander-Auer
Alexander-Auer marked this pull request as ready for review October 27, 2026 08:56
@Alexander-Auer
Alexander-Auer requested a review from aldbr October 27, 2026 08:56
@aldbr
aldbr merged commit 6301cb9 into DIRACGrid:main Oct 27, 2026
7 checks passed
Alexander-Auer pushed a commit to Alexander-Auer/intercede that referenced this pull request Oct 27, 2026
Alexander-Auer pushed a commit to Alexander-Auer/intercede that referenced this pull request Oct 27, 2026
… into feat/HTCondorCEBackend

Replaces the earlier versions this branch was built on with what was merged
upstream (DIRACGrid#27, DIRACGrid#28, DIRACGrid#29) and the credentials under review (DIRACGrid#30). The HTCondor-CE
schedd setting moves onto HTCondorCEConfig.
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.

2 participants