Files
Profa ef5d0f982f feat: Phase 1 infrastructure - Telemetry, Persistence, Constitution
Implements Phase 1 tasks from GitHub issue #63:

## 1.1 Telemetry Foundation
- OpenTelemetry SDK integration with 12 OTEL packages
- Bootstrap module with auto-instrumentation support
- Comprehensive metrics schema (agent, quality, system)
- OTEL Collector configuration (gRPC/HTTP exporters)

## 1.2 Data Persistence Layer
- SQLite-based event store with correlation tracking
- Reasoning chain capture for agent decision analysis
- Quality metrics aggregation with time-window support
- Prepared statements for performance optimization

## 1.3 Constitution Schema
- JSON Schema for constitution validation
- 4 base constitutions (default, test-generation, code-review, performance)
- Constitution loader with inheritance/merge support
- Agent-specific constitution lookup with path resolution fix

## Tests
- Rewrote mock-based tests to test real implementations
- 45+ unit tests for telemetry, persistence, constitution
- Integration tests for end-to-end verification

All code compiles cleanly and runtime verification passes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 16:38:57 +00:00

153 lines
4.3 KiB
TypeScript

/**
* Unit Tests for Telemetry Bootstrap
* Tests REAL implementation, not mocks
*/
import {
initTelemetry,
shutdownTelemetry,
getTracer,
getMeter,
withSpan
} from '../../../src/telemetry';
describe('Telemetry Bootstrap', () => {
afterEach(async () => {
// Clean shutdown after each test
await shutdownTelemetry();
});
describe('Initialization', () => {
it('should initialize telemetry with default config', async () => {
const result = await initTelemetry({
enableConsoleExport: true,
});
expect(result.success).toBe(true);
expect(result.serviceName).toBe('agentic-qe-fleet');
expect(result.environment).toBeDefined();
});
it('should initialize telemetry with custom config', async () => {
const result = await initTelemetry({
serviceName: 'test-service',
serviceVersion: '2.0.0',
environment: 'testing',
enableConsoleExport: true,
});
expect(result.success).toBe(true);
expect(result.serviceName).toBe('test-service');
});
it('should return already-initialized when called twice', async () => {
await initTelemetry({ enableConsoleExport: true });
const result = await initTelemetry({ enableConsoleExport: true });
expect(result.success).toBe(true);
expect(result.exporters).toContain('already-initialized');
});
it('should configure console exporters when enabled', async () => {
const result = await initTelemetry({
enableConsoleExport: true,
});
expect(result.exporters).toContain('console-trace');
expect(result.exporters).toContain('console-metrics');
});
});
describe('Tracer and Meter', () => {
beforeEach(async () => {
await initTelemetry({ enableConsoleExport: true });
});
it('should get tracer with name', () => {
const tracer = getTracer('test-tracer');
expect(tracer).toBeDefined();
expect(typeof tracer.startSpan).toBe('function');
});
it('should get meter with name', () => {
const meter = getMeter('test-meter');
expect(meter).toBeDefined();
expect(typeof meter.createCounter).toBe('function');
expect(typeof meter.createHistogram).toBe('function');
});
it('should create spans with withSpan helper', async () => {
const result = await withSpan('test-operation', async (span) => {
span.setAttribute('test.attribute', 'value');
return 'completed';
});
expect(result).toBe('completed');
});
it('should handle errors in withSpan', async () => {
await expect(
withSpan('failing-operation', async () => {
throw new Error('Test error');
})
).rejects.toThrow('Test error');
});
});
describe('Shutdown', () => {
it('should shutdown gracefully', async () => {
await initTelemetry({ enableConsoleExport: true });
const result = await shutdownTelemetry();
expect(result.success).toBe(true);
});
it('should handle shutdown when not initialized', async () => {
const result = await shutdownTelemetry();
expect(result.success).toBe(true);
});
});
describe('Metrics Creation', () => {
beforeEach(async () => {
await initTelemetry({ enableConsoleExport: true });
});
it('should create counter metric', () => {
const meter = getMeter('test');
const counter = meter.createCounter('test.counter', {
description: 'Test counter',
unit: 'count',
});
expect(counter).toBeDefined();
// Should not throw when adding
counter.add(1, { label: 'test' });
});
it('should create histogram metric', () => {
const meter = getMeter('test');
const histogram = meter.createHistogram('test.histogram', {
description: 'Test histogram',
unit: 'ms',
});
expect(histogram).toBeDefined();
// Should not throw when recording
histogram.record(100, { operation: 'test' });
});
it('should create up-down counter metric', () => {
const meter = getMeter('test');
const upDownCounter = meter.createUpDownCounter('test.gauge', {
description: 'Test gauge',
unit: 'items',
});
expect(upDownCounter).toBeDefined();
upDownCounter.add(5);
upDownCounter.add(-2);
});
});
});