From 0ab20bc2529be9ac60058b4bfb912227ffb087ff Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Thu, 6 Aug 2026 14:10:31 -0700 Subject: [PATCH] test(renderer): pin the exhaustion eviction policy, not just the cap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bound test asserted only the size cap, so it stayed green under the old wholesale clear(): after 200 distinct keys a clear-on-overflow leaves 72, which still satisfies the cap. Replay a key that oldest-first eviction retains and assert it emits no second breadcrumb — that fails under clear(), which would otherwise silently re-open the whole set to a repeat burst and flush the 30-entry ring the dedupe exists to protect. --- ...azy-with-retry.never-landed-reload.test.ts | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/lib/lazy-with-retry.never-landed-reload.test.ts b/src/renderer/src/lib/lazy-with-retry.never-landed-reload.test.ts index 52201345863..23d892f8c36 100644 --- a/src/renderer/src/lib/lazy-with-retry.never-landed-reload.test.ts +++ b/src/renderer/src/lib/lazy-with-retry.never-landed-reload.test.ts @@ -153,20 +153,36 @@ describe('loadLazyWithRetry when the recovery reload never lands', () => { }) it('bounds the exhaustion dedupe set so a hostile error name cannot grow it forever', async () => { - installBreadcrumbSink() + const breadcrumbs = installBreadcrumbSink() // error.name is library-controlled, so drive far more distinct keys than the cap. window.sessionStorage.setItem(RELOAD_GUARD_KEY, 'doc-before-the-reload') - for (let index = 0; index < 200; index += 1) { + const failWithName = (name: string): void => { const error = new SyntaxError("Unexpected token '}'") - error.name = `SyntaxError${index}` + error.name = name void loadLazyWithRetry(() => Promise.reject(error), { retries: 0, reloadKey: 'right-sidebar' }).catch(() => undefined) } + for (let index = 0; index < 200; index += 1) { + failWithName(`SyntaxError${index}`) + } await vi.advanceTimersByTimeAsync(0) expect(getRecordedExhaustionKeyCountForTest()).toBeLessThanOrEqual(128) + + // Eviction must be oldest-first, not wholesale: key 100 is among the newest + // 128 so it is still deduped. Clearing the set on overflow would drop it and + // let a repeat burst re-flush the 30-entry breadcrumb ring. + const before = breadcrumbs.filter( + (crumb) => crumb.name === 'lazy_chunk_recovery_exhausted' + ).length + failWithName('SyntaxError100') + await vi.advanceTimersByTimeAsync(0) + + expect( + breadcrumbs.filter((crumb) => crumb.name === 'lazy_chunk_recovery_exhausted') + ).toHaveLength(before) }) it('leaves no guard behind that would block a later document from recovering', async () => {