Source-candidate: poe d9a564e6d20f5f0fd75ce45b12cbbf8bb4c9d568\nSource-candidate: magica38ba5762b06716db1dee00d0afec162656488f5c\nValidated321whole-file phase plus whole bus1349/model-proxy100/webui490; final gate tooling checks pending, not landed.
16 lines
2.3 KiB
JavaScript
16 lines
2.3 KiB
JavaScript
// #650 first actual turn, one initial budget; prepared only, not executed.
|
|
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import { watchModelOutput } from '../src/model-stall.mjs';
|
|
const delay=ms=>new Promise(r=>setTimeout(r,ms));
|
|
async function doneWithin(watch){let timer;try{await Promise.race([watch.done,new Promise((_,reject)=>{timer=setTimeout(()=>reject(Error('watcher completion not observed')),5000);})]);}finally{clearTimeout(timer);}}
|
|
function fixture(t){const runDir=fs.mkdtempSync(join(tmpdir(),'clock650-'));let stops=0;const receipts=[];t.after(()=>fs.rmSync(runDir,{recursive:true,force:true}));const watch=watchModelOutput({runDir,armAtFirstTurn:true,seconds:0.1,keyId:'0123456789ab',stop:async()=>{stops++;},receipt:r=>receipts.push(r)});t.after(watch.cancel);return {runDir,watch,receipts,stops:()=>stops,arm:()=>fs.writeFileSync(join(runDir,'proxy-first-turn'),`turn ${process.hrtime.bigint()}\n`,{mode:0o600})};}
|
|
test('650 idle longer than initial budget remains unarmed',async t=>{const f=fixture(t);await delay(250);assert.equal(f.stops(),0,'idle time must not spend first-output budget');f.watch.cancel();await f.watch.done;assert.deepEqual(f.receipts,[]);});
|
|
test('650 first silent turn spends one initial budget then invokes existing stop callback',async t=>{const f=fixture(t);await delay(250);assert.equal(f.stops(),0,'silent turn clock is unarmed before first turn');f.arm();await doneWithin(f.watch);assert.equal(f.stops(),1);assert.deepEqual(f.receipts,[{action:'proxy-stall',keyIds:['0123456789ab']}]);});
|
|
test('650 first output cancels turn watcher without output text in receipt',async t=>{const f=fixture(t);f.arm();fs.writeFileSync(join(f.runDir,'proxy-first-output'),'output\n',{mode:0o600});await doneWithin(f.watch);assert.equal(f.stops(),0);assert.deepEqual(f.receipts,[]);});
|
|
test('650 later marker cannot extend already armed initial budget',async t=>{const f=fixture(t);f.arm();await delay(30);fs.writeFileSync(join(f.runDir,'proxy-first-turn'),`turn ${process.hrtime.bigint()+60_000_000_000n}\n`);await doneWithin(f.watch);assert.equal(f.stops(),1);});
|
|
test('650 idle run exit cancellation stops no process',async t=>{const f=fixture(t);f.watch.cancel();await f.watch.done;assert.equal(f.stops(),0);assert.deepEqual(f.receipts,[]);});
|