Skip to content

Commit

Permalink
async hooks tests
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford committed Oct 7, 2019
1 parent d6c483e commit d85bb91
Show file tree
Hide file tree
Showing 29 changed files with 302 additions and 76 deletions.
22 changes: 20 additions & 2 deletions test/async-hooks/init-hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ if (typeof global.gc === 'function') {

function noop() {}

const bootstrapIds = new Set();
let firstTriggerAsyncId;

class ActivityCollector {
constructor(start, {
allowNoInit = false,
Expand Down Expand Up @@ -61,6 +64,10 @@ class ActivityCollector {
this._asyncHook.disable();
}

get firstTriggerAsyncId() {
return firstTriggerAsyncId;
}

sanityCheck(types) {
if (types != null && !Array.isArray(types)) types = [ types ];

Expand Down Expand Up @@ -177,7 +184,13 @@ class ActivityCollector {
return h;
}

_init(uid, type, triggerAsyncId, handle) {
_init(uid, type, triggerAsyncId, handle, bootstrap) {
if (bootstrap) {
bootstrapIds.add(uid);
return;
} else if (!firstTriggerAsyncId) {
firstTriggerAsyncId = triggerAsyncId;
}
const activity = {
uid,
type,
Expand All @@ -190,38 +203,43 @@ class ActivityCollector {
this._stamp(activity, 'init');
this._activities.set(uid, activity);
this._maybeLog(uid, type, 'init');
this.oninit(uid, type, triggerAsyncId, handle);
this.oninit(uid, type, triggerAsyncId, handle, bootstrap);
}

_before(uid) {
if (bootstrapIds.has(uid)) return;
const h = this._getActivity(uid, 'before');
this._stamp(h, 'before');
this._maybeLog(uid, h && h.type, 'before');
this.onbefore(uid);
}

_after(uid) {
if (bootstrapIds.has(uid)) return;
const h = this._getActivity(uid, 'after');
this._stamp(h, 'after');
this._maybeLog(uid, h && h.type, 'after');
this.onafter(uid);
}

_destroy(uid) {
if (bootstrapIds.has(uid)) return;
const h = this._getActivity(uid, 'destroy');
this._stamp(h, 'destroy');
this._maybeLog(uid, h && h.type, 'destroy');
this.ondestroy(uid);
}

_promiseResolve(uid) {
if (bootstrapIds.has(uid)) return;
const h = this._getActivity(uid, 'promiseResolve');
this._stamp(h, 'promiseResolve');
this._maybeLog(uid, h && h.type, 'promiseResolve');
this.onpromiseResolve(uid);
}

_maybeLog(uid, type, name) {
if (bootstrapIds.has(uid)) return;
if (this._logid &&
(type == null || this._logtype == null || this._logtype === type)) {
print(`${this._logid}.${name}.uid-${uid}`);
Expand Down
3 changes: 2 additions & 1 deletion test/async-hooks/test-async-await.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const initHooks = require('./init-hooks');
const util = require('util');

const sleep = util.promisify(setTimeout);

// Either 'inited' or 'resolved'
const promisesInitState = new Map();
// Either 'before' or 'after' AND asyncId must be present in the other map
Expand All @@ -26,7 +27,7 @@ const hooks = initHooks({
});
hooks.enable();

function oninit(asyncId, type) {
function oninit(asyncId, type, triggerAsyncId, resource) {
if (type === 'PROMISE') {
promisesInitState.set(asyncId, 'inited');
}
Expand Down
2 changes: 1 addition & 1 deletion test/async-hooks/test-crypto-pbkdf2.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function onexit() {
const a = as[0];
assert.strictEqual(a.type, 'PBKDF2REQUEST');
assert.strictEqual(typeof a.uid, 'number');
assert.strictEqual(a.triggerAsyncId, 1);
assert.strictEqual(a.triggerAsyncId, hooks.firstTriggerAsyncId);
checkInvocations(a, { init: 1, before: 1, after: 1, destroy: 1 },
'when process exits');
}
2 changes: 1 addition & 1 deletion test/async-hooks/test-crypto-randomBytes.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function onexit() {
const a = as[0];
assert.strictEqual(a.type, 'RANDOMBYTESREQUEST');
assert.strictEqual(typeof a.uid, 'number');
assert.strictEqual(a.triggerAsyncId, 1);
assert.strictEqual(a.triggerAsyncId, hooks.firstTriggerAsyncId);
checkInvocations(a, { init: 1, before: 1, after: 1, destroy: 1 },
'when process exits');
}
15 changes: 12 additions & 3 deletions test/async-hooks/test-disable-in-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,30 @@
const common = require('../common');
const async_hooks = require('async_hooks');
const fs = require('fs');
const assert = require('assert');

let nestedCall = false;
let cnt = 0;

async_hooks.createHook({
init: common.mustCall(function() {
init: function(asyncId, type, triggerAsyncId, handle, bootstrap) {
if (type === 'TickObject' || type === 'PROMISE')
return;
cnt++;
nestedHook.disable();
if (!nestedCall) {
nestedCall = true;
fs.access(__filename, common.mustCall());
}
}, 2)
}
}).enable();

const nestedHook = async_hooks.createHook({
init: common.mustCall(2)
init: function(asyncId, type, triggerAsyncId, handle, bootstrap) {
cnt++;
}
}).enable();

fs.access(__filename, common.mustCall());

assert.strictEqual(cnt, 4);
29 changes: 25 additions & 4 deletions test/async-hooks/test-emit-before-after.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,33 @@ const expectedType = 'test_emit_before_after_type';
async_hooks.emitBefore(expectedId, expectedTriggerId);
async_hooks.emitAfter(expectedId);

initHooks({
onbefore: common.mustCall((id) => assert.strictEqual(id, expectedId)),
onafter: common.mustCall((id) => assert.strictEqual(id, expectedId)),
const ignoreIds = new Set();
const initIds = new Map();

let okCnt = 0;
const hooks = initHooks({
oninit(id, type) {
if (type === 'TickObject' || type === 'PROMISE') {
ignoreIds.add(id);
} else {
initIds.set(id, type);
}
},
onbefore(id) {
if (ignoreIds.has(id) || !initIds.has(id)) return;
assert.strictEqual(id, expectedId);
okCnt++;
},
onafter(id) {
if (ignoreIds.has(id) || !initIds.has(id)) return;
assert.strictEqual(id, expectedId);
okCnt++;
},
allowNoInit: true
}).enable();
});
hooks.enable();

async_hooks.emitInit(expectedId, expectedType, expectedTriggerId);
async_hooks.emitBefore(expectedId, expectedTriggerId);
async_hooks.emitAfter(expectedId);
assert.strictEqual(okCnt, 2);
13 changes: 9 additions & 4 deletions test/async-hooks/test-emit-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,18 @@ async_hooks.emitInit(expectedId, expectedType, expectedTriggerId,

hooks1.disable();

initHooks({
oninit: common.mustCall((id, type, triggerAsyncId, resource) => {
let okCnt = 0;
const hooks = initHooks({
oninit: (id, type, triggerAsyncId, resource) => {
if (type === 'PROMISE' || type === 'TickObject') return;
assert.strictEqual(id, expectedId);
assert.strictEqual(type, expectedType);
assert.notStrictEqual(triggerAsyncId, expectedTriggerId);
assert.strictEqual(resource.key, expectedResource.key);
})
}).enable();
okCnt++;
}
});
hooks.enable();

async_hooks.emitInit(expectedId, expectedType, null, expectedResource);
assert.strictEqual(okCnt, 1);
11 changes: 9 additions & 2 deletions test/async-hooks/test-enable-in-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,27 @@
const common = require('../common');
const async_hooks = require('async_hooks');
const fs = require('fs');
const assert = require('assert');

const nestedHook = async_hooks.createHook({
init: common.mustNotCall()
});
let nestedCall = false;

let cnt = 0;
async_hooks.createHook({
init: common.mustCall(() => {
init(asyncId, type) {
if (type === 'PROMISE' || type === 'TickObject')
return;
cnt++;
nestedHook.enable();
if (!nestedCall) {
nestedCall = true;
fs.access(__filename, common.mustCall());
}
}, 2)
}
}).enable();

fs.access(__filename, common.mustCall());

assert.strictEqual(cnt, 2);
2 changes: 1 addition & 1 deletion test/async-hooks/test-fseventwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ function onexit() {
const a = as[0];
assert.strictEqual(a.type, 'FSEVENTWRAP');
assert.strictEqual(typeof a.uid, 'number');
assert.strictEqual(a.triggerAsyncId, 1);
assert.strictEqual(a.triggerAsyncId, hooks.firstTriggerAsyncId);
checkInvocations(a, { init: 1, destroy: 1 }, 'when process exits');
}
2 changes: 1 addition & 1 deletion test/async-hooks/test-fsreqcallback-readFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fs.readFile(__filename, common.mustCall(onread));

function onread() {
const as = hooks.activitiesOfTypes('FSREQCALLBACK');
let lastParent = 1;
let lastParent = hooks.firstTriggerAsyncId;
for (let i = 0; i < as.length; i++) {
const a = as[i];
assert.strictEqual(a.type, 'FSREQCALLBACK');
Expand Down
2 changes: 1 addition & 1 deletion test/async-hooks/test-getaddrinforeqwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function onlookup() {
const a = as[0];
assert.strictEqual(a.type, 'GETADDRINFOREQWRAP');
assert.strictEqual(typeof a.uid, 'number');
assert.strictEqual(a.triggerAsyncId, 1);
assert.strictEqual(a.triggerAsyncId, hooks.firstTriggerAsyncId);
checkInvocations(a, { init: 1, before: 1 }, 'while in onlookup callback');
tick(2);
}
Expand Down
2 changes: 1 addition & 1 deletion test/async-hooks/test-getnameinforeqwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function onlookupService() {
const a = as[0];
assert.strictEqual(a.type, 'GETNAMEINFOREQWRAP');
assert.strictEqual(typeof a.uid, 'number');
assert.strictEqual(a.triggerAsyncId, 1);
assert.strictEqual(a.triggerAsyncId, hooks.firstTriggerAsyncId);
checkInvocations(a, { init: 1, before: 1 },
'while in onlookupService callback');
tick(2);
Expand Down
23 changes: 19 additions & 4 deletions test/async-hooks/test-late-hook-enable.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,22 @@ const fnsToTest = [setTimeout, (cb) => {
});
}];

let beforeCnt = 0;
let afterCnt = 0;
let destroyCnt = 0;

const hook = async_hooks.createHook({
before: common.mustNotCall(),
after: common.mustCall(() => {}, 3),
destroy: common.mustCall(() => {
before(asyncId) {
beforeCnt++;
},
after(asyncId) {
afterCnt++;
},
destroy(asyncId) {
destroyCnt++;
hook.disable();
nextTest();
}, 3)
}
});

nextTest();
Expand All @@ -47,3 +56,9 @@ function nextTest() {
}));
}
}

process.on('nextTick', () => {
assert.strictEqual(beforeCnt, 0);
assert.strictEqual(afterCnt, 3);
assert.strictEqual(destroyCnt, 3);
});
6 changes: 3 additions & 3 deletions test/async-hooks/test-pipewrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ const pipe2 = pipes[1];
const pipe3 = pipes[2];

assert.strictEqual(processwrap.type, 'PROCESSWRAP');
assert.strictEqual(processwrap.triggerAsyncId, 1);
assert.strictEqual(processwrap.triggerAsyncId, hooks.firstTriggerAsyncId);
checkInvocations(processwrap, { init: 1 },
'processwrap when sleep.spawn was called');

[ pipe1, pipe2, pipe3 ].forEach((x) => {
assert.strictEqual(x.type, 'PIPEWRAP');
assert.strictEqual(x.triggerAsyncId, 1);
assert.strictEqual(x.triggerAsyncId, hooks.firstTriggerAsyncId);
checkInvocations(x, { init: 1 }, 'pipe wrap when sleep.spawn was called');
});

Expand Down Expand Up @@ -73,7 +73,7 @@ function onexit() {

[ pipe1, pipe2, pipe3 ].forEach((x) => {
assert.strictEqual(x.type, 'PIPEWRAP');
assert.strictEqual(x.triggerAsyncId, 1);
assert.strictEqual(x.triggerAsyncId, hooks.firstTriggerAsyncId);
});

const ioEvents = Math.min(pipe2.before.length, pipe2.after.length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const hooks = initHooks();
hooks._allowNoInit = true;
hooks.enable();


process.on('exit', function onexit() {
hooks.disable();
hooks.sanityCheck('PROMISE');
Expand Down
2 changes: 1 addition & 1 deletion test/async-hooks/test-promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function onexit() {
const a0 = as[0];
assert.strictEqual(a0.type, 'PROMISE');
assert.strictEqual(typeof a0.uid, 'number');
assert.strictEqual(a0.triggerAsyncId, 1);
assert.strictEqual(a0.triggerAsyncId, hooks.firstTriggerAsyncId);
checkInvocations(a0, { init: 1 }, 'when process exits');

const a1 = as[1];
Expand Down
4 changes: 2 additions & 2 deletions test/async-hooks/test-statwatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ assert.strictEqual(as.length, 1);
const statwatcher1 = as[0];
assert.strictEqual(statwatcher1.type, 'STATWATCHER');
assert.strictEqual(typeof statwatcher1.uid, 'number');
assert.strictEqual(statwatcher1.triggerAsyncId, 1);
assert.strictEqual(statwatcher1.triggerAsyncId, hooks.firstTriggerAsyncId);
checkInvocations(statwatcher1, { init: 1 },
'watcher1: when started to watch file');

Expand All @@ -53,7 +53,7 @@ assert.strictEqual(as.length, 2);
const statwatcher2 = as[1];
assert.strictEqual(statwatcher2.type, 'STATWATCHER');
assert.strictEqual(typeof statwatcher2.uid, 'number');
assert.strictEqual(statwatcher2.triggerAsyncId, 1);
assert.strictEqual(statwatcher2.triggerAsyncId, hooks.firstTriggerAsyncId);
checkInvocations(statwatcher1, { init: 1 },
'watcher1: when started to watch second file');
checkInvocations(statwatcher2, { init: 1 },
Expand Down
4 changes: 3 additions & 1 deletion test/common/ongc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ function onGC(obj, gcListener) {
const async_hooks = require('async_hooks');

const onGcAsyncHook = async_hooks.createHook({
init: common.mustCallAtLeast(function(id, type) {
init: common.mustCallAtLeast(function(id, type, triggerAsncId, resource,
bootstrap) {
if (bootstrap) return;
if (this.trackedId === undefined) {
assert.strictEqual(type, gcTrackerTag);
this.trackedId = id;
Expand Down
3 changes: 2 additions & 1 deletion test/parallel/test-async-hooks-async-await.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ const assert = require('assert');

const asyncIds = [];
async_hooks.createHook({
init: (asyncId, type, triggerAsyncId) => {
init: (asyncId, type, triggerAsyncId, resource, bootstrap) => {
if (bootstrap) return;
asyncIds.push([triggerAsyncId, asyncId]);
}
}).enable();
Expand Down

0 comments on commit d85bb91

Please sign in to comment.