test(upgrade): pin typed-struct plateau on legacy-origin in-place upgrade (QA-606)#1870
test(upgrade): pin typed-struct plateau on legacy-origin in-place upgrade (QA-606)#1870kriszyp wants to merge 1 commit into
Conversation
…rade (QA-606) Regression anchor for the §2 G(cross-major-upgrade) × A(width-heterogeneous) interaction: a harperdb@4.7.34 -> current-main in-place-upgraded table, once `randomAccessFields: true` is active and NEW width-drifting writes are driven against it, must NOT route onto the unbounded typed-struct minting path (#1453-class OOM). It must plateau its typedStructs count identically to a fresh-install control under the same generator. Controlled A/B on one instance: the "upgraded" arm (WidthDrift, the QA-478 v4-origin migrated dataset) vs a "fresh control" arm (FreshControl, created by current main with an explicit randomAccessFields directive). Both driven by the identical width-heterogeneous generator at the same cadence. Verdict: both plateau at typedStructs=38 (cap 256), ratio 1.00x -> the OOM class does not reproduce on legacy-origin tables. Skips (like the sibling 4.x-upgrade.test.ts) unless HARPER_LEGACY_VERSION_PATH points at a v4.x `harperdb` install -- CI must provision one or this silently skips. Promoted from qa-explorer QA-606 / candidate P-395. Cold-gated GREEN on main 56a2bac (3/3 runs). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a new integration test suite (qa606-upgrade-structgrowth.test.ts) and its associated custom resource components to verify that an in-place upgraded database table plateaus its typed-struct count under a width-heterogeneous write workload when randomAccessFields is enabled, preventing OOM regressions. The reviewer feedback suggests replacing several instances of the global fetch API with the authenticated client.reqRest helper to ensure consistency, proper authorization, and cleaner response parsing.
| ); | ||
|
|
||
| // ── PRECONDITION 2 (hard): the migrated dataset decodes clean BEFORE we touch it ─ | ||
| const scan = await fetch(`${ctx.harper.httpURL}/ScanVerify606/?table=WidthDrift`).then((r) => r.json()); |
There was a problem hiding this comment.
Use the authenticated client.reqRest helper instead of the global fetch API. This ensures consistency with the rest of the test suite, automatically includes the required authorization headers, and avoids potential 401 Unauthorized errors if authentication is enforced on custom resources.
| const scan = await fetch(`${ctx.harper.httpURL}/ScanVerify606/?table=WidthDrift`).then((r) => r.json()); | |
| const scan = (await client.reqRest('/ScanVerify606/?table=WidthDrift')).body; |
| const preFlip = (await ( | ||
| await fetch(`${ctx.harper.httpURL}/StructReport606/?table=WidthDrift`) | ||
| ).json()) as StructReportResult; |
There was a problem hiding this comment.
| const postFlipWidthDrift = (await ( | ||
| await fetch(`${ctx.harper.httpURL}/StructReport606/?table=WidthDrift`) | ||
| ).json()) as StructReportResult; |
There was a problem hiding this comment.
| const postFlipFreshControl = (await ( | ||
| await fetch(`${ctx.harper.httpURL}/StructReport606/?table=FreshControl`) | ||
| ).json()) as StructReportResult; |
There was a problem hiding this comment.
|
Reviewed; no blockers found. |
cb1kenobi
left a comment
There was a problem hiding this comment.
I'm not sure I understand what this pull request is doing.
| typedStructs: enc && Array.isArray(enc.typedStructs) ? enc.typedStructs.length : null, | ||
| classicStructures: enc && Array.isArray(enc.structures) ? enc.structures.length : null, | ||
| maxOwnStructures: enc ? (enc.maxOwnStructures ?? null) : null, | ||
| storeCtor: store && store.constructor && store.constructor.name, |
There was a problem hiding this comment.
nit: could be simplified:
| storeCtor: store && store.constructor && store.constructor.name, | |
| storeCtor: store?.constructor?.name, |
Ethan-Arrowood
left a comment
There was a problem hiding this comment.
LGTM. Solid regression anchor — it pins the real invariant (a legacy-origin, in-place-upgraded table plateaus its typed-struct count instead of the #1453 OOM growth under randomAccessFields writes), and it's genuinely CI-exercised rather than dark: the integration workflow installs harperdb@4 and sets HARPER_LEGACY_VERSION_PATH, and the fail-loud preconditions (migration ran, decode-clean, structure flipped) stop it from silent-skipping to a false green. Green across Node 22/24/26.
Two non-blocking notes: worth folding in the fetch→client.reqRest consistency cleanup, and keep an eye on the added CI wall-clock (legacy boot + migrate + 2 restarts + 36k inserts, ~600s timeout) as the upgrade suite grows.
sent with Claude Opus 4.8
What this pins
A qa-explorer regression anchor for the §2 G(cross-major-upgrade) × A(width-heterogeneous) interaction — the corner QA-478 explicitly left uncovered.
QA-478 proved a
harperdb@4.7.34 → current-mainin-place upgrade migrates width-drifting records decode-clean, but it never drove new writes against the upgraded table withrandomAccessFields: trueactive — so it never exercised the unbounded typed-struct minting path (the #1453-class OOM). This spec closes that gap.Controlled A/B on one instance, identical width-heterogeneous generator + cadence on both arms:
WidthDrift, the v4.7.34-created, in-place-migrated dataset (a table with no persistedrandomAccessFieldsdirective, so it follows the global default on open).FreshControl, created by current main with an explicitrandomAccessFields: true.Verdict (green): both arms plateau at
typedStructs = 38(cap 256), upgraded/fresh ratio 1.00x — the OOM class does not reproduce on a legacy-origin table; the upgraded arm tracks the fresh-install control.Provenance & gating
56a2bace9— 3/3 runs (both armstailFlat=true, legacy precondition fired, i.e. not a silent skip). oxlint + prettier clean.This spec skips (like its sibling
integrationTests/upgrade/4.x-upgrade.test.ts) unlessHARPER_LEGACY_VERSION_PATHpoints at an installed v4.xharperdbpackage. It rides the same env var and skip-guard the existing 4.x upgrade suite already uses — no new mechanism — but CI must provision a v4.xharperdbinstall for it to actually run rather than skip.🤖 Generated with Claude Code