From bbc3ddcc6dcab2c2f7b9db7aaad22d9c979e2a56 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Mon, 10 Sep 2018 19:25:37 +0200 Subject: [PATCH] Updated to Node 10.10 (#363) * Updated to Node 10.10 * fix failing test, the code is correct --- README.md | 2 +- lib/_stream_readable.js | 13 +- test/browser/test-stream2-unpipe-drain.js | 2 +- test/common/README.md | 152 +++++++++++------- test/common/arraystream.js | 52 ++++++ test/common/dns.js | 2 +- test/common/hijackstdio.js | 57 +++++++ test/common/index.js | 141 ++-------------- test/common/index.mjs | 16 +- test/common/ongc.js | 53 ++++++ test/common/shared-lib-util.js | 38 +++-- test/common/tmpdir.js | 14 +- .../test-stream-once-readable-pipe.js | 71 ++++++++ test/parallel/test-stream-pipeline.js | 13 ++ ...est-stream-readable-reading-readingMore.js | 7 +- test/parallel/test-stream2-writable.js | 21 ++- 16 files changed, 421 insertions(+), 233 deletions(-) create mode 100644 test/common/arraystream.js create mode 100644 test/common/hijackstdio.js create mode 100644 test/common/ongc.js create mode 100644 test/parallel/test-stream-once-readable-pipe.js diff --git a/README.md b/README.md index 4a69842b6e..2bb9046091 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ npm install --save readable-stream This package is a mirror of the streams implementations in Node.js. -Full documentation may be found on the [Node.js website](https://nodejs.org/dist/v10.9.0/docs/api/stream.html). +Full documentation may be found on the [Node.js website](https://nodejs.org/dist/v10.10.0/docs/api/stream.html). If you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core, for background see [this blogpost](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html). diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 04b2ca931a..652fbcd5b4 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -512,7 +512,7 @@ function emitReadable(stream) { function emitReadable_(stream) { var state = stream._readableState; - debug('emit readable'); + debug('emitReadable_', state.destroyed, state.length, state.ended); if (!state.destroyed && (state.length || state.ended)) { stream.emit('readable'); } @@ -767,6 +767,7 @@ Readable.prototype.on = function (ev, fn) { } else if (ev === 'readable') { if (!state.endEmitted && !state.readableListening) { state.readableListening = state.needReadable = true; + state.flowing = false; state.emittedReadable = false; debug('on readable', state.length, state.reading); if (state.length) { @@ -815,6 +816,11 @@ Readable.prototype.removeAllListeners = function (ev) { function updateReadableListening(self) { self._readableState.readableListening = self.listenerCount('readable') > 0; + + // crude way to check if we should resume + if (self.listenerCount('data') > 0) { + self.resume(); + } } function nReadingNextTick(self) { @@ -829,7 +835,8 @@ Readable.prototype.resume = function () { if (!state.flowing) { debug('resume'); // we flow only if there is no one listening - // for readable + // for readable, but we still have to call + // resume() state.flowing = !state.readableListening; resume(this, state); } @@ -1035,4 +1042,4 @@ function indexOf(xs, x) { if (xs[i] === x) return i; } return -1; -} +} \ No newline at end of file diff --git a/test/browser/test-stream2-unpipe-drain.js b/test/browser/test-stream2-unpipe-drain.js index 5fff9539cb..d3ebbe86c0 100644 --- a/test/browser/test-stream2-unpipe-drain.js +++ b/test/browser/test-stream2-unpipe-drain.js @@ -58,7 +58,7 @@ module.exports = function (t) { dest.on('unpipe', function() { t.equal(src1.reads, 2); - t.equal(src2.reads, 2); + t.equal(src2.reads, 1); t.end(); }); }); diff --git a/test/common/README.md b/test/common/README.md index 75005f6442..b9d1525e42 100644 --- a/test/common/README.md +++ b/test/common/README.md @@ -42,9 +42,6 @@ tasks. Takes `whitelist` and concats that with predefined `knownGlobals`. -### arrayStream -A stream to push an array into a REPL - ### busyLoop(time) * `time` [<number>] @@ -180,24 +177,6 @@ Indicates whether `IPv6` is supported on this platform. Indicates if there are multiple localhosts available. -### hijackStderr(listener) -* `listener` [<Function>]: a listener with a single parameter - called `data`. - -Eavesdrop to `process.stderr.write` calls. Once `process.stderr.write` is -called, `listener` will also be called and the `data` of `write` function will -be passed to `listener`. What's more, `process.stderr.writeTimes` is a count of -the number of calls. - -### hijackStdout(listener) -* `listener` [<Function>]: a listener with a single parameter - called `data`. - -Eavesdrop to `process.stdout.write` calls. Once `process.stdout.write` is -called, `listener` will also be called and the `data` of `write` function will -be passed to `listener`. What's more, `process.stdout.writeTimes` is a count of -the number of calls. - ### inFreeBSDJail * [<boolean>] @@ -249,11 +228,6 @@ Platform check for Windows. Platform check for Windows 32-bit on Windows 64-bit. -### isCPPSymbolsNotMapped -* [<boolean>] - -Platform check for C++ symbols are mapped or not. - ### leakedGlobals() * return [<Array>] @@ -321,21 +295,6 @@ otherwise. ### noWarnCode See `common.expectWarning()` for usage. -### onGC(target, listener) -* `target` [<Object>] -* `listener` [<Object>] - * `ongc` [<Function>] - -Installs a GC listener for the collection of `target`. - -This uses `async_hooks` for GC tracking. This means that it enables -`async_hooks` tracking, which may affect the test functionality. It also -means that between a `global.gc()` call and the listener being invoked -a full `setImmediate()` invocation passes. - -`listener` is an object to make it easier to use a closure; the target object -should not be in scope when `listener.ongc()` is created. - ### opensslCli * [<boolean>] @@ -362,15 +321,16 @@ A port number for tests to use if one is needed. Logs '1..0 # Skipped: ' + `msg` -### restoreStderr() - -Restore the original `process.stderr.write`. Used to restore `stderr` to its -original state after calling [`common.hijackStdErr()`][]. +### pwdCommand +* [<array>] First two argument for the `spawn`/`exec` functions. -### restoreStdout() +Platform normalized `pwd` command options. Usage example: +```js +const common = require('../common'); +const { spawn } = require('child_process'); -Restore the original `process.stdout.write`. Used to restore `stdout` to its -original state after calling [`common.hijackStdOut()`][]. +spawn(...common.pwdCommand, { stdio: ['pipe'] }); +``` ### rootDir * [<string>] @@ -405,17 +365,19 @@ was disabled at compile time. Skip the rest of the tests in the current file when the Node.js executable was compiled with a pointer size smaller than 64 bits. -### spawnPwd(options) -* `options` [<Object>] -* return [<Object>] +## ArrayStream Module -Platform normalizes the `pwd` command. +The `ArrayStream` module provides a simple `Stream` that pushes elements from +a given array. -### spawnSyncPwd(options) -* `options` [<Object>] -* return [<Object>] + +```js +const ArrayStream = require('../common/arraystream'); +const stream = new ArrayStream(); +stream.run(['a', 'b', 'c']); +``` -Synchronous version of `spawnPwd`. +It can be used within tests as a simple mock stream. ## Countdown Module @@ -589,6 +551,52 @@ validateSnapshotNodes('TLSWRAP', [ ]); ``` +## hijackstdio Module + +The `hijackstdio` module provides utility functions for temporarily redirecting +`stdout` and `stderr` output. + + +```js +const { hijackStdout, restoreStdout } = require('../common/hijackstdio'); + +hijackStdout((data) => { + /* Do something with data */ + restoreStdout(); +}); + +console.log('this is sent to the hijacked listener'); +``` + +### hijackStderr(listener) +* `listener` [<Function>]: a listener with a single parameter + called `data`. + +Eavesdrop to `process.stderr.write()` calls. Once `process.stderr.write()` is +called, `listener` will also be called and the `data` of `write` function will +be passed to `listener`. What's more, `process.stderr.writeTimes` is a count of +the number of calls. + +### hijackStdout(listener) +* `listener` [<Function>]: a listener with a single parameter + called `data`. + +Eavesdrop to `process.stdout.write()` calls. Once `process.stdout.write()` is +called, `listener` will also be called and the `data` of `write` function will +be passed to `listener`. What's more, `process.stdout.writeTimes` is a count of +the number of calls. + +### restoreStderr() + +Restore the original `process.stderr.write()`. Used to restore `stderr` to its +original state after calling [`hijackstdio.hijackStdErr()`][]. + +### restoreStdout() + +Restore the original `process.stdout.write()`. Used to restore `stdout` to its +original state after calling [`hijackstdio.hijackStdOut()`][]. + + ## HTTP/2 Module The http2.js module provides a handful of utilities for creating mock HTTP/2 @@ -734,6 +742,34 @@ via `NODE_TEST_*` environment variables. For example, to configure `internet.addresses.INET_HOST`, set the environment variable `NODE_TEST_INET_HOST` to a specified host. +## ongc Module + +The `ongc` module allows a garbage collection listener to be installed. The +module exports a single `onGC()` function. + +```js +require('../common'); +const onGC = require('../common/ongc'); + +onGC({}, { ongc() { console.log('collected'); } }); +``` + +### onGC(target, listener) +* `target` [<Object>] +* `listener` [<Object>] + * `ongc` [<Function>] + +Installs a GC listener for the collection of `target`. + +This uses `async_hooks` for GC tracking. This means that it enables +`async_hooks` tracking, which may affect the test functionality. It also +means that between a `global.gc()` call and the listener being invoked +a full `setImmediate()` invocation passes. + +`listener` is an object to make it easier to use a closure; the target object +should not be in scope when `listener.ongc()` is created. + + ## tmpdir Module The `tmpdir` module supports the use of a temporary directory for testing. @@ -766,8 +802,8 @@ implementation with tests from [<boolean>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type [<number>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type [<string>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type -[`common.hijackStdErr()`]: #hijackstderrlistener -[`common.hijackStdOut()`]: #hijackstdoutlistener +[`hijackstdio.hijackStdErr()`]: #hijackstderrlistener +[`hijackstdio.hijackStdOut()`]: #hijackstdoutlistener [internationalization]: https://github.com/nodejs/node/wiki/Intl function forEach (xs, f) { diff --git a/test/common/arraystream.js b/test/common/arraystream.js new file mode 100644 index 0000000000..dafea14155 --- /dev/null +++ b/test/common/arraystream.js @@ -0,0 +1,52 @@ +'use strict'; + +/**/ +require('babel-polyfill'); +var util = require('util'); +for (var i in util) { + exports[i] = util[i]; +} /**/ /* eslint-disable node-core/required-modules */ +'use strict'; + +/**/ +var objectKeys = objectKeys || function (obj) { + var keys = []; + for (var key in obj) { + keys.push(key); + }return keys; +}; +/**/ + +var _require = require('../../'), + Stream = _require.Stream; + +var _require2 = require('util'), + inherits = _require2.inherits; + +function noop() {} + +// A stream to push an array into a REPL +function ArrayStream() { + this.run = function (data) { + var _this = this; + + forEach(data, function (line) { + _this.emit('data', line + '\n'); + }); + }; +} + +inherits(ArrayStream, Stream); +ArrayStream.prototype.readable = true; +ArrayStream.prototype.writable = true; +ArrayStream.prototype.pause = noop; +ArrayStream.prototype.resume = noop; +ArrayStream.prototype.write = noop; + +module.exports = ArrayStream; + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} \ No newline at end of file diff --git a/test/common/dns.js b/test/common/dns.js index 25aa816a6c..edb0432d09 100644 --- a/test/common/dns.js +++ b/test/common/dns.js @@ -61,7 +61,7 @@ function readDomainFromPacket(buffer, offset) { } else { // Pointer to another part of the packet. assert.strictEqual(length & 0xC0, 0xC0); - // eslint-disable-next-line + // eslint-disable-next-line space-infix-ops, space-unary-ops var pointeeOffset = buffer.readUInt16BE(offset) & ~0xC000; return { nread: 2, diff --git a/test/common/hijackstdio.js b/test/common/hijackstdio.js new file mode 100644 index 0000000000..26515d9154 --- /dev/null +++ b/test/common/hijackstdio.js @@ -0,0 +1,57 @@ +'use strict'; + +/**/ +require('babel-polyfill'); +var util = require('util'); +for (var i in util) { + exports[i] = util[i]; +} /**/ /* eslint-disable node-core/required-modules */ +'use strict'; + +/**/ +var objectKeys = objectKeys || function (obj) { + var keys = []; + for (var key in obj) { + keys.push(key); + }return keys; +}; +/**/ + +// Hijack stdout and stderr +var stdWrite = {}; +function hijackStdWritable(name, listener) { + var stream = process[name]; + var _write = stdWrite[name] = stream.write; + + stream.writeTimes = 0; + stream.write = function (data, callback) { + try { + listener(data); + } catch (e) { + process.nextTick(function () { + throw e; + }); + } + + _write.call(stream, data, callback); + stream.writeTimes++; + }; +} + +function restoreWritable(name) { + process[name].write = stdWrite[name]; + delete process[name].writeTimes; +} + +module.exports = { + hijackStdout: hijackStdWritable.bind(null, 'stdout'), + hijackStderr: hijackStdWritable.bind(null, 'stderr'), + restoreStdout: restoreWritable.bind(null, 'stdout'), + restoreStderr: restoreWritable.bind(null, 'stderr') +}; + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} \ No newline at end of file diff --git a/test/common/index.js b/test/common/index.js index 6fd2ae483a..c66138a5fe 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -53,21 +53,17 @@ var os = require('os'); var _require = require('child_process'), exec = _require.exec, execSync = _require.execSync, - spawn = _require.spawn, spawnSync = _require.spawnSync; -var stream = require('../../'); - /**/ + + var util = require('core-util-is'); util.inherits = require('inherits'); /**/ var Timer = { now: function () {} }; -var _process$binding = process.binding('config'), - hasTracing = _process$binding.hasTracing; - var _require2 = require('./fixtures'), fixturesDir = _require2.fixturesDir; @@ -106,23 +102,6 @@ exports.isOpenBSD = process.platform === 'openbsd'; exports.isLinux = process.platform === 'linux'; exports.isOSX = process.platform === 'darwin'; -var isGlibc = void 0; -exports.isGlibc = function () { - if (isGlibc !== undefined) return isGlibc; - try { - var lddOut = spawnSync('ldd', [process.execPath]).stdout; - var libcInfo = lddOut.toString().split('\n').map(function (line) { - return line.match(/libc\.so.+=>\s*(\S+)\s/); - }).filter(function (info) { - return info; - }); - if (libcInfo.length === 0) return isGlibc = false; - var nmOut = spawnSync('nm', ['-D', libcInfo[0][1]]).stdout; - if (/gnu_get_libc_version/.test(nmOut)) return isGlibc = true; - } catch (_e) {} - return isGlibc = false; -}; - exports.enoughTestMem = os.totalmem() > 0x70000000; /* 1.75 Gb */ var cpus = os.cpus(); /*exports.enoughTestCpu = Array.isArray(cpus) && @@ -235,6 +214,14 @@ if (exports.isLinux) { }); } /**/ +/**/if (!process.browser) { + Object.defineProperty(exports, 'localhostIPv6', { + get: function () { + return '::1'; + } + }); +} /**/ + // opensslCli defined lazily to reduce overhead of spawnSync /**/if (!process.browser) { Object.defineProperty(exports, 'opensslCli', { get: function () { @@ -267,14 +254,6 @@ if (exports.isLinux) { }); } /**/ -/**/if (!process.browser) { - Object.defineProperty(exports, 'hasTracing', { - get: function () { - return Boolean(hasTracing); - } - }); -} /**/ - /**/if (!process.browser) { Object.defineProperty(exports, 'hasFipsCrypto', { get: function () { @@ -330,21 +309,7 @@ exports.ddCommand = function (filename, kilobytes) { } }; -exports.spawnPwd = function (options) { - if (exports.isWindows) { - return spawn('cmd.exe', ['/d', '/c', 'cd'], options); - } else { - return spawn('pwd', [], options); - } -}; - -exports.spawnSyncPwd = function (options) { - if (exports.isWindows) { - return spawnSync('cmd.exe', ['/d', '/c', 'cd'], options); - } else { - return spawnSync('pwd', [], options); - } -}; +exports.pwdCommand = exports.isWindows ? ['cmd.exe', ['/d', '/c', 'cd']] : ['pwd', []]; exports.platformTimeout = function (ms) { if (process.features.debug) ms = 2 * ms; @@ -508,9 +473,9 @@ function _mustCallInner(fn) { } exports.hasMultiLocalhost = function hasMultiLocalhost() { - var _process$binding2 = process.binding('tcp_wrap'), - TCP = _process$binding2.TCP, - TCPConstants = _process$binding2.constants; + var _process$binding = process.binding('tcp_wrap'), + TCP = _process$binding.TCP, + TCPConstants = _process$binding.constants; var t = new TCP(TCPConstants.SOCKET); var ret = t.bind('127.0.0.2', 0); @@ -574,25 +539,6 @@ exports.skip = function (msg) { process.exit(0); }; -// A stream to push an array into a REPL -function ArrayStream() { - this.run = function (data) { - var _this = this; - - forEach(data, function (line) { - _this.emit('data', line + '\n'); - }); - }; -} - -util.inherits(ArrayStream, stream.Stream); -exports.ArrayStream = ArrayStream; -ArrayStream.prototype.readable = true; -ArrayStream.prototype.writable = true; -ArrayStream.prototype.pause = noop; -ArrayStream.prototype.resume = noop; -ArrayStream.prototype.write = noop; - // Returns true if the exit code "exitCode" and/or signal name "signal" // represent the exit code and/or signal name of a node process that aborted, // false otherwise. @@ -928,32 +874,6 @@ exports.getTTYfd = function getTTYfd() { return ttyFd; }; -// Hijack stdout and stderr -var stdWrite = {}; -function hijackStdWritable(name, listener) { - var stream = process[name]; - var _write = stdWrite[name] = stream.write; - - stream.writeTimes = 0; - stream.write = function (data, callback) { - try { - listener(data); - } catch (e) { - process.nextTick(function () { - throw e; - }); - } - - _write.call(stream, data, callback); - stream.writeTimes++; - }; -} - -function restoreWritable(name) { - process[name].write = stdWrite[name]; - delete process[name].writeTimes; -} - exports.runWithInvalidFD = function (func) { var fd = 1 << 30; // Get first known bad file descriptor. 1 << 30 is usually unlikely to @@ -967,39 +887,6 @@ exports.runWithInvalidFD = function (func) { exports.printSkipMessage('Could not generate an invalid fd'); }; -exports.hijackStdout = hijackStdWritable.bind(null, 'stdout'); -exports.hijackStderr = hijackStdWritable.bind(null, 'stderr'); -exports.restoreStdout = restoreWritable.bind(null, 'stdout'); -exports.restoreStderr = restoreWritable.bind(null, 'stderr'); -exports.isCPPSymbolsNotMapped = exports.isWindows || exports.isSunOS || exports.isAIX || exports.isLinuxPPCBE || exports.isFreeBSD; - -var gcTrackerMap = new WeakMap(); -var gcTrackerTag = 'NODE_TEST_COMMON_GC_TRACKER'; - -exports.onGC = function (obj, gcListener) { - var async_hooks = require('async_' + 'hooks'); - - var onGcAsyncHook = async_hooks.createHook({ - init: exports.mustCallAtLeast(function (id, type, trigger, resource) { - if (this.trackedId === undefined) { - assert.strictEqual(type, gcTrackerTag); - this.trackedId = id; - } - }), - destroy: function (id) { - assert.notStrictEqual(this.trackedId, -1); - if (id === this.trackedId) { - this.gcListener.ongc(); - onGcAsyncHook.disable(); - } - } - }).enable(); - onGcAsyncHook.gcListener = gcListener; - - gcTrackerMap.set(obj, new async_hooks.AsyncResource(gcTrackerTag)); - obj = null; -}; - function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); diff --git a/test/common/index.mjs b/test/common/index.mjs index c15315e9e9..de17d38e3c 100644 --- a/test/common/index.mjs +++ b/test/common/index.mjs @@ -17,7 +17,6 @@ const { isOpenBSD, isLinux, isOSX, - isGlibc, enoughTestMem, enoughTestCpu, rootDir, @@ -56,12 +55,7 @@ const { getBufferSources, disableCrashOnUnhandledRejection, getTTYfd, - runWithInvalidFD, - hijackStdout, - hijackStderr, - restoreStdout, - restoreStderr, - isCPPSymbolsNotMapped + runWithInvalidFD } = common; export { @@ -75,7 +69,6 @@ export { isOpenBSD, isLinux, isOSX, - isGlibc, enoughTestMem, enoughTestCpu, rootDir, @@ -114,12 +107,7 @@ export { getBufferSources, disableCrashOnUnhandledRejection, getTTYfd, - runWithInvalidFD, - hijackStdout, - hijackStderr, - restoreStdout, - restoreStderr, - isCPPSymbolsNotMapped + runWithInvalidFD }; function forEach (xs, f) { diff --git a/test/common/ongc.js b/test/common/ongc.js new file mode 100644 index 0000000000..abb1a39c3b --- /dev/null +++ b/test/common/ongc.js @@ -0,0 +1,53 @@ +'use strict'; + +/**/ +require('babel-polyfill'); +var util = require('util'); +for (var i in util) { + exports[i] = util[i]; +} /**/'use strict'; + +/**/ +var objectKeys = objectKeys || function (obj) { + var keys = []; + for (var key in obj) { + keys.push(key); + }return keys; +}; +/**/ + +var common = require('../common'); +var assert = require('assert'); +var gcTrackerMap = new WeakMap(); +var gcTrackerTag = 'NODE_TEST_COMMON_GC_TRACKER'; + +function onGC(obj, gcListener) { + var async_hooks = /*require('async_hooks'); + const onGcAsyncHook = async_hooks.createHook({ + init: common.mustCallAtLeast(function(id, type) { + if (this.trackedId === undefined) { + assert.strictEqual(type, gcTrackerTag); + this.trackedId = id; + } + }), + destroy(id) { + assert.notStrictEqual(this.trackedId, -1); + if (id === this.trackedId) { + this.gcListener.ongc(); + onGcAsyncHook.disable(); + } + } + }).enable();*/ + onGcAsyncHook.gcListener = gcListener; + + gcTrackerMap.set(obj, new async_hooks.AsyncResource(gcTrackerTag)); + obj = null; +} + +module.exports = onGC; + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} \ No newline at end of file diff --git a/test/common/shared-lib-util.js b/test/common/shared-lib-util.js index 399b9bdf50..3981645311 100644 --- a/test/common/shared-lib-util.js +++ b/test/common/shared-lib-util.js @@ -19,38 +19,48 @@ var objectKeys = objectKeys || function (obj) { var common = require('../common'); var path = require('path'); +var kNodeShared = Boolean(process.config.variables.node_shared); +var kShlibSuffix = process.config.variables.shlib_suffix; +var kExecPath = path.dirname(process.execPath); + // If node executable is linked to shared lib, need to take care about the // shared lib path. -exports.addLibraryPath = function (env) { - if (!process.config.variables.node_shared) { +function addLibraryPath(env) { + if (!kNodeShared) { return; } env = env || process.env; - env.LD_LIBRARY_PATH = (env.LD_LIBRARY_PATH ? env.LD_LIBRARY_PATH + path.delimiter : '') + path.join(path.dirname(process.execPath), 'lib.target'); + env.LD_LIBRARY_PATH = (env.LD_LIBRARY_PATH ? env.LD_LIBRARY_PATH + path.delimiter : '') + path.join(kExecPath, 'lib.target'); // For AIX. - env.LIBPATH = (env.LIBPATH ? env.LIBPATH + path.delimiter : '') + path.join(path.dirname(process.execPath), 'lib.target'); + env.LIBPATH = (env.LIBPATH ? env.LIBPATH + path.delimiter : '') + path.join(kExecPath, 'lib.target'); // For Mac OSX. - env.DYLD_LIBRARY_PATH = (env.DYLD_LIBRARY_PATH ? env.DYLD_LIBRARY_PATH + path.delimiter : '') + path.dirname(process.execPath); + env.DYLD_LIBRARY_PATH = (env.DYLD_LIBRARY_PATH ? env.DYLD_LIBRARY_PATH + path.delimiter : '') + kExecPath; // For Windows. - env.PATH = (env.PATH ? env.PATH + path.delimiter : '') + path.dirname(process.execPath); -}; + env.PATH = (env.PATH ? env.PATH + path.delimiter : '') + kExecPath; +} // Get the full path of shared lib. -exports.getSharedLibPath = function () { +function getSharedLibPath() { if (common.isWindows) { - return path.join(path.dirname(process.execPath), 'node.dll'); + return path.join(kExecPath, 'node.dll'); } else if (common.isOSX) { - return path.join(path.dirname(process.execPath), 'libnode.' + process.config.variables.shlib_suffix); + return path.join(kExecPath, 'libnode.' + kShlibSuffix); } else { - return path.join(path.dirname(process.execPath), 'lib.target', 'libnode.' + process.config.variables.shlib_suffix); + return path.join(kExecPath, 'lib.target', 'libnode.' + kShlibSuffix); } -}; +} // Get the binary path of stack frames. -exports.getBinaryPath = function () { - return process.config.variables.node_shared ? exports.getSharedLibPath() : process.execPath; +function getBinaryPath() { + return kNodeShared ? getSharedLibPath() : process.execPath; +} + +module.exports = { + addLibraryPath: addLibraryPath, + getBinaryPath: getBinaryPath, + getSharedLibPath: getSharedLibPath }; function forEach(xs, f) { diff --git a/test/common/tmpdir.js b/test/common/tmpdir.js index eb17dbbcc4..2da92326d8 100644 --- a/test/common/tmpdir.js +++ b/test/common/tmpdir.js @@ -66,11 +66,17 @@ var tmpdirName = '.tmp'; if (process.env.TEST_THREAD_ID) { tmpdirName += '.' + process.env.TEST_THREAD_ID; } -exports.path = path.join(testRoot, tmpdirName); -exports.refresh = function () { - rimrafSync(exports.path); - fs.mkdirSync(exports.path); +var tmpPath = path.join(testRoot, tmpdirName); + +function refresh() { + rimrafSync(this.path); + fs.mkdirSync(this.path); +} + +module.exports = { + path: tmpPath, + refresh: refresh }; function forEach(xs, f) { diff --git a/test/parallel/test-stream-once-readable-pipe.js b/test/parallel/test-stream-once-readable-pipe.js new file mode 100644 index 0000000000..ff17220325 --- /dev/null +++ b/test/parallel/test-stream-once-readable-pipe.js @@ -0,0 +1,71 @@ +'use strict'; + +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ + +var common = require('../common'); +var assert = require('assert/'); + +var _require = require('../../'), + Readable = _require.Readable, + Writable = _require.Writable; + +// This test ensures that if have 'readable' listener +// on Readable instance it will not disrupt the pipe. + +{ + var receivedData = ''; + var w = new Writable({ + write: function (chunk, env, callback) { + receivedData += chunk; + callback(); + } + }); + + var data = ['foo', 'bar', 'baz']; + var r = new Readable({ + read: function () {} + }); + + r.once('readable', common.mustCall()); + + r.pipe(w); + r.push(data[0]); + r.push(data[1]); + r.push(data[2]); + r.push(null); + + w.on('finish', common.mustCall(function () { + assert.strictEqual(receivedData, data.join('')); + })); +} + +{ + var _receivedData = ''; + var _w = new Writable({ + write: function (chunk, env, callback) { + _receivedData += chunk; + callback(); + } + }); + + var _data = ['foo', 'bar', 'baz']; + var _r = new Readable({ + read: function () {} + }); + + _r.pipe(_w); + _r.push(_data[0]); + _r.push(_data[1]); + _r.push(_data[2]); + _r.push(null); + _r.once('readable', common.mustCall()); + + _w.on('finish', common.mustCall(function () { + assert.strictEqual(_receivedData, _data.join('')); + })); +} +;require('tap').pass('sync run');var _list = process.listeners('uncaughtException');process.removeAllListeners('uncaughtException');_list.pop();_list.forEach(function (e) { + return process.on('uncaughtException', e); +}); \ No newline at end of file diff --git a/test/parallel/test-stream-pipeline.js b/test/parallel/test-stream-pipeline.js index d8021fc0b4..45006d3d9f 100644 --- a/test/parallel/test-stream-pipeline.js +++ b/test/parallel/test-stream-pipeline.js @@ -182,8 +182,13 @@ var promisify = require('util-promisify'); { var _server = http.createServer(function (req, res) { + var sent = false; var rs = new Readable({ read: function () { + if (sent) { + return; + } + sent = true; rs.push('hello'); }, @@ -213,8 +218,12 @@ var promisify = require('util-promisify'); { var _server2 = http.createServer(function (req, res) { + var sent = 0; var rs = new Readable({ read: function () { + if (sent++ > 10) { + return; + } rs.push('hello'); }, @@ -260,8 +269,12 @@ var promisify = require('util-promisify'); port: _server3.address().port }); + var sent = 0; var rs = new Readable({ read: function () { + if (sent++ > 10) { + return; + } rs.push('hello'); } }); diff --git a/test/parallel/test-stream-readable-reading-readingMore.js b/test/parallel/test-stream-readable-reading-readingMore.js index 5d383247bb..8fb6f898cf 100644 --- a/test/parallel/test-stream-readable-reading-readingMore.js +++ b/test/parallel/test-stream-readable-reading-readingMore.js @@ -34,10 +34,11 @@ var Readable = require('../../').Readable; assert.strictEqual(state.reading, false); } + var expectedReadingMore = [true, false]; readable.on('readable', common.mustCall(function () { - // 'readable' always gets called before 'end' - // since 'end' hasn't been emitted, more data could be incoming - assert.strictEqual(state.readingMore, true); + // there is only one readingMore scheduled from on('data'), + // after which everything is governed by the .read() call + assert.strictEqual(state.readingMore, expectedReadingMore.shift()); // if the stream has ended, we shouldn't be reading assert.strictEqual(state.ended, !state.reading); diff --git a/test/parallel/test-stream2-writable.js b/test/parallel/test-stream2-writable.js index 43b173b784..ed462c4246 100644 --- a/test/parallel/test-stream2-writable.js +++ b/test/parallel/test-stream2-writable.js @@ -75,7 +75,8 @@ for (var i = 0; i < chunks.length; i++) { }); tw.on('finish', common.mustCall(function () { - assert.deepStrictEqual(tw.buffer, chunks, 'got chunks in the right order'); + // got chunks in the right order + assert.deepStrictEqual(tw.buffer, chunks); })); forEach(chunks, function (chunk) { @@ -92,7 +93,8 @@ for (var i = 0; i < chunks.length; i++) { }); _tw.on('finish', common.mustCall(function () { - assert.deepStrictEqual(_tw.buffer, chunks, 'got chunks in the right order'); + // got chunks in the right order + assert.deepStrictEqual(_tw.buffer, chunks); })); var _i = 0; @@ -111,7 +113,8 @@ for (var i = 0; i < chunks.length; i++) { var drains = 0; _tw2.on('finish', common.mustCall(function () { - assert.deepStrictEqual(_tw2.buffer, chunks, 'got chunks in the right order'); + // got chunks in the right order + assert.deepStrictEqual(_tw2.buffer, chunks); assert.strictEqual(drains, 17); })); @@ -144,7 +147,8 @@ for (var i = 0; i < chunks.length; i++) { var encodings = ['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', undefined]; _tw3.on('finish', function () { - assert.deepStrictEqual(_tw3.buffer, chunks, 'got the expected chunks'); + // got the expected chunks + assert.deepStrictEqual(_tw3.buffer, chunks); }); forEach(chunks, function (chunk, i) { @@ -170,7 +174,8 @@ for (var i = 0; i < chunks.length; i++) { var _encodings = ['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', undefined]; _tw4.on('finish', function () { - assert.deepStrictEqual(_tw4.buffer, chunks, 'got the expected chunks'); + // got the expected chunks + assert.deepStrictEqual(_tw4.buffer, chunks); }); forEach(chunks, function (chunk, i) { @@ -198,8 +203,10 @@ for (var i = 0; i < chunks.length; i++) { _tw5.on('finish', common.mustCall(function () { process.nextTick(common.mustCall(function () { - assert.deepStrictEqual(_tw5.buffer, chunks, 'got chunks in the right order'); - assert.deepStrictEqual(callbacks._called, chunks, 'called all callbacks'); + // got chunks in the right order + assert.deepStrictEqual(_tw5.buffer, chunks); + // called all callbacks + assert.deepStrictEqual(callbacks._called, chunks); })); }));