import { test } from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync, writeFileSync } from 'node:fs'; import { spawnSync } from 'node:child_process'; import { join } from 'node:path'; import { tmp } from './helpers.mjs'; import { instrumentInnerTimer, removeInnerObservers, readProbeSeconds } from './case-inner-timing-fixture.mjs'; const scripts=['case1-accept.sh','case2-unit.sh']; const read=name=>readFileSync(new URL(`../../../scripts/${name}`,import.meta.url),'utf8'); for(const name of scripts)test(`inner timing ${name}: private copy preserves shipped bytes and rejects anchor drift`,t=>{ const clock=join(tmp(t,'timer-'),'clock'); const source=read(name),copy=instrumentInnerTimer(source,clock); assert.equal(removeInnerObservers(copy,clock),read(name)); for(const marker of ['SO_PEERCRED','MOSAIC_TESTER_SOCKET_V1','MOSAIC_LEGACY_STATUS']) assert.equal(copy.split(marker).length,source.split(marker).length,marker); for(const anchor of ['# row253-supervisor-begin\n','# row253-supervisor-end\n','"$sleep_bin" "$seconds" & timer=$!\n','finish() {\n local rc="$?"\n']){ assert.throws(()=>instrumentInnerTimer(source.replace(anchor,''),clock),/anchor/); assert.throws(()=>instrumentInnerTimer(source.replace(anchor,anchor+anchor),clock),/anchor/); } }); for(const name of scripts)test(`inner timing ${name}: real supervisor retains streams status and EXIT cleanup`,t=>{ const clock=join(tmp(t,'timer-'),"clock '$;literal");writeFileSync(clock,''); const source=instrumentInnerTimer(read(name),clock); const body=source.slice(source.indexOf('# row253-supervisor-begin'),source.indexOf('# row253-supervisor-end')); const result=spawnSync('/bin/bash',['-c',body+'\n/bin/bash -c "$TESTER_SUPERVISOR" -- 2 /usr/bin/setsid /usr/bin/sleep /bin/bash -c \'printf exact-out; printf exact-err >&2; /usr/bin/sleep 0.1; exit 7\''],{encoding:'utf8'}); assert.equal(result.status,87,result.stderr); assert.equal(result.stdout,'exact-out');assert.equal(result.stderr,'exact-err'); assert.match(readFileSync(clock,'utf8'),/^begin [0-9]+\.[0-9]{2}\nend [0-9]+\.[0-9]{2}\n$/); // The same strict parser used by the timing bands rejects a guard's partial, // duplicate or reversed pair, rather than substituting wall time. for(const invalid of ['begin 10.00\n','end 11.00\n','begin 10.00\nend 11.00\nbegin 12.00\nend 13.00\n','begin 11.00\nend 10.00\n']) assert.throws(()=>readProbeSeconds(invalid)); });