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