diff --git a/test/forkRequest.js b/test/forkRequest.js new file mode 100644 index 0000000..71c3b05 --- /dev/null +++ b/test/forkRequest.js @@ -0,0 +1,21 @@ +const fork = require('child_process').fork +const resolve = require('path').resolve + +module.exports = function forkRequest (address, delay = 100, cb) { + const childProcess = fork( + resolve(__dirname, 'request.js'), + [address, delay], + { windowsHide: true } + ) + + childProcess.on('message', (payload) => { + if (payload.error) { + cb(new Error(payload.error), JSON.parse(payload.response), payload.body) + return + } + cb(null, JSON.parse(payload.response), payload.body) + }) + childProcess.on('error', err => { + cb(err) + }) +} diff --git a/test/pressurehandler.test.js b/test/pressurehandler.test.js index 92de5a9..d65256e 100644 --- a/test/pressurehandler.test.js +++ b/test/pressurehandler.test.js @@ -2,7 +2,7 @@ const { test } = require('tap') const { promisify } = require('util') -const sget = require('simple-get').concat +const forkRequest = require('./forkRequest') const Fastify = require('fastify') const { monitorEventLoopDelay } = require('perf_hooks') const underPressure = require('../index') @@ -120,22 +120,16 @@ test('event loop delay', { skip: !monitorEventLoopDelay }, t => { }) fastify.get('/', (req, rep) => rep.send('A')) - - fastify.listen({ port: 0 }, async (err, address) => { + fastify.listen({ port: 3000 }, async (err, address) => { t.error(err) fastify.server.unref() - await wait(500) - process.nextTick(() => block(1500)) - - sget({ - method: 'GET', - url: address + '/' - }, (err, response, body) => { + forkRequest(address, 500, (err, response, body) => { t.error(err) - t.equal(body.toString(), 'B') + t.equal(body, 'B') fastify.close() }) + process.nextTick(() => block(1500)) }) }) @@ -158,16 +152,13 @@ test('heap bytes', t => { t.error(err) fastify.server.unref() - process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, monitorEventLoopDelay ? 750 : 250, (err, response, body) => { t.error(err) t.equal(body.toString(), 'B') fastify.close() }) + + process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) }) }) @@ -190,16 +181,13 @@ test('rss bytes', t => { t.error(err) fastify.server.unref() - process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, monitorEventLoopDelay ? 750 : 250, (err, response, body) => { t.error(err) t.equal(body.toString(), 'B') fastify.close() }) + + process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) }) }) @@ -222,16 +210,13 @@ test('event loop utilization', { skip: !isSupportedVersion }, t => { t.error(err) fastify.server.unref() - process.nextTick(() => block(1000)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, 500, (err, response, body) => { t.error(err) t.equal(body.toString(), 'B') fastify.close() }) + + process.nextTick(() => block(1000)) }) }) @@ -267,15 +252,11 @@ test('event loop delay (NaN)', { skip: !isSupportedVersion }, t => { t.error(err) fastify.server.unref() - process.nextTick(() => block(1000)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, 500, (err, response, body) => { t.error(err) t.equal(body.toString(), 'B') fastify.close() }) + process.nextTick(() => block(1000)) }) }) diff --git a/test/request.js b/test/request.js new file mode 100755 index 0000000..5cdc8bc --- /dev/null +++ b/test/request.js @@ -0,0 +1,42 @@ +'use strict' + +const sget = require('simple-get').concat +const promisify = require('util').promisify +const wait = promisify(setTimeout) + +const address = process.argv[2] +const delay = parseInt(process.argv[3]) + +// custom stringification to avoid circular reference breaking +function stringifyResponse (response) { + return JSON.stringify({ + statusCode: response.statusCode, + headers: response.headers + }) +} + +async function run () { + await wait(delay) + sget({ + method: 'GET', + url: address + }, function (error, response, body) { + if (error instanceof Error) { + process.send({ + error: error.message, + response: stringifyResponse(response), + body: body.toString() + }) + process.exit(1) + } + + process.send({ + error: null, + response: stringifyResponse(response), + body: body.toString() + }) + process.exit() + }) +} + +run() diff --git a/test/statusRoute.test.js b/test/statusRoute.test.js index a997ee1..bd055f2 100644 --- a/test/statusRoute.test.js +++ b/test/statusRoute.test.js @@ -1,7 +1,7 @@ 'use strict' const { test } = require('tap') -const sget = require('simple-get').concat +const forkRequest = require('./forkRequest') const Fastify = require('fastify') const { monitorEventLoopDelay } = require('perf_hooks') const underPressure = require('../index') @@ -24,17 +24,14 @@ test('Expose status route', t => { t.error(err) fastify.server.unref() - process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) - - sget({ - method: 'GET', - url: `${address}/status` - }, (err, response, body) => { + forkRequest(`${address}/status`, monitorEventLoopDelay ? 750 : 250, (err, response, body) => { t.error(err) t.equal(response.statusCode, 200) t.same(JSON.parse(body), { status: 'ok' }) fastify.close() }) + + process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) }) }) diff --git a/test/test.js b/test/test.js index f8087d8..b1d1261 100644 --- a/test/test.js +++ b/test/test.js @@ -2,7 +2,7 @@ const { test } = require('tap') const { promisify } = require('util') -const sget = require('simple-get').concat +const forkRequest = require('./forkRequest') const Fastify = require('fastify') const { monitorEventLoopDelay } = require('perf_hooks') const underPressure = require('../index') @@ -32,13 +32,7 @@ test('Should return 503 on maxEventLoopDelay', t => { await wait(500) } - // Increased to prevent Travis to fail - process.nextTick(() => block(1000)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, 500, (err, response, body) => { t.error(err) t.equal(response.statusCode, 503) t.equal(response.headers['retry-after'], '10') @@ -50,6 +44,8 @@ test('Should return 503 on maxEventLoopDelay', t => { }) fastify.close() }) + + process.nextTick(() => block(1000)) }) }) @@ -69,13 +65,7 @@ test('Should return 503 on maxEventloopUtilization', { skip: !isSupportedVersion t.error(err) fastify.server.unref() - // Increased to prevent Travis to fail - process.nextTick(() => block(1000)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, 500, (err, response, body) => { t.error(err) t.equal(response.statusCode, 503) t.equal(response.headers['retry-after'], '10') @@ -87,6 +77,8 @@ test('Should return 503 on maxEventloopUtilization', { skip: !isSupportedVersion }) fastify.close() }) + + process.nextTick(() => block(1000)) }) }) @@ -106,12 +98,7 @@ test('Should return 503 on maxHeapUsedBytes', t => { t.error(err) fastify.server.unref() - process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, monitorEventLoopDelay ? 750 : 250, (err, response, body) => { t.error(err) t.equal(response.statusCode, 503) t.equal(response.headers['retry-after'], '10') @@ -123,6 +110,8 @@ test('Should return 503 on maxHeapUsedBytes', t => { }) fastify.close() }) + + process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) }) }) @@ -142,12 +131,7 @@ test('Should return 503 on maxRssBytes', t => { t.error(err) fastify.server.unref() - process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, monitorEventLoopDelay ? 750 : 250, (err, response, body) => { t.error(err) t.equal(response.statusCode, 503) t.equal(response.headers['retry-after'], '10') @@ -159,6 +143,8 @@ test('Should return 503 on maxRssBytes', t => { }) fastify.close() }) + + process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) }) }) @@ -180,12 +166,7 @@ test('Custom message and retry after header', t => { t.error(err) fastify.server.unref() - process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, monitorEventLoopDelay ? 750 : 250, (err, response, body) => { t.error(err) t.equal(response.statusCode, 503) t.equal(response.headers['retry-after'], '50') @@ -197,6 +178,8 @@ test('Custom message and retry after header', t => { }) fastify.close() }) + + process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) }) }) @@ -231,12 +214,7 @@ test('Custom error instance', t => { t.error(err) fastify.server.unref() - process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, monitorEventLoopDelay ? 750 : 250, (err, response, body) => { t.error(err) t.equal(response.statusCode, 418) t.same(JSON.parse(body), { @@ -247,6 +225,8 @@ test('Custom error instance', t => { }) fastify.close() }) + + process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) }) }) @@ -280,17 +260,14 @@ test('memoryUsage name space', t => { await wait(500) } - process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, monitorEventLoopDelay ? 750 : 250, (err, response, body) => { t.error(err) t.equal(response.statusCode, 200) t.same(JSON.parse(body), { hello: 'world' }) fastify.close() }) + + process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) }) }) @@ -319,17 +296,14 @@ test('memoryUsage name space (without check)', t => { await wait(500) } - process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) - - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, monitorEventLoopDelay ? 750 : 250, (err, response, body) => { t.error(err) t.equal(response.statusCode, 200) t.same(JSON.parse(body), { hello: 'world' }) fastify.close() }) + + process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) }) }) @@ -355,10 +329,7 @@ test('Custom health check', t => { t.error(err) fastify.server.unref() - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, 0, (err, response, body) => { t.error(err) t.equal(response.statusCode, 503) t.equal(response.headers['retry-after'], '10') @@ -390,10 +361,7 @@ test('Custom health check', t => { t.error(err) fastify.server.unref() - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + forkRequest(address, 0, (err, response, body) => { t.error(err) t.equal(response.statusCode, 200) t.same(JSON.parse(body), { @@ -422,10 +390,8 @@ test('Custom health check', t => { fastify.listen({ port: 0 }, (err, address) => { t.error(err) fastify.server.unref() - sget({ - method: 'GET', - url: address - }, (err, response, body) => { + + forkRequest(address, 0, (err, response, body) => { check = false t.error(err) t.equal(response.statusCode, 200) @@ -434,23 +400,18 @@ test('Custom health check', t => { }) }) - setTimeout(function () { - sget({ - method: 'GET', - url: address - }, (err, response, body) => { - t.error(err) - t.equal(response.statusCode, 503) - t.equal(response.headers['retry-after'], '10') - t.same(JSON.parse(body), { - code: 'FST_UNDER_PRESSURE', - error: 'Service Unavailable', - message: 'Service Unavailable', - statusCode: 503 - }) - fastify.close() + forkRequest(address, 100, (err, response, body) => { + t.error(err) + t.equal(response.statusCode, 503) + t.equal(response.headers['retry-after'], '10') + t.same(JSON.parse(body), { + code: 'FST_UNDER_PRESSURE', + error: 'Service Unavailable', + message: 'Service Unavailable', + statusCode: 503 }) - }, 100) + fastify.close() + }) }) }) @@ -493,10 +454,7 @@ test('Custom health check', t => { fastify.server.unref() check = false - sget({ - method: 'GET', - url: address + '/status' - }, (err, response, body) => { + forkRequest(address + '/status', 0, (err, response, body) => { t.error(err) t.equal(response.statusCode, 503) t.equal(response.headers['retry-after'], '10') @@ -532,10 +490,7 @@ test('Custom health check', t => { fastify.server.unref() check = false - sget({ - method: 'GET', - url: address + '/status' - }, (err, response, body) => { + forkRequest(address + '/status', 0, (err, response, body) => { t.error(err) t.equal(response.statusCode, 503) t.equal(response.headers['retry-after'], '10') @@ -575,10 +530,7 @@ test('Custom health check', t => { t.error(err) fastify.server.unref() - sget({ - method: 'GET', - url: address + '/status' - }, (err, response, body) => { + forkRequest(address + '/status', 0, (err, response, body) => { t.error(err) t.equal(response.statusCode, 200) t.same(JSON.parse(body), { @@ -614,10 +566,7 @@ test('Custom health check', t => { t.error(err) fastify.server.unref() - sget({ - method: 'GET', - url: address + '/status' - }, (err, response, body) => { + forkRequest(address + '/status', 0, (err, response, body) => { t.error(err) t.equal(response.statusCode, 200) t.same(JSON.parse(body), {