First public release
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { overall, validateReport } from '@extant2000/evidence-record'
|
||||
import {
|
||||
checkPlan,
|
||||
formatPlan,
|
||||
peakRate,
|
||||
worstCaseBytes,
|
||||
type DeployStep,
|
||||
type SignatureBudget,
|
||||
} from '../src/index.js'
|
||||
|
||||
const step = (p: Partial<DeployStep> = {}): DeployStep => ({
|
||||
name: 'pull-base-image',
|
||||
destination: 'registry.gitlab.com',
|
||||
bytes: 200_000_000,
|
||||
durationSeconds: 60,
|
||||
where: '.gitlab-ci.yml',
|
||||
...p,
|
||||
})
|
||||
|
||||
describe('retries are cost, not a footnote', () => {
|
||||
it('counts every attempt in the worst case', () => {
|
||||
// A step budgeted at one attempt is budgeted at its best case.
|
||||
expect(worstCaseBytes(step({ bytes: 100, retries: 3 }))).toBe(300)
|
||||
expect(worstCaseBytes(step({ bytes: 100 }))).toBe(100)
|
||||
})
|
||||
|
||||
it('a plan that fits on first attempt and not with retries fails', () => {
|
||||
const budget: SignatureBudget = { maxTotalBytes: 250_000_000 }
|
||||
expect(overall(checkPlan([step({ retries: 1 })], budget))).toBe('pass')
|
||||
const r = checkPlan([step({ retries: 2 })], budget)
|
||||
expect(r.findings.find(f => f.id === 'total')!.determination).toBe('fail')
|
||||
expect(r.findings.find(f => f.id === 'total')!.detail).toContain('every retry counts')
|
||||
})
|
||||
})
|
||||
|
||||
describe('an unexpected destination is a different kind of problem', () => {
|
||||
const budget: SignatureBudget = { allowedDestinations: ['registry.gitlab.com'] }
|
||||
|
||||
it('fails a step reaching outside the declared set', () => {
|
||||
const r = checkPlan([step({ name: 'fetch-tool', destination: 'cdn.example.net', bytes: 1024 })], budget)
|
||||
expect(r.findings.find(f => f.id === 'fetch-tool')!.determination).toBe('fail')
|
||||
expect(r.findings.find(f => f.id === 'fetch-tool')!.severity).toBe('critical')
|
||||
})
|
||||
|
||||
it('stays critical however small the transfer', () => {
|
||||
// Volume is irrelevant: an unexpected host is supply chain or leak.
|
||||
const r = checkPlan([step({ name: 'ping', destination: 'evil.example', bytes: 1 })], budget)
|
||||
expect(r.findings.find(f => f.id === 'ping')!.severity).toBe('critical')
|
||||
expect(formatPlan([step({ name: 'ping', destination: 'evil.example', bytes: 1 })], budget))
|
||||
.toContain('Volume is irrelevant here')
|
||||
})
|
||||
|
||||
it('says so when no allowlist was supplied', () => {
|
||||
expect(formatPlan([step()], {})).toContain('no step could be checked against one')
|
||||
})
|
||||
|
||||
it('passes a step inside the declared set', () => {
|
||||
expect(overall(checkPlan([step()], budget))).toBe('pass')
|
||||
})
|
||||
})
|
||||
|
||||
describe('shape, not just total', () => {
|
||||
it('fails a burst that fits the total budget', () => {
|
||||
// 200 MB over 60s = 3.3 MB/s. The same bytes over an hour would pass.
|
||||
const r = checkPlan([step()], { maxTotalBytes: 1e9, maxBytesPerSecond: 1_000_000 })
|
||||
const f = r.findings.find(x => x.id === 'pull-base-image')!
|
||||
expect(f.determination).toBe('fail')
|
||||
expect(f.detail).toContain('the total is not the problem, the shape is')
|
||||
})
|
||||
|
||||
it('multiplies the peak by concurrency', () => {
|
||||
const budget: SignatureBudget = { maxBytesPerSecond: 5_000_000, concurrency: 4 }
|
||||
// 3.3 MB/s alone passes; x4 concurrent does not.
|
||||
expect(overall(checkPlan([step()], { maxBytesPerSecond: 5_000_000 }))).toBe('pass')
|
||||
expect(overall(checkPlan([step()], budget))).toBe('fail')
|
||||
})
|
||||
|
||||
it('cannot check a rate without a duration, and says so', () => {
|
||||
const r = checkPlan([step({ durationSeconds: undefined })], { maxBytesPerSecond: 1_000_000 })
|
||||
expect(r.findings.find(f => f.id === 'pull-base-image')!.determination).toBe('not-assessed')
|
||||
expect(peakRate(step({ durationSeconds: undefined }))).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('an unmeasured transfer is not a small one', () => {
|
||||
it('reports an unknown volume as not-assessed, never zero', () => {
|
||||
const r = checkPlan([step({ bytes: null })], { maxTotalBytes: 1e9 })
|
||||
const f = r.findings.find(x => x.id === 'pull-base-image')!
|
||||
expect(f.determination).toBe('not-assessed')
|
||||
expect(f.detail).toContain('An unmeasured transfer is not a small one')
|
||||
})
|
||||
|
||||
it('reports the total as a LOWER BOUND when any step is unmeasured', () => {
|
||||
// A partial sum presented as a total is how a budget check reassures
|
||||
// without checking.
|
||||
const r = checkPlan([step({ bytes: 1000 }), step({ name: 'unknown-pull', bytes: null })],
|
||||
{ maxTotalBytes: 1e9 })
|
||||
const total = r.findings.find(f => f.id === 'total')!
|
||||
expect(total.determination).toBe('not-assessed')
|
||||
expect(total.detail).toContain('lower bound, not a total')
|
||||
})
|
||||
|
||||
it('still fails when the KNOWN bytes alone exceed the budget', () => {
|
||||
// Unmeasured steps cannot rescue a plan that is already over.
|
||||
const r = checkPlan([step({ bytes: 2e9 }), step({ name: 'x', bytes: null })], { maxTotalBytes: 1e9 })
|
||||
expect(r.findings.find(f => f.id === 'total')!.determination).toBe('fail')
|
||||
})
|
||||
})
|
||||
|
||||
describe('conformance with the evidence-record standard', () => {
|
||||
it('an empty plan is not-assessed, and says what empty means', () => {
|
||||
expect(overall(checkPlan([]))).toBe('not-assessed')
|
||||
expect(formatPlan([])).toContain('An unenumerated step still moves bytes')
|
||||
})
|
||||
|
||||
it('every conclusion carries a citation', () => {
|
||||
expect(validateReport(checkPlan([step(), step({ name: 'b', destination: 'x', bytes: 5 })],
|
||||
{ maxTotalBytes: 1e9, allowedDestinations: ['registry.gitlab.com'] }))).toEqual([])
|
||||
})
|
||||
|
||||
it('cites the file each step is defined in', () => {
|
||||
expect(formatPlan([step()], {}, { evidence: 'full' })).toContain('.gitlab-ci.yml')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user