Files
safetynet/tests/broker-work-admission.test.mjs
T

49 lines
3.5 KiB
JavaScript
Raw Normal View History

import test from 'node:test';
import assert from 'node:assert/strict';
import {createRequire} from 'node:module';
const require=createRequire(import.meta.url),{createWorkAdmission}=require('../apps/network-broker/work-admission.cjs');
function deferred(){let resolve,reject;const promise=new Promise((yes,no)=>{resolve=yes;reject=no;});return {promise,resolve,reject};}
test('outer deadline and abort races cannot free never-settled worker admission',async()=>{
const admission=createWorkAdmission({maxJobs:2}),first=deferred(),second=deferred();
const bytes=Buffer.from('synthetic private body');
const work=admission.run(()=>first.promise,{payload:bytes});
assert.equal(await Promise.race([work,Promise.resolve('outer aborted')]),'outer aborted');
assert.equal(bytes.toString(),'synthetic private body');
const other=admission.run(()=>second.promise);
assert.equal(await Promise.race([other,Promise.resolve('outer deadline')]),'outer deadline');
assert.throws(()=>admission.run(()=>{throw Error('must not execute');}),{code:'work_capacity_exhausted'});
assert.equal(admission.status().active,2);
first.resolve(42);assert.equal(await work,42);assert.ok(bytes.every(value=>value===0));
assert.equal(admission.status().active,1);
second.resolve(17);assert.equal(await other,17);assert.equal(admission.status().active,0);
});
test('reservation is synchronous and shared across concurrent callbacks',async()=>{
const admission=createWorkAdmission({maxJobs:1}),pending=deferred();let calls=0;
const work=admission.run(()=>{calls++;return pending.promise;});
assert.throws(()=>admission.run(()=>calls++),{code:'work_capacity_exhausted'});assert.equal(calls,1);
pending.resolve();await work;
assert.equal(await admission.run(()=>++calls),2);
});
test('sync and async failure preserve identity release slot and wipe private payload',async()=>{
const admission=createWorkAdmission({maxJobs:1}),failure=new Error('synthetic worker failure'),bytes=Buffer.from('private');
assert.throws(()=>admission.run(()=>{throw failure;},{payload:bytes}),error=>error===failure);
assert.ok(bytes.every(value=>value===0));assert.equal(admission.status().active,0);
const other=Buffer.from('private');
await assert.rejects(admission.run(()=>Promise.reject(failure),{payload:other}),error=>error===failure);
assert.ok(other.every(value=>value===0));assert.equal(admission.status().active,0);
});
test('close rejects new work without claiming pending workers terminated',async()=>{
const admission=createWorkAdmission({maxJobs:1}),pending=deferred(),bytes=Buffer.from('still used');
const work=admission.run(()=>pending.promise,{payload:bytes});admission.close();
assert.deepEqual(admission.status(),{active:1,maxJobs:1,closed:true,available:0});
assert.equal(bytes.toString(),'still used');assert.throws(()=>admission.run(()=>true),{code:'work_admission_closed'});
pending.resolve();await work;assert.equal(admission.status().active,0);assert.ok(bytes.every(value=>value===0));
});
test('configuration and admission failures use fixed public errors and immutable status',()=>{
assert.throws(()=>createWorkAdmission({maxJobs:0}),{message:'work_configuration_invalid'});
const admission=createWorkAdmission();assert.equal(Object.isFrozen(admission.status()),true);
assert.throws(()=>admission.run(()=>{}, {payload:'private content'}),{message:'work_configuration_invalid'});
admission.close();const bytes=Buffer.from('not admitted');
assert.throws(()=>admission.run(()=>{}, {payload:bytes}),{code:'work_admission_closed'});
assert.ok(bytes.every(value=>value===0));
});