import test from 'node:test'; import assert from 'node:assert/strict'; import { stopModelRuns, MODEL_STOP_TIMEOUT_MS } from '../src/model-keys.mjs'; const run = { business: 'demo', role: 'coder', run: 'r-test', keyId: '0123456789ab', pid: 123, startTime: '456' }; const entry = { business: 'demo', instance: 'coder', run: 'r-test', modelKeyId: '0123456789ab', pid: 123, startTime: '456', live: true }; test('bounded proxy stop is five seconds by default', () => assert.equal(MODEL_STOP_TIMEOUT_MS, 5000)); for (const patch of [{ instance: 'other' }, { modelKeyId: 'fedcba987654' }, { pid: 999 }, { startTime: '999' }]) test(`proxy-stop-failed: mismatched ${Object.keys(patch)[0]} is never signalled`, async () => { let signals = 0; const receipts = []; await assert.rejects(stopModelRuns({ runs: [run], sessions: () => [{ ...entry, ...patch }], stop: async () => { signals++; }, receipt: r => receipts.push(r) }), e => e.code === 'proxy-stop-failed'); assert.equal(signals, 0); assert.equal(receipts[0].code, 'proxy-stop-failed'); }); test('proxy-stop-failed: hung SIGTERM path is bounded and error text is not logged', async () => { const receipts = [], start = performance.now(); await assert.rejects(stopModelRuns({ runs: [run], sessions: () => [entry], stop: () => new Promise(() => {}), receipt: r => receipts.push(r), timeoutMs: 20 }), e => e.code === 'proxy-stop-failed'); assert.ok(performance.now() - start < 1000); assert.deepEqual(receipts, [{ action: 'proxy-rotation', code: 'proxy-stop-failed', keyIds: ['0123456789ab'], run: 'r-test' }]); }); test('stop verifies the run exited and logs the proxy reason with ids only', async () => { let live = true; const receipts = []; await stopModelRuns({ runs: [run], sessions: () => [{ ...entry, live }], stop: async () => { live = false; return { stopped: true }; }, receipt: r => receipts.push(r), reason: 'proxy-stall' }); assert.deepEqual(receipts, [{ action: 'proxy-stall', keyIds: ['0123456789ab'], business: 'demo', agent: 'coder', run: 'r-test', outcome: 'stopped' }]); });