import test from 'node:test'; import assert from 'node:assert/strict'; import {fork} from 'node:child_process'; import {once} from 'node:events'; import fs from 'node:fs'; import https from 'node:https'; import http from 'node:http'; import tls from 'node:tls'; import net from 'node:net'; import {fileURLToPath} from 'node:url'; const cert=fs.readFileSync(new URL('./fixtures/icap/cert.pem',import.meta.url)),key=fs.readFileSync(new URL('./fixtures/icap/key.pem',import.meta.url)); const brokerNode=fileURLToPath(new URL('../.runtime/windows/broker/node.exe',import.meta.url)); function child(t) { assert.equal(fs.existsSync(brokerNode),true,'Verified bundled broker Node prerequisite'); const process=fork(fileURLToPath(new URL('./fixtures/broker-process-child.cjs',import.meta.url)),[],{execPath:brokerNode,execArgv:[],stdio:['ignore','ignore','ignore','ipc'],env:{SystemRoot:globalThis.process.env.SystemRoot}}); t.after(()=>{if(process.exitCode===null)process.kill();});return process; } function bounded(event,ms=3000){let timer;return Promise.race([event,new Promise((_,reject)=>timer=setTimeout(()=>reject(Error('test-deadline')),ms))]).finally(()=>clearTimeout(timer));} async function request(ready,destination,body) { return await new Promise((resolve,reject)=>{ const req=http.request({host:'127.0.0.1',port:ready.port,method:'CONNECT',path:destination,headers:{host:destination,'proxy-authorization':`Bearer ${ready.capability}`}}); req.setTimeout(2000,()=>req.destroy(Error('test-deadline')));req.on('error',reject); req.on('connect',(res,socket)=>{ if(res.statusCode!==200){socket.destroy();reject(Error('connect-rejected'));return;} const secure=tls.connect({socket,servername:'localhost',ca:cert,rejectUnauthorized:true});let text=''; secure.setTimeout(2000,()=>secure.destroy(Error('test-deadline')));secure.on('error',reject);secure.on('secureConnect',()=>secure.write(`POST /submit HTTP/1.1\r\nHost: ${destination}\r\nContent-Length: ${Buffer.byteLength(body)}\r\nConnection: close\r\n\r\n${body}`));secure.on('data',chunk=>text+=chunk);secure.on('end',()=>{secure.destroy();resolve(text);}); });req.end(); }); } test('separate Node child handles inspected CONNECT and closes on private IPC disconnect',async t=>{ const received=[];let connections=0; const target=https.createServer({key,cert},async(req,res)=>{const chunks=[];for await(const chunk of req)chunks.push(chunk);received.push(Buffer.concat(chunks).toString());res.writeHead(201);res.end('accepted');}); target.on('connection',()=>connections++);target.listen(0,'127.0.0.1');await once(target,'listening'); t.after(async()=>{target.closeAllConnections();await new Promise(r=>target.close(r));}); const destination=`localhost:${target.address().port}`,worker=child(t); const readyEvent=bounded(once(worker,'message'));worker.send({type:'start',config:{destination}}); const [ready]=await readyEvent;assert.equal(ready.type,'ready');assert.notEqual(worker.pid,process.pid);assert.match(ready.capability,/^[a-zA-Z0-9_-]{43}$/); assert.match(await request(ready,destination,'SECRET'),/^HTTP\/1.1 403/);assert.equal(connections,0); assert.match(await request(ready,destination,'public'),/^HTTP\/1.1 201/);assert.deepEqual(received,['public']); const exit=bounded(once(worker,'exit'));worker.disconnect();await exit; const failure=await new Promise(resolve=>{const socket=net.connect(ready.port,'127.0.0.1');socket.setTimeout(1000,()=>{socket.destroy();resolve('timeout');});socket.on('connect',()=>{socket.destroy();resolve('connected');});socket.on('error',error=>resolve(error.code));}); assert.equal(failure,'ECONNREFUSED'); }); test('invalid and oversized private bootstrap reject without spawning another process',async t=>{ for(const message of [{type:'command',command:'arbitrary'},{type:'start',config:{destination:'x'.repeat(70000)}}]) { const worker=child(t),reply=bounded(once(worker,'message')),exit=bounded(once(worker,'exit')); worker.send(message);assert.deepEqual((await reply)[0],{type:'error',code:'invalid-message'});await exit; } }); test('explicit private stop closes the sole child without restart',async t=>{ const worker=child(t),ready=bounded(once(worker,'message')); worker.send({type:'start',config:{destination:'localhost:443'}});assert.equal((await ready)[0].type,'ready'); const exit=bounded(once(worker,'exit'));worker.send({type:'stop'});await exit; assert.equal(worker.exitCode,0); });