Phase 2: analysis layer (analyze.js), cache guard, log hygiene
- analyze.js: burn rate, weekly reconstruction, cycle stagger, rotation rank, underspend alerts, log prune with weekly archive - logger.js: getCachedRun(maxAgeMinutes) — skip probing if recent data exists - monitor.js: cache guard at wake — 20-min dedup, zero extra API calls - test.js: fix type assertion for gemini-api/xai-api providers (+5 passing); add 14 new tests for cache guard and analyze.js (162 total, all green) - docs/analyze.md: usage reference Co-authored-by: Hannibal Smith <hannibal@trentuna.com>
This commit is contained in:
parent
1b4e299461
commit
34898b1196
6 changed files with 745 additions and 2 deletions
49
test.js
49
test.js
|
|
@ -99,7 +99,7 @@ assert('api-ateam in registry', names.includes('api-ateam'));
|
|||
assert('zai NOT in registry (not anthropic-messages)', !names.includes('zai'));
|
||||
for (const [name, p] of Object.entries(providers)) {
|
||||
assert(`${name} has baseUrl`, typeof p.baseUrl === 'string' && p.baseUrl.length > 0);
|
||||
assert(`${name} has type`, ['teams-direct', 'shelley-proxy', 'api-direct'].includes(p.type));
|
||||
assert(`${name} has type`, ['teams-direct', 'shelley-proxy', 'api-direct', 'gemini-api', 'xai-api'].includes(p.type));
|
||||
}
|
||||
|
||||
// ── 5. Teams header parser ───────────────────────────────────────────────────
|
||||
|
|
@ -415,6 +415,53 @@ assert('xai 429: severity = critical', x429.severity === 'critical');
|
|||
const x401 = parseXaiHeaders(null, 401, 'xai-key');
|
||||
assert('xai 401: status = invalid_key', x401.status === 'invalid_key');
|
||||
|
||||
// ── 13. Cache guard (getCachedRun) ─────────────────────────────────────────
|
||||
console.log('\n── 13. Cache guard ─────────────────────────────────────────────');
|
||||
const { getCachedRun } = await import('./logger.js');
|
||||
|
||||
assert('getCachedRun(0) returns null (zero-minute threshold)', getCachedRun(0) === null);
|
||||
|
||||
const cached20 = getCachedRun(20);
|
||||
assert('getCachedRun(20) returns null or valid object',
|
||||
cached20 === null || (typeof cached20 === 'object' && typeof cached20.ts === 'string'));
|
||||
|
||||
// ── 14. analyze.js smoke tests ───────────────────────────────────────────────
|
||||
console.log('\n── 14. analyze.js ──────────────────────────────────────────────');
|
||||
assert('analyze.js exists', existsSync(join(root, 'analyze.js')));
|
||||
assert('docs/analyze.md exists', existsSync(join(root, 'docs', 'analyze.md')));
|
||||
|
||||
const analyzeResult = runSafe('node analyze.js');
|
||||
assert('analyze.js exits 0', analyzeResult.code === 0,
|
||||
`exit code: ${analyzeResult.code}\n${analyzeResult.stderr}`);
|
||||
assert('analyze.js produces output', analyzeResult.stdout.length > 0);
|
||||
|
||||
const analyzeJson = runSafe('node analyze.js --json');
|
||||
assert('analyze.js --json exits 0', analyzeJson.code === 0,
|
||||
`exit code: ${analyzeJson.code}\n${analyzeJson.stderr}`);
|
||||
let analyzeData;
|
||||
try {
|
||||
analyzeData = JSON.parse(analyzeJson.stdout);
|
||||
assert('analyze.js --json is valid JSON', true);
|
||||
} catch (e) {
|
||||
assert('analyze.js --json is valid JSON', false, e.message);
|
||||
}
|
||||
if (analyzeData) {
|
||||
assert('analyze.js --json has burn_rates', 'burn_rates' in analyzeData);
|
||||
assert('analyze.js --json has stagger', 'stagger' in analyzeData);
|
||||
assert('analyze.js --json has rotation', 'rotation' in analyzeData);
|
||||
assert('analyze.js --json has weekly', 'weekly' in analyzeData);
|
||||
assert('analyze.js --json stagger is array', Array.isArray(analyzeData.stagger));
|
||||
assert('analyze.js --json rotation is array', Array.isArray(analyzeData.rotation));
|
||||
}
|
||||
|
||||
const analyzeRotation = runSafe('node analyze.js --rotation');
|
||||
assert('analyze.js --rotation exits 0', analyzeRotation.code === 0,
|
||||
`exit code: ${analyzeRotation.code}\n${analyzeRotation.stderr}`);
|
||||
|
||||
const analyzePruneDry = runSafe('node analyze.js --prune --dry-run');
|
||||
assert('analyze.js --prune --dry-run exits 0', analyzePruneDry.code === 0,
|
||||
`exit code: ${analyzePruneDry.code}\n${analyzePruneDry.stderr}`);
|
||||
|
||||
// ── Results ──────────────────────────────────────────────────────────────────
|
||||
console.log('\n' + '═'.repeat(50));
|
||||
console.log(`Tests: ${passed + failed} | Passed: ${passed} | Failed: ${failed}`);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue