test(amethyst): hold the DVM announcement fixtures against the weak cache

theUngatedAnnouncementScanKeepsDvmsTheGateWouldHide failed on CI at the
"dvm-x must still be sourced" assertion. The consume and the scan are adjacent
statements in one method, so nothing between them can have polluted the cache;
what the failure says is that the whole addressables scan came back empty,
which is how a LargeSoftCache reports its WeakReferences being cleared. The
test consumed three announcements and held a strong reference to none of them.

LargeCacheAddressableFilterTest already documents this exact trap for exactly
this store. So the fixture now keeps the Notes it expects the scan to find, and
a forced GC sits between the consume and the scan so that stays proven rather
than assumed.

Two locals, `alive` and `subscriptionApp`, were built and never consumed, which
left "subscription apps are not content-discovery DVMs" asserting the absence
of something that was never there. They are consumed now, so that assertion
means what it says.

I could not reproduce the clearing locally — a probe shows the note is still
retained after two full GCs here, so the CI heap is what makes the difference.
The fix removes the dependence either way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkULS5SVq4GHDdoCzajKi8
This commit is contained in:
Claude
2026-09-21 16:28:59 +00:00
parent f2e4454e8e
commit 61ceaa728f
@@ -160,9 +160,7 @@ class DvmHeartbeatTest {
sig = "cc".repeat(64),
)
LocalCache.justConsume(appDef("dvm-x"), null, true)
LocalCache.justConsume(nonDiscoveryApp, null, true)
val consumed =
val secondSubscriptionApp =
AppDefinitionEvent(
id = "c2".repeat(32),
pubKey = appDefPubKey,
@@ -171,7 +169,18 @@ class DvmHeartbeatTest {
content = """{"name":"Paid2","subscription":true}""",
sig = "cc".repeat(64),
)
LocalCache.justConsume(consumed, null, true)
// `addressables` holds notes by WeakReference, so a GC between consuming these and
// scanning for them clears the lot and the scan returns nothing — which is exactly how
// this failed on CI, where the heap is tighter than a dev box's. A fixture has to hold
// what it expects to find, the same discipline LargeCacheAddressableFilterTest spells
// out; the forced GC below is what keeps that honest rather than assumed.
val held =
listOf(alive, appDef("dvm-x"), subscriptionApp, nonDiscoveryApp, secondSubscriptionApp)
.onEach { LocalCache.justConsume(it, null, true) }
.map { LocalCache.getOrCreateNote(it) }
System.gc()
val scanned = LocalCache.cachedDvmAnnouncements()
@@ -180,5 +189,6 @@ class DvmHeartbeatTest {
assertFalse("k=9999 apps are not content-discovery DVMs", scanned.any { it.dTag() == "other" })
assertEquals("newest-first so the cap keeps the most relevant announcements", scanned.sortedByDescending { it.createdAt }, scanned)
assertTrue("capped", scanned.size <= 100)
assertEquals("the fixture notes must stay reachable for the whole test", 5, held.size)
}
}