-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: increase coverage of async_hooks #13336
Conversation
Unrelated to this PR, but I noticed that we |
|
||
async_hooks.runInAsyncIdScope(asyncId, common.mustCall(() => { | ||
assert.strictEqual(async_hooks.currentId(), asyncId); | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this test can go into parallel
(it doesn’t use any of the async hook test helpers here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@addaleax Done, PTAL :=)
385a979
to
629f23b
Compare
Sigh, I guess it is because it doesn't appear in https://github.com/nodejs/node/blob/master/vcbuild.bat#L68L82 |
test/async-hooks/test-emit-init.js
Outdated
const expectedId = async_hooks.newUid(); | ||
const expectedTriggerId = async_hooks.newUid(); | ||
const expectedType = 'test_emit_init_type'; | ||
const expectedResource = Symbol('test_emit_init_resource'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A resource must be an object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AndreasMadsen Updated, PTAL :=)
629f23b
to
d44fb25
Compare
Yep, that was my question 😄 . Why is it not present in |
/cc @refack regarding |
AFAIK there's no reason except nobody bothered to add it. |
Cross-ref: #13378 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I don't think we need to wait for the windows PR to be merged. These are mostly pure JS logic related tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing all this. Test coverage for async_hooks is important and happy to see more of it coming in. I have two suggestions and one of your test additions made me aware of a flaw in the AsyncResource()
constructor logic that needs to be fixed.
switch (process.argv[2]) { | ||
case 'test_init_callback': | ||
initHooks({ | ||
oninit: common.mustCall(() => { throw new Error('test_init_callback'); }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's the problem where if test_init_callback
is never hit then the common.mustCall()
will never run. Instead you'll need to do it like this:
const oninitMustCall = common.mustCall(() => { throw new Error('test_init_callback'); });
switch (process.argv[2]) {
case 'test_init_callback':
initHooks({ oninit: oninitMustCall }).enable();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😕 But IMO the actual intention here is just to ensure that the common.mustCall()
will run only when the test_init_callback
case is hit? Every switch case will be hit in different process because of spawnSync()
s below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But IMO the actual intention here is just to ensure that the
common.mustCall()
will run only when the test_init_callback case is hit?
Whoops. Missed that. You're correct.
@@ -9,9 +9,21 @@ const { AsyncResource } = async_hooks; | |||
const initHooks = require('./init-hooks'); | |||
const { checkInvocations } = require('./hook-checks'); | |||
|
|||
// Verify that if there is no registered hook, then those invalid parameters | |||
// won't be checked. | |||
assert.doesNotThrow(() => new AsyncResource()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I screwed up the logic here. It shouldn't return early before the arguments are checked. Otherwise it'll cause an async hook stack corruption. Here's the minimal test case:
new (require('async_hooks').AsyncResource)().emitBefore();
Here's the diff for the fix. Feel free to add it to this PR along with the above test case:
diff --git a/lib/async_hooks.js b/lib/async_hooks.js
index d5d5407..aec73ed 100644
--- a/lib/async_hooks.js
+++ b/lib/async_hooks.js
@@ -205,15 +205,15 @@ class AsyncResource {
}
this[trigger_id_symbol] = triggerId;
- // Return immediately if there's nothing to do.
- if (async_hook_fields[kInit] === 0)
- return;
-
if (typeof type !== 'string' || type.length <= 0)
throw new TypeError('type must be a string with length > 0');
if (!Number.isSafeInteger(triggerId) || triggerId < 0)
throw new RangeError('triggerId must be an unsigned integer');
+ // Return immediately if there's nothing to do.
+ if (async_hook_fields[kInit] === 0)
+ return;
+
processing_hook = true;
for (var i = 0; i < active_hooks_array.length; i++) {
if (typeof active_hooks_array[i][init_symbol] === 'function') {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, i'll do it in this PR :=)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@trevnorris Done, added the diff to this PR, PTAL :=)
|
||
switch (process.argv[2]) { | ||
case 'test_invalid_async_id': | ||
async_hooks.emitBefore(-1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make sure these run I' possibly do this:
const emitBeforeMustCall = common.mustCall(() => async_hooks.emitBefore(-1));
switch (process.argv[2]) {
case 'test_invalid_async_id':
emitBeforeMustCall();
Needs a rebase (just tried locally it goes smooth) |
d44fb25
to
69098bb
Compare
@refack I rebased it locally and the result shows that it goes very smooth 😃 |
Apparently GitHub is a whiny little ... |
@refack Now no conflicts checking and CI both seems good ... |
@trevnorris PTAL |
@DavidCai1993 Much thanks for the fix. |
Landed in 35353a4 |
PR-URL: #13336 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com>
PR-URL: #13336 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com>
PR-URL: nodejs#13378 Refs: nodejs#13340 Refs: nodejs#13336 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: João Reis <reis@janeasystems.com>
lib/async_hooks.js
test/async_hooks/test-embedder.api.async-event.*.js
totest/async_hooks/test-embedder.api.async-resource.*.js
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
async_hooks