Files
infocom-systems-design/node_modules/pino-abstract-transport/test/worker.test.js
2025-10-03 22:27:28 +03:00

365 lines
9.3 KiB
JavaScript

'use strict'
const { once } = require('events')
const { join } = require('path')
const ThreadStream = require('thread-stream')
const { MessageChannel } = require('worker_threads')
const { test } = require('tap')
workerTest('transport-on-data.js')
workerTest('transport-async-iteration.js', ' when using async iteration')
function workerTest (filename, description = '') {
test(`does not wait for pino to send config by default${description}`, function ({ same, plan }) {
plan(4)
const { port1, port2 } = new MessageChannel()
const stream = new ThreadStream({
filename: join(__dirname, 'fixtures', filename),
workerData: { port: port1 },
workerOpts: {
transferList: [port1]
}
})
const expected = [{
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'hello world'
}, {
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'another message',
prop: 42
}]
const emptyPinoConfig = {
levels: undefined,
messageKey: undefined,
errorKey: undefined
}
port2.on('message', function (message) {
same(expected.shift(), message.data)
same(emptyPinoConfig, message.pinoConfig)
})
const lines = expected.map(JSON.stringify).join('\n')
stream.write(lines)
stream.end()
})
test(`does not wait for pino to send config if transport is not expecting it${description}`, function ({ same, plan }) {
plan(4)
const { port1, port2 } = new MessageChannel()
const stream = new ThreadStream({
filename: join(__dirname, 'fixtures', filename),
workerData: {
port: port1,
pinoWillSendConfig: true
},
workerOpts: {
transferList: [port1]
}
})
const expected = [{
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'hello world'
}, {
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'another message',
prop: 42
}]
const emptyPinoConfig = {
levels: undefined,
messageKey: undefined,
errorKey: undefined
}
const pinoConfig = {
levels: {
labels: { 30: 'info' },
values: { info: 30 }
},
messageKey: 'msg',
errorKey: 'err'
}
stream.worker.postMessage({ code: 'PINO_CONFIG', config: pinoConfig })
// stream.emit('message', { code: 'PINO_CONFIG', config: pinoConfig })
port2.on('message', function (message) {
same(expected.shift(), message.data)
same(emptyPinoConfig, message.pinoConfig)
})
const lines = expected.map(JSON.stringify).join('\n')
stream.write(lines)
stream.end()
})
test(`waits for the pino config when pino intends to send it and the transport requests it${description}`, function ({ same, plan }) {
plan(4)
const { port1, port2 } = new MessageChannel()
const stream = new ThreadStream({
filename: join(__dirname, 'fixtures', filename),
workerData: {
port: port1,
pinoWillSendConfig: true,
opts: {
expectPinoConfig: true
}
},
workerOpts: {
transferList: [port1]
}
})
const expected = [{
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'hello world'
}, {
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'another message',
prop: 42
}]
const pinoConfig = {
levels: {
labels: { 30: 'info' },
values: { info: 30 }
},
messageKey: 'msg',
errorKey: 'err'
}
port2.on('message', function (message) {
same(expected.shift(), message.data)
same(pinoConfig, message.pinoConfig)
})
const lines = expected.map(JSON.stringify).join('\n')
stream.worker.postMessage({ code: 'PINO_CONFIG', config: pinoConfig })
// stream.emit('message', { code: 'PINO_CONFIG', config: pinoConfig })
stream.write(lines)
stream.end()
})
test(`continues to listen if it receives a message that is not PINO_CONFIG${description}`, function ({ same, plan }) {
plan(4)
const { port1, port2 } = new MessageChannel()
const stream = new ThreadStream({
filename: join(__dirname, 'fixtures', 'transport-on-data.js'),
workerData: {
port: port1,
pinoWillSendConfig: true,
opts: {
expectPinoConfig: true
}
},
workerOpts: {
transferList: [port1]
}
})
const expected = [{
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'hello world'
}, {
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'another message',
prop: 42
}]
const pinoConfig = {
levels: {
labels: { 30: 'info' },
values: { info: 30 }
},
messageKey: 'msg',
errorKey: 'err'
}
port2.on('message', function (message) {
same(expected.shift(), message.data)
same(pinoConfig, message.pinoConfig)
})
const lines = expected.map(JSON.stringify).join('\n')
stream.worker.postMessage('not a PINO_CONFIG')
// stream.emit('message', 'not a PINO_CONFIG')
stream.worker.postMessage({ code: 'NOT_PINO_CONFIG', config: { levels: 'foo', messageKey: 'bar', errorKey: 'baz' } })
// stream.emit('message', { code: 'NOT_PINO_CONFIG', config: { levels: 'foo', messageKey: 'bar', errorKey: 'baz' } })
stream.worker.postMessage({ code: 'PINO_CONFIG', config: pinoConfig })
// stream.emit('message', { code: 'PINO_CONFIG', config: pinoConfig })
stream.write(lines)
stream.end()
})
test(`waits for the pino config even if it is sent after write${description}`, function ({ same, plan }) {
plan(4)
const { port1, port2 } = new MessageChannel()
const stream = new ThreadStream({
filename: join(__dirname, 'fixtures', filename),
workerData: {
port: port1,
pinoWillSendConfig: true,
opts: {
expectPinoConfig: true
}
},
workerOpts: {
transferList: [port1]
}
})
const expected = [{
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'hello world'
}, {
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'another message',
prop: 42
}]
const pinoConfig = {
levels: {
labels: { 30: 'info' },
values: { info: 30 }
},
messageKey: 'msg',
errorKey: 'err'
}
port2.on('message', function (message) {
same(expected.shift(), message.data)
same(pinoConfig, message.pinoConfig)
})
const lines = expected.map(JSON.stringify).join('\n')
stream.write(lines)
stream.worker.postMessage({ code: 'PINO_CONFIG', config: pinoConfig })
// stream.emit('message', { code: 'PINO_CONFIG', config: pinoConfig })
stream.end()
})
test(`emits an error if the transport expects pino to send the config, but pino is not going to${description}`, async function ({ plan, same, ok }) {
plan(2)
const stream = new ThreadStream({
filename: join(__dirname, 'fixtures', filename),
workerData: {
opts: {
expectPinoConfig: true
}
}
})
const [err] = await once(stream, 'error')
same(err.message, 'This transport is not compatible with the current version of pino. Please upgrade pino to the latest version.')
ok(stream.destroyed)
})
}
test('waits for the pino config when pipelining', function ({ same, plan }) {
plan(2)
const { port1, port2 } = new MessageChannel()
const stream = new ThreadStream({
filename: join(__dirname, 'fixtures', 'worker-pipeline.js'),
workerData: {
pinoWillSendConfig: true,
targets: [{
target: './transport-transform.js',
options: {
opts: { expectPinoConfig: true }
}
}, {
target: './transport-on-data.js',
options: {
port: port1
}
}]
},
workerOpts: {
transferList: [port1]
}
})
const expected = [{
level: 'info(30)',
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'HELLO WORLD',
service: 'from transform'
}, {
level: 'info(30)',
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'ANOTHER MESSAGE',
prop: 42,
service: 'from transform'
}]
const lines = [{
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'hello world'
}, {
level: 30,
time: 1617955768092,
pid: 2942,
hostname: 'MacBook-Pro.local',
msg: 'another message',
prop: 42
}].map(JSON.stringify).join('\n')
const pinoConfig = {
levels: {
labels: { 30: 'info' },
values: { info: 30 }
},
messageKey: 'msg',
errorKey: 'err'
}
port2.on('message', function (message) {
same(expected.shift(), message.data)
})
stream.worker.postMessage({ code: 'PINO_CONFIG', config: pinoConfig })
// stream.emit('message', { code: 'PINO_CONFIG', config: pinoConfig })
stream.write(lines)
stream.end()
})