Files
gridpilot.gg/adapters/health/persistence/inmemory/InMemoryHealthCheckAdapter.test.ts
Marc Mintel 838f1602de
Some checks failed
CI / lint-typecheck (pull_request) Failing after 4m51s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
adapter tests
2026-01-24 21:39:59 +01:00

124 lines
3.7 KiB
TypeScript

import { InMemoryHealthCheckAdapter } from './InMemoryHealthCheckAdapter';
describe('InMemoryHealthCheckAdapter', () => {
let adapter: InMemoryHealthCheckAdapter;
beforeEach(() => {
adapter = new InMemoryHealthCheckAdapter();
adapter.setResponseTime(0); // Speed up tests
});
describe('Health Checks', () => {
it('should return healthy by default', async () => {
// When
const result = await adapter.performHealthCheck();
// Then
expect(result.healthy).toBe(true);
expect(adapter.getStatus()).toBe('connected');
});
it('should return unhealthy when configured to fail', async () => {
// Given
adapter.setShouldFail(true, 'Custom error');
// When
const result = await adapter.performHealthCheck();
// Then
expect(result.healthy).toBe(false);
expect(result.error).toBe('Custom error');
});
});
describe('Status Transitions', () => {
it('should transition to disconnected after 3 consecutive failures', async () => {
// Given
adapter.setShouldFail(true);
// When
await adapter.performHealthCheck(); // 1
expect(adapter.getStatus()).toBe('checking'); // Initial state is disconnected, first failure keeps it checking/disconnected
await adapter.performHealthCheck(); // 2
await adapter.performHealthCheck(); // 3
// Then
expect(adapter.getStatus()).toBe('disconnected');
});
it('should transition to degraded if reliability is low', async () => {
// Given
// We need 5 requests total, and reliability < 0.7
// 1 success, 4 failures (not consecutive)
await adapter.performHealthCheck(); // Success 1
adapter.setShouldFail(true);
await adapter.performHealthCheck(); // Failure 1
adapter.setShouldFail(false);
await adapter.performHealthCheck(); // Success 2 (resets consecutive)
adapter.setShouldFail(true);
await adapter.performHealthCheck(); // Failure 2
await adapter.performHealthCheck(); // Failure 3
adapter.setShouldFail(false);
await adapter.performHealthCheck(); // Success 3 (resets consecutive)
adapter.setShouldFail(true);
await adapter.performHealthCheck(); // Failure 4
await adapter.performHealthCheck(); // Failure 5
// Then
expect(adapter.getStatus()).toBe('degraded');
expect(adapter.getReliability()).toBeLessThan(70);
});
it('should recover status after a success', async () => {
// Given
adapter.setShouldFail(true);
await adapter.performHealthCheck();
await adapter.performHealthCheck();
await adapter.performHealthCheck();
expect(adapter.getStatus()).toBe('disconnected');
// When
adapter.setShouldFail(false);
await adapter.performHealthCheck();
// Then
expect(adapter.getStatus()).toBe('connected');
expect(adapter.isAvailable()).toBe(true);
});
});
describe('Metrics', () => {
it('should track average response time', async () => {
// Given
adapter.setResponseTime(10);
await adapter.performHealthCheck();
adapter.setResponseTime(20);
await adapter.performHealthCheck();
// Then
const health = adapter.getHealth();
expect(health.averageResponseTime).toBe(15);
expect(health.totalRequests).toBe(2);
});
});
describe('Maintenance', () => {
it('should clear state', async () => {
// Given
await adapter.performHealthCheck();
expect(adapter.getHealth().totalRequests).toBe(1);
// When
adapter.clear();
// Then
expect(adapter.getHealth().totalRequests).toBe(0);
expect(adapter.getStatus()).toBe('disconnected'); // Initial state
});
});
});