Repository navigation
Serialize the live classes that share the store, document the ones that do not (#1776) - #1783
Merged
erikdarlingdata merged 7 commits intoJul 28, 2026
Merged
Conversation
…at do not (#1776) Verified the issue's classification rather than applying it, and it moved in both directions. FOUR classes share the DARLING_TEST_PG database and now carry [Collection("live-postgres")]: StoreConfigProviderTests, DarlingEndpointToggleCliTests, ExcludedDatabasesStoreLiveTests, and the live compose round-trip. The issue listed three; DarlingComposeTests was missed and is the most aggressive of them, since it runs PgMigrations.MigrateAsync (DDL) against the shared store. It does NOT take the attribute directly. The class holds 127 tests, 126 of them pure, and serializing all of them to protect one is the slowdown the issue itself warns against. The live test is split into DarlingComposeLivePostgresTests, the shape roughly thirty files here already use. The parent's doc claimed "the live round-trip is exercised elsewhere", which is now true. THREE of the issue's six were substring false positives. DarlingManagedPostgresTests, DarlingStoreUpgradeTests and DarlingPgRuntimeVersionPinTests never read DARLING_TEST_PG at all - they read DARLING_TEST_PGRUNTIME (and _OLD / _NEWZIP), different variables that merely share the prefix. "Do not serialize" was the right answer for the wrong reason, so the recorded reason says which. TWO more were missed, both exempt: DarlingAlertTuningKnobsTests and DarlingDeliveryModeTests reach DARLING_TEST_PG only to CREATE and DROP their own database via ScratchPostgres. PayloadDimensionTests mentions the variable in prose only, like AlertEngineTests, and is out of scope. The meta-test matches the QUOTED literal, so DARLING_TEST_PGRUNTIME and doc- comment prose cannot match, and demands a decision rather than the attribute: either [Collection("live-postgres")] or an "#1776 own-store" comment. The failure message spells out both options and points at the split as the preferred shape for a mostly-pure class. Recorded on the three serialized classes: rolling the writes back protects the DATA, not the CONCURRENCY - an uncommitted write still holds its row locks and still fires the config_version bump trigger. That is why the existing "transaction-rolled-back" comments did not make them safe. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The project is flat today, so this is equivalent - but TopDirectoryOnly means the first test file someone puts in a subfolder escapes the rule silently, which is the exact failure mode the test exists to prevent. Verified while checking for holes: the quoted literal appears nowhere else in the repo, and [Collection] groups classes within an assembly, so scoping to this project is correct rather than lazy. Both facts are now recorded in the code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
erikdarlingdata
added a commit
that referenced
this pull request
Jul 28, 2026
Verified rather than estimated: 44 files declare a *LivePostgresTests class. The original figure understated it, and an inaccurate number in a rationale is still an inaccurate number. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Verified rather than estimated: 44 files declare a *LivePostgresTests class. The original figure understated it, and an inaccurate number in a rationale is still an inaccurate number. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
erikdarlingdata
force-pushed
the
feature/1776-live-postgres-collection-sweep
branch
from
July 28, 2026 04:06
78afcc8 to
81ad2cf
Compare
…gres-collection-sweep # Conflicts: # CHANGELOG.md
#1783) Reviewer addendum: the guard worked only because every ScratchPostgres consumer happens to duplicate the DARLING_TEST_PG read at its own call site. A routine DRY refactor moving that read into the helper would have blinded it for every consumer at once, silently - the exact failure it exists to prevent. A ScratchPostgres.CreateAsync reference now counts as a shared-store touch, because it is one: the helper connects to the DARLING_TEST_PG server and issues CREATE DATABASE on it. The rule follows REACHING the store rather than the spelling, so the legitimate refactor survives instead of being quietly forbidden. Matched with the trailing .CreateAsync( for the same reason the variable is matched quoted: prose says 'through ScratchPostgres' and a test method is named ...AgainstScratchPostgres, neither of which is a store access, and the helper's own file declares Task<ScratchPostgres> CreateAsync( and new ScratchPostgres(, so it does not match itself. Watched red: with the marker removed AND the env-var read made indirect - zero DARLING_TEST_PG literals left in the class, i.e. the post-refactor state - the guard still flagged DarlingAlertTuningKnobsTests.cs:27 via the new trigger. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…gres-collection-sweep # Conflicts: # CHANGELOG.md
erikdarlingdata
enabled auto-merge
July 28, 2026 04:21
erikdarlingdata
added a commit
that referenced
this pull request
Jul 28, 2026
Resolved to get CI to run at all, not as an arm-time step: a CONFLICTING PR has no merge ref, and pull_request workflows build the merge ref -- so Build and Claude Auto Review could not start on this PR while the conflict stood, while other branches' runs kept firing normally. That is what made this look like an Actions outage for ~25 minutes. CHANGELOG.md was the only conflict, and only in the link-ref block. Resolved KEEP-BOTH with no re-sorting: this branch's #1665/#1788 refs and dev's #1781/#1783/#1786/#1792 refs all retained, in the order they appeared. No entry text on either side was touched. Everything else auto-merged. Verified rather than assumed, because the dangerous case here is textual cleanliness hiding a semantic break: full solution rebuild 0 warnings / 0 errors, Darling suite 3549 passed / 0 failed. The one real collision this class of merge produced -- #1776's new live-store hygiene guard versus this branch's new own-store live test -- was found the same way and fixed in 59f877a before this merge. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 30, 2026
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.
Closes #1776.
I verified the issue's classification against the source rather than applying it, and it moved in both directions: one aggressor was missed, and three of the six were substring false positives.
Corrected classification
StoreConfigProviderTestsDarlingEndpointToggleCliTestsExcludedDatabasesStoreLiveTestsDarlingComposeTestsDarlingAlertTuningKnobsTestsScratchPostgres)DarlingDeliveryModeTestsScratchPostgres)DarlingManagedPostgresTestsDARLING_TEST_PGDarlingStoreUpgradeTestsDARLING_TEST_PGDarlingPgRuntimeVersionPinTestsDARLING_TEST_PGPayloadDimensionTestsAlertEngineTestsThe missed aggressor is the significant one.
DarlingComposeTests.RunComposedPanel_OldWindow_AgainstPlainPostgres_RunsCleanOnRawconnects straight to the shared database and runsPgMigrations.MigrateAsyncagainst it — DDL, concurrently with the sixty-odd serialized classes. That makes it the most aggressive of the four, and it was not on the list.Three of the six were a substring artifact.
DarlingManagedPostgresTests,DarlingStoreUpgradeTestsandDarlingPgRuntimeVersionPinTestsreadDARLING_TEST_PGRUNTIME(and_OLD/_NEWZIP) — different variables that merely share the prefix withDARLING_TEST_PG. They never touch the shared store at all. "Do not serialize them" was the right answer reached for the wrong reason, so the comment on each records which reason actually applies; otherwise the next sweep re-derives the same false positive.The judgement call on DarlingComposeTests
It does not take the attribute directly. The class holds 127 tests, 126 of them pure, and dragging all of them into the serialized collection to protect one live test is exactly the "slow the suite for no safety gain" the issue warns about. The live test is split into
DarlingComposeLivePostgresTests, which is the shape 44 other files in this project already use (counted, not estimated): a...SurfaceAndSqlTests/...LivePostgresTestspair. The parent class's doc comment already claimed "the live compile-and-run round-trip is exercised against a real store elsewhere" — that is now true rather than aspirational.Why the rollback comments did not make those classes safe
Two of the three serialized classes documented themselves as "transaction-rolled-back so they never clobber a shared dev store's singleton config rows", which reads like an exemption and is not one. Rolling back protects the data, not the concurrency: an uncommitted write still holds its row locks for the life of the transaction and still fires the
config_versionbump trigger. That is recorded on each class, because the next reader will otherwise draw the same wrong conclusion the comment invites.The meta-test
LivePostgresCollectionHygieneTestsrequires every class that reads the shared store to either carry[Collection("live-postgres")]or record an#1776 own-storeexemption. It demands a decision, not the attribute — a class that mints its own database genuinely should not serialize.Two details that matter:
"DARLING_TEST_PG", not a substring. That is what keepsDARLING_TEST_PGRUNTIMEout, and it also keeps out doc-comment prose (which writes the name bare), so a class that merely describes the variable is not dragged in. Matching the way the issue's original sweep did would make this test permanently red on three innocent classes.DocCommentHygieneTests: a guard that silently skips is a guard that silently stops guarding.The failure message names each offender with file and line and spells out both remedies, including the recommendation to split rather than serialize a mostly-pure class.
Mutation
[Collection("live-postgres")]fromStoreConfigProviderTestsStoreConfigProviderTests.cs:35 StoreConfigProviderTests, followed by the "Pick one, deliberately" guidanceWorth noting what M4 also proved: the explanatory comment left on the serialized classes begins
#1776:while the exemption marker is#1776 own-store, and the guard correctly refused to accept the former as an exemption. The two markers do not collide.Verification
Darling.Testsfull suite against a live PostgreSQL 18 + TimescaleDB 2.28.1 rig: 3649 passed, 0 failed, 7 skipped (base plus the one new meta-test; the compose split moves tests between classes without changing the count).dotnet build Darling/Darling.Tests/Darling.Tests.csproj -c Debug -t:Rebuild— 0 Warning(s), 0 Error(s).No production code is touched; this is test infrastructure only.
🤖 Generated with Claude Code