Chapter 13: tests, a real Postgres and a fake Jev
Every test in this folder starts a real Postgres of its own, a throwaway one
in a temporary directory, with the freshly built extension served in place.
And every test points that Postgres at a fake Jev: jev-mock (from
jevcrates), a real HTTP/2 server over real TLS on loopback, which answers
however the test tells it to and remembers every request it was sent.
flowchart LR
T["a test (tokio-postgres)"] -->|"SQL over a Unix socket"| P[("a throwaway Postgres<br/>with the built extension")]
P -->|"HTTP/2 + TLS, trusted through jev.ca_file"| M["jev-mock on loopback"]
T -.->|"what arrived, byte for byte"| M
That last arrow is the point. A test does not only check that the query returned the right number. It goes to the mock and checks what was actually sent: how many requests, on how many connections, with which headers, how many at once, which streams were reset. "The query came back" can hide a dozen sins; the wire cannot.
Aside. Why not wall-clock time? Because the machine that runs the suite is shared with other builds, and "this took under two seconds" failed there while passing alone. So timing is measured where it means something: the mock counts the peak number of requests in flight for concurrency, the connections it accepted for redials, the retry header for retries. A test may say a backoff waited at least its delay; it never says at most.
Try it.
nix develop -c buck2 test //tests:happy_pathruns the smallest one: one row, one Noul, and an assertion on every byte of the one request it sends. Every test also has a twin for Postgres 17,//tests:happy_path-pg17, andnix develop -c buck2 test //...runs the whole suite on both majors.
The tests
| File | What it holds the extension to |
|---|---|
| happy_path.rs | jev_prob end to end, asserting the exact request. |
| batching.rs | The batch scan: concurrency on one connection, filtered rows never sent, LIMIT, shared requests, rescans, aggregates, windows, CTEs, subqueries, partitions, reach, refusal before any request, EXPLAIN. |
| dml.rs | UPDATE, DELETE, INSERT … SELECT and SELECT … FOR UPDATE batched, and an EvalPlanQual recheck that never sends. |
| threshold.rs | jev(row, q [, threshold]): argument, then jev.threshold, then 0.5, sharing judgments with jev_prob. |
| score.rs | jev_score and jev_score_norm: 2–10 levels in the caller's order, one judgment between them. |
| choice.rs | jev_choice: options in the caller's order, 2–255 sent, one answered without asking. |
| confidence.rs | jev_confidence: the vendor's figure, sharing the Choice's or Score's judgment; 'noul' refused before sending. |
| eval.rs | jev_eval and the *_full functions: typed composites from the same judgment and cache row. |
| label_tree.rs | jev_choice_tree: one Choice per node, a round per request, each node cached. |
| shortlist.rs | jev_choice_shortlist: chunks in one request, finalists in a second, each cached. |
| cache.rs | The durable cache, and equal judgments sharing one request in a statement, including a call that asks again when a rescan drops the one it waited on. |
| canonical.rs | The row sent in a form that does not depend on the session and loses no digit. |
| budget.rs | jev.max_rows and jev.max_cost: refused before the first request, and stopped mid-statement. |
| ratelimit.rs | The cluster-wide rate limit, timed at the mock: two backends sharing one ceiling, a 429 halving the rate, a cancel ending the wait. |
| retries.rs | 408, 429 and 5xx retried at most twice, a server delay honoured, the retry count sent; any other status fails at once. |
| on_error.rs | jev.on_error: a 500 skips its row under unsure and fails the statement under error; a refused key raises under both. |
| cancel.rs | A timed-out or cancelled request resets its HTTP/2 stream, proven at the server. |
| keepalive.rs | Pings while a scan runs and only then, and an unanswered one replacing the connection. |
| dns.rs | Host names resolved through hickory on the executor, against jev.dns_servers. |
| latency.rs | The extension's own overhead per call, against a mock that answers instantly. |
| stats.rs | jev_stats() counts this session's work, and every retry, redial and answer is logged at DEBUG1 with its request id. |
| api_key.rs | The key from exactly one place: TYPESAFE_API_KEY or jev.api_key_file, never both. |
| privileges.rs | Spending takes an explicit GRANT, and no function is executable by PUBLIC. |
| settings.rs | Settings checked when they are set, not only when used. |
| replay.rs | Fixture replay by exact request bytes, and a request the fixture lacks failing with the request named. |
| gate_layout_parity.rs, gate_unsure_band.rs, gate_label_tree.rs, gate_ranking.rs | Each release gate's recorded live answers replayed through the extension, so a change to what it sends fails naming the request (chapter 15). |
| sidecar.rs | The scan over a postgres_fdw loopback foreign table, and a server listing this extension in extensions refused at plan time. |
| sidecar_cli.rs | The sidecar CLI against a throwaway target and sidecar (chapter 12). |
For the people who maintain it
| Path | What |
|---|---|
| support/ | The library every test shares: the throwaway Postgres, the instance wired to the mock, the gates' rows and SQL. Chapter 14. |
| fixtures/ | The release gates' recorded live answers. Chapter 15. |
| BUCK | One first_party_test per file, each given the built extension, the server of its major and the fixtures through the environment. |
| run-check.sh | The repo's whole check, nix develop -c buck2 test //..., queued on a lock so two checks in one checkout do not race the same buck daemon. Mefi Studio runs it to verify finished agent work. |
← Previous: Chapter 12, cli/ · Up: postjevsql · Next: Chapter 14, support/ →