Improve unit test coverage
## Current situation Unit test coverage for the engine is at **26.0%** (up from **19%** at the start of this effort). The first round of improvements covered all testable pure functions and utilities across ~50 packages, including: - Type conversion helpers (`pkg/util/ptypes`) - Branching path construction and parsing (`pkg/util/branching`) - Database marker operations (`internal/retrieval/dbmarker`) - PostgreSQL log file management (`pkg/util/pglog`) - Pool management logic (`internal/provision/pool`) - Clone/snapshot storage and state (`internal/cloning`, `internal/observer`) - Branch tree traversal and config validation (`internal/srv`) - Retrieval state, validation, and mode detection (`internal/retrieval`) - Snapshot recovery config building and WAL parsing (`internal/retrieval/engine/postgres/snapshot`) - Logical dump/restore job configuration (`internal/retrieval/engine/postgres/logical`) - Physical backup tool helpers (`internal/retrieval/engine/postgres/physical`) - Auth middleware and API error handling (`internal/srv/mw`, `internal/srv/api`) - Diagnostic log collection (`internal/diagnostic`) - Docker helper functions (`internal/provision/docker`) - PostgreSQL config path helpers and file operations (`internal/provision/databases/postgres/pgconfig`) - Container helper functions (`internal/retrieval/engine/postgres/tools/cont`) - Filesystem type detection (`internal/provision/pool`) - Config rotation and serialization (`pkg/config`) A `test-coverage` Makefile target was also added to measure coverage conveniently. ## What is needed to significantly improve coverage The 26% ceiling represents the limit of what can be tested without refactoring. The remaining untested code is tightly coupled to external infrastructure: ### 1. Docker client interface extraction (~10-15% coverage gain) Most provisioning and retrieval code calls `*client.Client` methods directly. Extracting a Docker client interface and injecting it as a dependency would allow mocking container create/start/stop/remove/exec operations in tests. Key packages affected: - `internal/provision/docker` - `internal/provision/databases/postgres` - `internal/retrieval/engine/postgres/tools/cont` - `internal/retrieval/engine/postgres/physical` - `internal/retrieval/engine/postgres/logical` ### 2. HTTP handler dependency injection (~5-8% coverage gain) Handlers in `internal/srv/` construct their dependencies inline or access them through closures. Introducing injected interfaces for cloning, provisioning, and observer services would allow testing request/response flows without running a full server. Key areas: - Clone API handlers - Branch API handlers - Snapshot API handlers - Instance status endpoints ### 3. Database connection mocking (~3-5% coverage gain) Observer and some cloning code connects to real PostgreSQL instances. Abstracting the database layer behind an interface would allow testing query logic in isolation. Key packages: - `internal/observer` - `internal/cloning` ### Estimated coverage with refactoring: **45-50%** Each of these areas requires interface extraction and dependency injection refactoring as a prerequisite before tests can be written. This should be done incrementally, one area at a time, to minimize risk.
issue