From def075ced0db1358dfdb0bc8676954e156db2311 Mon Sep 17 00:00:00 2001 From: tamirms Date: Sat, 12 Sep 2026 07:31:37 +0100 Subject: [PATCH] rpcv2: wait for the hot DB destroys before the lifecycle e2e shuts down TestE2E_DaemonLifecycle_FirstStartIngestFreezeLookupRestartPrune waited for the discard counter, which rises when a chunk is demoted, and then cancelled the daemon and asserted that the chunks' hot keys were gone. The key goes with the deferred destroy at the end of the run, after the grace wait, and a shutdown during that wait skips the destroy by design, so the assertion raced the tick and failed once in a while under -race. The test now also waits for both hot DB directories to be removed before shutting down, the proof the prune step already uses for its index file. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01M23ZvEkyrFjyUUbm7zLwob --- cmd/stellar-rpc/internal/rpcv2/e2e_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cmd/stellar-rpc/internal/rpcv2/e2e_test.go b/cmd/stellar-rpc/internal/rpcv2/e2e_test.go index 5447a6aeb..dbb022638 100644 --- a/cmd/stellar-rpc/internal/rpcv2/e2e_test.go +++ b/cmd/stellar-rpc/internal/rpcv2/e2e_test.go @@ -348,6 +348,23 @@ func TestE2E_DaemonLifecycle_FirstStartIngestFreezeLookupRestartPrune(t *testing return metrics.discardedCount() >= 2 }, 60*time.Second, 50*time.Millisecond, "the boundary ticks must freeze+fold+discard chunks 0 and 1") + // discardedCount rises when the stage DEMOTES a chunk; the destroy that removes + // its hot DB and key is deferred to end-of-run (after the grace wait), and a + // shutdown mid-grace skips it (the demoted keys would then persist for the + // next run). Wait for both hot DB directories to be gone — proof the destroys + // ran — BEFORE shutting the daemon down, as the prune step does with the + // index file. + hotLayout := config.NewLayoutFromPaths( + config.Config{Storage: config.StorageConfig{DefaultDataDir: dataDir}}.WithDefaults().ResolvePaths()) + require.Eventually(t, func() bool { + for _, c := range []chunk.ID{c0, c1} { + if _, statErr := os.Stat(hotLayout.HotChunkPath(c)); !os.IsNotExist(statErr) { + return false + } + } + return true + }, 60*time.Second, 50*time.Millisecond, "chunks 0 and 1 hot DBs are destroyed while the daemon runs") + require.GreaterOrEqual(t, served.Load(), int32(1), "reads were served") require.Equal(t, c0First, core.fromSeen.Load(), "first start resumes the ingestion stream at genesis (last committed ledger + 1)")