import test from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { assessPacket, weightedMean } from './observation.mjs'; const packets = JSON.parse(readFileSync(new URL('./packets.json', import.meta.url), 'utf8')); const base = () => structuredClone(packets.base); for (const c of packets.cases) test(c.id, () => { const p = base(); Object.assign(p, c.patch); if (c.patch.observer) p.observer = { ...packets.base.observer, ...c.patch.observer }; const result = assessPacket(p); assert.equal(result.decision, c.expectedDecision); assert.equal(result.reason, c.expectedReason); assert.equal(result.authorizesAwsChange, false); }); test('incumbent traffic masks candidate latency in a mixed population', () => { assert.equal(weightedMean([{ count: 180, sum: 18000000 }, { count: 20, sum: 8000000 }]), 130000); assert.equal(weightedMean([{ count: 20, sum: 8000000 }]), 400000); const p = base(); p.observations.forEach((o) => { o.sumLatencyMicros = 8000000; }); assert.deepEqual(assessPacket(p), { decision: 'STOP_REVIEW', reason: 'both-local-windows-breach', meansMicros: [400000, 400000], authorizesAwsChange: false }); }); test('incumbent errors do not become candidate errors', () => { assert.equal(18 / 200, 0.09); assert.equal(0 / 20, 0); assert.equal(18 / 180, 0.1); }); test('notBreaching cannot turn absent candidate coverage into evidence', () => { const p = base(); p.observer.treatMissingData = 'notBreaching'; p.observations[0].sampleCount = 0; assert.equal(assessPacket(p).reason, 'observation-coverage'); }); test('wrong observed config even when observer definition is correct', () => { const p = base(); p.observations[1].config = p.oldConfig; assert.equal(assessPacket(p).reason, 'observation-identity'); }); test('missing and nonfinite numbers cannot silently become zero', () => { for (const value of [undefined, null, NaN, Infinity, -1, 0.1, '20']) { const p = base(); p.observations[0].sampleCount = value; assert.equal(assessPacket(p).decision, 'HOLD'); } }); test('window identity prevents duplicate or stale observations', () => { const p = base(); p.observations[1] = structuredClone(p.observations[0]); assert.equal(assessPacket(p).reason, 'observation-identity'); }); test('sparse first, second and both expected windows hold without authorization', () => { for (const missing of [[0], [1], [0, 1]]) { const p = base(); for (const index of missing) delete p.expectedWindows[index]; assert.deepEqual(assessPacket(p), {decision:'HOLD', reason:'window-contract', authorizesAwsChange:false}); } }); test('malformed expected-window records hold instead of throwing', () => { for (const invalid of [null, undefined, false, 60, 'window', [], {}]) { const p = base(); p.expectedWindows[0] = invalid; assert.deepEqual(assessPacket(p), { decision: 'HOLD', reason: 'window-contract', authorizesAwsChange: false }); } }); test('threshold is strictly above and one bad window remains unresolved', () => { const p = base(); p.observations.forEach((o) => { o.sumLatencyMicros = 4000000; }); assert.equal(assessPacket(p).decision, 'HOLD_QUALITY'); p.observations[1].sumLatencyMicros = 4000001; assert.equal(assessPacket(p).reason, 'mixed-local-windows'); }); test('no other deployment mode is silently admitted', () => { const p = base(); p.scope = 'ROLLING'; assert.equal(assessPacket(p).reason, 'scope'); }); test('unsafe aggregate arithmetic is rejected', () => { assert.throws(() => weightedMean([{ count: 1, sum: Number.MAX_SAFE_INTEGER }, { count: 1, sum: 1 }])); }); test('changed variant name does not pass a canary scope declaration', () => { const p = base(); p.newVariant = 'Candidate'; assert.equal(assessPacket(p).reason, 'update-identity'); }); test('correct metric name in wrong namespace is held', () => { const p = base(); p.observer.namespace = 'Custom/Example'; assert.equal(assessPacket(p).reason, 'metric-contract'); });