From 88558fe48b5ca6a2abbbb142016e2987a5b67d0f Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sat, 1 Aug 2026 07:37:57 -0700 Subject: [PATCH] test(crash-reporting): cover speech churn breadcrumb name-coalescing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The churn breadcrumb's registration in COALESCED_RENDERER_BREADCRUMB_NAMES and NAME_ONLY_COALESCED_BREADCRUMB_NAMES had no test: the storm test only asserted the constant equals its own literal. Removing either registration kept the whole suite green. It carries no message field, so without the name-only entry rendererBreadcrumbCoalesceKey returns undefined and every firing takes its own ring slot — the eviction this breadcrumb exists to avoid. --- ...ash-reporting-renderer-breadcrumbs.test.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main/ipc/crash-reporting-renderer-breadcrumbs.test.ts b/src/main/ipc/crash-reporting-renderer-breadcrumbs.test.ts index 1fb1bb12d7b..76e59cca6fc 100644 --- a/src/main/ipc/crash-reporting-renderer-breadcrumbs.test.ts +++ b/src/main/ipc/crash-reporting-renderer-breadcrumbs.test.ts @@ -275,6 +275,27 @@ describe('renderer breadcrumb IPC routing', () => { } }) + // Why: each window emits its own churn notice with a different payload, so + // coalescing by name is what keeps a download storm to one ring slot. Without + // the registration these carry no message and fall through uncoalesced — + // evicting the pre-crash trail this breadcrumb exists to sit beside. + it('coalesces speech model-state churn by name across windows', () => { + emitRendererBreadcrumb({ + name: 'speech_model_state_churn', + data: { refreshes: 250, noOpRefreshes: 249, windowMs: 4200 } + }) + emitRendererBreadcrumb({ + name: 'speech_model_state_churn', + data: { refreshes: 250, noOpRefreshes: 12, windowMs: 3100 } + }) + + expect(recordCrashBreadcrumbMock).not.toHaveBeenCalled() + expect(recordCoalescedCrashBreadcrumbMock).toHaveBeenCalledTimes(2) + for (const call of recordCoalescedCrashBreadcrumbMock.mock.calls) { + expect(call[0]).toMatchObject({ coalesceKey: 'speech_model_state_churn' }) + } + }) + // Why kind-scoped: a routine post-wake atlas reset must never suppress the // context-loss crumb that says the driver gave up on this renderer. it('coalesces WebGL diagnostics per kind so one kind cannot mask another', () => {