This commit is contained in:
112
packages/core/tests/telemetry.test.ts
Normal file
112
packages/core/tests/telemetry.test.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { TelemetryCollector } from '../src/telemetry.js';
|
||||
import * as fs from 'node:fs';
|
||||
import * as os from 'node:os';
|
||||
import * as path from 'node:path';
|
||||
|
||||
describe('TelemetryCollector', () => {
|
||||
let tmpDir: string;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = path.join(os.tmpdir(), `waggle-telemetry-test-${Date.now()}`);
|
||||
fs.mkdirSync(tmpDir, { recursive: true });
|
||||
});
|
||||
|
||||
it('records events when enabled', () => {
|
||||
const collector = new TelemetryCollector(tmpDir, true);
|
||||
collector.recordToolUse('web_search');
|
||||
collector.recordToolUse('web_search');
|
||||
collector.recordToolUse('save_memory');
|
||||
|
||||
const report = collector.getReport();
|
||||
expect(report.totalEvents).toBe(3);
|
||||
const webSearch = report.events.find(e => e.name === 'web_search');
|
||||
expect(webSearch?.count).toBe(2);
|
||||
});
|
||||
|
||||
it('silently drops events when disabled', () => {
|
||||
const collector = new TelemetryCollector(tmpDir, false);
|
||||
collector.recordToolUse('web_search');
|
||||
collector.recordCommand('/research');
|
||||
collector.recordError('timeout');
|
||||
|
||||
const report = collector.getReport();
|
||||
expect(report.totalEvents).toBe(0);
|
||||
});
|
||||
|
||||
it('no PII in collected data — tool names only', () => {
|
||||
const collector = new TelemetryCollector(tmpDir, true);
|
||||
collector.recordToolUse('connector_github_create_issue');
|
||||
collector.recordError('api_timeout');
|
||||
collector.recordCapabilityGap('email sending');
|
||||
|
||||
const report = collector.getReport();
|
||||
for (const event of report.events) {
|
||||
// Only category, name, count, date — no message content or file paths
|
||||
expect(Object.keys(event).sort()).toEqual(['category', 'count', 'date', 'name']);
|
||||
}
|
||||
});
|
||||
|
||||
it('daily aggregation: same-day events merge counts', () => {
|
||||
const collector = new TelemetryCollector(tmpDir, true);
|
||||
collector.recordToolUse('bash');
|
||||
collector.recordToolUse('bash');
|
||||
collector.recordToolUse('bash');
|
||||
|
||||
const report = collector.getReport();
|
||||
const bashEvents = report.events.filter(e => e.name === 'bash');
|
||||
expect(bashEvents).toHaveLength(1);
|
||||
expect(bashEvents[0].count).toBe(3);
|
||||
});
|
||||
|
||||
it('flush writes to telemetry.json', () => {
|
||||
const collector = new TelemetryCollector(tmpDir, true);
|
||||
collector.recordToolUse('search_memory');
|
||||
collector.flush();
|
||||
|
||||
const filePath = path.join(tmpDir, 'telemetry.json');
|
||||
expect(fs.existsSync(filePath)).toBe(true);
|
||||
|
||||
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
||||
expect(data).toHaveLength(1);
|
||||
expect(data[0].name).toBe('search_memory');
|
||||
|
||||
collector.close();
|
||||
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it('report covers last N days', () => {
|
||||
const collector = new TelemetryCollector(tmpDir, true);
|
||||
collector.recordToolUse('today_tool');
|
||||
|
||||
const report = collector.getReport(7);
|
||||
expect(report.events.length).toBeGreaterThan(0);
|
||||
expect(report.dateRange.from).toBeTruthy();
|
||||
});
|
||||
|
||||
it('setEnabled toggles collection', () => {
|
||||
const collector = new TelemetryCollector(tmpDir, false);
|
||||
expect(collector.isEnabled()).toBe(false);
|
||||
|
||||
collector.setEnabled(true);
|
||||
expect(collector.isEnabled()).toBe(true);
|
||||
|
||||
collector.recordToolUse('test_tool');
|
||||
expect(collector.getReport().totalEvents).toBe(1);
|
||||
});
|
||||
|
||||
it('recordSession aggregates duration and interaction count', () => {
|
||||
const collector = new TelemetryCollector(tmpDir, true);
|
||||
collector.recordSession(30000, 15);
|
||||
collector.recordSession(20000, 10);
|
||||
|
||||
const report = collector.getReport();
|
||||
const duration = report.events.find(e => e.name === 'duration_total_ms');
|
||||
const interactions = report.events.find(e => e.name === 'interaction_count');
|
||||
const sessions = report.events.find(e => e.name === 'session_count');
|
||||
|
||||
expect(duration?.count).toBe(50000);
|
||||
expect(interactions?.count).toBe(25);
|
||||
expect(sessions?.count).toBe(2);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user