Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0aab92f

Browse filesBrowse files
MayaLekovaaddaleax
authored andcommitted
test: add test for async hooks parity for async/await
Add a basic test ensuring parity between before-after and init-promiseResolve hooks when using async/await. Add ability to initHooks and to checkInvocations utilities to transmit promiseResolve hook as well. See: #20516 PR-URL: #20626 Refs: #20516 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Benedikt Meurer <benedikt.meurer@gmail.com>
1 parent 7a98008 commit 0aab92f
Copy full SHA for 0aab92f

File tree

Expand file treeCollapse file tree

3 files changed

+106
-2
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+106
-2
lines changed
Open diff view settings
Collapse file

‎test/async-hooks/hook-checks.js‎

Copy file name to clipboardExpand all lines: test/async-hooks/hook-checks.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ exports.checkInvocations = function checkInvocations(activity, hooks, stage) {
2525
);
2626

2727
// Check that actual invocations for all hooks match the expected invocations
28-
[ 'init', 'before', 'after', 'destroy' ].forEach(checkHook);
28+
[ 'init', 'before', 'after', 'destroy', 'promiseResolve' ].forEach(checkHook);
2929

3030
function checkHook(k) {
3131
const val = hooks[k];
Collapse file

‎test/async-hooks/init-hooks.js‎

Copy file name to clipboardExpand all lines: test/async-hooks/init-hooks.js
+14-1Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class ActivityCollector {
2525
onbefore,
2626
onafter,
2727
ondestroy,
28+
onpromiseResolve,
2829
logid = null,
2930
logtype = null
3031
} = {}) {
@@ -39,13 +40,16 @@ class ActivityCollector {
3940
this.onbefore = typeof onbefore === 'function' ? onbefore : noop;
4041
this.onafter = typeof onafter === 'function' ? onafter : noop;
4142
this.ondestroy = typeof ondestroy === 'function' ? ondestroy : noop;
43+
this.onpromiseResolve = typeof onpromiseResolve === 'function' ?
44+
onpromiseResolve : noop;
4245

4346
// Create the hook with which we'll collect activity data
4447
this._asyncHook = async_hooks.createHook({
4548
init: this._init.bind(this),
4649
before: this._before.bind(this),
4750
after: this._after.bind(this),
48-
destroy: this._destroy.bind(this)
51+
destroy: this._destroy.bind(this),
52+
promiseResolve: this._promiseResolve.bind(this)
4953
});
5054
}
5155

@@ -206,6 +210,13 @@ class ActivityCollector {
206210
this.ondestroy(uid);
207211
}
208212

213+
_promiseResolve(uid) {
214+
const h = this._getActivity(uid, 'promiseResolve');
215+
this._stamp(h, 'promiseResolve');
216+
this._maybeLog(uid, h && h.type, 'promiseResolve');
217+
this.onpromiseResolve(uid);
218+
}
219+
209220
_maybeLog(uid, type, name) {
210221
if (this._logid &&
211222
(type == null || this._logtype == null || this._logtype === type)) {
@@ -219,6 +230,7 @@ exports = module.exports = function initHooks({
219230
onbefore,
220231
onafter,
221232
ondestroy,
233+
onpromiseResolve,
222234
allowNoInit,
223235
logid,
224236
logtype
@@ -228,6 +240,7 @@ exports = module.exports = function initHooks({
228240
onbefore,
229241
onafter,
230242
ondestroy,
243+
onpromiseResolve,
231244
allowNoInit,
232245
logid,
233246
logtype
Collapse file
+91Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
'use strict';
2+
const common = require('../common');
3+
4+
// This test ensures async hooks are being properly called
5+
// when using async-await mechanics. This involves:
6+
// 1. Checking that all initialized promises are being resolved
7+
// 2. Checking that for each 'before' corresponding hook 'after' hook is called
8+
9+
const assert = require('assert');
10+
const initHooks = require('./init-hooks');
11+
12+
const util = require('util');
13+
14+
const sleep = util.promisify(setTimeout);
15+
// either 'inited' or 'resolved'
16+
const promisesInitState = new Map();
17+
// either 'before' or 'after' AND asyncId must be present in the other map
18+
const promisesExecutionState = new Map();
19+
20+
const hooks = initHooks({
21+
oninit,
22+
onbefore,
23+
onafter,
24+
ondestroy: null, // Intentionally not tested, since it will be removed soon
25+
onpromiseResolve
26+
});
27+
hooks.enable();
28+
29+
function oninit(asyncId, type, triggerAsyncId, resource) {
30+
if (type === 'PROMISE') {
31+
promisesInitState.set(asyncId, 'inited');
32+
}
33+
}
34+
35+
function onbefore(asyncId) {
36+
if (!promisesInitState.has(asyncId)) {
37+
return;
38+
}
39+
promisesExecutionState.set(asyncId, 'before');
40+
}
41+
42+
function onafter(asyncId) {
43+
if (!promisesInitState.has(asyncId)) {
44+
return;
45+
}
46+
47+
assert.strictEqual(promisesExecutionState.get(asyncId), 'before',
48+
'after hook called for promise without prior call' +
49+
'to before hook');
50+
assert.strictEqual(promisesInitState.get(asyncId), 'resolved',
51+
'after hook called for promise without prior call' +
52+
'to resolve hook');
53+
promisesExecutionState.set(asyncId, 'after');
54+
}
55+
56+
function onpromiseResolve(asyncId) {
57+
assert(promisesInitState.has(asyncId),
58+
'resolve hook called for promise without prior call to init hook');
59+
60+
promisesInitState.set(asyncId, 'resolved');
61+
}
62+
63+
const timeout = common.platformTimeout(10);
64+
65+
function checkPromisesInitState() {
66+
for (const initState of promisesInitState.values()) {
67+
assert.strictEqual(initState, 'resolved',
68+
'promise initialized without being resolved');
69+
}
70+
}
71+
72+
function checkPromisesExecutionState() {
73+
for (const executionState of promisesExecutionState.values()) {
74+
assert.strictEqual(executionState, 'after',
75+
'mismatch between before and after hook calls');
76+
}
77+
}
78+
79+
process.on('beforeExit', common.mustCall(() => {
80+
hooks.disable();
81+
hooks.sanityCheck('PROMISE');
82+
83+
checkPromisesInitState();
84+
checkPromisesExecutionState();
85+
}));
86+
87+
async function asyncFunc() {
88+
await sleep(timeout);
89+
}
90+
91+
asyncFunc();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.