const { test } = require('tap'); const net = require('net'); const childProcess = require('child_process'); const sandbox = require('@log4js-node/sandboxed-module'); const log4js = require('../../lib/log4js'); test('multiprocess appender shutdown (master)', { timeout: 10000 }, (t) => { log4js.configure({ appenders: { stdout: { type: 'stdout' }, multi: { type: 'multiprocess', mode: 'master', loggerPort: 12345, appender: 'stdout', }, }, categories: { default: { appenders: ['multi'], level: 'debug' } }, }); setTimeout(() => { log4js.shutdown(() => { setTimeout(() => { net .connect({ port: 12345 }, () => { t.fail('connection should not still work'); t.end(); }) .on('error', (err) => { t.ok(err, 'we got a connection error'); t.end(); }); }, 1000); }); }, 1000); }); test('multiprocess appender shutdown (worker)', (t) => { const fakeConnection = { evts: {}, msgs: [], on(evt, cb) { this.evts[evt] = cb; }, write(data) { this.msgs.push(data); }, removeAllListeners() { this.removeAllListenersCalled = true; }, end(cb) { this.endCb = cb; }, }; const logLib = sandbox.require('../../lib/log4js', { requires: { net: { createConnection() { return fakeConnection; }, }, }, }); logLib.configure({ appenders: { worker: { type: 'multiprocess', mode: 'worker' } }, categories: { default: { appenders: ['worker'], level: 'debug' } }, }); logLib .getLogger() .info( 'Putting something in the buffer before the connection is established' ); // nothing been written yet. t.equal(fakeConnection.msgs.length, 0); let shutdownFinished = false; logLib.shutdown(() => { shutdownFinished = true; }); // still nothing been written yet. t.equal(fakeConnection.msgs.length, 0); fakeConnection.evts.connect(); setTimeout(() => { t.equal(fakeConnection.msgs.length, 2); t.ok(fakeConnection.removeAllListenersCalled); fakeConnection.endCb(); t.ok(shutdownFinished); t.end(); }, 500); }); test('multiprocess appender crash (worker)', (t) => { const loggerPort = 12346; const vcr = require('../../lib/appenders/recording'); log4js.configure({ appenders: { console: { type: 'recording' }, multi: { type: 'multiprocess', mode: 'master', loggerPort, appender: 'console', }, }, categories: { default: { appenders: ['multi'], level: 'debug' } }, }); const worker = childProcess.fork(require.resolve('../multiprocess-worker'), [ 'start-multiprocess-worker', loggerPort, ]); worker.on('message', (m) => { if (m === 'worker is done') { setTimeout(() => { worker.kill(); t.equal(vcr.replay()[0].data[0], 'Logging from worker'); log4js.shutdown(() => t.end()); }, 100); } }); });