mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
ef5d0f982f
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>
153 lines
4.3 KiB
TypeScript
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);
|
|
});
|
|
});
|
|
});
|