feat(audit): add rolling phase0 artifact retention tooling
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
collectRollingPhase0ArtifactFiles,
|
||||
planRollingPhase0ArtifactRetention,
|
||||
} from './phase0BaselineArtifactRetention.js';
|
||||
|
||||
describe('phase0BaselineArtifactRetention', () => {
|
||||
it('collects only rolling-tag phase-0 artifact files', () => {
|
||||
const rows = collectRollingPhase0ArtifactFiles([
|
||||
'phase0_baseline_live_2026-02-27-010203.json',
|
||||
'phase0_baseline_live_gateway_2026-02-27-010203.md',
|
||||
'phase0_baseline_live_backend_pi_embedded_2026-02-27-010203.jsonl',
|
||||
'phase0_baseline_live_backend_native_2026-02-27-010203.json',
|
||||
'phase0_baseline_live_backend_drift_2026-02-27-010203.md',
|
||||
'phase0_baseline_live_2026-02-27.json',
|
||||
'phase0_baseline_live_gateway_2026-02-27.jsonl',
|
||||
'phase0_baseline_2026-02-25.md',
|
||||
'phase0_baseline_live_backend_pi_embedded_2026-02-27.md',
|
||||
'not_a_phase0_file.txt',
|
||||
]);
|
||||
|
||||
expect(rows).toHaveLength(5);
|
||||
expect(rows.map((row) => row.family).sort()).toEqual([
|
||||
'backend_drift',
|
||||
'backend_native',
|
||||
'backend_pi_embedded',
|
||||
'channel',
|
||||
'gateway',
|
||||
]);
|
||||
});
|
||||
|
||||
it('keeps most recent rolling tags per family and prunes older ones', () => {
|
||||
const files = [
|
||||
'phase0_baseline_live_2026-02-27-010203.json',
|
||||
'phase0_baseline_live_2026-02-27-010203.jsonl',
|
||||
'phase0_baseline_live_2026-02-27-020304.json',
|
||||
'phase0_baseline_live_2026-02-27-020304.md',
|
||||
'phase0_baseline_live_gateway_2026-02-27-010203.json',
|
||||
'phase0_baseline_live_gateway_2026-02-27-020304.json',
|
||||
'phase0_baseline_live_backend_pi_embedded_2026-02-27-010203.json',
|
||||
'phase0_baseline_live_backend_pi_embedded_2026-02-27-020304.json',
|
||||
'phase0_baseline_live_backend_native_2026-02-27-010203.json',
|
||||
'phase0_baseline_live_backend_native_2026-02-27-020304.json',
|
||||
'phase0_baseline_live_backend_drift_2026-02-27-010203.json',
|
||||
'phase0_baseline_live_backend_drift_2026-02-27-020304.json',
|
||||
'phase0_baseline_live_2026-02-27.json',
|
||||
];
|
||||
|
||||
const plan = planRollingPhase0ArtifactRetention(files, 1);
|
||||
expect(plan.families).toEqual([
|
||||
{ family: 'channel', total_tags: 2, keep_tags: 1, remove_tags: 1 },
|
||||
{ family: 'gateway', total_tags: 2, keep_tags: 1, remove_tags: 1 },
|
||||
{ family: 'backend_pi_embedded', total_tags: 2, keep_tags: 1, remove_tags: 1 },
|
||||
{ family: 'backend_native', total_tags: 2, keep_tags: 1, remove_tags: 1 },
|
||||
{ family: 'backend_drift', total_tags: 2, keep_tags: 1, remove_tags: 1 },
|
||||
]);
|
||||
|
||||
const removeSet = new Set(plan.remove.map((row) => row.file_name));
|
||||
expect(removeSet.has('phase0_baseline_live_2026-02-27-010203.json')).toBe(true);
|
||||
expect(removeSet.has('phase0_baseline_live_2026-02-27-010203.jsonl')).toBe(true);
|
||||
expect(removeSet.has('phase0_baseline_live_gateway_2026-02-27-010203.json')).toBe(true);
|
||||
expect(removeSet.has('phase0_baseline_live_backend_pi_embedded_2026-02-27-010203.json')).toBe(true);
|
||||
expect(removeSet.has('phase0_baseline_live_backend_native_2026-02-27-010203.json')).toBe(true);
|
||||
expect(removeSet.has('phase0_baseline_live_backend_drift_2026-02-27-010203.json')).toBe(true);
|
||||
|
||||
const keepSet = new Set(plan.keep.map((row) => row.file_name));
|
||||
expect(keepSet.has('phase0_baseline_live_2026-02-27.json')).toBe(false);
|
||||
expect(keepSet.has('phase0_baseline_live_2026-02-27-020304.json')).toBe(true);
|
||||
expect(keepSet.has('phase0_baseline_live_2026-02-27-020304.md')).toBe(true);
|
||||
});
|
||||
|
||||
it('supports zero keep limit', () => {
|
||||
const plan = planRollingPhase0ArtifactRetention([
|
||||
'phase0_baseline_live_2026-02-27-010203.json',
|
||||
'phase0_baseline_live_gateway_2026-02-27-010203.json',
|
||||
], 0);
|
||||
|
||||
expect(plan.keep).toHaveLength(0);
|
||||
expect(plan.remove.map((row) => row.file_name).sort()).toEqual([
|
||||
'phase0_baseline_live_2026-02-27-010203.json',
|
||||
'phase0_baseline_live_gateway_2026-02-27-010203.json',
|
||||
]);
|
||||
});
|
||||
|
||||
it('rejects negative keep limit', () => {
|
||||
expect(() => planRollingPhase0ArtifactRetention([], -1)).toThrow('keepPerFamily');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user