Skip to content

The PostgreSQL 17 cap tests expect the managed-conf behavior: the old value in darling-managed.conf is capped, and an operator's out-of-range line refuses the start - #4463

Merged
erikdarlingdata merged 5 commits into
devfrom
fix/nightly-475-mwm-operator-line
Sep 27, 2026
Merged

erikdarlingdata merged 5 commits into
devfrom
fix/nightly-475-mwm-operator-line

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

Why

Postgres17Store_WithTheOldCapInItsConf_StartsThroughTheBootstrap_Gated simulated "a build before #3909" by
appending a bare, unmarked maintenance_work_mem = 2048MB line to postgresql.conf after the first
EnsureRunningAsync() call. That first call already migrates the store's conf to the one included
darling-managed.conf file, so the appended line landed below the include -- the exact position an
operator's own line occupies, per the migration classifier's own rule.

History confirms this: every write of maintenance_work_mem this service has ever made carries its own
marker, never a bare line.

History: how maintenance_work_mem was written

No commit ever wrote maintenance_work_mem bare below the include. The test's setup line was never a shape
this product produces -- confirming this is a stale test (S), not a product defect.

What changes

Test-only, in Darling/Darling.Tests/DarlingManagedPostgresTests.cs. No product code changed.

  1. Postgres17Store_WithTheOldCapInItsConf_StartsThroughTheBootstrap_Gated is renamed and reworked to
    Postgres17Store_WithTheOldValueInItsManagedConf_StartsWithTheCap_Gated: after the first start, it
    replaces the one maintenance_work_mem assignment inside the rendered darling-managed.conf with the
    old, uncapped 2048MB -- the shape the managed file itself can carry -- then recomputes the header's
    # body-sha256= line over the edited body, the same way the product's own write path would, so the file
    still reads as the product's own render (ManagedConfFile.IsHandEdited is asserted false on it) rather
    than an operator hand edit. A hand edit is never overwritten and would only ever reach the last-good
    fallback in EnsureManagedConfReadyAsync, never the re-render this fact means to pin. It then asserts
    the second start:

    • took the re-render path, not the last-good fallback: second.LastManagedConfWriteResult shows
      Written: true, HandEdited: false, and second.LastStartUsedLastGoodManagedConf is false;
    • leaves exactly one maintenance_work_mem assignment in darling-managed.conf, and it isn't the old
      2048MB;
    • runs the server on exactly the value the re-render wrote (read back from the file), and that value is at
      or under the 2047 MB cap.

    The rendered value depends on the host's RAM. The first test-only run on this branch expected the cap
    itself and failed on a CI runner whose RAM renders 1536 MB, under the cap, so the cap never engaged. The
    product has no seam to pin the RAM input, and adding one would be a product change, so the fact now
    asserts the host's own render instead. ManagedConfFileTests pins the cap arithmetic for any RAM without a
    server.

    • leaves postgresql.conf carrying the include and no maintenance_work_mem line of its own.
  2. New fact Postgres17Store_OperatorLineBelowIncludeOutOfRange_RefusesToStartNamingTheFix_Gated: appends
    a bare, out-of-range line below the include (the honest shape of an operator edit) and asserts the second
    start throws InvalidOperationException naming maintenance_work_mem and the fix instruction from
    BuildManagedConfValidationFailureMessage, then that the store is not left running (stop is a safe
    no-op, and a connection attempt fails). Its doc comment no longer claims this data directory has never
    had a last-good file -- the first start above already succeeded, so it saved one
    (DarlingManagedPostgres.SaveLastGoodManagedConf), and the test now asserts that file exists before the
    second start. The fallback is tried and still refused, because the rejected line lives in
    postgresql.conf below the include, not in darling-managed.conf: restoring the last-good managed file
    leaves the operator's own line in place untouched.

Both facts stay gated on DARLING_TEST_PGRUNTIME_OLD, Windows, and pg_ctl.exe present, same as before.

Both facts read conf lines as ACTIVE assignments through the product's own parser (DarlingManagedPostgres.ParseConfText, via a small ActiveValues helper), never as raw substrings: initdb writes commented sample lines such as #maintenance_work_mem = 64MB into postgresql.conf, and a substring check on the key name matches them. The non-gated fact ActiveValues_SkipsInitdbsCommentedSampleLines_AndCountsAnOperatorLine pins that with lines copied from PostgreSQL 17's postgresql.conf.sample.

Gated tests that must pass

These run only on a test-only nightly.yml run (publish=false); PR CI doesn't run them.

  • Postgres17Store_WithTheOldValueInItsManagedConf_StartsWithTheCap_Gated
  • Postgres17Store_OperatorLineBelowIncludeOutOfRange_RefusesToStartNamingTheFix_Gated
  • Postgres17StoreWithTheOldCap_StartsAfterTheHeal_Gated (unchanged; must stay green)

Test plan

  • dotnet build Darling/Darling.Tests/Darling.Tests.csproj -c Release -p:EnableWindowsTargeting=true: 0
    warnings, 0 errors.
  • dotnet build Lite.Tests/Lite.Tests.csproj -p:EnableWindowsTargeting=true: 0 warnings, 0 errors.
  • In-process run on macOS (DarlingManagedPostgresTests, no DARLING_TEST_PGRUNTIME_OLD set): both new
    gated facts SKIP for the expected reason; 181 total, 5 failed -- all five are pre-existing macOS
    path-separator failures unrelated to this change (ResolveDataDirectory_TrimsATrailingSeparator,
    PathConventions_DefaultDataDirectory_AndCredentialBesideIt, RoleCredentialPaths_BesideTheDataDirectory,
    McpCredentialPath_BesideTheDataDirectory_AndDistinctFile,
    EnsureConfAppended_ThreeExistingV8Blocks_CollapseToOneOnTheNextHeal), none in the file this PR touches.
  • DocCommentHygieneTests: 77/77 green.
  • Two fast, non-gated pins already on dev cover fact 1's cap from two different angles, and are named
    here (not added new) for what each one actually pins:
    • ManagedConfFileTests.RenderBody_CarriesEveryManagedConfMarkersOwnedKeys (its class summary, ~line 387)
      pins the RENDER itself: DeriveMemorySettings's formula caps maintenance_work_mem at
      MaintenanceWorkMemCapMb for ANY RAM size a fresh render can derive -- this is the per-start render
      fact 1 exercises through the product's own bootstrap.
    • ManagedConfMigrationRunnerTests.RunStepA_CarriedMaintenanceWorkMemOver2047_Postgres17_Caps pins the
      one-time Move the managed store's settings into one included file, darling-managed.conf (#4215) #4336 Step A migration's carry-over instead: a pre-existing, over-limit value already on disk
      from before the render's own cap existed, capped once when Step A runs.
      Both ran green (33/33 in ManagedConfFileTests; the Step A class also green).
  • The two gated facts themselves cannot run on macOS (Windows-only bundled runtime) and both SKIP for the
    expected reason (no DARLING_TEST_PGRUNTIME_OLD set); they are named above for the nightly workflow
    run to confirm.

Total

  • DarlingManagedPostgresTests: Total: 181, Errors: 0, Failed: 5, Skipped: 10, Not Run: 0 (the 5 failures
    are the same pre-existing macOS path-separator failures listed above, unrelated to this change and present
    identically with this change reverted).
  • ManagedConfFileTests: Total: 33, Errors: 0, Failed: 0, Skipped: 0, Not Run: 0.
  • DocCommentHygieneTests: Total: 77, Errors: 0, Failed: 0, Skipped: 0, Not Run: 0.

CHANGELOG entry

None: a test-only change. The product's managed-conf behavior on PostgreSQL 17 was already correct; only the test's out-of-date expectation changes.

Refs

Refs #4336 (the commit that moved settings into darling-managed.conf and made the old test's setup line an
operator line), #3909 (why the cap exists at all), #4405 (lines below the include are the operator's; across a major upgrade they are carried and probed), #4444 (a different, unrelated fix that this
PR does not touch or depend on).

The gated PostgreSQL 17 maintenance_work_mem cap test simulated a
pre-#3909 build by appending a bare, unmarked line to
postgresql.conf after the store's conf had already migrated to the
one included darling-managed.conf file (#4336). No build of this
service has ever written that setting bare; every write (v3, v7, v8,
v14) carries its own marker. So the appended line was, by the
migration classifier's own rule, an operator's line below the
include -- and the product now correctly refuses to start on it
rather than silently absorb it.

Two gated facts replace the one:
- Postgres17Store_WithTheOldValueInItsManagedConf_StartsWithTheCap_Gated
  puts the old, uncapped value directly into darling-managed.conf
  (the shape the file can carry) and asserts the second start comes
  up with the value capped, exactly one assignment in the managed
  file, and no maintenance_work_mem line in postgresql.conf itself.
- Postgres17Store_OperatorLineBelowIncludeOutOfRange_RefusesToStartNamingTheFix_Gated
  appends the bare operator line below the include and asserts the
  second start throws, naming the setting and the fix, and never
  leaves the store running.
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review September 27, 2026 11:08
@erikdarlingdata
erikdarlingdata merged commit 38f142f into dev Sep 27, 2026
23 of 24 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/nightly-475-mwm-operator-line branch September 27, 2026 11:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant