Skip to content

Commit

Permalink
test: simplify test-async-hooks-http-parser-destroy
Browse files Browse the repository at this point in the history
Simplify test-async-hooks-http-parser-destroy and improve it's reporting
when failing. (Also makes it easier to run on older versions of Node.js
because it doesn't rely on internal test modules that won't work there.)

Before, failures looked like this (edited slightly to conform to our
commit message 72-char line length restriction):

    The expression evaluated to a falsy value:
    assert.ok(destroyedIds.indexOf(createdAsyncId) >= 0)

Now, you get a slightly better idea of what's up. (Is it missing one ID?
More than one? All of them?):

    Input A expected to strictly deep-equal input B:
    + expected - actual ... Lines skipped

      Set {
        1009,
    ...
        1025,
    -   158,
    -   159,
    -   161,
    -   162,
    -   164,
    -   165,
    -   167,
    -   168,
    -   170,
    ...
    +   159,
    +   162,
    +   165,
    +   168,
    +   171,
    +   174,
    +   177,
    +   180,
    +   183,

This test still fails as expected on 10.14.1 and passees on 10.14.2
(where the regression it tests for was fixed). (You will need to comment
on the `require('../common');` line first but that's now the only change
you need to make this run in older versions.)

Refs: #26610
  • Loading branch information
Trott committed Apr 19, 2019
1 parent 2e4ceb5 commit 079d054
Showing 1 changed file with 40 additions and 33 deletions.
73 changes: 40 additions & 33 deletions test/parallel/test-async-hooks-http-parser-destroy.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use strict';
const common = require('../common');
const Countdown = require('../common/countdown');
require('../common');
const assert = require('assert');
const async_hooks = require('async_hooks');
const http = require('http');
Expand All @@ -12,50 +11,58 @@ const http = require('http');
const N = 50;
const KEEP_ALIVE = 100;

const createdIds = [];
const destroyedIds = [];
// XXX (trott): 'destroy' event can happen more than once for some asyncIds.
// Using a Set for now to work around the bug, but it can be simplified perhaps
// once https://github.com/nodejs/node/issues/26961 is fixed.
const createdIds = new Set();
const destroyedIds = new Set();
async_hooks.createHook({
init: common.mustCallAtLeast((asyncId, type) => {
init: (asyncId, type) => {
if (type === 'HTTPPARSER') {
createdIds.push(asyncId);
createdIds.add(asyncId);
}
}, N),
},
destroy: (asyncId) => {
destroyedIds.push(asyncId);
if (createdIds.has(asyncId)) {
destroyedIds.add(asyncId);
// Each HTTP request results in two createdIds and two destroyedIds.
if (destroyedIds.size === N * 2)
server.close();
}
}
}).enable();

const server = http.createServer(function(req, res) {
res.end('Hello');
});
const server = http.createServer((req, res) => { res.end('Hello'); });

const keepAliveAgent = new http.Agent({
keepAlive: true,
keepAliveMsecs: KEEP_ALIVE,
});

const countdown = new Countdown(N, () => {
server.close(() => {
// Give the server sockets time to close (which will also free their
// associated parser objects) after the server has been closed.
setTimeout(() => {
createdIds.forEach((createdAsyncId) => {
assert.ok(destroyedIds.indexOf(createdAsyncId) >= 0);
});
}, KEEP_ALIVE * 2);
});
});

server.listen(0, function() {
server.listen(0, () => {
for (let i = 0; i < N; ++i) {
(function makeRequest() {
http.get({
port: server.address().port,
agent: keepAliveAgent
}, function(res) {
countdown.dec();
res.resume();
});
})();
http.get(
{ port: server.address().port, agent: keepAliveAgent },
(res) => { res.resume(); }
);
}
});

function checkOnExit() {
assert.deepStrictEqual(destroyedIds, createdIds);
// Each HTTP request results in two createdIds and two destroyedIds.
assert.strictEqual(createdIds.size, N * 2);
}

// Ordinary exit.
process.on('exit', checkOnExit);

// Test runner tools/test.py will send SIGTERM if timeout.
// Signals aren't received in workers, but that's OK. The test will still fail
// if it times out. It just won't provide the additional information that this
// handler does.
process.on('SIGTERM', () => {
console.error('Received SIGTERM. (Timed out?)');
checkOnExit();
process.exit(1);
});

0 comments on commit 079d054

Please sign in to comment.