alunduil / alunduil/zfs-replicate
A wrapture trial on the process boundary settles whether it replaces pytest-mock
- Lenguaje dominante
- Python
- Estrellas
- 24
- Forks
- 6
- Merge medio
- 3 h 11 min
- PR fusionados (30 d)
- 49
Descripción
## Summary
Trial [wrapture](https://github.com/GrahamDumpleton/wrapture) against the suite's two existing patching seams and decide whether it replaces `pytest-mock`, supplements it at named seams, or neither.
## Current behaviour
`pytest-mock==3.15.1` sits in the test group. `zfs_test/conftest.py`'s `fails_with` fixture and five test modules — `cli_test/log_test.py`, `cli_test/main_test.py`, `task_test/execute_test.py`, `snapshot_test/send_test.py`, `filesystem_test/create_test.py` — reach for `mocker.patch.object`.
`docs/reference/testing.md` fixes the convention. "The process boundary" says code that runs a command replaces `zfs.replicate.process.run` (or `process.open`) through the `mocker` fixture, returning a fake `CompletedProcess` or `Popen`, so no external binary runs. "Command-line tests" says a fixture patches the collaborators a command dispatches to, such as `snapshot.list` and `task.execute`, and hands back the stub the test asserts against.
## Motivation
wrapture (`wrapt` + `capture`) attaches bindings to call sites without modifying the observed code, and does monkey patching, test observation, and tracing from one mechanism. Against `unittest.mock`, the claims that matter here are that it watches the real code run rather than fabricating values, sees calls an object makes to itself, records call nesting and ordering, and can assert on what *didn't* happen on an error path — inject a send failure, then verify no destroy followed.
This suite patches at two narrow, already-documented seams, which makes it a cheap and well-bounded surface to try that on. Upstream is beta ahead of 1.0.0 and explicitly asking for reports from real code, so the trial is worth something in both directions.
## Approach and alternatives
Port `fails_with`, one process-boundary module, and one command-line module to wrapture bindings, and run both versions side by side before deleting either.
Set aside:
- Keep `pytest-mock` unchanged. Nothing forces a change; this is what the trial has to beat.
- Convert the whole suite up front. The dependency is pre-1.0, and the trial is what produces the evidence for a wider move.
## Scope
`pyproject.toml` (test group), `zfs_test/conftest.py`, `zfs_test/replicate_test/snapshot_test/send_test.py`, `zfs_test/replicate_test/cli_test/main_test.py`, `docs/reference/testing.md`.
## Out of scope
wrapture's OpenTelemetry export and any tracing in production code paths. Converting the remaining test modules, which becomes a follow-up if the trial lands.
## Acceptance criteria
- [ ] `fails_with`, one process-boundary module, and one command-line module have a wrapture equivalent, run beside the `pytest-mock` version
- [ ] The comparison is recorded: what each version asserts, what wrapture caught that `mocker.patch.object` cannot express, and what it made harder
- [ ] The pinning question is settled — this repo pins test dependencies exactly, while upstream says a pre-1.0 pin is unnecessary because `pip install wrapture` tracks the pre-release
- [ ] A decision is recorded: replace, supplement at named seams, or neither
- [ ] If adopted, `docs/reference/testing.md` carries the convention and `pyproject.toml` the dependency
- [ ] If not adopted, this closes with the reasons recorded
- [ ] Tests and pre-commit pass
## Related issues
#425 produced `docs/reference/testing.md`, the document a positive outcome revises.
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.