feat(test): move stateful coverage to proptest-state-machine - #26
Merged
Merged
Conversation
Replace the hand-rolled generated-history runner with proptest-state-machine and make the PostgreSQL harness a concrete StateMachineTest driven by an independent reference model. Let the state-machine strategy own transition generation, sequencing, precondition-aware shrinking, and replay while retaining the existing operation-level PostgreSQL contract assertions, stale-attempt fencing coverage, and storage invariant audits after every transition. Keep one database connection alive for each generated case so the session-scoped fake clock remains stable throughout execution and shrinking. The reference model independently tracks durable task creation and logical time and is checked against the concrete state after every operation. Remove the previous Vec<Operation>/TestRunner/run_history path entirely, update the stateful test terminology, and add proptest-state-machine to the development dependency and third-party metadata.
Restore the aggregate diagnostics emitted by the stateful PostgreSQL campaign after the migration to proptest-state-machine. Accumulate coverage across completed state-machine SUT instances and report the generated workload, task and run outcomes, retry and checkpoint behavior, maintenance activity, rejected stale mutations, and operations that were intentionally skipped or produced no change. Keep coverage collection within the new state-machine lifecycle rather than reintroducing any part of the previous generated-history runner. This preserves the useful visibility into what each property-testing campaign actually exercised while retaining the new model-based generation and shrinking path exclusively.
Build on the restored stateful campaign diagnostics by making generated operations substantially more intentional under proptest-state-machine. Bias normal claims toward productive work and move empty-queue coverage into an explicit probe, then extend the reference model with conservative knowledge about runnable work, active runs, and replayable checkpoints. Use that model state to avoid generating positive-path operations when the harness has no evidence they can succeed. Add explicit checkpoint replay coverage with first-write-wins assertions and move stale checkpoint mutation checks into a dedicated probe path. Preserve the existing PostgreSQL operation contracts, invariant audits, stale mutation coverage, and campaign summaries while reducing wasted transition budget from empty claims and unavailable checkpoint replays. The resulting suite keeps PostgreSQL as the real system under test while using the reference model to guide generation and shrinking toward meaningful lifecycle histories.
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.
Summary
Move Steda's PostgreSQL stateful test suite fully onto
proptest-state-machineand replace the previous hand-rolled generated-history runner with an explicit reference model and state-machine SUT.The new harness keeps the strongest parts of the existing suite — real PostgreSQL execution, operation-level assertions, stale mutation checks, fake-time behavior, and invariant audits after every transition — while making generation and shrinking substantially more intentional.
What changed
Vec<Operation>/TestRunnerhistory runner withproptest-state-machine.ReferenceStateMachinethat tracks the minimum durable state needed to guide useful transition generation.StateMachineTestimplementation and retain one connection for the full generated case so the session-scoped fake clock remains stable.Why
The previous stateful suite already exercised long randomized histories against the real database, but operation generation was largely state-oblivious and shrinking had no independent semantic model to work from.
Using
proptest-state-machinegives the suite:The model is intentionally conservative. It does not attempt to mirror all PostgreSQL implementation details; it only tracks enough state to guide meaningful generation while the database and invariant audits remain the authoritative correctness checks.
Coverage
A representative 64-case run currently exercises roughly 4,000 transitions and includes:
After making claims model-aware, natural empty claims dropped from hundreds per campaign to low double digits while explicit empty-claim probes continue to cover the negative contract.
Checkpoint replay generation is likewise state-aware now: successful explicit replays are exercised without spending transition budget on unavailable replay attempts.
Validation
make test-statefulpasses with the full generated campaign, and the suite continues to audit PostgreSQL invariants after every transition.Example result:
This leaves Steda with one stateful testing path: a model-based
proptest-state-machineharness driving the real PostgreSQL implementation.