node/test/async-hooks/test-enable-disable.js

268 lines
8.4 KiB
JavaScript
Raw Normal View History

// Test Steps Explained
// ====================
//
// Initializing hooks:
//
// We initialize 3 hooks. For hook2 and hook3 we register a callback for the
// "before" and in case of hook3 also for the "after" invocations.
//
// Enabling hooks initially:
//
// We only enable hook1 and hook3 initially.
//
// Enabling hook2:
//
// When hook3's "before" invocation occurs we enable hook2. Since this
// happens right before calling `onfirstImmediate` hook2 will miss all hook
// invocations until then, including the "init" and "before" of the first
// Immediate.
// However afterwards it collects all invocations that follow on the first
// Immediate as well as all invocations on the second Immediate.
//
// This shows that a hook can enable another hook inside a life time event
// callback.
//
//
// Disabling hook1
//
// Since we registered the "before" callback for hook2 it will execute it
// right before `onsecondImmediate` is called.
// At that point we disable hook1 which is why it will miss all invocations
// afterwards and thus won't include the second "after" as well as the
// "destroy" invocations
//
// This shows that a hook can disable another hook inside a life time event
// callback.
//
// Disabling hook3
//
// When the second "after" invocation occurs (after onsecondImmediate), hook3
// disables itself.
// As a result it will not receive the "destroy" invocation.
//
// This shows that a hook can disable itself inside a life time event callback.
//
// Sample Test Log
// ===============
//
// - setting up first Immediate
// hook1.init.uid-5
// hook3.init.uid-5
// - finished setting first Immediate
//
// hook1.before.uid-5
// hook3.before.uid-5
// - enabled hook2
// - entering onfirstImmediate
//
// - setting up second Immediate
// hook1.init.uid-6
// hook3.init.uid-6
// hook2.init.uid-6
// - finished setting second Immediate
//
// - exiting onfirstImmediate
// hook1.after.uid-5
// hook3.after.uid-5
// hook2.after.uid-5
// hook1.destroy.uid-5
// hook3.destroy.uid-5
// hook2.destroy.uid-5
// hook1.before.uid-6
// hook3.before.uid-6
// hook2.before.uid-6
// - disabled hook1
// - entering onsecondImmediate
// - exiting onsecondImmediate
// hook3.after.uid-6
// - disabled hook3
// hook2.after.uid-6
// hook2.destroy.uid-6
test: adding tests for initHooks API Async wrap providers tested: - crypto.randomBytes - crypto.pbkdf2 - fs event wrap - fsreqwrap access - fsreqwrap readFile - getaddrinforeq wrap - getnameinforeq wrap - pipe connect wrap - query wrap - pipewrap - processwrap - shutdown wrap - tcpwrap - udpwrap - send wrap - detailed signal wrap - statwatcher - timerwrap via setTimeout - timerwrap via setInterval - for Immediate - http parser request - http parser response - connection via ssl server - tls wrap - write wrap - ttywrap via readstream - ttywrap via wriream - zctx via zlib binding deflate Embedder API: - async-event tests - one test looks at the happy paths - another ensures that in cases of events emitted in an order that doesn't make sense, the order is enforced by async hooks throwing a meaningful error - embedder enforcement tests are split up since async hook stack corruption now the process - therefore we launch a child and check for error output of the offending code Additional tests: - tests that show that we can enable/disable hooks inside their lifetime events - tests that verify the graph of resources triggering the creation of other resources Test Helpers: - init-hooks: - returns one collector instance - when created an async hook is created and the lifetime events are registered to call the appropriate collector functions - the collector also exposes `enable` and `disable` functions which call through to the async hook - hook checks: - checks invocations of life time hooks against the actual invocations that were collected - in some cases like `destroy` a min/max range of invocations can be supplied since in these cases the exact number is non-deterministic - verify graph: - verifies the triggerIds of specific async resources are as expected, i.e. the creation of resources was triggered by the resource we expect - includes a printGraph function to generate easily readable test input for verify graph - both functions prune TickObjects to create less brittle and easier to understand tests PR-URL: https://github.com/nodejs/node/pull/12892 Ref: https://github.com/nodejs/node/pull/11883 Ref: https://github.com/nodejs/node/pull/8531 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2016-11-22 16:13:44 +00:00
'use strict';
const common = require('../common');
const assert = require('assert');
const tick = require('../common/tick');
test: adding tests for initHooks API Async wrap providers tested: - crypto.randomBytes - crypto.pbkdf2 - fs event wrap - fsreqwrap access - fsreqwrap readFile - getaddrinforeq wrap - getnameinforeq wrap - pipe connect wrap - query wrap - pipewrap - processwrap - shutdown wrap - tcpwrap - udpwrap - send wrap - detailed signal wrap - statwatcher - timerwrap via setTimeout - timerwrap via setInterval - for Immediate - http parser request - http parser response - connection via ssl server - tls wrap - write wrap - ttywrap via readstream - ttywrap via wriream - zctx via zlib binding deflate Embedder API: - async-event tests - one test looks at the happy paths - another ensures that in cases of events emitted in an order that doesn't make sense, the order is enforced by async hooks throwing a meaningful error - embedder enforcement tests are split up since async hook stack corruption now the process - therefore we launch a child and check for error output of the offending code Additional tests: - tests that show that we can enable/disable hooks inside their lifetime events - tests that verify the graph of resources triggering the creation of other resources Test Helpers: - init-hooks: - returns one collector instance - when created an async hook is created and the lifetime events are registered to call the appropriate collector functions - the collector also exposes `enable` and `disable` functions which call through to the async hook - hook checks: - checks invocations of life time hooks against the actual invocations that were collected - in some cases like `destroy` a min/max range of invocations can be supplied since in these cases the exact number is non-deterministic - verify graph: - verifies the triggerIds of specific async resources are as expected, i.e. the creation of resources was triggered by the resource we expect - includes a printGraph function to generate easily readable test input for verify graph - both functions prune TickObjects to create less brittle and easier to understand tests PR-URL: https://github.com/nodejs/node/pull/12892 Ref: https://github.com/nodejs/node/pull/11883 Ref: https://github.com/nodejs/node/pull/8531 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2016-11-22 16:13:44 +00:00
const initHooks = require('./init-hooks');
const { checkInvocations } = require('./hook-checks');
if (!common.isMainThread)
common.skip('Worker bootstrapping works differently -> different timing');
test: adding tests for initHooks API Async wrap providers tested: - crypto.randomBytes - crypto.pbkdf2 - fs event wrap - fsreqwrap access - fsreqwrap readFile - getaddrinforeq wrap - getnameinforeq wrap - pipe connect wrap - query wrap - pipewrap - processwrap - shutdown wrap - tcpwrap - udpwrap - send wrap - detailed signal wrap - statwatcher - timerwrap via setTimeout - timerwrap via setInterval - for Immediate - http parser request - http parser response - connection via ssl server - tls wrap - write wrap - ttywrap via readstream - ttywrap via wriream - zctx via zlib binding deflate Embedder API: - async-event tests - one test looks at the happy paths - another ensures that in cases of events emitted in an order that doesn't make sense, the order is enforced by async hooks throwing a meaningful error - embedder enforcement tests are split up since async hook stack corruption now the process - therefore we launch a child and check for error output of the offending code Additional tests: - tests that show that we can enable/disable hooks inside their lifetime events - tests that verify the graph of resources triggering the creation of other resources Test Helpers: - init-hooks: - returns one collector instance - when created an async hook is created and the lifetime events are registered to call the appropriate collector functions - the collector also exposes `enable` and `disable` functions which call through to the async hook - hook checks: - checks invocations of life time hooks against the actual invocations that were collected - in some cases like `destroy` a min/max range of invocations can be supplied since in these cases the exact number is non-deterministic - verify graph: - verifies the triggerIds of specific async resources are as expected, i.e. the creation of resources was triggered by the resource we expect - includes a printGraph function to generate easily readable test input for verify graph - both functions prune TickObjects to create less brittle and easier to understand tests PR-URL: https://github.com/nodejs/node/pull/12892 Ref: https://github.com/nodejs/node/pull/11883 Ref: https://github.com/nodejs/node/pull/8531 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2016-11-22 16:13:44 +00:00
// Include "Unknown"s because hook2 will not be able to identify
// the type of the first Immediate since it will miss its `init` invocation.
const types = [ 'Immediate', 'Unknown' ];
//
// Initializing hooks
//
const hook1 = initHooks();
const hook2 = initHooks({ onbefore: onhook2Before, allowNoInit: true });
const hook3 = initHooks({ onbefore: onhook3Before, onafter: onhook3After });
//
// Enabling hook1 and hook3 only, hook2 is still disabled
//
hook1.enable();
// Verify that the hook is enabled even if .enable() is called twice.
hook1.enable();
test: adding tests for initHooks API Async wrap providers tested: - crypto.randomBytes - crypto.pbkdf2 - fs event wrap - fsreqwrap access - fsreqwrap readFile - getaddrinforeq wrap - getnameinforeq wrap - pipe connect wrap - query wrap - pipewrap - processwrap - shutdown wrap - tcpwrap - udpwrap - send wrap - detailed signal wrap - statwatcher - timerwrap via setTimeout - timerwrap via setInterval - for Immediate - http parser request - http parser response - connection via ssl server - tls wrap - write wrap - ttywrap via readstream - ttywrap via wriream - zctx via zlib binding deflate Embedder API: - async-event tests - one test looks at the happy paths - another ensures that in cases of events emitted in an order that doesn't make sense, the order is enforced by async hooks throwing a meaningful error - embedder enforcement tests are split up since async hook stack corruption now the process - therefore we launch a child and check for error output of the offending code Additional tests: - tests that show that we can enable/disable hooks inside their lifetime events - tests that verify the graph of resources triggering the creation of other resources Test Helpers: - init-hooks: - returns one collector instance - when created an async hook is created and the lifetime events are registered to call the appropriate collector functions - the collector also exposes `enable` and `disable` functions which call through to the async hook - hook checks: - checks invocations of life time hooks against the actual invocations that were collected - in some cases like `destroy` a min/max range of invocations can be supplied since in these cases the exact number is non-deterministic - verify graph: - verifies the triggerIds of specific async resources are as expected, i.e. the creation of resources was triggered by the resource we expect - includes a printGraph function to generate easily readable test input for verify graph - both functions prune TickObjects to create less brittle and easier to understand tests PR-URL: https://github.com/nodejs/node/pull/12892 Ref: https://github.com/nodejs/node/pull/11883 Ref: https://github.com/nodejs/node/pull/8531 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2016-11-22 16:13:44 +00:00
hook3.enable();
//
// Enabling hook2
//
let enabledHook2 = false;
function onhook3Before() {
if (enabledHook2) return;
hook2.enable();
enabledHook2 = true;
}
//
// Disabling hook1
//
let disabledHook3 = false;
function onhook2Before() {
if (disabledHook3) return;
hook1.disable();
// Verify that the hook is disabled even if .disable() is called twice.
hook1.disable();
test: adding tests for initHooks API Async wrap providers tested: - crypto.randomBytes - crypto.pbkdf2 - fs event wrap - fsreqwrap access - fsreqwrap readFile - getaddrinforeq wrap - getnameinforeq wrap - pipe connect wrap - query wrap - pipewrap - processwrap - shutdown wrap - tcpwrap - udpwrap - send wrap - detailed signal wrap - statwatcher - timerwrap via setTimeout - timerwrap via setInterval - for Immediate - http parser request - http parser response - connection via ssl server - tls wrap - write wrap - ttywrap via readstream - ttywrap via wriream - zctx via zlib binding deflate Embedder API: - async-event tests - one test looks at the happy paths - another ensures that in cases of events emitted in an order that doesn't make sense, the order is enforced by async hooks throwing a meaningful error - embedder enforcement tests are split up since async hook stack corruption now the process - therefore we launch a child and check for error output of the offending code Additional tests: - tests that show that we can enable/disable hooks inside their lifetime events - tests that verify the graph of resources triggering the creation of other resources Test Helpers: - init-hooks: - returns one collector instance - when created an async hook is created and the lifetime events are registered to call the appropriate collector functions - the collector also exposes `enable` and `disable` functions which call through to the async hook - hook checks: - checks invocations of life time hooks against the actual invocations that were collected - in some cases like `destroy` a min/max range of invocations can be supplied since in these cases the exact number is non-deterministic - verify graph: - verifies the triggerIds of specific async resources are as expected, i.e. the creation of resources was triggered by the resource we expect - includes a printGraph function to generate easily readable test input for verify graph - both functions prune TickObjects to create less brittle and easier to understand tests PR-URL: https://github.com/nodejs/node/pull/12892 Ref: https://github.com/nodejs/node/pull/11883 Ref: https://github.com/nodejs/node/pull/8531 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2016-11-22 16:13:44 +00:00
disabledHook3 = true;
}
//
// Disabling hook3 during the second "after" invocations it sees
//
let count = 2;
function onhook3After() {
if (!--count) {
hook3.disable();
}
}
setImmediate(common.mustCall(onfirstImmediate));
//
// onfirstImmediate is called after all "init" and "before" callbacks of the
// active hooks were invoked
//
function onfirstImmediate() {
const as1 = hook1.activitiesOfTypes(types);
const as2 = hook2.activitiesOfTypes(types);
const as3 = hook3.activitiesOfTypes(types);
assert.strictEqual(as1.length, 1);
test: adding tests for initHooks API Async wrap providers tested: - crypto.randomBytes - crypto.pbkdf2 - fs event wrap - fsreqwrap access - fsreqwrap readFile - getaddrinforeq wrap - getnameinforeq wrap - pipe connect wrap - query wrap - pipewrap - processwrap - shutdown wrap - tcpwrap - udpwrap - send wrap - detailed signal wrap - statwatcher - timerwrap via setTimeout - timerwrap via setInterval - for Immediate - http parser request - http parser response - connection via ssl server - tls wrap - write wrap - ttywrap via readstream - ttywrap via wriream - zctx via zlib binding deflate Embedder API: - async-event tests - one test looks at the happy paths - another ensures that in cases of events emitted in an order that doesn't make sense, the order is enforced by async hooks throwing a meaningful error - embedder enforcement tests are split up since async hook stack corruption now the process - therefore we launch a child and check for error output of the offending code Additional tests: - tests that show that we can enable/disable hooks inside their lifetime events - tests that verify the graph of resources triggering the creation of other resources Test Helpers: - init-hooks: - returns one collector instance - when created an async hook is created and the lifetime events are registered to call the appropriate collector functions - the collector also exposes `enable` and `disable` functions which call through to the async hook - hook checks: - checks invocations of life time hooks against the actual invocations that were collected - in some cases like `destroy` a min/max range of invocations can be supplied since in these cases the exact number is non-deterministic - verify graph: - verifies the triggerIds of specific async resources are as expected, i.e. the creation of resources was triggered by the resource we expect - includes a printGraph function to generate easily readable test input for verify graph - both functions prune TickObjects to create less brittle and easier to understand tests PR-URL: https://github.com/nodejs/node/pull/12892 Ref: https://github.com/nodejs/node/pull/11883 Ref: https://github.com/nodejs/node/pull/8531 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2016-11-22 16:13:44 +00:00
// hook2 was not enabled yet .. it is enabled after hook3's "before" completed
assert.strictEqual(as2.length, 0);
assert.strictEqual(as3.length, 1);
test: adding tests for initHooks API Async wrap providers tested: - crypto.randomBytes - crypto.pbkdf2 - fs event wrap - fsreqwrap access - fsreqwrap readFile - getaddrinforeq wrap - getnameinforeq wrap - pipe connect wrap - query wrap - pipewrap - processwrap - shutdown wrap - tcpwrap - udpwrap - send wrap - detailed signal wrap - statwatcher - timerwrap via setTimeout - timerwrap via setInterval - for Immediate - http parser request - http parser response - connection via ssl server - tls wrap - write wrap - ttywrap via readstream - ttywrap via wriream - zctx via zlib binding deflate Embedder API: - async-event tests - one test looks at the happy paths - another ensures that in cases of events emitted in an order that doesn't make sense, the order is enforced by async hooks throwing a meaningful error - embedder enforcement tests are split up since async hook stack corruption now the process - therefore we launch a child and check for error output of the offending code Additional tests: - tests that show that we can enable/disable hooks inside their lifetime events - tests that verify the graph of resources triggering the creation of other resources Test Helpers: - init-hooks: - returns one collector instance - when created an async hook is created and the lifetime events are registered to call the appropriate collector functions - the collector also exposes `enable` and `disable` functions which call through to the async hook - hook checks: - checks invocations of life time hooks against the actual invocations that were collected - in some cases like `destroy` a min/max range of invocations can be supplied since in these cases the exact number is non-deterministic - verify graph: - verifies the triggerIds of specific async resources are as expected, i.e. the creation of resources was triggered by the resource we expect - includes a printGraph function to generate easily readable test input for verify graph - both functions prune TickObjects to create less brittle and easier to understand tests PR-URL: https://github.com/nodejs/node/pull/12892 Ref: https://github.com/nodejs/node/pull/11883 Ref: https://github.com/nodejs/node/pull/8531 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2016-11-22 16:13:44 +00:00
// Check that hook1 and hook3 captured the same Immediate and that it is valid
const firstImmediate = as1[0];
assert.strictEqual(as3[0].uid, as1[0].uid);
assert.strictEqual(firstImmediate.type, 'Immediate');
assert.strictEqual(typeof firstImmediate.uid, 'number');
assert.strictEqual(typeof firstImmediate.triggerAsyncId, 'number');
test: adding tests for initHooks API Async wrap providers tested: - crypto.randomBytes - crypto.pbkdf2 - fs event wrap - fsreqwrap access - fsreqwrap readFile - getaddrinforeq wrap - getnameinforeq wrap - pipe connect wrap - query wrap - pipewrap - processwrap - shutdown wrap - tcpwrap - udpwrap - send wrap - detailed signal wrap - statwatcher - timerwrap via setTimeout - timerwrap via setInterval - for Immediate - http parser request - http parser response - connection via ssl server - tls wrap - write wrap - ttywrap via readstream - ttywrap via wriream - zctx via zlib binding deflate Embedder API: - async-event tests - one test looks at the happy paths - another ensures that in cases of events emitted in an order that doesn't make sense, the order is enforced by async hooks throwing a meaningful error - embedder enforcement tests are split up since async hook stack corruption now the process - therefore we launch a child and check for error output of the offending code Additional tests: - tests that show that we can enable/disable hooks inside their lifetime events - tests that verify the graph of resources triggering the creation of other resources Test Helpers: - init-hooks: - returns one collector instance - when created an async hook is created and the lifetime events are registered to call the appropriate collector functions - the collector also exposes `enable` and `disable` functions which call through to the async hook - hook checks: - checks invocations of life time hooks against the actual invocations that were collected - in some cases like `destroy` a min/max range of invocations can be supplied since in these cases the exact number is non-deterministic - verify graph: - verifies the triggerIds of specific async resources are as expected, i.e. the creation of resources was triggered by the resource we expect - includes a printGraph function to generate easily readable test input for verify graph - both functions prune TickObjects to create less brittle and easier to understand tests PR-URL: https://github.com/nodejs/node/pull/12892 Ref: https://github.com/nodejs/node/pull/11883 Ref: https://github.com/nodejs/node/pull/8531 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2016-11-22 16:13:44 +00:00
checkInvocations(as1[0], { init: 1, before: 1 },
'hook1[0]: on first immediate');
checkInvocations(as3[0], { init: 1, before: 1 },
'hook3[0]: on first immediate');
// Setup the second Immediate, note that now hook2 is enabled and thus
// will capture all lifetime events of this Immediate
setImmediate(common.mustCall(onsecondImmediate));
}
//
// Once we exit onfirstImmediate the "after" callbacks of the active hooks are
// invoked
//
let hook1First, hook2First, hook3First;
let hook1Second, hook2Second, hook3Second;
//
// onsecondImmediate is called after all "before" callbacks of the active hooks
// are invoked again
//
function onsecondImmediate() {
const as1 = hook1.activitiesOfTypes(types);
const as2 = hook2.activitiesOfTypes(types);
const as3 = hook3.activitiesOfTypes(types);
assert.strictEqual(as1.length, 2);
assert.strictEqual(as2.length, 2);
assert.strictEqual(as3.length, 2);
test: adding tests for initHooks API Async wrap providers tested: - crypto.randomBytes - crypto.pbkdf2 - fs event wrap - fsreqwrap access - fsreqwrap readFile - getaddrinforeq wrap - getnameinforeq wrap - pipe connect wrap - query wrap - pipewrap - processwrap - shutdown wrap - tcpwrap - udpwrap - send wrap - detailed signal wrap - statwatcher - timerwrap via setTimeout - timerwrap via setInterval - for Immediate - http parser request - http parser response - connection via ssl server - tls wrap - write wrap - ttywrap via readstream - ttywrap via wriream - zctx via zlib binding deflate Embedder API: - async-event tests - one test looks at the happy paths - another ensures that in cases of events emitted in an order that doesn't make sense, the order is enforced by async hooks throwing a meaningful error - embedder enforcement tests are split up since async hook stack corruption now the process - therefore we launch a child and check for error output of the offending code Additional tests: - tests that show that we can enable/disable hooks inside their lifetime events - tests that verify the graph of resources triggering the creation of other resources Test Helpers: - init-hooks: - returns one collector instance - when created an async hook is created and the lifetime events are registered to call the appropriate collector functions - the collector also exposes `enable` and `disable` functions which call through to the async hook - hook checks: - checks invocations of life time hooks against the actual invocations that were collected - in some cases like `destroy` a min/max range of invocations can be supplied since in these cases the exact number is non-deterministic - verify graph: - verifies the triggerIds of specific async resources are as expected, i.e. the creation of resources was triggered by the resource we expect - includes a printGraph function to generate easily readable test input for verify graph - both functions prune TickObjects to create less brittle and easier to understand tests PR-URL: https://github.com/nodejs/node/pull/12892 Ref: https://github.com/nodejs/node/pull/11883 Ref: https://github.com/nodejs/node/pull/8531 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2016-11-22 16:13:44 +00:00
// Assign the info collected by each hook for each immediate for easier
// reference.
// hook2 saw the "init" of the second immediate before the
// "after" of the first which is why they are ordered the opposite way
hook1First = as1[0];
hook1Second = as1[1];
hook2First = as2[1];
hook2Second = as2[0];
hook3First = as3[0];
hook3Second = as3[1];
// Check that all hooks captured the same Immediate and that it is valid
const secondImmediate = hook1Second;
assert.strictEqual(hook2Second.uid, hook3Second.uid);
assert.strictEqual(hook1Second.uid, hook3Second.uid);
assert.strictEqual(secondImmediate.type, 'Immediate');
assert.strictEqual(typeof secondImmediate.uid, 'number');
assert.strictEqual(typeof secondImmediate.triggerAsyncId, 'number');
test: adding tests for initHooks API Async wrap providers tested: - crypto.randomBytes - crypto.pbkdf2 - fs event wrap - fsreqwrap access - fsreqwrap readFile - getaddrinforeq wrap - getnameinforeq wrap - pipe connect wrap - query wrap - pipewrap - processwrap - shutdown wrap - tcpwrap - udpwrap - send wrap - detailed signal wrap - statwatcher - timerwrap via setTimeout - timerwrap via setInterval - for Immediate - http parser request - http parser response - connection via ssl server - tls wrap - write wrap - ttywrap via readstream - ttywrap via wriream - zctx via zlib binding deflate Embedder API: - async-event tests - one test looks at the happy paths - another ensures that in cases of events emitted in an order that doesn't make sense, the order is enforced by async hooks throwing a meaningful error - embedder enforcement tests are split up since async hook stack corruption now the process - therefore we launch a child and check for error output of the offending code Additional tests: - tests that show that we can enable/disable hooks inside their lifetime events - tests that verify the graph of resources triggering the creation of other resources Test Helpers: - init-hooks: - returns one collector instance - when created an async hook is created and the lifetime events are registered to call the appropriate collector functions - the collector also exposes `enable` and `disable` functions which call through to the async hook - hook checks: - checks invocations of life time hooks against the actual invocations that were collected - in some cases like `destroy` a min/max range of invocations can be supplied since in these cases the exact number is non-deterministic - verify graph: - verifies the triggerIds of specific async resources are as expected, i.e. the creation of resources was triggered by the resource we expect - includes a printGraph function to generate easily readable test input for verify graph - both functions prune TickObjects to create less brittle and easier to understand tests PR-URL: https://github.com/nodejs/node/pull/12892 Ref: https://github.com/nodejs/node/pull/11883 Ref: https://github.com/nodejs/node/pull/8531 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2016-11-22 16:13:44 +00:00
checkInvocations(hook1First, { init: 1, before: 1, after: 1, destroy: 1 },
'hook1First: on second immediate');
checkInvocations(hook1Second, { init: 1, before: 1 },
'hook1Second: on second immediate');
// hook2 missed the "init" and "before" since it was enabled after they
// occurred
checkInvocations(hook2First, { after: 1, destroy: 1 },
'hook2First: on second immediate');
checkInvocations(hook2Second, { init: 1, before: 1 },
'hook2Second: on second immediate');
checkInvocations(hook3First, { init: 1, before: 1, after: 1, destroy: 1 },
'hook3First: on second immediate');
checkInvocations(hook3Second, { init: 1, before: 1 },
'hook3Second: on second immediate');
tick(1);
}
//
// Once we exit onsecondImmediate the "after" callbacks of the active hooks are
// invoked again.
// During this second "after" invocation hook3 disables itself
// (see onhook3After).
//
process.on('exit', onexit);
function onexit() {
hook1.disable();
hook2.disable();
hook3.disable();
hook1.sanityCheck();
hook2.sanityCheck();
hook3.sanityCheck();
checkInvocations(hook1First, { init: 1, before: 1, after: 1, destroy: 1 },
'hook1First: when process exits');
// hook1 was disabled during hook2's "before" of the second immediate
// and thus did not see "after" and "destroy"
checkInvocations(hook1Second, { init: 1, before: 1 },
'hook1Second: when process exits');
// hook2 missed the "init" and "before" since it was enabled after they
// occurred
checkInvocations(hook2First, { after: 1, destroy: 1 },
'hook2First: when process exits');
checkInvocations(hook2Second, { init: 1, before: 1, after: 1, destroy: 1 },
'hook2Second: when process exits');
checkInvocations(hook3First, { init: 1, before: 1, after: 1, destroy: 1 },
'hook3First: when process exits');
// We don't see a "destroy" invocation here since hook3 disabled itself
test: adding tests for initHooks API Async wrap providers tested: - crypto.randomBytes - crypto.pbkdf2 - fs event wrap - fsreqwrap access - fsreqwrap readFile - getaddrinforeq wrap - getnameinforeq wrap - pipe connect wrap - query wrap - pipewrap - processwrap - shutdown wrap - tcpwrap - udpwrap - send wrap - detailed signal wrap - statwatcher - timerwrap via setTimeout - timerwrap via setInterval - for Immediate - http parser request - http parser response - connection via ssl server - tls wrap - write wrap - ttywrap via readstream - ttywrap via wriream - zctx via zlib binding deflate Embedder API: - async-event tests - one test looks at the happy paths - another ensures that in cases of events emitted in an order that doesn't make sense, the order is enforced by async hooks throwing a meaningful error - embedder enforcement tests are split up since async hook stack corruption now the process - therefore we launch a child and check for error output of the offending code Additional tests: - tests that show that we can enable/disable hooks inside their lifetime events - tests that verify the graph of resources triggering the creation of other resources Test Helpers: - init-hooks: - returns one collector instance - when created an async hook is created and the lifetime events are registered to call the appropriate collector functions - the collector also exposes `enable` and `disable` functions which call through to the async hook - hook checks: - checks invocations of life time hooks against the actual invocations that were collected - in some cases like `destroy` a min/max range of invocations can be supplied since in these cases the exact number is non-deterministic - verify graph: - verifies the triggerIds of specific async resources are as expected, i.e. the creation of resources was triggered by the resource we expect - includes a printGraph function to generate easily readable test input for verify graph - both functions prune TickObjects to create less brittle and easier to understand tests PR-URL: https://github.com/nodejs/node/pull/12892 Ref: https://github.com/nodejs/node/pull/11883 Ref: https://github.com/nodejs/node/pull/8531 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
2016-11-22 16:13:44 +00:00
// during its "after" invocation
checkInvocations(hook3Second, { init: 1, before: 1, after: 1 },
'hook3Second: when process exits');
}