2018-06-25 00:28:42 +02:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
/* global it:false */
|
|
|
|
|
|
2026-02-14 09:53:14 +01:00
|
|
|
import expect from 'expect.js';
|
|
|
|
|
import fs from 'node:fs';
|
|
|
|
|
import net from 'node:net';
|
|
|
|
|
import path from 'node:path';
|
|
|
|
|
import paths from '../paths.js';
|
|
|
|
|
import safe from 'safetydance';
|
|
|
|
|
import * as syslogServer from '../../syslog.js';
|
|
|
|
|
import timers from 'timers/promises';
|
2018-06-25 00:28:42 +02:00
|
|
|
|
2026-02-14 09:53:14 +01:00
|
|
|
/* global describe:false */
|
|
|
|
|
/* global after:false */
|
2024-03-30 19:17:04 +01:00
|
|
|
|
|
|
|
|
async function sendMessage(message) {
|
|
|
|
|
const client = net.createConnection(paths.SYSLOG_SOCKET_FILE);
|
|
|
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
client.on('connect', function () {
|
|
|
|
|
client.end(message, function (error) {
|
|
|
|
|
if (error) return reject(error);
|
|
|
|
|
resolve();
|
|
|
|
|
});
|
|
|
|
|
});
|
2018-06-25 00:28:42 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-30 19:17:04 +01:00
|
|
|
async function verifyMessage(pattern, fileName) {
|
2018-06-25 00:28:42 +02:00
|
|
|
// give the server some time to write to disk
|
2024-03-30 19:17:04 +01:00
|
|
|
await timers.setTimeout(250);
|
|
|
|
|
const data = fs.readFileSync(path.join(paths.LOG_DIR, fileName), { encoding: 'utf8' });
|
|
|
|
|
const found = data.match(new RegExp(pattern));
|
|
|
|
|
if (found === null) throw new Error(`${pattern} not found in ${fileName}`);
|
2018-06-25 00:28:42 +02:00
|
|
|
}
|
|
|
|
|
|
2025-02-14 17:26:54 +01:00
|
|
|
describe('Syslog', function () {
|
2018-06-25 00:28:42 +02:00
|
|
|
this.timeout(5000);
|
|
|
|
|
|
2023-04-14 19:31:45 +02:00
|
|
|
after(async function () {
|
2024-03-30 19:17:04 +01:00
|
|
|
await syslogServer.stop();
|
2018-06-25 00:28:42 +02:00
|
|
|
});
|
|
|
|
|
|
2023-04-14 19:31:45 +02:00
|
|
|
it('can start', async function () {
|
2024-03-30 19:17:04 +01:00
|
|
|
await syslogServer.start();
|
2018-06-25 00:28:42 +02:00
|
|
|
});
|
|
|
|
|
|
2024-03-30 19:17:04 +01:00
|
|
|
it('handle good message', async function () {
|
2018-06-25 00:28:42 +02:00
|
|
|
// IETF (RFC 5424) message, with structured data and chained hostnames
|
|
|
|
|
const ietfLine = '<110>1 2009-05-03T14:00:39.529966+02:00 host.example.org/relay.example.org testapp 2138 - [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"][exampleSDID@32474 iut="4" eventSource="Application" eventID="1012"][ssign VER="0111" RSID="1" SG="0" SPRI="0" GBC="2" FMN="1" CNT="7" HB="K6wzcombEvKJ+UTMcn9bPryAeaU= zrkDcIeaDluypaPCY8WWzwHpPok= zgrWOdpx16ADc7UmckyIFY53icE= XfopJ+S8/hODapiBBCgVQaLqBKg= J67gKMFl/OauTC20ibbydwIlJC8= M5GziVgB6KPY3ERU1HXdSi2vtdw= Wxd/lU7uG/ipEYT9xeqnsfohyH0=" SIGN="AKBbX4J7QkrwuwdbV7Taujk2lvOf8gCgC62We1QYfnrNHz7FzAvdySuMyfM="] BOMAn application event log entry';
|
|
|
|
|
|
2024-03-30 19:17:04 +01:00
|
|
|
await sendMessage(ietfLine);
|
|
|
|
|
await verifyMessage(/An application event log entry/, 'testapp/app.log');
|
2018-06-25 00:28:42 +02:00
|
|
|
});
|
|
|
|
|
|
2024-03-30 19:17:04 +01:00
|
|
|
it('ignores invalid message', async function () {
|
2018-06-25 00:28:42 +02:00
|
|
|
const invalidLine = 'foobar';
|
2024-03-30 19:17:04 +01:00
|
|
|
await sendMessage(invalidLine);
|
|
|
|
|
const [error] = await safe(verifyMessage(/foobar/, 'testapp/app.log'));
|
|
|
|
|
expect(error).to.be.ok();
|
2018-06-25 00:28:42 +02:00
|
|
|
});
|
|
|
|
|
|
2024-03-30 19:17:04 +01:00
|
|
|
it('can handle message with colons', async function () {
|
2018-06-25 00:37:47 +02:00
|
|
|
// this is what we see from docker syslog
|
2018-06-25 00:28:42 +02:00
|
|
|
const message = '<30>1 2018-06-24T22:22:53Z my.test.com testapp 26599 testapp - This: contains two : colons';
|
|
|
|
|
|
2024-03-30 19:17:04 +01:00
|
|
|
await sendMessage(message);
|
|
|
|
|
await verifyMessage(/This: contains two : colons/, 'testapp/app.log');
|
2018-06-25 00:28:42 +02:00
|
|
|
});
|
|
|
|
|
});
|