diff --git a/run-tests b/run-tests index 23b062b60..2631b93dc 100755 --- a/run-tests +++ b/run-tests @@ -4,7 +4,7 @@ set -eu readonly source_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" readonly DATA_DIR="${HOME}/.cloudron_test" -readonly DEFAULT_TESTS="./syslog/*-test.js ./src/test/*-test.js ./src/routes/test/*-test.js" +readonly DEFAULT_TESTS="./src/test/*-test.js ./src/routes/test/*-test.js" ! "${source_dir}/src/test/check-install" && exit 1 @@ -68,9 +68,6 @@ docker pull cloudron/base:4.2.0@sha256:46da2fffb36353ef714f97ae8e962bd2c212ca091 echo "=> Create iptables blocklist" sudo ipset create cloudron_blocklist hash:net || true -echo "=> Starting cloudron-syslog" -syslog/service.js "${DATA_DIR}/platformdata/logs/" & - echo "=> Ensure database" mysql -h"${MYSQL_IP}" -uroot -ppassword -e "ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password';" mysql -h"${MYSQL_IP}" -uroot -ppassword -e 'CREATE DATABASE IF NOT EXISTS box' diff --git a/src/test/syslog-test.js b/src/test/syslog-test.js index ac18dcef7..d1b79d9a2 100644 --- a/src/test/syslog-test.js +++ b/src/test/syslog-test.js @@ -6,81 +6,67 @@ 'use strict'; -const dgram = require('dgram'), - expect = require('expect.js'), +const expect = require('expect.js'), fs = require('fs'), + net = require('net'), path = require('path'), - os = require('os'), - server = require('./server.js'); + paths = require('../paths.js'), + safe = require('safetydance'), + syslogServer = require('../../syslog.js'), + timers = require('timers/promises'); -const PORT = 5678; -const LOG_FOLDER = path.join(os.tmpdir(), '/cloudron-syslog-test/'); +async function sendMessage(message) { + const client = net.createConnection(paths.SYSLOG_SOCKET_FILE); -function sendMessage(message, callback) { - const client = dgram.createSocket('udp4'); - - client.send(message, PORT, 'localhost', function (error) { - if (error) return callback(error); - - client.close(); - - callback(); + return new Promise((resolve, reject) => { + client.on('connect', function () { + client.end(message, function (error) { + if (error) return reject(error); + resolve(); + }); + }); }); } -function verifyMessage(pattern, fileName, callback) { +async function verifyMessage(pattern, fileName) { // give the server some time to write to disk - setTimeout(function () { - const data = fs.readFileSync(path.join(LOG_FOLDER, fileName), { encoding: 'utf8' }); - const found = data.match(new RegExp(pattern)); - return callback(found === null ? new Error('not found') : null); - }, 250); + 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}`); } describe('Daemon', function () { this.timeout(5000); after(async function () { - fs.rmSync(LOG_FOLDER, { recursive: true, force: true }); - await server.stop(); + await syslogServer.stop(); }); it('can start', async function () { - await server.start({ port: PORT, logFolder: LOG_FOLDER }); + await syslogServer.start(); }); - it('handle good message', function (done) { + it('handle good message', async function () { // 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'; - sendMessage(ietfLine, function (error) { - expect(error).to.not.be.ok(); - - verifyMessage(/An application event log entry/, 'testapp/app.log', done); - }); + await sendMessage(ietfLine); + await verifyMessage(/An application event log entry/, 'testapp/app.log'); }); - it('ignores invalid message', function (done) { + it('ignores invalid message', async function () { const invalidLine = 'foobar'; - - sendMessage(invalidLine, function (error) { - expect(error).to.not.be.ok(); - - verifyMessage(/foobar/, 'testapp/app.log', function (error) { - expect(error).to.be.ok(); - done(); - }); - }); + await sendMessage(invalidLine); + const [error] = await safe(verifyMessage(/foobar/, 'testapp/app.log')); + expect(error).to.be.ok(); }); - it('can handle message with :', function (done) { + it('can handle message with colons', async function () { // this is what we see from docker syslog const message = '<30>1 2018-06-24T22:22:53Z my.test.com testapp 26599 testapp - This: contains two : colons'; - sendMessage(message, function (error) { - expect(error).to.not.be.ok(); - - verifyMessage(/This: contains two : colons/, 'testapp/app.log', done); - }); + await sendMessage(message); + await verifyMessage(/This: contains two : colons/, 'testapp/app.log'); }); }); diff --git a/syslog.js b/syslog.js index 86bec7399..64a5a3e58 100755 --- a/syslog.js +++ b/syslog.js @@ -2,6 +2,11 @@ 'use strict'; +exports = module.exports = { + start, + stop +}; + const debug = require('debug')('syslog:server'), fs = require('fs'), net = require('net'), @@ -70,4 +75,6 @@ async function main() { }); } -main(); +if (require.main === module) { + main(); +}