# v0.26.0 — Test and Concurrency Hardening

> **Full technical details:** [v0.26.0.md-full.md](v0.26.0.md-full.md)

**Status: ✅ Released** | **Scope: Large** (~7–8 weeks)

> Systematic testing of concurrent operations, fuzz targets for every parser
> and configuration path, a complete code modularisation of the refresh
> engine, and tighter error handling throughout.

---

## What problem does this solve?

After v0.25.0's performance improvements, the focus shifted to correctness
under concurrent operations — situations that are difficult to test but very
much happen in production: modifying a stream table while it is being
refreshed, dropping one while a refresh is in-flight, two worker processes
racing to claim the same task. These scenarios had not been explicitly tested.

---

## Concurrency Test Matrix

Four concurrent-operation scenarios are now tested with deterministic end-to-end
tests:

**ALTER + REFRESH** — one database connection runs `alter_stream_table(query => ...)`
while another is mid-refresh. Expected outcome: no deadlock, no catalog corruption.
Either the refresh completes with the old query or is cleanly aborted and
retried with the new query.

**DROP + REFRESH** — `drop_stream_table()` is called while a refresh is in
progress. Expected outcome: clean abort, no orphaned change buffers, no
dangling catalog rows.

**Parallel worker duplicate pick** — two worker processes must never claim
the same stream table for simultaneous refresh. Deterministic test: pre-register
a slow refresh under one worker; verify the second worker picks a different task.

**Concurrent canary promotion race** — if two refreshes both trigger a canary
buffer promotion at the same time, exactly one succeeds and the metadata
is consistent afterward.

---

## Predictive Model Accuracy Harness

A dedicated test suite validates that the predictive cost model from v0.22.0
behaves correctly under three synthetic workload shapes:

- **Sawtooth** — alternating large and small change batches
- **Bursty** — occasional large spikes with mostly quiet periods
- **Single spike** — one extreme outlier in an otherwise steady workload

The harness verifies that the model recovers within N samples after an outlier
and that pre-emptive FULL refresh only fires when it would actually be faster.

---

## SLA Tier Oscillation Damping

The SLA-driven tier assignment from v0.22.0 could oscillate — a stream table
repeatedly moving between tiers as its refresh latency hovered near a tier
boundary. **Hysteresis** prevents this: 3 consecutive SLA breaches are
required before downgrading a tier, and 3 consecutive successes before
upgrading. A property test with randomised latency distributions around the
SLA boundary verifies tier stability.

---

## Fuzz Targets

Three new fuzz targets run in CI:

- **Cron expression parser** — pathological input strings for `parse_cron_expr()`,
  guarding against denial-of-service via slow parsing
- **GUC string-to-enum coercion** — fuzz all configuration value parsing
  (`refresh_mode`, `cdc_mode`, `change_buffer_durability`, `diff_output_format`)
- **CDC trigger payload** — fuzz the trigger payload deserialization path
  with malformed row data

Each fuzz target runs for 10 million iterations in CI without panics.

---

## ARCH-1B: Refresh Engine Modularisation

The `src/refresh.rs` module — which grew to 8,400 lines over the project's
history — was split into four focused sub-modules:

- `refresh/orchestrator.rs` — scheduling integration, adaptive mode selection
- `refresh/codegen.rs` — delta SQL template construction
- `refresh/merge.rs` — DIFFERENTIAL, FULL, and TopK MERGE executors
- `refresh/phd1.rs` — phantom row cleanup logic

The public API and all tests are unchanged. This is a pure code organisation
improvement that reduces the risk of unintended interactions between concerns.

---

## Typed Error Variants

Bare `pgrx::error!()` calls in the diagnostics, monitoring, and publication
modules were replaced with typed `PgTrickleError` enum variants:

- `DiagnosticError` — errors from diagnostic and inspection functions
- `PublicationError` — errors from downstream publication management
- Scheduler timestamp errors now include a HINT suggesting "check system clock"

Typed errors are more consistent, easier to test, and produce more actionable
messages for operators.

---

## Scale Tests

Two scale tests (run as opt-in `#[ignore]` tests) validate at larger scale:

- **1,000-partition source table** — trigger installation and first refresh
  complete within 60 seconds
- **Multi-database worker starvation** — two databases sharing a worker pool;
  one floods the pool while the other's hot-tier stream table must still
  refresh within its SLA

---

## Scope

v0.26.0 is the most comprehensive testing release in the project's history.
The concurrency tests catch races that could only manifest in production,
the fuzz targets catch parser crashes before they reach users, and the
modularisation reduces future maintenance risk. The result is a codebase
significantly more trustworthy for long-term production operation.
