Skip to content

Commit e3e56f1

Browse files
thlorenzaddaleax
authored andcommittedMay 10, 2017
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: nodejs#12892 Ref: nodejs#11883 Ref: nodejs#8531 Reviewed-By: Andreas Madsen <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Sam Roberts <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
1 parent 4a7233c commit e3e56f1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+3322
-0
lines changed
 

Diff for: ‎test/async-hooks/coverage.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## AsyncHooks Coverage Overview
2+
3+
Showing which kind of async resource is covered by which test:
4+
5+
| Resource Type | Test |
6+
|----------------------|----------------------------------------|
7+
| CONNECTION | test-connection.ssl.js |
8+
| FSEVENTWRAP | test-fseventwrap.js |
9+
| FSREQWRAP | test-fsreqwrap-{access,readFile}.js |
10+
| GETADDRINFOREQWRAP | test-getaddrinforeqwrap.js |
11+
| GETNAMEINFOREQWRAP | test-getnameinforeqwrap.js |
12+
| HTTPPARSER | test-httpparser.{request,response}.js |
13+
| Immediate | test-immediate.js |
14+
| JSSTREAM | TODO (crashes when accessing directly) |
15+
| PBKDF2REQUEST | test-crypto-pbkdf2.js |
16+
| PIPECONNECTWRAP | test-pipeconnectwrap.js |
17+
| PIPEWRAP | test-pipewrap.js |
18+
| PROCESSWRAP | test-pipewrap.js |
19+
| QUERYWRAP | test-querywrap.js |
20+
| RANDOMBYTESREQUEST | test-crypto-randomBytes.js |
21+
| SHUTDOWNWRAP | test-shutdownwrap.js |
22+
| SIGNALWRAP | test-signalwrap.js |
23+
| STATWATCHER | test-statwatcher.js |
24+
| TCPCONNECTWRAP | test-tcpwrap.js |
25+
| TCPWRAP | test-tcpwrap.js |
26+
| TIMERWRAP | test-timerwrap.set{Timeout,Interval}.js|
27+
| TLSWRAP | test-tlswrap.js |
28+
| TTYWRAP | test-ttywrap.{read,write}stream.js |
29+
| UDPSENDWRAP | test-udpsendwrap.js |
30+
| UDPWRAP | test-udpwrap.js |
31+
| WRITEWRAP | test-writewrap.js |
32+
| ZLIB | test-zlib.zlib-binding.deflate.js |

Diff for: ‎test/async-hooks/hook-checks.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
'use strict';
2+
const assert = require('assert');
3+
require('../common');
4+
5+
/**
6+
* Checks the expected invocations against the invocations that actually
7+
* occurred.
8+
*
9+
* @name checkInvocations
10+
* @function
11+
* @param {Object} activity including timestamps for each life time event,
12+
* i.e. init, before ...
13+
* @param {Object} hooks the expected life time event invocations with a count
14+
* indicating how oftn they should have been invoked,
15+
* i.e. `{ init: 1, before: 2, after: 2 }`
16+
* @param {String} stage the name of the stage in the test at which we are
17+
* checking the invocations
18+
*/
19+
exports.checkInvocations = function checkInvocations(activity, hooks, stage) {
20+
const stageInfo = `Checking invocations at stage "${stage}":\n `;
21+
22+
assert.ok(activity != null,
23+
`${stageInfo} Trying to check invocation for an activity, ` +
24+
'but it was empty/undefined.'
25+
);
26+
27+
// Check that actual invocations for all hooks match the expected invocations
28+
[ 'init', 'before', 'after', 'destroy' ].forEach(checkHook);
29+
30+
function checkHook(k) {
31+
const val = hooks[k];
32+
// Not expected ... all good
33+
if (val == null) return;
34+
35+
if (val === 0) {
36+
// Didn't expect any invocations, but it was actually invoked
37+
const invocations = activity[k].length;
38+
const msg = `${stageInfo} Called "${k}" ${invocations} time(s), ` +
39+
'but expected no invocations.';
40+
assert(activity[k] === null && activity[k] === undefined, msg);
41+
} else {
42+
// Expected some invocations, make sure that it was invoked at all
43+
const msg1 = `${stageInfo} Never called "${k}", ` +
44+
`but expected ${val} invocation(s).`;
45+
assert(activity[k] !== null && activity[k] !== undefined, msg1);
46+
47+
// Now make sure that the expected count and
48+
// the actual invocation count match
49+
const msg2 = `${stageInfo} Called "${k}" ${activity[k].length} ` +
50+
`time(s), but expected ${val} invocation(s).`;
51+
assert.strictEqual(activity[k].length, val, msg2);
52+
}
53+
}
54+
};

0 commit comments

Comments
 (0)