Repository navigation
test: persona soak harness with an invariant oracle - #624
Merged
Merged
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
Mia, Tom, Priya, Sam, Alex and a chaos agent run concurrently against one disposable database on the queue-storage engine. An oracle checks duplicate terminal rows, terminal-and-live overlap, unexplained cancels, stalls, promotion lag, lost jobs, cron double-fires and server crashes, and a failed run writes a reproducer. scripts/persona-soak.sh runs the engine matrix in private containers.
… handlers, document the new personas
…h recovery from the statistics reset
…, exit the Python process with its parent
…te, resume paused queues reliably, treat unfinished backlog as a finding
hardbyte
force-pushed
the
brian/persona-soak-0.6
branch
from
November 5, 2026 13:07
34e1148 to
32117ac
Compare
21 tasks
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.
Review prerequisite
Merge this branch only with #644, including the corrected shared oracle at
412419f864567c29386d9651cad93b82f6ddd997. This head still uses the earlier oracle. The corrected harness requires durable attempt-specific terminal proof, treats failed final lookups as inconclusive, accounts for materialized claims, and handles Python startup/drain restarts. It correlates migration sessions with probe phases, fences reads crossing process kills, keeps terminal observations tied to the greatest proven lease, and requires successfulCLOSEDproof before reporting a retained-session leak. Ambiguous or missing evidence remains inconclusive; still-live losses and proven conflicts remain failures.Historical results below predate these corrections and need validation with the corrected harness before release acceptance. Those reports have not been recomputed or retrospectively cleared.
What this adds
A persona-driven soak harness with an invariant oracle, for validating a release candidate and as the base for later readiness work. Eleven personas run concurrently against one disposable database on the queue-storage engine, the way several applications share an
awaschema.awa/tests/persona_soak_test.rsis one ignored test binary; the harness is inawa/tests/persona_soak/(config, connection budget, ledger, oracle, report, one module per persona) andawa/tests/persona_soak/python/soak_python.py.scripts/persona-soak.shruns the engine matrix in private Docker containers (postgres:17,postgres:18, an assert-enabled-O0PostgreSQL 18 image) on separate ports and removes them afterwards.docs/test-plan.mdhas a "Persona soak" section with the variables.Personas
insert_manybursts (above the bind limit), COPY batches, tiny jobs, three runtimesqueue_stripe_count), scheduled jobs, a rate-limited queueawa serveserverbefore_idpaging, job detail, DLQ, runtime, cron and kind pagesawa-pythonprocess: single inserts, a 6,500-row transactionalinsert_many, COPY, enqueues in transactions that sometimes roll back; async workers (complete, raise,RetryAfter,Snooze, progress, deadline overrun, a handler that ignores its deadline) on queues one of which is shared with a Rust runtime; a periodic migrate-then-query probeInvariants
Checked while the load runs and again after it stops, against a client-side ledger (terminal rows are pruned by ring rotation within seconds, so the database alone cannot answer):
migrate()pg_postmaster_start_time(), crash-recovery detected from the statistics reset time, andterminated by signal,TRAP:,server process (PIDand similar lines in the server logSlow or failing admin endpoints and latency that grows with history or backlog are reported as non-fatal findings. A failed run writes
report.md,report.jsonandreproducer.md(seed, personas, violating rows, timeline, server log excerpt).Running it
The UI personas need
cargo build --release -p awa-cli; the Python persona needs a virtualenv built withuv venv awa-python/.venv && uv pip install maturin && (cd awa-python && maturin develop --release). The script does both.AWA_SOAK_PERSONAS,AWA_SOAK_SECONDS,AWA_SOAK_SEED,AWA_SOAK_SCALE,SOAK_PG_CPUSand the oracle thresholds are described indocs/test-plan.md.Results
All runs on the queue-storage engine, load phase length in the first column, seed and persona set as shown. Containers were capped at 12 CPUs for the 75-minute runs and the final PostgreSQL 17 run; the host has 24.
promotion_stall(3 jobs, 10.2 s) right after a graceful restart of the leader: the leader handover gap (leader_election_interval, 10 s). The harness did not widen its window after restarts; fixedlost_job(48 firehose jobs). Harness race: a producer overwrote the ledger entry of jobs a worker had already run; fixed. Not reproduced since, with forensics enabledpromotion_stallx3 (15-19 s) while the admin queries held the container at 1,839% CPUpromotion_stallx31 (overdue up to 124 s), see below-O0, 75 min, scale 0.1terminated by signallines or crash recovery.promotion_stallx24 (up to 140 s) on a server at 1,190% CPUThe assert-enabled run used the instrumented
awa-pg18-cassert:18.6-O0-epqlog5image, which logs every run-time partition-pruning setup with its query text (about 190 MB/s under this workload).scripts/persona-soak.shfilters those messages through a FIFO for that image and defaults to the uninstrumentedawa-pg18-cassert:18.6-O0build, which needs no filter.75-minute run activity (PG18 release): 2.0M firehose jobs and 25 100k-row bursts, 376k Python jobs (56 batch inserts of 6,500 rows, 3,395 rolled-back enqueues, none visible afterwards), 1,851 cron fires, 37 runtime kills, 19 Python kills, 28 leader terminations, 405 terminated connections, 19 pool exhaustions, 16 rolling restarts, 33 queue pauses. Peak 225 connections of 400, database 3.7 GB at the end, container average 714% CPU (peak 1,221%) and 9 GB memory.
Observations on AWA
These are not invariant violations; they are what the UI and operator personas saw.
GET /api/kindscallsadmin::job_kind_overviewsuncached. Itscurrent_jobsquery takes about 2 s with fresh planner statistics and did not finish in 120 s after the schema's statistics were removed. Under mixed load it ran past 150 s in every 15-minute run. The other overview endpoints degrade with backlog and retained history too: with the PG18 75-minute run's firehose backlog,/api/queues,/api/stats,/api/stats/timeseriesand/api/jobshad median latencies of 2.5-7 s and p99 of 38-41 s. Each slow poll starts another query, so the pool fills and the server returns 500s.GET /api/jobs?tag=...did not answer within a 45 s client timeout against a large table.-O0server. The episodes follow leader terminations and rolling restarts of the leader but also occur outside chaos windows; both runs had the container at its CPU limit for long stretches. Not isolated further here.