diff options
author | Trevor Norris <trev.norris@gmail.com> | 2017-03-09 16:13:34 -0700 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2017-05-10 22:22:26 +0200 |
commit | 7e3a3c962f09233c53cee7ebe381341d7c8b7162 (patch) | |
tree | 02963f7724ed9099a3566f13b16619fddffe0793 /test | |
parent | c0bde73f1bbfedd4e77ddf87cf0bcec7bac9a61e (diff) | |
download | android-node-v8-7e3a3c962f09233c53cee7ebe381341d7c8b7162.tar.gz android-node-v8-7e3a3c962f09233c53cee7ebe381341d7c8b7162.tar.bz2 android-node-v8-7e3a3c962f09233c53cee7ebe381341d7c8b7162.zip |
async_hooks: initial async_hooks implementation
Fill this commit messsage with more details about the change once all
changes are rebased.
* Add lib/async_hooks.js
* Add JS methods to AsyncWrap for handling the async id stack
* Introduce AsyncReset() so that JS functions can reset the id and again
trigger the init hooks, allow AsyncWrap::Reset() to be called from JS
via asyncReset().
* Add env variable to test additional things in test/common.js
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>
Diffstat (limited to 'test')
-rw-r--r-- | test/common/index.js | 59 | ||||
-rw-r--r-- | test/parallel/test-async-wrap-destroyid.js | 37 | ||||
-rw-r--r-- | test/parallel/test-async-wrap-getasyncid.js | 21 |
3 files changed, 114 insertions, 3 deletions
diff --git a/test/common/index.js b/test/common/index.js index a10adc4d0d..482680bd2f 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -64,6 +64,50 @@ exports.enoughTestCpu = Array.isArray(cpus) && exports.rootDir = exports.isWindows ? 'c:\\' : '/'; exports.buildType = process.config.target_defaults.default_configuration; +// If env var is set then enable async_hook hooks for all tests. +if (process.env.NODE_TEST_WITH_ASYNC_HOOKS) { + const destroydIdsList = {}; + const destroyListList = {}; + const initHandles = {}; + const async_wrap = process.binding('async_wrap'); + + process.on('exit', () => { + // itterate through handles to make sure nothing crashes + for (const k in initHandles) + util.inspect(initHandles[k]); + }); + + const _addIdToDestroyList = async_wrap.addIdToDestroyList; + async_wrap.addIdToDestroyList = function addIdToDestroyList(id) { + if (destroyListList[id] !== undefined) { + process._rawDebug(destroyListList[id]); + process._rawDebug(); + throw new Error(`same id added twice (${id})`); + } + destroyListList[id] = new Error().stack; + _addIdToDestroyList(id); + }; + + require('async_hooks').createHook({ + init(id, ty, tr, h) { + if (initHandles[id]) { + throw new Error(`init called twice for same id (${id})`); + } + initHandles[id] = h; + }, + before() { }, + after() { }, + destroy(id) { + if (destroydIdsList[id] !== undefined) { + process._rawDebug(destroydIdsList[id]); + process._rawDebug(); + throw new Error(`destroy called for same id (${id})`); + } + destroydIdsList[id] = new Error().stack; + }, + }).enable(); +} + function rimrafSync(p) { let st; try { @@ -684,3 +728,18 @@ exports.crashOnUnhandledRejection = function() { process.on('unhandledRejection', (err) => process.nextTick(() => { throw err; })); }; + +exports.getTTYfd = function getTTYfd() { + const tty = require('tty'); + let tty_fd = 0; + if (!tty.isatty(tty_fd)) tty_fd++; + else if (!tty.isatty(tty_fd)) tty_fd++; + else if (!tty.isatty(tty_fd)) tty_fd++; + else try { + tty_fd = require('fs').openSync('/dev/tty'); + } catch (e) { + // There aren't any tty fd's available to use. + return -1; + } + return tty_fd; +}; diff --git a/test/parallel/test-async-wrap-destroyid.js b/test/parallel/test-async-wrap-destroyid.js new file mode 100644 index 0000000000..75f8ed9e66 --- /dev/null +++ b/test/parallel/test-async-wrap-destroyid.js @@ -0,0 +1,37 @@ +'use strict'; + +const common = require('../common'); +const async_wrap = process.binding('async_wrap'); +const assert = require('assert'); +const async_hooks = require('async_hooks'); +const RUNS = 5; +let test_id = null; +let run_cntr = 0; +let hooks = null; + +process.on('beforeExit', common.mustCall(() => { + process.removeAllListeners('uncaughtException'); + hooks.disable(); + assert.strictEqual(test_id, null); + assert.strictEqual(run_cntr, RUNS); +})); + + +hooks = async_hooks.createHook({ + destroy(id) { + if (id === test_id) { + run_cntr++; + test_id = null; + } + }, +}).enable(); + + +(function runner(n) { + assert.strictEqual(test_id, null); + if (n <= 0) return; + + test_id = (Math.random() * 1e9) >>> 0; + async_wrap.addIdToDestroyList(test_id); + setImmediate(common.mustCall(runner), n - 1); +})(RUNS); diff --git a/test/parallel/test-async-wrap-getasyncid.js b/test/parallel/test-async-wrap-getasyncid.js index 5e2ce3a820..98aa3c857a 100644 --- a/test/parallel/test-async-wrap-getasyncid.js +++ b/test/parallel/test-async-wrap-getasyncid.js @@ -218,9 +218,24 @@ if (common.hasCrypto) { { - const tty_wrap = process.binding('tty_wrap'); - if (tty_wrap.isTTY(0)) { - testInitialized(new tty_wrap.TTY(0, false), 'TTY'); + // Do our best to grab a tty fd. + const tty_fd = common.getTTYfd(); + if (tty_fd >= 0) { + const tty_wrap = process.binding('tty_wrap'); + // fd may still be invalid, so guard against it. + const handle = (() => { + try { + return new tty_wrap.TTY(tty_fd, false); + } catch (e) { + return null; + } + })(); + if (handle !== null) + testInitialized(handle, 'TTY'); + else + delete providers.TTYWRAP; + } else { + delete providers.TTYWRAP; } } |