Skip to content

Commit b18ae46

Browse files
committed
test(health): isolate lag-only degradation for checks.indexer.status
Add an explicitly-isolated test that induces indexerLagDegraded alone (lag > 60s, failure-rate counters healthy) and asserts checks.indexer.status reflects it as "degraded", while also asserting eventsFailed/indexerDegraded stay healthy so the test can't pass on a failure-rate coincidence. The prior lag test relied on beforeEach defaults implicitly rather than asserting isolation explicitly. Closes #1294
1 parent 2f6d9a0 commit b18ae46

1 file changed

Lines changed: 31 additions & 0 deletions

File tree

backend/tests/health.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,37 @@ describe('GET /health', () => {
105105
expect(res.body.checks.indexer.status).toBe('degraded');
106106
});
107107

108+
it('returns checks.indexer.status "degraded" for lag-only degradation, with failure-rate signals asserted healthy (#1294)', async () => {
109+
vi.stubEnv('STREAM_CONTRACT_ID', 'CSOME_CONTRACT_ADDRESS');
110+
prismaMock.indexerState.findUnique.mockResolvedValue(makeState(120));
111+
// Explicitly (re)assert the failure-rate counters are healthy so this
112+
// test isolates lag-only degradation rather than relying on beforeEach
113+
// defaults implicitly — the mismatch this test guards against is
114+
// checks.indexer.status staying "ok" while lag alone drives the
115+
// top-level status to "degraded".
116+
vi.mocked(sorobanEventWorker.getEventCounters).mockReturnValue({
117+
eventsProcessed: 42,
118+
eventsFailed: 0,
119+
lastErrorAt: null,
120+
degraded: false,
121+
});
122+
123+
const res = await request(app).get('/health');
124+
125+
expect(res.status).toBe(503);
126+
expect(res.body.status).toBe('degraded');
127+
expect(res.body.indexerLag).toBeGreaterThan(60);
128+
// Failure-rate degradation is NOT a contributing factor.
129+
expect(res.body.eventsFailed).toBe(0);
130+
expect(res.body.indexerDegraded).toBe(false);
131+
// The granular breakdown must match the top-level verdict during a
132+
// lag-only incident.
133+
expect(res.body.checks.indexer.status).toBe('degraded');
134+
expect(res.body.checks.indexer.enabled).toBe(true);
135+
expect(res.body.checks.indexer.lagSeconds).toBeGreaterThan(60);
136+
expect(res.body.checks.database.status).toBe('ok');
137+
});
138+
108139
it('returns 503 when DB is down regardless of indexer state', async () => {
109140
vi.stubEnv('STREAM_CONTRACT_ID', '');
110141
prismaMock.$queryRaw.mockRejectedValue(new Error('DB connection refused'));

0 commit comments

Comments
 (0)