Files
mcpctl/src/mcplocal/tests/tiered-health.test.ts
Michal b8c5cf718a
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / typecheck (pull_request) Has been cancelled
CI / test (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
CI / package (pull_request) Has been cancelled
feat: implement v2 3-tier architecture (mcpctl → mcplocal → mcpd)
- Rename local-proxy to mcplocal with HTTP server, LLM pipeline, mcpd discovery
- Add LLM pre-processing: token estimation, filter cache, metrics, Gemini CLI + DeepSeek providers
- Add mcpd auth (login/logout) and MCP proxy endpoints
- Update CLI: dual URLs (mcplocalUrl/mcpdUrl), auth commands, --direct flag
- Add tiered health monitoring, shell completions, e2e integration tests
- 57 test files, 597 tests passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 11:42:06 +00:00

305 lines
8.8 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { TieredHealthMonitor } from '../src/health/tiered.js';
import type { TieredHealthMonitorDeps } from '../src/health/tiered.js';
import type { McpdClient } from '../src/http/mcpd-client.js';
import { ProviderRegistry } from '../src/providers/registry.js';
import type { LlmProvider } from '../src/providers/types.js';
function mockMcpdClient(overrides?: {
getResult?: unknown;
getFails?: boolean;
instancesResult?: { instances: Array<{ name: string; status: string }> };
instancesFails?: boolean;
}): McpdClient {
const client = {
get: vi.fn(async (path: string) => {
if (path === '/health') {
if (overrides?.getFails) {
throw new Error('Connection refused');
}
return overrides?.getResult ?? { status: 'ok' };
}
if (path === '/instances') {
if (overrides?.instancesFails) {
throw new Error('Connection refused');
}
return overrides?.instancesResult ?? { instances: [] };
}
return {};
}),
post: vi.fn(),
put: vi.fn(),
delete: vi.fn(),
forward: vi.fn(),
} as unknown as McpdClient;
return client;
}
function mockLlmProvider(name: string): LlmProvider {
return {
name,
complete: vi.fn(),
listModels: vi.fn(async () => []),
isAvailable: vi.fn(async () => true),
};
}
describe('TieredHealthMonitor', () => {
let providerRegistry: ProviderRegistry;
beforeEach(() => {
providerRegistry = new ProviderRegistry();
});
describe('mcplocal health', () => {
it('reports healthy status with uptime', async () => {
const monitor = new TieredHealthMonitor({
mcpdClient: null,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.mcplocal.status).toBe('healthy');
expect(result.mcplocal.uptime).toBeGreaterThanOrEqual(0);
});
it('reports null llmProvider when none registered', async () => {
const monitor = new TieredHealthMonitor({
mcpdClient: null,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.mcplocal.llmProvider).toBeNull();
});
it('reports active llmProvider name when one is registered', async () => {
const provider = mockLlmProvider('openai');
providerRegistry.register(provider);
const monitor = new TieredHealthMonitor({
mcpdClient: null,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.mcplocal.llmProvider).toBe('openai');
});
it('reports the currently active provider when multiple registered', async () => {
providerRegistry.register(mockLlmProvider('openai'));
providerRegistry.register(mockLlmProvider('anthropic'));
providerRegistry.setActive('anthropic');
const monitor = new TieredHealthMonitor({
mcpdClient: null,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.mcplocal.llmProvider).toBe('anthropic');
});
});
describe('mcpd health', () => {
it('reports connected when mcpd /health responds successfully', async () => {
const client = mockMcpdClient();
const monitor = new TieredHealthMonitor({
mcpdClient: client,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.mcpd.status).toBe('connected');
expect(result.mcpd.url).toBe('http://localhost:3100');
});
it('reports disconnected when mcpd /health throws', async () => {
const client = mockMcpdClient({ getFails: true });
const monitor = new TieredHealthMonitor({
mcpdClient: client,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.mcpd.status).toBe('disconnected');
expect(result.mcpd.url).toBe('http://localhost:3100');
});
it('reports disconnected when mcpdClient is null', async () => {
const monitor = new TieredHealthMonitor({
mcpdClient: null,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.mcpd.status).toBe('disconnected');
expect(result.mcpd.url).toBe('http://localhost:3100');
});
it('includes the configured mcpd URL in the response', async () => {
const monitor = new TieredHealthMonitor({
mcpdClient: null,
providerRegistry,
mcpdUrl: 'http://custom-host:9999',
});
const result = await monitor.checkHealth();
expect(result.mcpd.url).toBe('http://custom-host:9999');
});
});
describe('instances', () => {
it('returns instances from mcpd /instances endpoint', async () => {
const client = mockMcpdClient({
instancesResult: {
instances: [
{ name: 'slack', status: 'running' },
{ name: 'github', status: 'stopped' },
],
},
});
const monitor = new TieredHealthMonitor({
mcpdClient: client,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.instances).toHaveLength(2);
expect(result.instances[0]).toEqual({ name: 'slack', status: 'running' });
expect(result.instances[1]).toEqual({ name: 'github', status: 'stopped' });
});
it('returns empty array when mcpdClient is null', async () => {
const monitor = new TieredHealthMonitor({
mcpdClient: null,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.instances).toEqual([]);
});
it('returns empty array when /instances request fails', async () => {
const client = mockMcpdClient({ instancesFails: true });
const monitor = new TieredHealthMonitor({
mcpdClient: client,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.instances).toEqual([]);
});
it('returns empty array when mcpd has no instances', async () => {
const client = mockMcpdClient({
instancesResult: { instances: [] },
});
const monitor = new TieredHealthMonitor({
mcpdClient: client,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.instances).toEqual([]);
});
});
describe('full integration', () => {
it('returns complete tiered status with all sections', async () => {
providerRegistry.register(mockLlmProvider('openai'));
const client = mockMcpdClient({
instancesResult: {
instances: [
{ name: 'slack', status: 'running' },
],
},
});
const monitor = new TieredHealthMonitor({
mcpdClient: client,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
// Verify structure
expect(result).toHaveProperty('mcplocal');
expect(result).toHaveProperty('mcpd');
expect(result).toHaveProperty('instances');
// mcplocal
expect(result.mcplocal.status).toBe('healthy');
expect(typeof result.mcplocal.uptime).toBe('number');
expect(result.mcplocal.llmProvider).toBe('openai');
// mcpd
expect(result.mcpd.status).toBe('connected');
// instances
expect(result.instances).toHaveLength(1);
expect(result.instances[0]?.name).toBe('slack');
});
it('handles degraded scenario: no mcpd, no provider', async () => {
const monitor = new TieredHealthMonitor({
mcpdClient: null,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.mcplocal.status).toBe('healthy');
expect(result.mcplocal.llmProvider).toBeNull();
expect(result.mcpd.status).toBe('disconnected');
expect(result.instances).toEqual([]);
});
it('handles mcpd connected but instances endpoint failing', async () => {
const client = mockMcpdClient({ instancesFails: true });
const monitor = new TieredHealthMonitor({
mcpdClient: client,
providerRegistry,
mcpdUrl: 'http://localhost:3100',
});
const result = await monitor.checkHealth();
expect(result.mcpd.status).toBe('connected');
expect(result.instances).toEqual([]);
});
});
});