diff --git a/.eslintignore b/.eslintignore index 507305bc8f0a..e1376c84099a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,5 @@ lib/internal/v8_prof_polyfill.js +lib/internal/v8_prof_processor.js lib/punycode.js test/addons/doc-*/ test/fixtures diff --git a/.eslintrc b/.eslintrc index bf3fc3378f2d..33a7919d88c9 100644 --- a/.eslintrc +++ b/.eslintrc @@ -84,6 +84,8 @@ rules: # list: https://github.com/eslint/eslint/tree/master/docs/rules#variables ## disallow use of undefined variables (globals) no-undef: 2 + ## disallow declaration of variables that are not used in the code + no-unused-vars: [2, {"args": "none"}] # Custom rules in tools/eslint-rules require-buffer: 2 diff --git a/CHANGELOG.md b/CHANGELOG.md index cb3a1744cca8..f5f4bcf5dffc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,128 @@ # Node.js ChangeLog +## 2016-01-06, Version 5.4.0 (Stable), @Fishrock123 + +### Notable changes + +* **http**: + - A new status code was added: 451 - "Unavailable For Legal Reasons" (Max Barinov) [#4377](https://github.com/nodejs/node/pull/4377). + - Idle sockets that have been kept alive now handle errors (José F. Romaniello) [#4482](https://github.com/nodejs/node/pull/4482). +* This release also includes several minor performance improvements: + - **assert**: deepEqual is now speedier when comparing TypedArrays (Claudio Rodriguez) [#4330](https://github.com/nodejs/node/pull/4330). + - **lib**: Use arrow functions instead of bind where possible (Minwoo Jung) [node#3622](https://github.com/nodejs/node/pull/3622). + - **node**: Improved accessor perf of `process.env` (Trevor Norris) [#3780](https://github.com/nodejs/node/pull/3780). + - **node**: Improved performance of `process.hrtime()` (Trevor Norris) [#3780](https://github.com/nodejs/node/pull/3780), (Evan Lucas) [#4484](https://github.com/nodejs/node/pull/4484). + - **node**: Improved GetActiveHandles performance (Trevor Norris) [#3780](https://github.com/nodejs/node/pull/3780). + - **util**: Use faster iteration in `util.format()` (Jackson Tian) [#3964](https://github.com/nodejs/node/pull/3964). + +### Known issues + +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). +* Unicode characters in filesystem paths are not handled consistently across platforms or Node.js APIs. See [#2088](https://github.com/nodejs/node/issues/2088), [#3401](https://github.com/nodejs/node/issues/3401) and [#3519](https://github.com/nodejs/node/issues/3519). + +### Commits + +* [[`d265fc821a`](https://github.com/nodejs/node/commit/d265fc821a)] - **assert**: typed array deepequal performance fix (Claudio Rodriguez) [#4330](https://github.com/nodejs/node/pull/4330) +* [[`6d8053ab56`](https://github.com/nodejs/node/commit/6d8053ab56)] - **buffer**: faster case for create Buffer from new Buffer(0) (Jackson Tian) [#4326](https://github.com/nodejs/node/pull/4326) +* [[`8781c59878`](https://github.com/nodejs/node/commit/8781c59878)] - **buffer**: refactor create buffer (Jackson Tian) [#4340](https://github.com/nodejs/node/pull/4340) +* [[`252628294b`](https://github.com/nodejs/node/commit/252628294b)] - **child_process**: guard against race condition (Rich Trott) [#4418](https://github.com/nodejs/node/pull/4418) +* [[`fcf632bc6a`](https://github.com/nodejs/node/commit/fcf632bc6a)] - **crypto**: load PFX chain the same way as regular one (Fedor Indutny) [#4165](https://github.com/nodejs/node/pull/4165) +* [[`a5094a35a0`](https://github.com/nodejs/node/commit/a5094a35a0)] - **debugger**: guard against call from non-node context (Ben Noordhuis) [#4328](https://github.com/nodejs/node/pull/4328) +* [[`b4c51c5b76`](https://github.com/nodejs/node/commit/b4c51c5b76)] - **deps**: backport 200315c from V8 upstream (Vladimir Kurchatkin) [#4128](https://github.com/nodejs/node/pull/4128) +* [[`334e73942e`](https://github.com/nodejs/node/commit/334e73942e)] - **doc**: fix heading level error in Buffer doc (Shigeki Ohtsu) [#4537](https://github.com/nodejs/node/pull/4537) +* [[`5be0259181`](https://github.com/nodejs/node/commit/5be0259181)] - **doc**: close backtick in process.title description (Dave) [#4534](https://github.com/nodejs/node/pull/4534) +* [[`35aec4c14d`](https://github.com/nodejs/node/commit/35aec4c14d)] - **doc**: fix numbering in stream.markdown (Richard Sun) [#4538](https://github.com/nodejs/node/pull/4538) +* [[`982f3227a5`](https://github.com/nodejs/node/commit/982f3227a5)] - **doc**: improvements to dgram.markdown copy (James M Snell) [#4437](https://github.com/nodejs/node/pull/4437) +* [[`6cdfa38d23`](https://github.com/nodejs/node/commit/6cdfa38d23)] - **doc**: improvements to errors.markdown copy (James M Snell) [#4454](https://github.com/nodejs/node/pull/4454) +* [[`6c7bcd5007`](https://github.com/nodejs/node/commit/6c7bcd5007)] - **doc**: fix website wg mislink (jona) [#4357](https://github.com/nodejs/node/pull/4357) +* [[`eee50821dc`](https://github.com/nodejs/node/commit/eee50821dc)] - **doc**: mention that http.Server inherits from net.Server (Ryan Sobol) [#4455](https://github.com/nodejs/node/pull/4455) +* [[`c745b4d5f8`](https://github.com/nodejs/node/commit/c745b4d5f8)] - **doc**: explain ClientRequest#setTimeout time unit (Ben Ripkens) [#4458](https://github.com/nodejs/node/pull/4458) +* [[`40076bf7f8`](https://github.com/nodejs/node/commit/40076bf7f8)] - **doc**: fix spelling error in lib/url.js comment (Nik Nyby) [#4390](https://github.com/nodejs/node/pull/4390) +* [[`5a223d64e3`](https://github.com/nodejs/node/commit/5a223d64e3)] - **doc**: add anchors for _transform _flush _writev in stream.markdown (iamchenxin) [#4448](https://github.com/nodejs/node/pull/4448) +* [[`e8bbeecc4c`](https://github.com/nodejs/node/commit/e8bbeecc4c)] - **doc**: improvements to debugger.markdown copy (James M Snell) [#4436](https://github.com/nodejs/node/pull/4436) +* [[`ccd75fe3fb`](https://github.com/nodejs/node/commit/ccd75fe3fb)] - **doc**: improvements to events.markdown copy (James M Snell) [#4468](https://github.com/nodejs/node/pull/4468) +* [[`ed15962777`](https://github.com/nodejs/node/commit/ed15962777)] - **doc**: improvements to dns.markdown copy (James M Snell) [#4449](https://github.com/nodejs/node/pull/4449) +* [[`e177cc9fdf`](https://github.com/nodejs/node/commit/e177cc9fdf)] - **doc**: improvements to console.markdown copy (James M Snell) [#4428](https://github.com/nodejs/node/pull/4428) +* [[`c1bc9a1023`](https://github.com/nodejs/node/commit/c1bc9a1023)] - **doc**: improve child_process.markdown copy (James M Snell) [#4383](https://github.com/nodejs/node/pull/4383) +* [[`150f62847c`](https://github.com/nodejs/node/commit/150f62847c)] - **doc**: copyedit setTimeout() documentation (Rich Trott) [#4434](https://github.com/nodejs/node/pull/4434) +* [[`9e667354be`](https://github.com/nodejs/node/commit/9e667354be)] - **doc**: fix formatting in process.markdown (Rich Trott) [#4433](https://github.com/nodejs/node/pull/4433) +* [[`bc1c0dc3fb`](https://github.com/nodejs/node/commit/bc1c0dc3fb)] - **doc**: catch the WORKING_GROUPS.md bootstrap docs up to date (James M Snell) [#4367](https://github.com/nodejs/node/pull/4367) +* [[`c835ba3601`](https://github.com/nodejs/node/commit/c835ba3601)] - **doc**: improve assert.markdown copy (James M Snell) [#4360](https://github.com/nodejs/node/pull/4360) +* [[`e79eda74c0`](https://github.com/nodejs/node/commit/e79eda74c0)] - **doc**: copyedit releases.md (Rich Trott) [#4384](https://github.com/nodejs/node/pull/4384) +* [[`6450d8667f`](https://github.com/nodejs/node/commit/6450d8667f)] - **doc**: improve grammar in tls docs (Adri Van Houdt) [#4315](https://github.com/nodejs/node/pull/4315) +* [[`474a0f081a`](https://github.com/nodejs/node/commit/474a0f081a)] - **doc**: improvements to buffer.markdown copy (James M Snell) [#4370](https://github.com/nodejs/node/pull/4370) +* [[`57684d650e`](https://github.com/nodejs/node/commit/57684d650e)] - **doc**: improve addons.markdown copy (James M Snell) [#4320](https://github.com/nodejs/node/pull/4320) +* [[`04dd861221`](https://github.com/nodejs/node/commit/04dd861221)] - **doc**: fix, modernize examples in docs (James M Snell) [#4282](https://github.com/nodejs/node/pull/4282) +* [[`5ce6e99474`](https://github.com/nodejs/node/commit/5ce6e99474)] - **doc**: Typo in buffer.markdown referencing buf.write() (chrisjohn404) [#4324](https://github.com/nodejs/node/pull/4324) +* [[`699bf2c464`](https://github.com/nodejs/node/commit/699bf2c464)] - **doc**: fix link in addons.markdown (Nicholas Young) [#4331](https://github.com/nodejs/node/pull/4331) +* [[`e742422757`](https://github.com/nodejs/node/commit/e742422757)] - **fs**: use pushValueToArray for readdir(Sync) (Trevor Norris) [#3780](https://github.com/nodejs/node/pull/3780) +* [[`1dd2d015d2`](https://github.com/nodejs/node/commit/1dd2d015d2)] - **(SEMVER-MINOR)** **http**: handle errors on idle sockets (José F. Romaniello) [#4482](https://github.com/nodejs/node/pull/4482) +* [[`083ae166bb`](https://github.com/nodejs/node/commit/083ae166bb)] - **http**: use `self.keepAlive` instead of `self.options.keepAlive` (Damian Schenkelman) [#4407](https://github.com/nodejs/node/pull/4407) +* [[`ffb4a6e0e4`](https://github.com/nodejs/node/commit/ffb4a6e0e4)] - **http**: fix non-string header value concatenation (Brian White) [#4460](https://github.com/nodejs/node/pull/4460) +* [[`c77fd6829a`](https://github.com/nodejs/node/commit/c77fd6829a)] - **(SEMVER-MINOR)** **http**: 451 status code "Unavailable For Legal Reasons" (Max Barinov) [#4377](https://github.com/nodejs/node/pull/4377) +* [[`8f7af9a489`](https://github.com/nodejs/node/commit/8f7af9a489)] - **http**: remove excess calls to removeSocket (Dave) [#4172](https://github.com/nodejs/node/pull/4172) +* [[`b841967103`](https://github.com/nodejs/node/commit/b841967103)] - **http**: Remove an unnecessary assignment (Bo Borgerson) [#4323](https://github.com/nodejs/node/pull/4323) +* [[`b8366e76dd`](https://github.com/nodejs/node/commit/b8366e76dd)] - **http_parser**: use pushValueToArray for headers (Trevor Norris) [#3780](https://github.com/nodejs/node/pull/3780) +* [[`ca97e7276e`](https://github.com/nodejs/node/commit/ca97e7276e)] - **https**: use `servername` in agent key (Fedor Indutny) [#4389](https://github.com/nodejs/node/pull/4389) +* [[`b5aaccc6af`](https://github.com/nodejs/node/commit/b5aaccc6af)] - **lib**: remove unused modules (Rich Trott) [#4396](https://github.com/nodejs/node/pull/4396) +* [[`921fb540c1`](https://github.com/nodejs/node/commit/921fb540c1)] - **node**: improve performance of process.hrtime() (Evan Lucas) [#4484](https://github.com/nodejs/node/pull/4484) +* [[`ecef817a28`](https://github.com/nodejs/node/commit/ecef817a28)] - **node**: improve accessor perf of process.env (Trevor Norris) [#3780](https://github.com/nodejs/node/pull/3780) +* [[`89f056bdf3`](https://github.com/nodejs/node/commit/89f056bdf3)] - **node**: improve performance of hrtime() (Trevor Norris) [#3780](https://github.com/nodejs/node/pull/3780) +* [[`c8fc217dc7`](https://github.com/nodejs/node/commit/c8fc217dc7)] - **node**: improve GetActiveHandles performance (Trevor Norris) [#3780](https://github.com/nodejs/node/pull/3780) +* [[`8464667071`](https://github.com/nodejs/node/commit/8464667071)] - **node**: fix erroneously named function call (Trevor Norris) [#3780](https://github.com/nodejs/node/pull/3780) +* [[`e57fd51a5e`](https://github.com/nodejs/node/commit/e57fd51a5e)] - **os**: fix crash in GetInterfaceAddresses (Martin Bark) [#4272](https://github.com/nodejs/node/pull/4272) +* [[`65c40d753f`](https://github.com/nodejs/node/commit/65c40d753f)] - **repl**: remove unused function (Rich Trott) +* [[`3d41a44dba`](https://github.com/nodejs/node/commit/3d41a44dba)] - **repl**: Fixed node repl history edge case. (Mudit Ameta) [#4108](https://github.com/nodejs/node/pull/4108) +* [[`d11930d604`](https://github.com/nodejs/node/commit/d11930d604)] - **repl**: use String#repeat instead of Array#join (Evan Lucas) [#3900](https://github.com/nodejs/node/pull/3900) +* [[`4220d25626`](https://github.com/nodejs/node/commit/4220d25626)] - **test**: fix linting for the v5.x branch (Jeremiah Senkpiel) [#4547](https://github.com/nodejs/node/pull/4547) +* [[`4b14f1c983`](https://github.com/nodejs/node/commit/4b14f1c983)] - **test**: remove unused vars (Rich Trott) [#4536](https://github.com/nodejs/node/pull/4536) +* [[`2a69ab32ec`](https://github.com/nodejs/node/commit/2a69ab32ec)] - **test**: add test-domain-exit-dispose-again back (Julien Gilli) [#4256](https://github.com/nodejs/node/pull/4256) +* [[`ae0246641c`](https://github.com/nodejs/node/commit/ae0246641c)] - **test**: remove unused vars from parallel tests (Rich Trott) [#4511](https://github.com/nodejs/node/pull/4511) +* [[`984db93e7c`](https://github.com/nodejs/node/commit/984db93e7c)] - **test**: fix flaky test-cluster-shared-leak (Rich Trott) [#4510](https://github.com/nodejs/node/pull/4510) +* [[`30b0d7583a`](https://github.com/nodejs/node/commit/30b0d7583a)] - **test**: fix flaky streams test (Rich Trott) [#4516](https://github.com/nodejs/node/pull/4516) +* [[`46fefbc1b5`](https://github.com/nodejs/node/commit/46fefbc1b5)] - **test**: fix flaky test-http-agent-keepalive (Rich Trott) [#4524](https://github.com/nodejs/node/pull/4524) +* [[`e04a8401d9`](https://github.com/nodejs/node/commit/e04a8401d9)] - **test**: remove flaky designations for tests (Rich Trott) [#4519](https://github.com/nodejs/node/pull/4519) +* [[`a703b1bf73`](https://github.com/nodejs/node/commit/a703b1bf73)] - **test**: remove time check (Rich Trott) [#4494](https://github.com/nodejs/node/pull/4494) +* [[`02b3a5be52`](https://github.com/nodejs/node/commit/02b3a5be52)] - **test**: refactor test-fs-empty-readStream (Rich Trott) [#4490](https://github.com/nodejs/node/pull/4490) +* [[`ab3e5c1417`](https://github.com/nodejs/node/commit/ab3e5c1417)] - **test**: write to tmp dir rather than fixture dir (Rich Trott) [#4489](https://github.com/nodejs/node/pull/4489) +* [[`06043fdfa3`](https://github.com/nodejs/node/commit/06043fdfa3)] - **test**: remove unused modules (Rich Trott) [#4475](https://github.com/nodejs/node/pull/4475) +* [[`f1a66bc249`](https://github.com/nodejs/node/commit/f1a66bc249)] - **test**: clarify role of domains in test (Rich Trott) [#4474](https://github.com/nodejs/node/pull/4474) +* [[`08a3490dd6`](https://github.com/nodejs/node/commit/08a3490dd6)] - **test**: inherit JOBS from environment (Johan Bergström) [#4495](https://github.com/nodejs/node/pull/4495) +* [[`3bfc18763a`](https://github.com/nodejs/node/commit/3bfc18763a)] - **test**: improve assert message (Rich Trott) [#4461](https://github.com/nodejs/node/pull/4461) +* [[`d46d850461`](https://github.com/nodejs/node/commit/d46d850461)] - **test**: shorten path for bogus socket (Rich Trott) [#4478](https://github.com/nodejs/node/pull/4478) +* [[`f68f86cd0a`](https://github.com/nodejs/node/commit/f68f86cd0a)] - **test**: fix race condition in test-http-client-onerror (Devin Nakamura) [#4346](https://github.com/nodejs/node/pull/4346) +* [[`ec0b6362cf`](https://github.com/nodejs/node/commit/ec0b6362cf)] - **test**: remove unused assert module imports (Rich Trott) [#4438](https://github.com/nodejs/node/pull/4438) +* [[`ba2445046c`](https://github.com/nodejs/node/commit/ba2445046c)] - **test**: don't use cwd for relative path (Johan Bergström) [#4477](https://github.com/nodejs/node/pull/4477) +* [[`5110e4deed`](https://github.com/nodejs/node/commit/5110e4deed)] - **test**: don't assume a certain folder structure (Johan Bergström) [#3325](https://github.com/nodejs/node/pull/3325) +* [[`55c6946400`](https://github.com/nodejs/node/commit/55c6946400)] - **test**: make temp path customizable (Johan Bergström) [#3325](https://github.com/nodejs/node/pull/3325) +* [[`b19d19efaa`](https://github.com/nodejs/node/commit/b19d19efaa)] - **test**: extend timeout in Debug mode (Rich Trott) [#4431](https://github.com/nodejs/node/pull/4431) +* [[`c6a99ddd37`](https://github.com/nodejs/node/commit/c6a99ddd37)] - **test**: remove unused variables from net tests (Rich Trott) [#4430](https://github.com/nodejs/node/pull/4430) +* [[`54004f0e26`](https://github.com/nodejs/node/commit/54004f0e26)] - **test**: remove unused vars in ChildProcess tests (Rich Trott) [#4425](https://github.com/nodejs/node/pull/4425) +* [[`e72112f90e`](https://github.com/nodejs/node/commit/e72112f90e)] - **test**: fix flaky cluster-disconnect-race (Brian White) [#4457](https://github.com/nodejs/node/pull/4457) +* [[`715afc9bbd`](https://github.com/nodejs/node/commit/715afc9bbd)] - **test**: fix flaky cluster-net-send (Brian White) [#4444](https://github.com/nodejs/node/pull/4444) +* [[`03c4bc704f`](https://github.com/nodejs/node/commit/03c4bc704f)] - **test**: fix flaky child-process-fork-regr-gh-2847 (Brian White) [#4442](https://github.com/nodejs/node/pull/4442) +* [[`684eb32072`](https://github.com/nodejs/node/commit/684eb32072)] - **test**: remove unused variables from HTTPS tests (Rich Trott) [#4426](https://github.com/nodejs/node/pull/4426) +* [[`585c01f674`](https://github.com/nodejs/node/commit/585c01f674)] - **test**: remove unused variables from TLS tests (Rich Trott) [#4424](https://github.com/nodejs/node/pull/4424) +* [[`c36ca37e2a`](https://github.com/nodejs/node/commit/c36ca37e2a)] - **test**: remove unused variables form http tests (Rich Trott) [#4422](https://github.com/nodejs/node/pull/4422) +* [[`c639d0f1fe`](https://github.com/nodejs/node/commit/c639d0f1fe)] - **test**: mark test-debug-no-context is flaky (Rich Trott) [#4421](https://github.com/nodejs/node/pull/4421) +* [[`cd79ec268d`](https://github.com/nodejs/node/commit/cd79ec268d)] - **test**: remove unnecessary assignments (Rich Trott) [#4408](https://github.com/nodejs/node/pull/4408) +* [[`0799a9abaf`](https://github.com/nodejs/node/commit/0799a9abaf)] - **test**: remove unused var from test-assert.js (Rich Trott) [#4405](https://github.com/nodejs/node/pull/4405) +* [[`3710028a85`](https://github.com/nodejs/node/commit/3710028a85)] - **test**: remove unused `util` imports (Rich Trott) [#4397](https://github.com/nodejs/node/pull/4397) +* [[`8c9d0c1f6f`](https://github.com/nodejs/node/commit/8c9d0c1f6f)] - **test**: refactor test-net-connect-options-ipv6 (Rich Trott) [#4395](https://github.com/nodejs/node/pull/4395) +* [[`874209022f`](https://github.com/nodejs/node/commit/874209022f)] - **test**: fix http-response-multiheaders (Santiago Gimeno) [#3958](https://github.com/nodejs/node/pull/3958) +* [[`71b79bcf54`](https://github.com/nodejs/node/commit/71b79bcf54)] - **test**: test each block in addon.md contains js & cc (Rod Vagg) [#4411](https://github.com/nodejs/node/pull/4411) +* [[`00b37de243`](https://github.com/nodejs/node/commit/00b37de243)] - **test**: fix domain-top-level-error-handler-throw (Santiago Gimeno) [#4364](https://github.com/nodejs/node/pull/4364) +* [[`6d14b6520f`](https://github.com/nodejs/node/commit/6d14b6520f)] - **test**: use platformTimeout() in more places (Brian White) [#4387](https://github.com/nodejs/node/pull/4387) +* [[`82f74caa56`](https://github.com/nodejs/node/commit/82f74caa56)] - **test**: fix flaky test-net-error-twice (Brian White) [#4342](https://github.com/nodejs/node/pull/4342) +* [[`96501e55be`](https://github.com/nodejs/node/commit/96501e55be)] - **test**: try other ipv6 localhost alternatives (Brian White) [#4325](https://github.com/nodejs/node/pull/4325) +* [[`69343d6d2e`](https://github.com/nodejs/node/commit/69343d6d2e)] - **tls_wrap**: clear errors on return (Fedor Indutny) [#4515](https://github.com/nodejs/node/pull/4515) +* [[`ca9812cf4d`](https://github.com/nodejs/node/commit/ca9812cf4d)] - **tools**: fix warning in doc parsing (Shigeki Ohtsu) [#4537](https://github.com/nodejs/node/pull/4537) +* [[`386030b524`](https://github.com/nodejs/node/commit/386030b524)] - **tools**: implement no-unused-vars for eslint (Rich Trott) [#4536](https://github.com/nodejs/node/pull/4536) +* [[`14a947fc70`](https://github.com/nodejs/node/commit/14a947fc70)] - **tools**: run tick processor without forking (Matt Loring) [#4224](https://github.com/nodejs/node/pull/4224) +* [[`8039ca06eb`](https://github.com/nodejs/node/commit/8039ca06eb)] - **util**: faster arrayToHash (Jackson Tian) [#3964](https://github.com/nodejs/node/pull/3964) + ## 2015-12-16, Version 5.3.0 (Stable), @cjihrig ### Notable changes diff --git a/Makefile b/Makefile index a99b112508c4..94eb41995367 100644 --- a/Makefile +++ b/Makefile @@ -493,6 +493,9 @@ bench-url: all bench-events: all @$(NODE) benchmark/common.js events +bench-util: all + @$(NODE) benchmark/common.js util + bench-all: bench bench-misc bench-array bench-buffer bench-url bench-events bench: bench-net bench-http bench-fs bench-tls diff --git a/WORKING_GROUPS.md b/WORKING_GROUPS.md index aa573844b790..7472deb59917 100644 --- a/WORKING_GROUPS.md +++ b/WORKING_GROUPS.md @@ -37,7 +37,7 @@ back in to the TSC. * [Starting a Working Group](#starting-a-wg) * [Bootstrap Governance](#bootstrap-governance) -### [Website](https://github.com/nodejs/website) +### [Website](https://github.com/nodejs/nodejs.org) The website working group's purpose is to build and maintain a public website for the `Node.js` project. @@ -452,40 +452,13 @@ By making a contribution to this project, I certify that: * (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. +### Moderation Policy + +The [Node.js Moderation Policy] applies to this WG. ### Code of Conduct -This Code of Conduct is adapted from [Rust's wonderful -CoC](https://github.com/rust-lang/rust/wiki/Note-development-policy#conduct). - -* We are committed to providing a friendly, safe and welcoming - environment for all, regardless of gender, sexual orientation, - disability, ethnicity, religion, or similar personal characteristic. -* Please avoid using overtly sexual nicknames or other nicknames that - might detract from a friendly, safe and welcoming environment for - all. -* Please be kind and courteous. There's no need to be mean or rude. -* Respect that people have differences of opinion and that every - design or implementation choice carries a trade-off and numerous - costs. There is seldom a right answer. -* Please keep unstructured critique to a minimum. If you have solid - ideas you want to experiment with, make a fork and see how it works. -* We will exclude you from interaction if you insult, demean or harass - anyone. That is not welcome behaviour. We interpret the term - "harassment" as including the definition in the [Citizen Code of - Conduct](http://citizencodeofconduct.org/); if you have any lack of - clarity about what might be included in that concept, please read - their definition. In particular, we don't tolerate behavior that - excludes people in socially marginalized groups. -* Private harassment is also unacceptable. No matter who you are, if - you feel you have been or are being harassed or made uncomfortable - by a community member, please contact one of the channel ops or any - of the TC members immediately with a capture (log, photo, email) of - the harassment if possible. Whether you're a regular contributor or - a newcomer, we care about making this community a safe place for you - and we've got your back. -* Likewise any spamming, trolling, flaming, baiting or other - attention-stealing behaviour is not welcome. -* Avoid the use of personal pronouns in code comments or - documentation. There is no need to address persons when explaining - code (e.g. "When the developer") +The [Node.js Code of Conduct][] applies to this WG. + +[Node.js Code of Conduct]: https://github.com/nodejs/node/blob/master/CODE_OF_CONDUCT.md +[Node.js Moderation Policy]: https://github.com/nodejs/TSC/blob/master/Moderation-Policy.md diff --git a/benchmark/assert/deepequal-prims-and-objs-big-array.js b/benchmark/assert/deepequal-prims-and-objs-big-array.js new file mode 100644 index 000000000000..d8d2b57331f7 --- /dev/null +++ b/benchmark/assert/deepequal-prims-and-objs-big-array.js @@ -0,0 +1,37 @@ +'use strict'; +var common = require('../common.js'); +var assert = require('assert'); +var bench = common.createBenchmark(main, { + prim: [ + null, + undefined, + 'a', + 1, + true, + {0: 'a'}, + [1, 2, 3], + new Array([1, 2, 3]) + ], + n: [25] +}); + +function main(conf) { + var prim = conf.prim; + var n = +conf.n; + var primArray; + var primArrayCompare; + var x; + + primArray = new Array(); + primArrayCompare = new Array(); + for (x = 0; x < (1e5); x++) { + primArray.push(prim); + primArrayCompare.push(prim); + } + + bench.start(); + for (x = 0; x < n; x++) { + assert.deepEqual(primArray, primArrayCompare); + } + bench.end(n); +} diff --git a/benchmark/assert/deepequal-prims-and-objs-big-loop.js b/benchmark/assert/deepequal-prims-and-objs-big-loop.js new file mode 100644 index 000000000000..5f0519bb3b45 --- /dev/null +++ b/benchmark/assert/deepequal-prims-and-objs-big-loop.js @@ -0,0 +1,30 @@ +'use strict'; +var common = require('../common.js'); +var assert = require('assert'); +var bench = common.createBenchmark(main, { + prim: [ + null, + undefined, + 'a', + 1, + true, + {0: 'a'}, + [1, 2, 3], + new Array([1, 2, 3]) + ], + n: [1e5] +}); + +function main(conf) { + var prim = conf.prim; + var n = +conf.n; + var x; + + bench.start(); + + for (x = 0; x < n; x++) { + assert.deepEqual(new Array([prim]), new Array([prim])); + } + + bench.end(n); +} diff --git a/benchmark/assert/deepequal-typedarrays.js b/benchmark/assert/deepequal-typedarrays.js new file mode 100644 index 000000000000..99c13206d756 --- /dev/null +++ b/benchmark/assert/deepequal-typedarrays.js @@ -0,0 +1,22 @@ +'use strict'; +var common = require('../common.js'); +var assert = require('assert'); +var bench = common.createBenchmark(main, { + type: ('Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array ' + + 'Float32Array Float64Array Uint8ClampedArray').split(' '), + n: [1] +}); + +function main(conf) { + var type = conf.type; + var clazz = global[type]; + var n = +conf.n; + + bench.start(); + var actual = new clazz(n * 1e6); + var expected = new clazz(n * 1e6); + + assert.deepEqual(actual, expected); + + bench.end(n); +} diff --git a/benchmark/buffers/buffer_zero.js b/benchmark/buffers/buffer_zero.js new file mode 100644 index 000000000000..461378758b59 --- /dev/null +++ b/benchmark/buffers/buffer_zero.js @@ -0,0 +1,18 @@ +'use strict'; + +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + n: [1024] +}); + +const zero = new Buffer(0); + +function main(conf) { + var n = +conf.n; + bench.start(); + for (let i = 0; i < n * 1024; i++) { + new Buffer(zero); + } + bench.end(n); +} diff --git a/benchmark/fs/bench-readdir.js b/benchmark/fs/bench-readdir.js new file mode 100644 index 000000000000..2f0eab6a821f --- /dev/null +++ b/benchmark/fs/bench-readdir.js @@ -0,0 +1,22 @@ +'use strict'; + +const common = require('../common'); +const fs = require('fs'); + +const bench = common.createBenchmark(main, { + n: [1e4], +}); + + +function main(conf) { + const n = conf.n >>> 0; + + bench.start(); + (function r(cntr) { + if (--cntr <= 0) + return bench.end(n); + fs.readdir(__dirname + '/../../lib/', function() { + r(cntr); + }); + }(n)); +} diff --git a/benchmark/fs/bench-readdirSync.js b/benchmark/fs/bench-readdirSync.js new file mode 100644 index 000000000000..9f89649138cd --- /dev/null +++ b/benchmark/fs/bench-readdirSync.js @@ -0,0 +1,19 @@ +'use strict'; + +const common = require('../common'); +const fs = require('fs'); + +const bench = common.createBenchmark(main, { + n: [1e4], +}); + + +function main(conf) { + const n = conf.n >>> 0; + + bench.start(); + for (var i = 0; i < n; i++) { + fs.readdirSync(__dirname + '/../../lib/'); + } + bench.end(n); +} diff --git a/benchmark/http/bench-parser.js b/benchmark/http/bench-parser.js new file mode 100644 index 000000000000..989d9a994fa0 --- /dev/null +++ b/benchmark/http/bench-parser.js @@ -0,0 +1,55 @@ +'use strict'; + +const common = require('../common'); +const HTTPParser = process.binding('http_parser').HTTPParser; +const REQUEST = HTTPParser.REQUEST; +const kOnHeaders = HTTPParser.kOnHeaders | 0; +const kOnHeadersComplete = HTTPParser.kOnHeadersComplete | 0; +const kOnBody = HTTPParser.kOnBody | 0; +const kOnMessageComplete = HTTPParser.kOnMessageComplete | 0; +const CRLF = '\r\n'; + +const bench = common.createBenchmark(main, { + fields: [4, 8, 16, 32], + n: [1e5], +}); + + +function main(conf) { + const fields = conf.fields >>> 0; + const n = conf.n >>> 0; + var header = `GET /hello HTTP/1.1${CRLF}Content-Type: text/plain${CRLF}`; + + for (var i = 0; i < fields; i++) { + header += `X-Filler${i}: ${Math.random().toString(36).substr(2)}${CRLF}`; + } + header += CRLF; + + processHeader(new Buffer(header), n); +} + + +function processHeader(header, n) { + const parser = newParser(REQUEST); + + bench.start(); + for (var i = 0; i < n; i++) { + parser.execute(header, 0, header.length); + parser.reinitialize(REQUEST); + } + bench.end(n); +} + + +function newParser(type) { + const parser = new HTTPParser(type); + + parser.headers = []; + + parser[kOnHeaders] = function() { }; + parser[kOnHeadersComplete] = function() { }; + parser[kOnBody] = function() { }; + parser[kOnMessageComplete] = function() { }; + + return parser; +} diff --git a/benchmark/misc/bench-env.js b/benchmark/misc/bench-env.js new file mode 100644 index 000000000000..66f966f587bb --- /dev/null +++ b/benchmark/misc/bench-env.js @@ -0,0 +1,18 @@ +'use strict'; + +const common = require('../common'); + +const bench = common.createBenchmark(main, { + n: [1e5], +}); + + +function main(conf) { + const n = conf.n >>> 0; + bench.start(); + for (var i = 0; i < n; i++) { + // Access every item in object to process values. + Object.keys(process.env); + } + bench.end(n); +} diff --git a/benchmark/misc/bench-hrtime.js b/benchmark/misc/bench-hrtime.js new file mode 100644 index 000000000000..661dff43b010 --- /dev/null +++ b/benchmark/misc/bench-hrtime.js @@ -0,0 +1,18 @@ +'use strict'; + +const common = require('../common'); + +const bench = common.createBenchmark(main, { + n: [1e6] +}); + + +function main(conf) { + const n = conf.n >>> 0; + + bench.start(); + for (var i = 0; i < n; i++) { + process.hrtime(); + } + bench.end(n); +} diff --git a/benchmark/util/inspect.js b/benchmark/util/inspect.js new file mode 100644 index 000000000000..8a59e6b48e54 --- /dev/null +++ b/benchmark/util/inspect.js @@ -0,0 +1,15 @@ +var util = require('util'); + +var common = require('../common.js'); + +var bench = common.createBenchmark(main, {n: [5e6]}); + +function main(conf) { + var n = conf.n | 0; + + bench.start(); + for (var i = 0; i < n; i += 1) { + var r = util.inspect({a: 'a', b: 'b', c: 'c', d: 'd'}); + } + bench.end(n); +} diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index 9a66c317bf33..ed2c5058a492 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -1,39 +1,52 @@ # Addons -Addons are dynamically-linked shared objects. They can provide glue to C and -C++ libraries. The API (at the moment) is rather complex, involving -knowledge of several libraries: +Node.js Addons are dynamically-linked shared objects, written in C or C++, that +can be loaded into Node.js using the `require()` function, and used just as if +they were an ordinary Node.js module. They are used primarily to provide an +interface between JavaScript running in Node.js and C/C++ libraries. - - V8 JavaScript, a C++ library. Used for interfacing with JavaScript: - creating objects, calling functions, etc. Documented mostly in the +At the moment, the method for implementing Addons is rather complicated, +involving knowledge of several components and APIs : + + - V8: the C++ library Node.js currently uses to provide the + JavaScript implementation. V8 provides the mechanisms for creating objects, + calling functions, etc. V8's API is documented mostly in the `v8.h` header file (`deps/v8/include/v8.h` in the Node.js source tree), which is also available [online][]. - - [libuv][], C event loop library. Anytime one needs to wait for a file - descriptor to become readable, wait for a timer, or wait for a signal - to be received, one will need to interface with libuv. That is, if you - perform any I/O, libuv will need to be used. - - - Internal Node.js libraries. The most important class is `node::ObjectWrap` - which you will likely want to derive from. - - - Others. Look in `deps/` for what else is available. - -Node.js statically compiles all its dependencies into the executable. -When compiling your module, you don't need to worry about linking to -any of these libraries. + - [libuv][]: The C library that implements the Node.js event loop, its worker + threads and all of the asynchronous behaviors of the platform. It also + serves as a cross-platform abstraction library, giving easy, POSIX-like + access across all major operating systems to many common system tasks, such + as interacting with the filesystem, sockets, timers and system events. libuv + also provides a pthreads-like threading abstraction that may be used to + power more sophisticated asynchronous Addons that need to move beyond the + standard event loop. Addon authors are encouraged to think about how to + avoid blocking the event loop with I/O or other time-intensive tasks by + off-loading work via libuv to non-blocking system operations, worker threads + or a custom use of libuv's threads. + + - Internal Node.js libraries. Node.js itself exports a number of C/C++ APIs + that Addons can use — the most important of which is the + `node::ObjectWrap` class. + + - Node.js includes a number of other statically linked libraries including + OpenSSL. These other libraries are located in the `deps/` directory in the + Node.js source tree. Only the V8 and OpenSSL symbols are purposefully + re-exported by Node.js and may be used to various extents by Addons. + See [Linking to Node.js' own dependencies][] for additional information. All of the following examples are available for [download][] and may be used as a starting-point for your own Addon. ## Hello world -To get started, let's make a small Addon which is the C++ equivalent of -the following JavaScript code: +This "Hello world" example is a simple Addon, written in C++, that is the +equivalent of the following JavaScript code: module.exports.hello = function() { return 'world'; }; -First we create a file `hello.cc`: +First, create the file `hello.cc`: // hello.cc #include @@ -60,7 +73,8 @@ First we create a file `hello.cc`: } // namespace demo -Note that all Node.js addons must export an initialization function: +Note that all Node.js Addons must export an initialization function following +the pattern: void Initialize(Local exports); NODE_MODULE(module_name, Initialize) @@ -68,13 +82,19 @@ Note that all Node.js addons must export an initialization function: There is no semi-colon after `NODE_MODULE` as it's not a function (see `node.h`). -The `module_name` needs to match the filename of the final binary (excluding +The `module_name` must match the filename of the final binary (excluding the .node suffix). -The source code needs to be built into `addon.node`, the binary Addon. To -do this, we create a file called `binding.gyp` which describes the configuration -to build your module in a JSON-like format. This file gets compiled by -[node-gyp][]. +In the `hello.cc` example, then, the initialization function is `init` and the +Addon module name is `addon`. + +### Building + +Once the source code has been written, it must be compiled into the binary +`addon.node` file. To do so, create a file called `binding.gyp` in the +top-level of the project describing the build configuration of your module +using a JSON-like format. This file is used by [node-gyp][] -- a tool written +specifically to compile Node.js Addons. { "targets": [ @@ -85,37 +105,109 @@ to build your module in a JSON-like format. This file gets compiled by ] } -The next step is to generate the appropriate project build files for the -current platform. Use `node-gyp configure` for that. +*Note: A version of the `node-gyp` utility is bundled and distributed with +Node.js as part of `npm`. This version is not made directly available for +developers to use and is intended only to support the ability to use the +`npm install` command to compile and install Addons. Developers who wish to +use `node-gyp` directly can install it using the command +`npm install -g node-gyp`. See the `node-gyp` [installation instructions] for +more information, including platform-specific requirements.* -Now you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file -(on Windows) in the `build/` directory. Next, invoke the `node-gyp build` -command. +Once the `binding.gyp` file has been created, use `node-gyp configure` to +generate the appropriate project build files for the current platform. This +will generate either a `Makefile` (on Unix platforms) or a `vcxproj` file +(on Windows) in the `build/` directory. -Now you have your compiled `.node` bindings file! The compiled bindings end up -in `build/Release/`. +Next, invoke the `node-gyp build` command to generate the compiled `addon.node` +file. This will be put into the `build/Release/` directory. -You can now use the binary addon in a Node.js project `hello.js` by pointing -`require` to the recently built `hello.node` module: +When using `npm install` to install a Node.js Addon, npm uses its own bundled +version of `node-gyp` to perform this same set of actions, generating a +compiled version of the Addon for the user's platform on demand. + +Once built, the binary Addon can be used from within Node.js by pointing +`require()` to the built `addon.node` module: // hello.js - var addon = require('./build/Release/addon'); + const addon = require('./build/Release/addon'); console.log(addon.hello()); // 'world' -Please see patterns below for further information or +Please see the examples below for further information or for an example in production. +Because the exact path to the compiled Addon binary can vary depending on how +it is compiled (i.e. sometimes it may be in `./build/Debug/`), Addons can use +the [bindings][] package to load the compiled module. + +Note that while the `bindings` package implementation is more sophisticated +in how it locates Addon modules, it is essentially using a try-catch pattern +similar to: + + try { + return require('./build/Release/addon.node'); + } catch (err) { + return require('./build/Debug/addon.node'); + } + +### Linking to Node.js' own dependencies -## Addon patterns +Node.js uses a number of statically linked libraries such as V8, libuv and +OpenSSL. All Addons are required to link to V8 and may link to any of the +other dependencies as well. Typically, this is as simple as including +the appropriate `#include <...>` statements (e.g. `#include `) and +`node-gyp` will locate the appropriate headers automatically. However, there +are a few caveats to be aware of: -Below are some addon patterns to help you get started. Consult the online -[v8 reference][] for help with the various v8 calls, and v8's -[Embedder's Guide][] for an explanation of several concepts used such as -handles, scopes, function templates, etc. +* When `node-gyp` runs, it will detect the specific release version of Node.js +and download either the full source tarball or just the headers. If the full +source is downloaded, Addons will have complete access to the full set of +Node.js dependencies. However, if only the Node.js headers are downloaded, then +only the symbols exported by Node.js will be available. -In order to use these examples, you need to compile them using `node-gyp`. -Create the following `binding.gyp` file: +* `node-gyp` can be run using the `--nodedir` flag pointing at a local Node.js +source image. Using this option, the Addon will have access to the full set of +dependencies. + +### Loading Addons using require() + +The filename extension of the compiled Addon binary is `.node` (as opposed +to `.dll` or `.so`). The `require()` function is written to look for files +with the `.node` file extension and initialize those as dynamically-linked +libraries. + +When calling `require()`, the `.node` extension can usually be +omitted and Node.js will still find and initialize the Addon. One caveat, +however, is that Node.js will first attempt to locate and load modules or +JavaScript files that happen to share the same base name. For instance, if +there is a file `addon.js` in the same directory as the binary `addon.node`, +then `require('addon')` will give precedence to the `addon.js` file and load it +instead. + +## Native Abstractions for Node.js + +Each of the examples illustrated in this document make direct use of the +Node.js and V8 APIs for implementing Addons. It is important to understand +that the V8 API can, and has, changed dramatically from one V8 release to the +next (and one major Node.js release to the next). With each change, Addons may +need to be updated and recompiled in order to continue functioning. The Node.js +release schedule is designed to minimize the frequency and impact of such +changes but there is little that Node.js can do currently to ensure stability +of the V8 APIs. + +The [Native Abstrations for Node.js][] (or `nan`) provide a set of tools that +Addon developers are recommended to use to keep compatibility between past and +future releases of V8 and Node.js. See the `nan` [examples][] for an +illustration of how it can be used. + +## Addon examples + +Following are some example Addons intended to help developers get started. The +examples make use of the V8 APIs. Refer to the online [V8 reference][] for help +with the various V8 calls, and V8's [Embedder's Guide][] for an explanation of +several concepts used such as handles, scopes, function templates, etc. + +Each of these examples using the following `binding.gyp` file: { "targets": [ @@ -126,22 +218,26 @@ Create the following `binding.gyp` file: ] } -In cases where there is more than one `.cc` file, simply add the file name to -the `sources` array. For example: +In cases where there is more than one `.cc` file, simply add the additional +filename to the `sources` array. For example: "sources": ["addon.cc", "myexample.cc"] -Now that you have your `binding.gyp` ready, you can configure and build the -addon: +Once the `binding.gyp` file is ready, the example Addons can be configured and +built using `node-gyp`: $ node-gyp configure build ### Function arguments -The following pattern illustrates how to read arguments from JavaScript -function calls and return a result. This is the main and only needed source -`addon.cc`: +Addons will typically expose objects and functions that can be accessed from +JavaScript running within Node.js. When functions are invoked from JavaScript, +the input arguments and return value must be mapped to and from the C/C++ +code. + +The following example illustrates how to read function arguments passed from +JavaScript and how to return a result: // addon.cc #include @@ -157,24 +253,33 @@ function calls and return a result. This is the main and only needed source using v8::String; using v8::Value; + // This is the implementation of the "add" method + // Input arguments are passed using the + // const FunctionCallbackInfo& args struct void Add(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); + // Check the number of arguments passed. if (args.Length() < 2) { + // Throw an Error that is passed back to JavaScript isolate->ThrowException(Exception::TypeError( String::NewFromUtf8(isolate, "Wrong number of arguments"))); return; } + // Check the argument types if (!args[0]->IsNumber() || !args[1]->IsNumber()) { isolate->ThrowException(Exception::TypeError( String::NewFromUtf8(isolate, "Wrong arguments"))); return; } + // Perform the operation double value = args[0]->NumberValue() + args[1]->NumberValue(); Local num = Number::New(isolate, value); + // Set the return value (using the passed in + // FunctionCallbackInfo&) args.GetReturnValue().Set(num); } @@ -186,18 +291,19 @@ function calls and return a result. This is the main and only needed source } // namespace demo -You can test it with the following JavaScript snippet: +Once compiled, the example Addon can be required and used from within Node.js: // test.js - var addon = require('./build/Release/addon'); + const addon = require('./build/Release/addon'); console.log( 'This should be eight:', addon.add(3,5) ); ### Callbacks -You can pass JavaScript functions to a C++ function and execute them from -there. Here's `addon.cc`: +It is common practice within Addons to pass JavaScript functions to a C++ +function and execute them from there. The following example illustrates how +to invoke such callbacks: // addon.cc #include @@ -230,25 +336,26 @@ there. Here's `addon.cc`: } // namespace demo Note that this example uses a two-argument form of `Init()` that receives -the full `module` object as the second argument. This allows the addon +the full `module` object as the second argument. This allows the Addon to completely overwrite `exports` with a single function instead of adding the function as a property of `exports`. -To test it, run the following JavaScript snippet: +To test it, run the following JavaScript: // test.js - var addon = require('./build/Release/addon'); + const addon = require('./build/Release/addon'); addon(function(msg){ console.log(msg); // 'hello world' }); +Note that, in this example, the callback function is invoked synchronously. ### Object factory -You can create and return new objects from within a C++ function with this -`addon.cc` pattern, which returns an object with property `msg` that echoes -the string passed to `createObject()`: +Addons can create and return new objects from within a C++ function as +illustrated in the following example. An object is created and returned with a +property `msg` that echoes the string passed to `createObject()`: // addon.cc #include @@ -282,7 +389,7 @@ the string passed to `createObject()`: To test it in JavaScript: // test.js - var addon = require('./build/Release/addon'); + const addon = require('./build/Release/addon'); var obj1 = addon('hello'); var obj2 = addon('world'); @@ -291,8 +398,8 @@ To test it in JavaScript: ### Function factory -This pattern illustrates how to create and return a JavaScript function that -wraps a C++ function: +Another common scenario is creating JavaScript functions that wrap C++ +functions and returning those back to JavaScript: // addon.cc #include @@ -336,7 +443,7 @@ wraps a C++ function: To test: // test.js - var addon = require('./build/Release/addon'); + const addon = require('./build/Release/addon'); var fn = addon(); console.log(fn()); // 'hello world' @@ -344,9 +451,8 @@ To test: ### Wrapping C++ objects -Here, we will create a wrapper for a C++ object/class `MyObject` that can be -instantiated in JavaScript through the `new` operator. First, prepare the main -module `addon.cc`: +It is also possible to wrap C++ objects/classes in a way that allows new +instances to be created using the JavaScript `new` operator: // addon.cc #include @@ -365,7 +471,7 @@ module `addon.cc`: } // namespace demo -Then, in `myobject.h`, make your wrapper inherit from `node::ObjectWrap`: +Then, in `myobject.h`, the wrapper class inherits from `node::ObjectWrap`: // myobject.h #ifndef MYOBJECT_H @@ -394,8 +500,8 @@ Then, in `myobject.h`, make your wrapper inherit from `node::ObjectWrap`: #endif -And in `myobject.cc`, implement the various methods that you want to expose. -Here we expose the method `plusOne` by adding it to the constructor's +In `myobject.cc`, implement the various methods that are to be exposed. +Below, the method `plusOne()` is exposed by adding it to the constructor's prototype: // myobject.cc @@ -467,10 +573,25 @@ prototype: } // namespace demo +To build this example, the `myobject.cc` file must be added to the +`binding.gyp`: + + { + "targets": [ + { + "target_name": "addon", + "sources": [ + "addon.cc", + "myobject.cc" + ] + } + ] + } + Test it with: // test.js - var addon = require('./build/Release/addon'); + const addon = require('./build/Release/addon'); var obj = new addon.MyObject(10); console.log( obj.plusOne() ); // 11 @@ -479,15 +600,14 @@ Test it with: ### Factory of wrapped objects -This is useful when you want to be able to create native objects without -explicitly instantiating them with the `new` operator in JavaScript. For -example: +Alternatively, it is possible to use a factory pattern to avoid explicitly +creating object instances using the JavaScript `new` operator: var obj = addon.createObject(); // instead of: // var obj = new addon.Object(); -Let's register our `createObject` method in `addon.cc`: +First, the `createObject()` method is implemented in `addon.cc`: // addon.cc #include @@ -516,8 +636,8 @@ Let's register our `createObject` method in `addon.cc`: } // namespace demo -In `myobject.h`, we now introduce the static method `NewInstance` that takes -care of instantiating the object. In other words, it does the job of `new` in +In `myobject.h`, the static method `NewInstance()` is added to handle +instantiating the object. This method takes the place of using `new` in JavaScript: // myobject.h @@ -548,7 +668,7 @@ JavaScript: #endif -The implementation is similar to the above in `myobject.cc`: +The implementation in `myobject.cc` is similar to the previous example: // myobject.cc #include @@ -627,10 +747,25 @@ The implementation is similar to the above in `myobject.cc`: } // namespace demo +Once again, to build this example, the `myobject.cc` file must be added to the +`binding.gyp`: + + { + "targets": [ + { + "target_name": "addon", + "sources": [ + "addon.cc", + "myobject.cc" + ] + } + ] + } + Test it with: // test.js - var createObject = require('./build/Release/addon'); + const createObject = require('./build/Release/addon'); var obj = createObject(10); console.log( obj.plusOne() ); // 11 @@ -645,10 +780,10 @@ Test it with: ### Passing wrapped objects around -In addition to wrapping and returning C++ objects, you can pass them around -by unwrapping them with the Node.js helper function `node::ObjectWrap::Unwrap`. -In the following `addon.cc`, we introduce a function `add()` that can take on -two `MyObject` objects: +In addition to wrapping and returning C++ objects, it is possible to pass +wrapped objects around by unwrapping them with the Node.js helper function +`node::ObjectWrap::Unwrap`. The following examples shows a function `add()` +that can take two `MyObject` objects as input arguments: // addon.cc #include @@ -692,8 +827,8 @@ two `MyObject` objects: } // namespace demo -To make things interesting, we introduce a public method in `myobject.h` so we -can probe private values after unwrapping the object: +In `myobject.h`, a new public method is added to allow access to private values +after unwrapping the object. // myobject.h #ifndef MYOBJECT_H @@ -792,7 +927,7 @@ The implementation of `myobject.cc` is similar to before: Test it with: // test.js - var addon = require('./build/Release/addon'); + const addon = require('./build/Release/addon'); var obj1 = addon.createObject(10); var obj2 = addon.createObject(20); @@ -801,6 +936,11 @@ Test it with: console.log(result); // 30 ### AtExit hooks + +An "AtExit" hook is a function that is invoked after the Node.js event loop +has ended by before the JavaScript VM is terminated and Node.js shuts down. +"AtExit" hooks are registered using the `node::AtExit` API. + #### void AtExit(callback, args) * `callback`: `void (*)(void*)` - A pointer to the function to call at exit. @@ -809,11 +949,12 @@ Test it with: Registers exit hooks that run after the event loop has ended but before the VM is killed. -Callbacks are run in last-in first-out order. AtExit takes two parameters: -a pointer to a callback function to run at exit, and a pointer to untyped -context data to be passed to that callback. +AtExit takes two parameters: a pointer to a callback function to run at exit, +and a pointer to untyped context data to be passed to that callback. + +Callbacks are run in last-in first-out order. -The file `addon.cc` implements AtExit below: +The following `addon.cc` implements AtExit: // addon.cc #undef NDEBUG @@ -866,11 +1007,16 @@ The file `addon.cc` implements AtExit below: Test in JavaScript by running: // test.js - var addon = require('./build/Release/addon'); + const addon = require('./build/Release/addon'); [online]: https://v8docs.nodesource.com/ [libuv]: https://github.com/libuv/libuv -[download]: https://github.com/rvagg/node-addon-examples +[download]: https://github.com/nodejs/node-addon-examples [node-gyp]: https://github.com/nodejs/node-gyp -[v8 reference]: http://izs.me/v8-docs/main.html -[Embedder's Guide]: https://code.google.com/apis/v8/embed.html +[V8 reference]: https://v8docs.nodesource.com/ +[Embedder's Guide]: https://developers.google.com/v8/embed +[Native Abstrations for Node.js]: https://github.com/nodejs/nan +[examples]: https://github.com/nodejs/nan/tree/master/examples/ +[bindings]: https://github.com/TooTallNate/node-bindings +[Linking to Node.js' own dependencies]: #linking-to-node-js-own-dependencies +[installation instructions]: https://github.com/nodejs/node-gyp#installation diff --git a/doc/api/assert.markdown b/doc/api/assert.markdown index a3fb229161b3..bab280f325ff 100644 --- a/doc/api/assert.markdown +++ b/doc/api/assert.markdown @@ -2,107 +2,333 @@ Stability: 3 - Locked -This module is used so that Node.js can test itself. It can be accessed with -`require('assert')`. However, it is recommended that a userland assertion -library be used instead. +The `assert` module provides a simple set of assertion tests that can be used +to test invariants and implement unit tests. While the `assert` module is +generally intended for internal use by Node.js itself, it can be used by user +code calling `require('assert')`. + +The API for the `assert` module is [Locked][]. This means that there will be no +additions or changes to any of the methods implemented and exposed by +the module. ## assert(value[, message]), assert.ok(value[, message]) -Tests if value is truthy. It is equivalent to +Tests if `value` is truthy. It is equivalent to `assert.equal(!!value, true, message)`. +If `value` is not truthy, an `AssertionError` is thrown with a `message` +property set equal to the value of the `message` parameter. If the `message` +parameter is `undefined`, a default error message is assigned. + + const assert = require('assert'); + + assert(true); // OK + assert(1); // OK + assert(false); + // throws "AssertionError: false == true" + assert(0); + // throws "AssertionError: 0 == true" + assert(false, 'it\'s false'); + // throws "AssertionError: it's false" + + assert.ok(true); // OK + assert.ok(1); // OK + assert.ok(false); + // throws "AssertionError: false == true" + assert.ok(0); + // throws "AssertionError: 0 == true" + assert.ok(false, 'it\'s false'); + // throws "AssertionError: it's false" + ## assert.deepEqual(actual, expected[, message]) -Tests for deep equality. Primitive values are compared with the equal -comparison operator ( `==` ). +Tests for deep equality between the `actual` and `expected` parameters. +Primitive values are compared with the equal comparison operator ( `==` ). -This only considers enumerable properties. It does not test object prototypes, -attached symbols, or non-enumerable properties. This can lead to some -potentially surprising results. For example, this does not throw an -`AssertionError` because the properties on the [`Error`][] object are -non-enumerable: +Only enumerable "own" properties are considered. The `deepEqual()` +implementation does not test object prototypes, attached symbols, or +non-enumerable properties. This can lead to some potentially surprising +results. For example, the following example does not throw an `AssertionError` +because the properties on the [`Error`][] object are non-enumerable: // WARNING: This does not throw an AssertionError! assert.deepEqual(Error('a'), Error('b')); +"Deep" equality means that the enumerable "own" properties of child objects +are evaluated also: + + const assert = require('assert'); + + const obj1 = { + a : { + b : 1 + } + }; + const obj2 = { + a : { + b : 2 + } + }; + const obj3 = { + a : { + b : 1 + } + } + const obj4 = Object.create(obj1); + + assert.deepEqual(obj1, obj1); + // OK, object is equal to itself + + assert.deepEqual(obj1, obj2); + // AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } } + // values of b are different + + assert.deepEqual(obj1, obj3); + // OK, objects are equal + + assert.deepEqual(obj1, obj4); + // AssertionError: { a: { b: 1 } } deepEqual {} + // Prototypes are ignored + +If the values are not equal, an `AssertionError` is thrown with a `message` +property set equal to the value of the `message` parameter. If the `message` +parameter is undefined, a default error message is assigned. + ## assert.deepStrictEqual(actual, expected[, message]) -Tests for deep equality. Primitive values are compared with the strict equality -operator ( `===` ). +Generally identical to `assert.deepEqual` with the exception that primitive +values are compared using the strict equality operator ( `===` ). + + const assert = require('assert'); + + assert.deepEqual({a:1}, {a:'1'}); + // OK, because 1 == '1' + + assert.deepStrictEqual({a:1}, {a:'1'}); + // AssertionError: { a: 1 } deepStrictEqual { a: '1' } + // because 1 !== '1' using strict equality + +If the values are not equal, an `AssertionError` is thrown with a `message` +property set equal to the value of the `message` parameter. If the `message` +parameter is undefined, a default error message is assigned. ## assert.doesNotThrow(block[, error][, message]) -Expects `block` not to throw an error. See [`assert.throws()`][] for more details. +Asserts that the function `block` does not throw an error. See +[`assert.throws()`][] for more details. + +When `assert.doesNotThrow()` is called, it will immediately call the `block` +function. + +If an error is thrown and it is the same type as that specified by the `error` +parameter, then an `AssertionError` is thrown. If the error is of a different +type, or if the `error` parameter is undefined, the error is propagated back +to the caller. -If `block` throws an error and if it is of a different type from `error`, the -thrown error will get propagated back to the caller. The following call will -throw the [`TypeError`][], since we're not matching the error types in the -assertion. +The following, for instance, will throw the [`TypeError`][] because there is no +matching error type in the assertion: assert.doesNotThrow( function() { - throw new TypeError("Wrong value"); + throw new TypeError('Wrong value'); }, SyntaxError ); -In case `error` matches with the error thrown by `block`, an `AssertionError` -is thrown instead. +However, the following will result in an `AssertionError` with the message +'Got unwanted exception (TypeError)..': assert.doesNotThrow( function() { - throw new TypeError("Wrong value"); + throw new TypeError('Wrong value'); }, TypeError ); +If an `AssertionError` is thrown and a value is provided for the `message` +parameter, the value of `message` will be appended to the `AssertionError` +message: + + assert.doesNotThrow( + function() { + throw new TypeError('Wrong value'); + }, + TypeError, + 'Whoops' + ); + // Throws: AssertionError: Got unwanted exception (TypeError). Whoops + ## assert.equal(actual, expected[, message]) -Tests shallow, coercive equality with the equal comparison operator ( `==` ). +Tests shallow, coercive equality between the `actual` and `expected` parameters +using the equal comparison operator ( `==` ). + + const assert = require('assert'); + + assert.equal(1, 1); + // OK, 1 == 1 + assert.equal(1, '1'); + // OK, 1 == '1' + + assert.equal(1, 2); + // AssertionError: 1 == 2 + assert.equal({a: {b: 1}}, {a: {b: 1}}); + //AssertionError: { a: { b: 1 } } == { a: { b: 1 } } + +If the values are not equal, an `AssertionError` is thrown with a `message` +property set equal to the value of the `message` parameter. If the `message` +parameter is undefined, a default error message is assigned. ## assert.fail(actual, expected, message, operator) -Throws an `AssertionError`. If `message` is falsy, it displays the values for -`actual` and `expected` separated by the provided `operator`. Otherwise, it -displays `message` (and does not use `actual`, `expected`, and `operator`). +Throws an `AssertionError`. If `message` is falsy, the error message is set as +the values of `actual` and `expected` separated by the provided `operator`. +Otherwise, the error message is the value of `message`. + + const assert = require('assert'); + + assert.fail(1, 2, undefined, '>'); + // AssertionError: 1 > 2 + + assert.fail(1, 2, 'whoops', '>'); + // AssertionError: whoops ## assert.ifError(value) Throws `value` if `value` is truthy. This is useful when testing the `error` argument in callbacks. + const assert = require('assert'); + + assert.ifError(0); // OK + assert.ifError(1); // Throws 1 + assert.ifError('error') // Throws 'error' + assert.ifError(new Error()); // Throws Error + ## assert.notDeepEqual(actual, expected[, message]) Tests for any deep inequality. Opposite of [`assert.deepEqual`][]. + const assert = require('assert'); + + const obj1 = { + a : { + b : 1 + } + }; + const obj2 = { + a : { + b : 2 + } + }; + const obj3 = { + a : { + b : 1 + } + } + const obj4 = Object.create(obj1); + + assert.deepEqual(obj1, obj1); + AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } + + assert.deepEqual(obj1, obj2); + // OK, obj1 and obj2 are not deeply equal + + assert.deepEqual(obj1, obj3); + // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } + + assert.deepEqual(obj1, obj4); + // OK, obj1 and obj2 are not deeply equal + +If the values are deeply equal, an `AssertionError` is thrown with a `message` +property set equal to the value of the `message` parameter. If the `message` +parameter is undefined, a default error message is assigned. + ## assert.notDeepStrictEqual(actual, expected[, message]) -Tests for deep inequality. Opposite of [`assert.deepStrictEqual`][]. +Tests for deep strict inequality. Opposite of [`assert.deepStrictEqual`][]. + + const assert = require('assert'); + + assert.notDeepEqual({a:1}, {a:'1'}); + // AssertionError: { a: 1 } notDeepEqual { a: '1' } + + assert.notDeepStrictEqual({a:1}, {a:'1'}); + // OK + +If the values are deeply and strictly equal, an `AssertionError` is thrown +with a `message` property set equal to the value of the `message` parameter. If +the `message` parameter is undefined, a default error message is assigned. ## assert.notEqual(actual, expected[, message]) Tests shallow, coercive inequality with the not equal comparison operator ( `!=` ). + const assert = require('assert'); + + assert.notEqual(1, 2); + // OK + + assert.notEqual(1, 1); + // AssertionError: 1 != 1 + + assert.notEqual(1, '1'); + // AssertionError: 1 != '1' + +If the values are equal, an `AssertionError` is thrown with a `message` +property set equal to the value of the `message` parameter. If the `message` +parameter is undefined, a default error message is assigned. + ## assert.notStrictEqual(actual, expected[, message]) Tests strict inequality as determined by the strict not equal operator ( `!==` ). + const assert = require('assert'); + + assert.notStrictEqual(1, 2); + // OK + + assert.notStrictEqual(1, 1); + // AssertionError: 1 != 1 + + assert.notStrictEqual(1, '1'); + // OK + +If the values are strictly equal, an `AssertionError` is thrown with a +`message` property set equal to the value of the `message` parameter. If the +`message` parameter is undefined, a default error message is assigned. + ## assert.strictEqual(actual, expected[, message]) Tests strict equality as determined by the strict equality operator ( `===` ). + const assert = require('assert'); + + assert.strictEqual(1, 2); + // AssertionError: 1 === 2 + + assert.strictEqual(1, 1); + // OK + + assert.strictEqual(1, '1'); + // AssertionError: 1 === '1' + +If the values are not strictly equal, an `AssertionError` is thrown with a +`message` property set equal to the value of the `message` parameter. If the +`message` parameter is undefined, a default error message is assigned. + ## assert.throws(block[, error][, message]) -Expects `block` to throw an error. `error` can be a constructor, [`RegExp`][], or -validation function. +Expects the function `block` to throw an error. If specified, `error` can be a +constructor, [`RegExp`][], or validation function. Validate instanceof using constructor: assert.throws( function() { - throw new Error("Wrong value"); + throw new Error('Wrong value'); }, Error ); @@ -111,7 +337,7 @@ Validate error message using [`RegExp`][]: assert.throws( function() { - throw new Error("Wrong value"); + throw new Error('Wrong value'); }, /value/ ); @@ -120,19 +346,20 @@ Custom error validation: assert.throws( function() { - throw new Error("Wrong value"); + throw new Error('Wrong value'); }, function(err) { if ( (err instanceof Error) && /value/.test(err) ) { return true; } }, - "unexpected error" + 'unexpected error' ); +[Locked]: documentation.html#documentation_stability_index [`assert.deepEqual`]: #assert_assert_deepequal_actual_expected_message [`assert.deepStrictEqual`]: #assert_assert_deepstrictequal_actual_expected_message [`assert.throws()`]: #assert_assert_throws_block_error_message [`Error`]: errors.html#errors_class_error [`RegExp`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions -[`TypeError`]: errors.html#errors_class_typeerror \ No newline at end of file +[`TypeError`]: errors.html#errors_class_typeerror diff --git a/doc/api/buffer.markdown b/doc/api/buffer.markdown index 9fd570408164..090a3eef51ac 100644 --- a/doc/api/buffer.markdown +++ b/doc/api/buffer.markdown @@ -2,20 +2,50 @@ Stability: 2 - Stable -Pure JavaScript is Unicode-friendly but not nice to binary data. When -dealing with TCP streams or the file system, it's necessary to handle octet -streams. Node.js has several strategies for manipulating, creating, and -consuming octet streams. +Prior to the introduction of `TypedArray` in ECMAScript 2015 (ES6), the +JavaScript language had no mechanism for reading or manipulating streams +of binary data. The `Buffer` class was introduced as part of the Node.js +API to make it possible to interact with octet streams in the context of things +like TCP streams and file system operations. -Raw data is stored in instances of the `Buffer` class. A `Buffer` is similar -to an array of integers but corresponds to a raw memory allocation outside -the V8 heap. A `Buffer` cannot be resized. +Now that `TypedArray` has been added in ES6, the `Buffer` class implements the +`Uint8Array` API in a manner that is more optimized and suitable for Node.js' +use cases. -The `Buffer` class is a global, making it very rare that one would need -to ever `require('buffer')`. +Instances of the `Buffer` class are similar to arrays of integers but +correspond to fixed-sized, raw memory allocations outside the V8 heap. +The size of the `Buffer` is established when it is created and cannot be +resized. -Converting between Buffers and JavaScript string objects requires an explicit -encoding method. The different string encodings are: +The `Buffer` class is a global within Node.js, making it unlikely that one +would need to ever use `require('buffer')`. + + const buf1 = new Buffer(10); + // creates a buffer of length 10 + + const buf2 = new Buffer([1,2,3]); + // creates a buffer containing [01, 02, 03] + + const buf3 = new Buffer('test'); + // creates a buffer containing ASCII bytes [74, 65, 73, 74] + + const buf4 = new Buffer('tést', 'utf8'); + // creates a buffer containing UTF8 bytes [74, c3, a9, 73, 74] + +## Buffers and Character Encodings + +Buffers are commonly used to represent sequences of encoded characters +such as UTF8, UCS2, Base64 or even Hex-encoded data. It is possible to +convert back and forth between Buffers and ordinary JavaScript string objects +by using an explicit encoding method. + + const buf = new Buffer('hello world', 'ascii'); + console.log(buf.toString('hex')); + // prints: 68656c6c6f20776f726c64 + console.log(buf.toString('base64')); + // prints: aGVsbG8gd29ybGQ= + +The character encodings currently supported by Node.js include: * `'ascii'` - for 7-bit ASCII data only. This encoding method is very fast and will strip the high bit if set. @@ -36,21 +66,72 @@ encoding method. The different string encodings are: * `'hex'` - Encode each byte as two hexadecimal characters. -Creating a typed array from a `Buffer` works with the following caveats: +## Buffers and TypedArray -1. The buffer's memory is copied, not shared. +Buffers are also `Uint8Array` TypedArray instances. However, there are subtle +incompatibilities with the TypedArray specification in ECMAScript 2015. For +instance, while `ArrayBuffer#slice()` creates a copy of the slice, +the implementation of [`Buffer#slice()`][] creates a view over the existing +Buffer without copying, making `Buffer#slice()` far more efficient. -2. The buffer's memory is interpreted as an array, not a byte array. That is, - `new Uint32Array(new Buffer([1,2,3,4]))` creates a 4-element `Uint32Array` +It is also possible to create new TypedArray instances from a `Buffer` with the +following caveats: + +1. The Buffer instances's memory is copied to the TypedArray, not shared. + +2. The Buffer's memory is interpreted as an array of distinct elements, and not +as a byte array of the target type. That is, +`new Uint32Array(new Buffer([1,2,3,4]))` creates a 4-element `Uint32Array` with elements `[1,2,3,4]`, not a `Uint32Array` with a single element `[0x1020304]` or `[0x4030201]`. -NOTE: Node.js v0.8 retained a reference to the buffer in `array.buffer` instead -of cloning it. +It is possible to create a new Buffer that shares the same allocated memory as +a TypedArray instance by using the TypeArray objects `.buffer` property: + + const arr = new Uint16Array(2); + arr[0] = 5000; + arr[1] = 4000; + + const buf1 = new Buffer(arr); // copies the buffer + const buf2 = new Buffer(arr.buffer); // shares the memory with arr; -While more efficient, it introduces subtle incompatibilities with the typed -arrays specification. `ArrayBuffer#slice()` makes a copy of the slice while -[`Buffer#slice()`][] creates a view. + console.log(buf1); + // Prints: , copied buffer has only two elements + console.log(buf2); + // Prints: + + arr[1] = 6000; + console.log(buf1); + // Prints: + console.log(buf2); + // Prints: + +Note that when creating a Buffer using the TypeArray's `.buffer`, it is not +currently possible to use only a portion of the underlying `ArrayBuffer`. To +create a Buffer that uses only a part of the `ArrayBuffer`, use the +`buf.slice()` function after the Buffer is created: + + const arr = new Uint16Array(20); + const buf = new Buffer(arr.buffer).slice(0, 16); + console.log(buf.length); + // Prints: 16 + +## Buffers and ES6 iteration + +Buffers can be iterated over using the ECMAScript 2015 (ES6) `for..of` syntax: + + const buf = new Buffer([1, 2, 3]); + + for (var b of buf) + console.log(b) + + // Prints: + // 1 + // 2 + // 3 + +Additionally, the `buffer.values()`, `buffer.keys()`, and `buffer.entries()` +methods can be used to create iterators. ## Class: Buffer @@ -61,7 +142,11 @@ It can be constructed in a variety of ways. * `array` Array -Allocates a new buffer using an `array` of octets. +Allocates a new Buffer using an `array` of octets. + + const buf = new Buffer([0x62,0x75,0x66,0x66,0x65,0x72]); + // creates a new Buffer containing ASCII bytes + // ['b','u','f','f','e','r'] ### new Buffer(buffer) @@ -69,26 +154,80 @@ Allocates a new buffer using an `array` of octets. Copies the passed `buffer` data onto a new `Buffer` instance. + const buf1 = new Buffer('buffer'); + const buf2 = new Buffer(buf1); + + buf1[0] = 0x61; + console.log(buf1.toString()); + // 'auffer' + console.log(buf2.toString()); + // 'buffer' (copy is not changed) + +### new Buffer(arrayBuffer) + +* `arrayBuffer` - The `.buffer` property of a `TypedArray` or a `new + ArrayBuffer()` + +When passed a reference to the `.buffer` property of a `TypedArray` instance, +the newly created Buffer will share the same allocated memory as the +TypedArray. + + const arr = new Uint16Array(2); + arr[0] = 5000; + arr[1] = 4000; + + const buf = new Buffer(arr.buffer); // shares the memory with arr; + + console.log(buf); + // Prints: + + // changing the TypdArray changes the Buffer also + arr[1] = 6000; + + console.log(buf); + // Prints: + ### new Buffer(size) * `size` Number -Allocates a new buffer of `size` bytes. `size` must be less than -1,073,741,824 bytes (1 GB) on 32-bit architectures or -2,147,483,648 bytes (2 GB) on 64-bit architectures. -Otherwise, a [`RangeError`][] is thrown. +Allocates a new Buffer of `size` bytes. The `size` must be less than +or equal to the value of `require('buffer').kMaxLength` (on 64-bit +architectures, `kMaxLength` is `(2^31)-1`). Otherwise, a [`RangeError`][] is +thrown. If a `size` less than 0 is specified, a zero-length Buffer will be +created. -Unlike `ArrayBuffers`, the underlying memory for buffers is not initialized. So -the contents of a newly created `Buffer` are unknown and could contain -sensitive data. Use [`buf.fill(0)`][] to initialize a buffer to zeroes. +Unlike `ArrayBuffers`, the underlying memory for Buffer instances created in +this way is not initialized. The contents of a newly created `Buffer` are +unknown and could contain sensitive data. Use [`buf.fill(0)`][] to initialize a +Buffer to zeroes. + + const buf = new Buffer(5); + console.log(buf); + // + // (octets will be different, every time) + buf.fill(0); + console.log(buf); + // ### new Buffer(str[, encoding]) * `str` String - string to encode. * `encoding` String - encoding to use, Optional. -Allocates a new buffer containing the given `str`. -`encoding` defaults to `'utf8'`. +Creates a new Buffer containing the given JavaScript string `str`. If +provided, the `encoding` parameter identifies the strings character encoding. +If not provided, `encoding` defaults to `'utf8'`. + + const buf1 = new Buffer('this is a tést'); + console.log(buf1.toString()); + // prints: this is a tést + console.log(buf1.toString('ascii')); + // prints: this is a tC)st + + const buf2 = new Buffer('7468697320697320612074c3a97374', 'hex'); + console.log(buf2.toString()); + // prints: this is a tést ### Class Method: Buffer.byteLength(string[, encoding]) @@ -96,16 +235,16 @@ Allocates a new buffer containing the given `str`. * `encoding` String, Optional, Default: 'utf8' * Return: Number -Gives the actual byte length of a string. `encoding` defaults to `'utf8'`. -This is not the same as [`String.prototype.length`][] since that returns the -number of *characters* in a string. +Returns the actual byte length of a string. If not specified, `encoding` +defaults to `'utf8'`. This is not the same as [`String.prototype.length`][] +since that returns the number of *characters* in a string. Example: - str = '\u00bd + \u00bc = \u00be'; + const str = '\u00bd + \u00bc = \u00be'; - console.log(str + ": " + str.length + " characters, " + - Buffer.byteLength(str, 'utf8') + " bytes"); + console.log(`${str}: ${str.length} characters, ` + + `${Buffer.byteLength(str, 'utf8')} bytes`); // ½ + ¼ = ¾: 9 characters, 12 bytes @@ -114,45 +253,36 @@ Example: * `buf1` {Buffer} * `buf2` {Buffer} -The same as [`buf1.compare(buf2)`][]. Useful for sorting an Array of Buffers: +Compares `buf1` to `buf2` typically for the purpose of sorting arrays of +Buffers. This is equivalent is calling `buf1.compare(buf2)`. - var arr = [Buffer('1234'), Buffer('0123')]; + const arr = [Buffer('1234'), Buffer('0123')]; arr.sort(Buffer.compare); ### Class Method: Buffer.concat(list[, totalLength]) * `list` {Array} List of Buffer objects to concat -* `totalLength` {Number} Total length of the buffers in the list when concatenated +* `totalLength` {Number} Total length of the Buffers in the list when concatenated -Returns a buffer which is the result of concatenating all the buffers in -the list together. +Returns a new Buffer which is the result of concatenating all the Buffers in +the `list` together. -If the list has no items, or if the totalLength is 0, then it returns a -zero-length buffer. +If the list has no items, or if the `totalLength` is 0, then a new zero-length +Buffer is returned. -If totalLength is not provided, it is read from the buffers in the list. -However, this adds an additional loop to the function, so it is faster +If `totalLength` is not provided, it is calculated from the Buffers in the +`list`. This, however, adds an additional loop to the function, so it is faster to provide the length explicitly. -Example: build a single buffer from a list of three buffers: - - var buf1 = new Buffer(10); - var buf2 = new Buffer(14); - var buf3 = new Buffer(18); - - buf1.fill(0); - buf2.fill(0); - buf3.fill(0); +Example: build a single Buffer from a list of three Buffers: - var buffers = [buf1, buf2, buf3]; - - var totalLength = 0; - for (var i = 0; i < buffers.length; i++) { - totalLength += buffers[i].length; - } + const buf1 = new Buffer(10).fill(0); + const buf2 = new Buffer(14).fill(0); + const buf3 = new Buffer(18).fill(0); + const totalLength = buf1.length + buf2.length + buf3.length; console.log(totalLength); - var bufA = Buffer.concat(buffers, totalLength); + const bufA = Buffer.concat([buf1, buf2, buf3], totalLength); console.log(bufA); console.log(bufA.length); @@ -165,7 +295,7 @@ Example: build a single buffer from a list of three buffers: * `obj` Object * Return: Boolean -Tests if `obj` is a `Buffer`. +Returns 'true' if `obj` is a Buffer. ### Class Method: Buffer.isEncoding(encoding) @@ -176,45 +306,117 @@ otherwise. ### buffer.entries() -Creates iterator for `[index, byte]` arrays. +Creates and returns an [iterator][] of `[index, byte]` pairs from the Buffer +contents. + + const buf = new Buffer('buffer'); + for (var pair of buf.entries()) { + console.log(pair); + } + // prints: + // [0, 98] + // [1, 117] + // [2, 102] + // [3, 102] + // [4, 101] + // [5, 114] ### buffer.keys() -Creates iterator for buffer keys (indices). +Creates and returns an [iterator][] of Buffer keys (indices). + + const buf = new Buffer('buffer'); + for (var key of buf.keys()) { + console.log(key); + } + // prints: + // 0 + // 1 + // 2 + // 3 + // 4 + // 5 ### buffer.values() -Creates iterator for buffer values (bytes). This function is called automatically -when `buffer` is used in a `for..of` statement. +Creates and returns an [iterator][] for Buffer values (bytes). This function is +called automatically when the Buffer is used in a `for..of` statement. + + const buf = new Buffer('buffer'); + for (var value of buf.values()) { + console.log(value); + } + // prints: + // 98 + // 117 + // 102 + // 102 + // 101 + // 114 + + for (var value of buf) { + console.log(value); + } + // prints: + // 98 + // 117 + // 102 + // 102 + // 101 + // 114 ### buf[index] -Get and set the octet at `index`. The values refer to individual bytes, -so the legal range is between `0x00` and `0xFF` hex or `0` and `255`. +The index operator `[index]` can be used to get and set the octet at position +`index` in the Buffer. The values refer to individual bytes, so the legal value +range is between `0x00` and `0xFF` (hex) or `0` and `255` (decimal). -Example: copy an ASCII string into a buffer, one byte at a time: +Example: copy an ASCII string into a Buffer, one byte at a time: - str = "Node.js"; - buf = new Buffer(str.length); + const str = "Node.js"; + const buf = new Buffer(str.length); for (var i = 0; i < str.length ; i++) { buf[i] = str.charCodeAt(i); } console.log(buf); - - // Node.js + // Prints: Node.js ### buf.compare(otherBuffer) * `otherBuffer` {Buffer} -Returns a number indicating whether `this` comes before, after, or is -the same as the `otherBuffer` in sort order. - +Compares two Buffer instances and returns a number indicating whether `buf` +comes before, after, or is the same as the `otherBuffer` in sort order. +Comparison is based on the actual sequence of bytes in each Buffer. + +* `0` is returned if `otherBuffer` is the same as `buf` +* `1` is returned if `otherBuffer` should come *before* `buf` when sorted. +* `-1` is returned if `otherBuffer` should come *after* `buf` when sorted. + +``` +const buf1 = new Buffer('ABC'); +const buf2 = new Buffer('BCD'); +const buf3 = new Buffer('ABCD'); + +console.log(buf1.compare(buf1)); + // Prints: 0 +console.log(buf1.compare(buf2)); + // Prints: -1 +console.log(buf1.compare(buf3)); + // Prints: 1 +console.log(buf2.compare(buf1)); + // Prints: 1 +console.log(buf2.compare(buf3)); + // Prints: 1 + +[buf1, buf2, buf3].sort(Buffer.compare); + // produces sort order [buf1, buf3, buf2] +``` ### buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd]) @@ -223,7 +425,7 @@ the same as the `otherBuffer` in sort order. * `sourceStart` Number, Optional, Default: 0 * `sourceEnd` Number, Optional, Default: `buffer.length` -Copies data from a region of this buffer to a region in the target buffer even +Copies data from a region of this Buffer to a region in the target Buffer even if the target memory region overlaps with the source. If `undefined`, the `targetStart` and `sourceStart` parameters default to `0` while `sourceEnd` defaults to `buffer.length`. @@ -233,23 +435,21 @@ Returns the number of bytes copied. Example: build two Buffers, then copy `buf1` from byte 16 through byte 19 into `buf2`, starting at the 8th byte in `buf2`. - buf1 = new Buffer(26); - buf2 = new Buffer(26); + const buf1 = new Buffer(26); + const buf2 = new Buffer(26).fill('!'); for (var i = 0 ; i < 26 ; i++) { buf1[i] = i + 97; // 97 is ASCII a - buf2[i] = 33; // ASCII ! } buf1.copy(buf2, 8, 16, 20); console.log(buf2.toString('ascii', 0, 25)); + // Prints: !!!!!!!!qrst!!!!!!!!!!!!! - // !!!!!!!!qrst!!!!!!!!!!!!! - -Example: Build a single buffer, then copy data from one region to an overlapping -region in the same buffer +Example: Build a single Buffer, then copy data from one region to an overlapping +region in the same Buffer - buf = new Buffer(26); + const buf = new Buffer(26); for (var i = 0 ; i < 26 ; i++) { buf[i] = i + 97; // 97 is ASCII a @@ -264,7 +464,17 @@ region in the same buffer * `otherBuffer` {Buffer} -Returns a boolean indicating whether `this` and `otherBuffer` have the same bytes. +Returns a boolean indicating whether `this` and `otherBuffer` have exactly the +same bytes. + + const buf1 = new Buffer('ABC'); + const buf2 = new Buffer('414243', 'hex'); + const buf3 = new Buffer('ABCD'); + + console.log(buf1.equals(buf2)); + // Prints: true + console.log(buf1.equals(buf3)); + // Prints: false ### buf.fill(value[, offset][, end]) @@ -272,12 +482,13 @@ Returns a boolean indicating whether `this` and `otherBuffer` have the same byte * `offset` Number, Optional * `end` Number, Optional -Fills the buffer with the specified value. If the `offset` (defaults to `0`) +Fills the Buffer with the specified value. If the `offset` (defaults to `0`) and `end` (defaults to `buffer.length`) are not given it will fill the entire -buffer. +Buffer. The method returns a reference to the Buffer so calls can be chained. - var b = new Buffer(50); - b.fill("h"); + const b = new Buffer(50).fill('h'); + console.log(b.toString()); + // Prints: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh ### buf.indexOf(value[, byteOffset]) @@ -285,10 +496,26 @@ buffer. * `byteOffset` Number, Optional, Default: 0 * Return: Number -Operates similar to [`Array#indexOf()`][]. Accepts a String, Buffer or Number. -Strings are interpreted as UTF8. Buffers will use the entire buffer. So in order -to compare a partial Buffer use [`Buffer#slice()`][]. Numbers can range from 0 to -255. +Operates similar to [`Array#indexOf()`][] in that it returns either the +starting index position of `value` in Buffer or `-1` if the Buffer does not +contain `value`. The `value` can be a String, Buffer or Number. Strings are +interpreted as UTF8. Buffers will use the entire Buffer (to compare a partial +Buffer use [`Buffer#slice()`][]). Numbers can range from 0 to 255. + + const buf = new Buffer('this is a buffer'); + + buf.indexOf('this'); + // returns 0 + buf.indexOf('is'); + // returns 2 + buf.indexOf(new Buffer('a buffer')); + // returns 8 + buf.indexOf(97); // ascii for 'a' + // returns 8 + buf.indexOf(new Buffer('a buffer example')); + // returns -1 + buf.indexOf(new Buffer('a buffer example').slice(0,8)); + // returns 8 ### buf.includes(value[, byteOffset][, encoding]) @@ -296,40 +523,59 @@ to compare a partial Buffer use [`Buffer#slice()`][]. Numbers can range from 0 t * `byteOffset` Number, Optional, Default: 0 * `encoding` String, Optional, Default: 'utf8' -Operates similar to -[Array#includes()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes). -Accepts a String, Buffer or Number. Strings are interpreted as UTF8 unless -overridden with the `encoding` argument. Buffers will use the entire buffer. -So in order to compare a partial Buffer use `Buffer#slice()`. Numbers can range -from 0 to 255. +Operates similar to [Array#includes()][]. The `value` can be a String, Buffer +or Number. Strings are interpreted as UTF8 unless overridden with the +`encoding` argument. Buffers will use the entire Buffer (to compare a partial Buffer use `Buffer#slice()`). Numbers can range from 0 to 255. + +The `byteOffset` indicates the index in `buf` where searching begins. + + const buf = new Buffer('this is a buffer'); + + buf.includes('this'); + // returns true + buf.includes('is'); + // returns true + buf.includes(new Buffer('a buffer')); + // returns true + buf.includes(97); // ascii for 'a' + // returns true + buf.includes(new Buffer('a buffer example')); + // returns false + buf.includes(new Buffer('a buffer example').slice(0,8)); + // returns true + buf.includes('this', 4); + // returns false ### buf.length * Number -The size of the buffer in bytes. Note that this is not necessarily the size -of the contents. `length` refers to the amount of memory allocated for the -buffer object. It does not change when the contents of the buffer are changed. +Returns the amount of memory allocated for the Buffer in number of bytes. Note +that this does not necessarily reflect the amount of usable data within the +Buffer. For instance, in the example below, a Buffer with 1234 bytes is +allocated, but only 11 ASCII bytes are written. - buf = new Buffer(1234); + const buf = new Buffer(1234); console.log(buf.length); - buf.write("some string", 0, "ascii"); - console.log(buf.length); + // Prints: 1234 - // 1234 - // 1234 + buf.write('some string', 0, 'ascii'); + console.log(buf.length); + // Prints: 1234 While the `length` property is not immutable, changing the value of `length` can result in undefined and inconsistent behavior. Applications that wish to -modify the length of a buffer should therefore treat `length` as read-only and -use [`buf.slice`][] to create a new buffer. +modify the length of a Buffer should therefore treat `length` as read-only and +use [`buf.slice`][] to create a new Buffer. - buf = new Buffer(10); - buf.write("abcdefghj", 0, "ascii"); - console.log(buf.length); // 10 + const buf = new Buffer(10); + buf.write('abcdefghj', 0, 'ascii'); + console.log(buf.length); + // Prints: 10 buf = buf.slice(0,5); - console.log(buf.length); // 5 + console.log(buf.length); + // Prints: 5 ### buf.readDoubleBE(offset[, noAssert]) ### buf.readDoubleLE(offset[, noAssert]) @@ -338,28 +584,25 @@ use [`buf.slice`][] to create a new buffer. * `noAssert` Boolean, Optional, Default: false * Return: Number -Reads a 64-bit double from the buffer at the specified offset with specified -endian format. - -Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. Defaults to `false`. +Reads a 64-bit double from the Buffer at the specified `offset` with specified +endian format (`readDoubleBE()` returns big endian, `readDoubleLE()` returns +little endian). -Example: - - var buf = new Buffer(8); +Setting `noAssert` to `true` skips validation of the `offset`. This allows the +`offset` to be beyond the end of the Buffer. When not specified, `noAssert` +defaults to `false`. - buf[0] = 0x55; - buf[1] = 0x55; - buf[2] = 0x55; - buf[3] = 0x55; - buf[4] = 0x55; - buf[5] = 0x55; - buf[6] = 0xd5; - buf[7] = 0x3f; + const buf = new Buffer([1,2,3,4,5,6,7,8]); - console.log(buf.readDoubleLE(0)); + buf.readDoubleBE(); + // Returns: 8.20788039913184e-304 + buf.readDoubleLE(); + // Returns: 5.447603722011605e-270 + buf.readDoubleLE(1); + // throws RangeError: Index out of range - // 0.3333333333333333 + buf.readDoubleLE(1, true); // Warning: reads passed end of buffer! + // Segmentation fault! don't do this! ### buf.readFloatBE(offset[, noAssert]) ### buf.readFloatLE(offset[, noAssert]) @@ -368,24 +611,25 @@ Example: * `noAssert` Boolean, Optional, Default: false * Return: Number -Reads a 32-bit float from the buffer at the specified offset with specified -endian format. - -Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. Defaults to `false`. - -Example: +Reads a 32-bit float from the Buffer at the specified `offset` with specified +endian format (`readFloatBE()` returns big endian, `readFloatLE()` returns +little endian). - var buf = new Buffer(4); +Setting `noAssert` to `true` skips validation of the `offset`. This allows the +`offset` to be beyond the end of the Buffer. When not specified, `noAssert` +defaults to `false`. - buf[0] = 0x00; - buf[1] = 0x00; - buf[2] = 0x80; - buf[3] = 0x3f; + const buf = new Buffer([1,2,3,4]); - console.log(buf.readFloatLE(0)); + buf.readFloatBE(); + // Returns: 2.387939260590663e-38 + buf.readFloatLE(); + // Returns: 1.539989614439558e-36 + buf.readFloatLE(1); + // throws RangeError: Index out of range - // 0x01 + buf.readFloatLE(1, true); // Warning: reads passed end of buffer! + // Segmentation fault! don't do this! ### buf.readInt8(offset[, noAssert]) @@ -393,13 +637,20 @@ Example: * `noAssert` Boolean, Optional, Default: false * Return: Number -Reads a signed 8-bit integer from the buffer at the specified offset. +Reads a signed 8-bit integer from the Buffer at the specified `offset`. + +Setting `noAssert` to `true` skips validation of the `offset`. This allows the +`offset` to be beyond the end of the Buffer. When not specified, `noAssert` +defaults to `false`. -Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. Defaults to `false`. +Integers read from the Buffer are interpreted as two's complement signed values. -Works as `buffer.readUInt8`, except buffer contents are treated as two's -complement signed values. + const buf = new Buffer([1,-2,3,4]); + + buf.readInt8(0); + // returns 1 + buf.readInt8(1); + // returns -2 ### buf.readInt16BE(offset[, noAssert]) ### buf.readInt16LE(offset[, noAssert]) @@ -408,14 +659,22 @@ complement signed values. * `noAssert` Boolean, Optional, Default: false * Return: Number -Reads a signed 16-bit integer from the buffer at the specified offset with -specified endian format. +Reads a signed 16-bit integer from the Buffer at the specified `offset` with +the specified endian format (`readInt16BE()` returns big endian, +`readInt16LE()` returns little endian). + +Setting `noAssert` to `true` skips validation of the `offset`. This allows the +`offset` to be beyond the end of the Buffer. When not specified, `noAssert` +defaults to `false`. -Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. Defaults to `false`. +Integers read from the Buffer are interpreted as two's complement signed values. -Works as `buffer.readUInt16*`, except buffer contents are treated as two's -complement signed values. + const buf = new Buffer([1,-2,3,4]); + + buf.readInt16BE(); + // returns 510 + buf.readInt16LE(1); + // returns -511 ### buf.readInt32BE(offset[, noAssert]) ### buf.readInt32LE(offset[, noAssert]) @@ -424,14 +683,22 @@ complement signed values. * `noAssert` Boolean, Optional, Default: false * Return: Number -Reads a signed 32-bit integer from the buffer at the specified offset with -specified endian format. +Reads a signed 32-bit integer from the Buffer at the specified `offset` with +the specified endian format (`readInt32BE()` returns big endian, +`readInt32LE()` returns little endian). + +Setting `noAssert` to `true` skips validation of the `offset`. This allows the +`offset` to be beyond the end of the Buffer. When not specified, `noAssert` +defaults to `false`. -Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. Defaults to `false`. +Integers read from the Buffer are interpreted as two's complement signed values. -Works as `buffer.readUInt32*`, except buffer contents are treated as two's -complement signed values. + const buf = new Buffer([1,-2,3,4]); + + buf.readInt32BE(); + // returns 33424132 + buf.readInt32LE(1); + // returns 67370497 ### buf.readIntBE(offset, byteLength[, noAssert]) ### buf.readIntLE(offset, byteLength[, noAssert]) @@ -441,17 +708,22 @@ complement signed values. * `noAssert` {Boolean} Default: false * Return: {Number} -A generalized version of all numeric read methods. Supports up to 48 bits of -accuracy. For example: +Reads `byteLength` number of bytes from the Buffer at the specified `offset` +and interprets the result as a two's complement signed value. Supports up to 48 +bits of accuracy. For example: + + const buf = new Buffer(6); + buf.writeUInt16LE(0x90ab, 0); + buf.writeUInt32LE(0x12345678, 2); + buf.readIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) + // Returns: '1234567890ab' - var b = new Buffer(6); - b.writeUInt16LE(0x90ab, 0); - b.writeUInt32LE(0x12345678, 2); - b.readUIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) - // output: '1234567890ab' + buf.readIntBE(0, 6).toString(16); + // Returns: -546f87a9cbee -Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. Defaults to `false`. +Setting `noAssert` to `true` skips validation of the `offset`. This allows the +`offset` to be beyond the end of the Buffer. When not specified, `noAssert` +defaults to `false`. ### buf.readUInt8(offset[, noAssert]) @@ -459,28 +731,18 @@ may be beyond the end of the buffer. Defaults to `false`. * `noAssert` Boolean, Optional, Default: false * Return: Number -Reads an unsigned 8-bit integer from the buffer at the specified offset. +Reads an unsigned 8-bit integer from the Buffer at the specified `offset`. -Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. Defaults to `false`. +Setting `noAssert` to `true` skips validation of the `offset`. This allows the +`offset` to be beyond the end of the Buffer. When not specified, `noAssert` +defaults to `false`. -Example: - - var buf = new Buffer(4); - - buf[0] = 0x3; - buf[1] = 0x4; - buf[2] = 0x23; - buf[3] = 0x42; - - for (ii = 0; ii < buf.length; ii++) { - console.log(buf.readUInt8(ii)); - } + const buf = new Buffer([1,-2,3,4]); - // 0x3 - // 0x4 - // 0x23 - // 0x42 + buf.readUInt8(0); + // returns 1 + buf.readUInt8(1); + // returns 254 ### buf.readUInt16BE(offset[, noAssert]) ### buf.readUInt16LE(offset[, noAssert]) @@ -489,34 +751,30 @@ Example: * `noAssert` Boolean, Optional, Default: false * Return: Number -Reads an unsigned 16-bit integer from the buffer at the specified offset with -specified endian format. +Reads an unsigned 16-bit integer from the Buffer at the specified `offset` with +specified endian format (`readInt32BE()` returns big endian, +`readInt32LE()` returns little endian). -Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. Defaults to `false`. +Setting `noAssert` to `true` skips validation of the `offset`. This allows the +`offset` to be beyond the end of the Buffer. When not specified, `noAssert` +defaults to `false`. Example: - var buf = new Buffer(4); - - buf[0] = 0x3; - buf[1] = 0x4; - buf[2] = 0x23; - buf[3] = 0x42; - - console.log(buf.readUInt16BE(0)); - console.log(buf.readUInt16LE(0)); - console.log(buf.readUInt16BE(1)); - console.log(buf.readUInt16LE(1)); - console.log(buf.readUInt16BE(2)); - console.log(buf.readUInt16LE(2)); - - // 0x0304 - // 0x0403 - // 0x0423 - // 0x2304 - // 0x2342 - // 0x4223 + const buf = new Buffer([0x3, 0x4, 0x23, 0x42]); + + buf.readUInt16BE(0); + // Returns: 0x0304 + buf.readUInt16LE(0); + // Returns: 0x0403 + buf.readUInt16BE(1); + // Returns: 0x0423 + buf.readUInt16LE(1); + // Returns: 0x2304 + buf.readUInt16BE(2); + // Returns: 0x2342 + buf.readUInt16LE(2); + // Returns: 0x4223 ### buf.readUInt32BE(offset[, noAssert]) ### buf.readUInt32LE(offset[, noAssert]) @@ -525,26 +783,22 @@ Example: * `noAssert` Boolean, Optional, Default: false * Return: Number -Reads an unsigned 32-bit integer from the buffer at the specified offset with -specified endian format. +Reads an unsigned 32-bit integer from the Buffer at the specified `offset` with +specified endian format (`readInt32BE()` returns big endian, +`readInt32LE()` returns little endian). -Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. Defaults to `false`. +Setting `noAssert` to `true` skips validation of the `offset`. This allows the +`offset` to be beyond the end of the Buffer. When not specified, `noAssert` +defaults to `false`. Example: - var buf = new Buffer(4); + const buf = new Buffer([0x3, 0x4, 0x23, 0x42]); - buf[0] = 0x3; - buf[1] = 0x4; - buf[2] = 0x23; - buf[3] = 0x42; - - console.log(buf.readUInt32BE(0)); + buf.readUInt32BE(0); + // Returns: 0x03042342 console.log(buf.readUInt32LE(0)); - - // 0x03042342 - // 0x42230403 + // Returns: 0x42230403 ### buf.readUIntBE(offset, byteLength[, noAssert]) ### buf.readUIntLE(offset, byteLength[, noAssert]) @@ -554,42 +808,61 @@ Example: * `noAssert` {Boolean} Default: false * Return: {Number} -A generalized version of all numeric read methods. Supports up to 48 bits of -accuracy. For example: +Reads `byteLength` number of bytes from the Buffer at the specified `offset` +and interprets the result as an unsigned integer. Supports up to 48 +bits of accuracy. For example: + + const buf = new Buffer(6); + buf.writeUInt16LE(0x90ab, 0); + buf.writeUInt32LE(0x12345678, 2); + buf.readUIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) + // Returns: '1234567890ab' + + buf.readUIntBE(0, 6).toString(16); + // Returns: ab9078563412 - var b = new Buffer(6); - b.writeUInt16LE(0x90ab, 0); - b.writeUInt32LE(0x12345678, 2); - b.readUIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) - // output: '1234567890ab' +Setting `noAssert` to `true` skips validation of the `offset`. This allows the +`offset` to be beyond the end of the Buffer. When not specified, `noAssert` +defaults to `false`. ### buf.slice([start[, end]]) * `start` Number, Optional, Default: 0 * `end` Number, Optional, Default: `buffer.length` -Returns a new buffer which references the same memory as the old, but offset +Returns a new Buffer that references the same memory as the original, but offset and cropped by the `start` (defaults to `0`) and `end` (defaults to -`buffer.length`) indexes. Negative indexes start from the end of the buffer. +`buffer.length`) indexes. -**Modifying the new buffer slice will modify memory in the original buffer!** +**Note that modifying the new Buffer slice will modify the memory in the original Buffer because the allocated memory of the two objects overlap.** Example: build a Buffer with the ASCII alphabet, take a slice, then modify one byte from the original Buffer. - var buf1 = new Buffer(26); + const buf1 = new Buffer(26); for (var i = 0 ; i < 26 ; i++) { buf1[i] = i + 97; // 97 is ASCII a } - var buf2 = buf1.slice(0, 3); - console.log(buf2.toString('ascii', 0, buf2.length)); + const buf2 = buf1.slice(0, 3); + buf2.toString('ascii', 0, buf2.length); + // Returns: 'abc' buf1[0] = 33; - console.log(buf2.toString('ascii', 0, buf2.length)); + buf2.toString('ascii', 0, buf2.length); + // Returns : '!bc' - // abc - // !bc +Specifying negative indexes causes the slice to be generated relative to the +end of the Buffer rather than the beginning. + + const buf = new Buffer('buffer'); + + buf.slice(-6, -1).toString(); + // Returns 'buffe', equivalent to buf.slice(0, 5) + buf.slice(-6, -2).toString(); + // Returns 'buff', equivalent to buf.slice(0, 4) + buf.slice(-5, -2).toString(); + // Returns 'uff', equivalent to buf.slice(1, 4) ### buf.toString([encoding][, start][, end]) @@ -597,22 +870,23 @@ byte from the original Buffer. * `start` Number, Optional, Default: 0 * `end` Number, Optional, Default: `buffer.length` -Decodes and returns a string from buffer data encoded using the specified -character set encoding. If `encoding` is `undefined` or `null`, then `encoding` -defaults to `'utf8'`. The `start` and `end` parameters default to `0` and -`buffer.length` when `undefined`. +Decodes and returns a string from the Buffer data using the specified +character set `encoding`. If `encoding` is `undefined` or `null`, then +`encoding` defaults to `'utf8'`. The `start` and `end` parameters default to +`0` and `buffer.length` when `undefined`. - buf = new Buffer(26); + const buf = new Buffer(26); for (var i = 0 ; i < 26 ; i++) { buf[i] = i + 97; // 97 is ASCII a } - buf.toString('ascii'); // outputs: abcdefghijklmnopqrstuvwxyz - buf.toString('ascii',0,5); // outputs: abcde - buf.toString('utf8',0,5); // outputs: abcde - buf.toString(undefined,0,5); // encoding defaults to 'utf8', outputs abcde - -See `buffer.write()` example, above. - + buf.toString('ascii'); + // Returns: 'abcdefghijklmnopqrstuvwxyz' + buf.toString('ascii',0,5); + // Returns: 'abcde' + buf.toString('utf8',0,5); + // Returns: 'abcde' + buf.toString(undefined,0,5); + // Returns: 'abcde', encoding defaults to 'utf8' ### buf.toJSON() @@ -621,20 +895,20 @@ implicitly calls this function when stringifying a Buffer instance. Example: - var buf = new Buffer('test'); - var json = JSON.stringify(buf); + const buf = new Buffer('test'); + const json = JSON.stringify(buf); console.log(json); - // '{"type":"Buffer","data":[116,101,115,116]}' + // Prints: '{"type":"Buffer","data":[116,101,115,116]}' - var copy = JSON.parse(json, function(key, value) { + const copy = JSON.parse(json, (key, value) => { return value && value.type === 'Buffer' ? new Buffer(value.data) : value; }); - console.log(copy); - // + console.log(copy.toString()); + // Prints: 'test' ### buf.write(string[, offset][, length][, encoding]) @@ -643,16 +917,18 @@ Example: * `length` Number, Optional, Default: `buffer.length - offset` * `encoding` String, Optional, Default: 'utf8' -Writes `string` to the buffer at `offset` using the given encoding. -`offset` defaults to `0`, `encoding` defaults to `'utf8'`. `length` is -the number of bytes to write. Returns number of octets written. If `buffer` did -not contain enough space to fit the entire string, it will write a partial -amount of the string. `length` defaults to `buffer.length - offset`. -The method will not write partial characters. +Writes `string` to the Buffer at `offset` using the given `encoding`. +When undefined, `offset` defaults to `0`, and `encoding` defaults to `'utf8'`. +The `length` parameter is the number of bytes to write, when undefined `length` +defaults to `buffer.length - offset`. If the Buffer did not contain enough +space to fit the entire string, only a partial amount of the string will be +written however, the will not write only partially encoded characters. The +return value indicates the number of octets written. - buf = new Buffer(256); - len = buf.write('\u00bd + \u00bc = \u00be', 0); - console.log(len + " bytes: " + buf.toString('utf8', 0, len)); + const buf = new Buffer(256); + const len = buf.write('\u00bd + \u00bc = \u00be', 0); + console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`); + // Prints: 12 bytes: ½ + ¼ = ¾ ### buf.writeDoubleBE(value, offset[, noAssert]) ### buf.writeDoubleLE(value, offset[, noAssert]) @@ -661,27 +937,27 @@ The method will not write partial characters. * `offset` Number * `noAssert` Boolean, Optional, Default: false -Writes `value` to the buffer at the specified offset with specified endian -format. `value` must be a valid 64-bit double. +Writes `value` to the Buffer at the specified `offset` with specified endian +format (`writeDoubleBE()` writes big endian, `writeDoubleLE()` writes little +endian). The `value` argument must be a valid 64-bit double. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be -beyond the end of the buffer leading to the values being silently dropped. This +beyond the end of the Buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Example: - var buf = new Buffer(8); + const buf = new Buffer(8); buf.writeDoubleBE(0xdeadbeefcafebabe, 0); console.log(buf); + // Prints: buf.writeDoubleLE(0xdeadbeefcafebabe, 0); console.log(buf); - - // - // + // Prints: ### buf.writeFloatBE(value, offset[, noAssert]) ### buf.writeFloatLE(value, offset[, noAssert]) @@ -690,27 +966,28 @@ Example: * `offset` Number * `noAssert` Boolean, Optional, Default: false -Writes `value` to the buffer at the specified offset with specified endian -format. Behavior is unspecified if `value` is not a 32-bit float. +Writes `value` to the Buffer at the specified `offset` with specified endian +format (`writeFloatBE()` writes big endian, `writeFloatLE()` writes little +endian). Behavior is unspecified if `value` is anything other than a 32-bit +float. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be -beyond the end of the buffer leading to the values being silently dropped. This +beyond the end of the Buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Example: - var buf = new Buffer(4); + const buf = new Buffer(4); buf.writeFloatBE(0xcafebabe, 0); console.log(buf); + // Prints: buf.writeFloatLE(0xcafebabe, 0); console.log(buf); - - // - // + // Prints: ### buf.writeInt8(value, offset[, noAssert]) @@ -718,16 +995,21 @@ Example: * `offset` Number * `noAssert` Boolean, Optional, Default: false -Writes `value` to the buffer at the specified offset. `value` must be a +Writes `value` to the Buffer at the specified `offset`. The `value` must be a valid signed 8-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be -beyond the end of the buffer leading to the values being silently dropped. This +beyond the end of the Buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. -Works as `buffer.writeUInt8`, except value is written out as a two's complement -signed integer into `buffer`. +The `value` is interpreted and written as a two's complement signed integer. + + const buf = new Buffer(2); + buf.writeInt8(2, 0); + buf.writeInt8(-2, 1); + console.log(buf); + // Prints: ### buf.writeInt16BE(value, offset[, noAssert]) ### buf.writeInt16LE(value, offset[, noAssert]) @@ -736,16 +1018,22 @@ signed integer into `buffer`. * `offset` Number * `noAssert` Boolean, Optional, Default: false -Writes `value` to the buffer at the specified offset with specified endian -format. `value` must be a valid signed 16-bit integer. +Writes `value` to the Buffer at the specified `offset` with specified endian +format (`writeInt16BE()` writes big endian, `writeInt16LE()` writes little +endian). The `value` must be a valid signed 16-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be -beyond the end of the buffer leading to the values being silently dropped. This +beyond the end of the Buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. -Works as `buffer.writeUInt16*`, except value is written out as a two's -complement signed integer into `buffer`. +The `value` is interpreted and written as a two's complement signed integer. + + const buf = new Buffer(4); + buf.writeInt16BE(0x0102,0); + buf.writeInt16LE(0x0304,2); + console.log(buf); + // Prints: ### buf.writeInt32BE(value, offset[, noAssert]) ### buf.writeInt32LE(value, offset[, noAssert]) @@ -754,35 +1042,49 @@ complement signed integer into `buffer`. * `offset` Number * `noAssert` Boolean, Optional, Default: false -Writes `value` to the buffer at the specified offset with specified endian -format. `value` must be a valid signed 32-bit integer. +Writes `value` to the Buffer at the specified `offset` with specified endian +format (`writeInt32BE()` writes big endian, `writeInt32LE()` writes little +endian). The `value` must be a valid signed 32-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be -beyond the end of the buffer leading to the values being silently dropped. This +beyond the end of the Buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. -Works as `buffer.writeUInt32*`, except value is written out as a two's -complement signed integer into `buffer`. +The `value` is interpreted and written as a two's complement signed integer. + + const buf = new Buffer(8); + buf.writeInt32BE(0x01020304,0); + buf.writeInt32LE(0x05060708,4); + console.log(buf); + // Prints: ### buf.writeIntBE(value, offset, byteLength[, noAssert]) ### buf.writeIntLE(value, offset, byteLength[, noAssert]) -* `value` {Number} Bytes to be written to buffer +* `value` {Number} Bytes to be written to Buffer * `offset` {Number} `0 <= offset <= buf.length` * `byteLength` {Number} `0 < byteLength <= 6` * `noAssert` {Boolean} Default: false * Return: {Number} -Writes `value` to the buffer at the specified `offset` and `byteLength`. +Writes `value` to the Buffer at the specified `offset` and `byteLength`. Supports up to 48 bits of accuracy. For example: - var b = new Buffer(6); - b.writeUIntBE(0x1234567890ab, 0, 6); - // + const buf1 = new Buffer(6); + buf1.writeUIntBE(0x1234567890ab, 0, 6); + console.log(buf1); + // Prints: -Set `noAssert` to `true` to skip validation of `value` and `offset`. Defaults -to `false`. + const buf2 = new Buffer(6); + buf2.writeUIntLE(0x1234567890ab, 0, 6); + console.log(buf2); + // Prints: + +Set `noAssert` to true to skip validation of `value` and `offset`. This means +that `value` may be too large for the specific function and `offset` may be +beyond the end of the Buffer leading to the values being silently dropped. This +should not be used unless you are certain of correctness. Defaults to `false`. ### buf.writeUInt8(value, offset[, noAssert]) @@ -790,25 +1092,24 @@ to `false`. * `offset` Number * `noAssert` Boolean, Optional, Default: false -Writes `value` to the buffer at the specified offset. `value` must be a +Writes `value` to the Buffer at the specified `offset`. The `value` must be a valid unsigned 8-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be -beyond the end of the buffer leading to the values being silently dropped. This +beyond the end of the Buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Example: - var buf = new Buffer(4); + const buf = new Buffer(4); buf.writeUInt8(0x3, 0); buf.writeUInt8(0x4, 1); buf.writeUInt8(0x23, 2); buf.writeUInt8(0x42, 3); console.log(buf); - - // + // Prints: ### buf.writeUInt16BE(value, offset[, noAssert]) ### buf.writeUInt16LE(value, offset[, noAssert]) @@ -817,29 +1118,29 @@ Example: * `offset` Number * `noAssert` Boolean, Optional, Default: false -Writes `value` to the buffer at the specified offset with specified endian -format. `value` must be a valid unsigned 16-bit integer. +Writes `value` to the Buffer at the specified `offset` with specified endian +format (`writeUInt16BE()` writes big endian, `writeUInt16LE()` writes little +endian). The `value` must be a valid unsigned 16-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be -beyond the end of the buffer leading to the values being silently dropped. This +beyond the end of the Buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Example: - var buf = new Buffer(4); + const buf = new Buffer(4); buf.writeUInt16BE(0xdead, 0); buf.writeUInt16BE(0xbeef, 2); console.log(buf); + // Prints: buf.writeUInt16LE(0xdead, 0); buf.writeUInt16LE(0xbeef, 2); console.log(buf); - - // - // + // Prints: ### buf.writeUInt32BE(value, offset[, noAssert]) ### buf.writeUInt32LE(value, offset[, noAssert]) @@ -848,73 +1149,60 @@ Example: * `offset` Number * `noAssert` Boolean, Optional, Default: false -Writes `value` to the buffer at the specified offset with specified endian -format. `value` must be a valid unsigned 32-bit integer. +Writes `value` to the Buffer at the specified `offset` with specified endian +format (`writeUInt32BE()` writes big endian, `writeUInt32LE()` writes little +endian). The `value` must be a valid unsigned 32-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be -beyond the end of the buffer leading to the values being silently dropped. This +beyond the end of the Buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Example: - var buf = new Buffer(4); + const buf = new Buffer(4); buf.writeUInt32BE(0xfeedface, 0); console.log(buf); + // Prints: buf.writeUInt32LE(0xfeedface, 0); console.log(buf); - - // - // + // Prints: ### buf.writeUIntBE(value, offset, byteLength[, noAssert]) ### buf.writeUIntLE(value, offset, byteLength[, noAssert]) -* `value` {Number} Bytes to be written to buffer +* `value` {Number} Bytes to be written to Buffer * `offset` {Number} `0 <= offset <= buf.length` * `byteLength` {Number} `0 < byteLength <= 6` * `noAssert` {Boolean} Default: false * Return: {Number} -Writes `value` to the buffer at the specified `offset` and `byteLength`. +Writes `value` to the Buffer at the specified `offset` and `byteLength`. Supports up to 48 bits of accuracy. For example: - var b = new Buffer(6); - b.writeUIntBE(0x1234567890ab, 0, 6); - // + const buf = new Buffer(6); + buf.writeUIntBE(0x1234567890ab, 0, 6); + console.log(buf); + // Prints: -Set `noAssert` to `true` to skip validation of `value` and `offset`. Defaults -to `false`. +Set `noAssert` to true to skip validation of `value` and `offset`. This means +that `value` may be too large for the specific function and `offset` may be +beyond the end of the Buffer leading to the values being silently dropped. This +should not be used unless you are certain of correctness. Defaults to `false`. ## buffer.INSPECT_MAX_BYTES * Number, Default: 50 -How many bytes will be returned when `buffer.inspect()` is called. This can -be overridden by user modules. See [`util.inspect()`][] for more details on -`buffer.inspect()` behavior. - -Note that this is a property on the buffer module returned by -`require('buffer')`, not on the Buffer global or a buffer instance. - -## ES6 iteration - -Buffers can be iterated over using `for..of` syntax: +Returns the maximum number of bytes that will be returned when +`buffer.inspect()` is called. This can be overridden by user modules. See +[`util.inspect()`][] for more details on `buffer.inspect()` behavior. - var buf = new Buffer([1, 2, 3]); - - for (var b of buf) - console.log(b) - - // 1 - // 2 - // 3 - -Additionally, the `buffer.values()`, `buffer.keys()`, and `buffer.entries()` -methods can be used to create iterators. +Note that this is a property on the `buffer` module as returned by +`require('buffer')`, not on the Buffer global or a Buffer instance. ## Class: SlowBuffer @@ -927,12 +1215,12 @@ usage since v8 does not need to track and cleanup as many `Persistent` objects. In the case where a developer may need to retain a small chunk of memory from a pool for an indeterminate amount of time, it may be appropriate to create an -un-pooled Buffer instance using SlowBuffer and copy out the relevant bits. +un-pooled Buffer instance using `SlowBuffer` then copy out the relevant bits. // need to keep around a few small chunks of memory - var store = []; + const store = []; - socket.on('readable', function() { + socket.on('readable', () => { var data = socket.read(); // allocate for retained data var sb = new SlowBuffer(10); @@ -941,10 +1229,12 @@ un-pooled Buffer instance using SlowBuffer and copy out the relevant bits. store.push(sb); }); -This should be used only as a last resort *after* a developer has observed -undue memory retention in their applications. +Use of `SlowBuffer` should be used only as a last resort *after* a developer +has observed undue memory retention in their applications. +[iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols [`Array#indexOf()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf +[Array#includes()]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes [`buf.fill(0)`]: #buffer_buf_fill_value_offset_end [`buf.slice`]: #buffer_buf_slice_start_end [`buf1.compare(buf2)`]: #buffer_buf_compare_otherbuffer diff --git a/doc/api/child_process.markdown b/doc/api/child_process.markdown index e9e4b3711cbf..029b63fd8e43 100644 --- a/doc/api/child_process.markdown +++ b/doc/api/child_process.markdown @@ -2,358 +2,113 @@ Stability: 2 - Stable -Node.js provides a tri-directional `popen(3)` facility through the -`child_process` module. +The `child_process` module provides the ability to spawn child processes in +a manner that is similar, but not identical, to [`popen(3)`][]. This capability +is primarily provided by the `child_process.spawn()` function: -It is possible to stream data through a child's `stdin`, `stdout`, and -`stderr` in a fully non-blocking way. (Note that some programs use -line-buffered I/O internally. That doesn't affect Node.js but it means -data you send to the child process may not be immediately consumed.) + const spawn = require('child_process').spawn; + const ls = spawn('ls', ['-lh', '/usr']); -To create a child process, use `require('child_process').spawn()` or -`require('child_process').fork()`. The semantics of each are slightly -different as explained [below][]. - -For scripting purposes you may find the [synchronous counterparts][] more -convenient. - -## Class: ChildProcess - -`ChildProcess` is an [`EventEmitter`][]. - -Child processes always have three streams associated with them. `child.stdin`, -`child.stdout`, and `child.stderr`. These may be shared with the stdio -streams of the parent process, or they may be separate stream objects -which can be piped to and from. - -The `ChildProcess` class is not intended to be used directly. Use the -[`spawn()`][], [`exec()`][], [`execFile()`][], or [`fork()`][] methods to create -an instance of `ChildProcess`. - -### Event: 'close' - -* `code` {Number} the exit code, if it exited normally. -* `signal` {String} the signal passed to kill the child process, if it - was killed by the parent. - -This event is emitted when the stdio streams of a child process have all -terminated. This is distinct from `'exit'`, since multiple processes -might share the same stdio streams. - -### Event: 'disconnect' - -This event is emitted after calling the `.disconnect()` method in the parent -or in the child. After disconnecting it is no longer possible to send messages, -and the `.connected` property is false. - -### Event: 'error' - -* `err` {Error Object} the error. - -Emitted when: - -1. The process could not be spawned, or -2. The process could not be killed, or -3. Sending a message to the child process failed. - -Note that the `'exit'` event may or may not fire after an error has occurred. -If you are listening on both events to fire a function, remember to guard -against calling your function twice. - -See also [`ChildProcess#kill()`][] and [`ChildProcess#send()`][]. - -### Event: 'exit' - -* `code` {Number} the exit code, if it exited normally. -* `signal` {String} the signal passed to kill the child process, if it - was killed by the parent. - -This event is emitted after the child process ends. If the process terminated -normally, `code` is the final exit code of the process, otherwise `null`. If -the process terminated due to receipt of a signal, `signal` is the string name -of the signal, otherwise `null`. - -Note that the child process stdio streams might still be open. - -Also, note that Node.js establishes signal handlers for `SIGINT` and -`SIGTERM`. It will not terminate due to receipt of those signals. It will exit. - -See `waitpid(2)`. - -### Event: 'message' - -* `message` {Object} a parsed JSON object or primitive value. -* `sendHandle` {Handle object} a [`net.Socket`][] or [`net.Server`][] object, or - undefined. - -Messages sent by `.send(message, [sendHandle])` are obtained using the -`'message'` event. - -### child.connected - -* {Boolean} Set to false after `.disconnect` is called - -If `.connected` is false, it is no longer possible to send messages. - -### child.disconnect() - -Close the IPC channel between parent and child, allowing the child to exit -gracefully once there are no other connections keeping it alive. After calling -this method the `.connected` flag will be set to `false` in both the parent and -child, and it is no longer possible to send messages. - -The `'disconnect'` event will be emitted when there are no messages in the -process of being received, most likely immediately. - -Note that you can also call `process.disconnect()` in the child process when the -child process has any open IPC channels with the parent (i.e [`fork()`][]). - -### child.kill([signal]) - -* `signal` {String} - -Send a signal to the child process. If no argument is given, the process will -be sent `'SIGTERM'`. See `signal(7)` for a list of available signals. - - var spawn = require('child_process').spawn, - grep = spawn('grep', ['ssh']); - - grep.on('close', function (code, signal) { - console.log('child process terminated due to receipt of signal ' + signal); + ls.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); }); - // send SIGHUP to process - grep.kill('SIGHUP'); - -May emit an `'error'` event when the signal cannot be delivered. Sending a -signal to a child process that has already exited is not an error but may -have unforeseen consequences. Specifically, if the process identifier (PID) has -been reassigned to another process, the signal will be delivered to that -process instead. What happens next is anyone's guess. - -Note that while the function is called `kill`, the signal delivered to the -child process may not actually kill it. `kill` really just sends a signal -to a process. - -See `kill(2)` - -### child.pid - -* {Integer} - -The process identifier (PID) of the child process. - -Example: - - var spawn = require('child_process').spawn, - grep = spawn('grep', ['ssh']); - - console.log('Spawned child pid: ' + grep.pid); - grep.stdin.end(); - -### child.send(message[, sendHandle][, callback]) - -* `message` {Object} -* `sendHandle` {Handle object} -* `callback` {Function} -* Return: Boolean - -When using [`child_process.fork()`][] you can write to the child using -`child.send(message[, sendHandle][, callback])` and messages are received by -a `'message'` event on the child. - -For example: - - var cp = require('child_process'); - - var n = cp.fork(__dirname + '/sub.js'); - - n.on('message', function(m) { - console.log('PARENT got message:', m); + ls.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); }); - n.send({ hello: 'world' }); - -And then the child script, `'sub.js'` might look like this: - - process.on('message', function(m) { - console.log('CHILD got message:', m); + ls.on('close', (code) => { + console.log(`child process exited with code ${code}`); }); - process.send({ foo: 'bar' }); +By default, pipes for `stdin`, `stdout` and `stderr` are established between +the parent Node.js process and the spawned child. It is possible to stream data +through these pipes in a non-blocking way. *Note, however, that some programs +use line-buffered I/O internally. While that does not affect Node.js, it can +mean that data sent to the child process may not be immediately consumed.* + +The `child_process.spawn()` method spawns the child process asynchronously, +without blocking the Node.js event loop. The `child_process.spawnSync()` +function provides equivalent functionality in a synchronous manner that blocks +the event loop until the spawned process either exits of is terminated. + +For convenience, the `child_process` module provides a handful of synchronous +and asynchronous alternatives to `child_process.spawn()` and +`child_process.spawnSync()`, each of which are documented fully [below][]. +*Note that each of these alternatives are implemented on top of +`child_process.spawn()` or `child_process.spawnSync()`.* + + * `child_process.exec()`: spawns a shell and runs a command within that shell, + passing the `stdout` and `stderr` to a callback function when complete. + * `child_process.execFile()`: similar to `child_process.exec()` except that + it spawns the command directly without first spawning a shell. + * `child_process.fork()`: spawns a new Node.js process and invokes a + specified module with an IPC communication channel established that allows + sending messages between parent and child. + * `child_process.execSync()`: a synchronous version of + `child_process.exec()` that *will* block the Node.js event loop. + * `child_process.execFileSync()`: a synchronous version of + `child_process.execFile()` that *will* block the Node.js event loop. + +For certain use cases, such as automating shell scripts, the +[synchronous counterparts][] may be more convenient. In many cases, however, +the synchronous methods can have significant impact on performance due to +stalling the event loop while spawned processes complete. -In the child, the `process` object will have a `send()` method, and `process` -will emit objects each time it receives a message on its channel. - -There is a special case when sending a `{cmd: 'NODE_foo'}` message. All messages -containing a `NODE_` prefix in its `cmd` property will not be emitted in -the `'message'` event, since they are internal messages used by Node.js core. -Messages containing the prefix are emitted in the `'internalMessage'` event. -Avoid using this feature; it is subject to change without notice. - -The `sendHandle` option to `child.send()` is for sending a TCP server or -socket object to another process. The child will receive the object as its -second argument to the `'message'` event. - -The `callback` option is a function that is invoked after the message is -sent but before the target may have received it. It is called with a single -argument: `null` on success, or an [`Error`][] object on failure. - -`child.send()` emits an `'error'` event if no callback was given and the message -cannot be sent, for example because the child process has already exited. - -`child.send()` returns `false` if the channel has closed or when the backlog of -unsent messages exceeds a threshold that makes it unwise to send more. -Otherwise, it returns `true`. Use the callback mechanism to implement flow -control. - -#### Example: sending server object - -Here is an example of sending a server: - - var child = require('child_process').fork('child.js'); +## Asynchronous Process Creation - // Open up the server object and send the handle. - var server = require('net').createServer(); - server.on('connection', function (socket) { - socket.end('handled by parent'); +The `child_process.spawn()`, `child_process.fork()`, `child_process.exec()`, +and `child_process.execFile()` methods all follow the idiomatic asynchronous +programming pattern typical of other Node.js APIs. + +Each of the methods returns a [ChildProcess][] instance. These objects +implement the Node.js [EventEmitter][] API, allowing the parent process to +register listener functions that are called when certain events occur during +the life cycle of the child process. + +The `child_process.exec()` and `child_process.execFile()` methods additionally +allow for an optional `callback` function to be specified that is invoked +when the child process terminates. + +### Spawning `.bat` and `.cmd` files on Windows + +The importance of the distinction between `child_process.exec()` and +`child_process.execFile()` can vary based on platform. On Unix-type operating +systems (Unix, Linux, OSX) `child_process.execFile()` can be more efficient +because it does not spawn a shell. On Windows, however, `.bat` and `.cmd` +files are not executable on their own without a terminal and therefore cannot +be launched using `child_process.execFile()` (or even `child_process.spawn()`). +When running on Windows, `.bat` and `.cmd` files can only be invoked using +either `child_process.exec()` or by spawning `cmd.exe` and passing the `.bat` +or `.cmd` file as an argument (which is what `child_process.exec()` does). + + // On Windows Only ... + const spawn = require('child_process').spawn; + const bat = spawn('cmd.exe', ['/c', 'my.bat']); + + bat.stdout.on('data', (data) => { + console.log(data); }); - server.listen(1337, function() { - child.send('server', server); - }); - -And the child would then receive the server object as: - process.on('message', function(m, server) { - if (m === 'server') { - server.on('connection', function (socket) { - socket.end('handled by child'); - }); - } + bat.stderr.on('data', (data) => { + console.log(data); }); -Note that the server is now shared between the parent and child, this means -that some connections will be handled by the parent and some by the child. - -For `dgram` servers the workflow is exactly the same. Here you listen on -a `'message'` event instead of `'connection'` and use `server.bind` instead of -`server.listen`. (Currently only supported on UNIX platforms.) - -#### Example: sending socket object - -Here is an example of sending a socket. It will spawn two children and handle -connections with the remote address `74.125.127.100` as VIP by sending the -socket to a "special" child process. Other sockets will go to a "normal" -process. - - var normal = require('child_process').fork('child.js', ['normal']); - var special = require('child_process').fork('child.js', ['special']); - - // Open up the server and send sockets to child - var server = require('net').createServer(); - server.on('connection', function (socket) { - - // if this is a VIP - if (socket.remoteAddress === '74.125.127.100') { - special.send('socket', socket); - return; - } - // just the usual... - normal.send('socket', socket); + bat.on('exit', (code) => { + console.log(`Child exited with code ${code}`); }); - server.listen(1337); - -The `child.js` could look like this: - process.on('message', function(m, socket) { - if (m === 'socket') { - socket.end('You were handled as a ' + process.argv[2] + ' person'); + // OR... + const exec = require('child_process').exec; + exec('my.bat', (err, stdout, stderr) => { + if (err) { + console.error(err); + return; } + console.log(stdout); }); -Note that once a single socket has been sent to a child the parent can no -longer keep track of when the socket is destroyed. To indicate this condition -the `.connections` property becomes `null`. -It is also recommended not to use `.maxConnections` in this condition. - -### child.stderr - -* {Stream object} - -A `Readable Stream` that represents the child process's `stderr`. - -If the child was not spawned with `stdio[2]` set to `'pipe'`, then this will -not be set. - -`child.stderr` is shorthand for `child.stdio[2]`. Both properties will refer -to the same object, or null. - -### child.stdin - -* {Stream object} - -A `Writable Stream` that represents the child process's `stdin`. -If the child is waiting to read all its input, it will not continue until this -stream has been closed via `end()`. - -If the child was not spawned with `stdio[0]` set to `'pipe'`, then this will -not be set. - -`child.stdin` is shorthand for `child.stdio[0]`. Both properties will refer -to the same object, or null. - -### child.stdio - -* {Array} - -A sparse array of pipes to the child process, corresponding with positions in -the [`stdio`][] option to [`spawn()`][] that have been set to `'pipe'`. -Note that streams 0-2 are also available as ChildProcess.stdin, -ChildProcess.stdout, and ChildProcess.stderr, respectively. - -In the following example, only the child's fd `1` is setup as a pipe, so only -the parent's `child.stdio[1]` is a stream, all other values in the array are -`null`. - - var assert = require('assert'); - var fs = require('fs'); - var child_process = require('child_process'); - - child = child_process.spawn('ls', { - stdio: [ - 0, // use parents stdin for child - 'pipe', // pipe child's stdout to parent - fs.openSync('err.out', 'w') // direct child's stderr to a file - ] - }); - - assert.equal(child.stdio[0], null); - assert.equal(child.stdio[0], child.stdin); - - assert(child.stdout); - assert.equal(child.stdio[1], child.stdout); - - assert.equal(child.stdio[2], null); - assert.equal(child.stdio[2], child.stderr); - -### child.stdout - -* {Stream object} - -A `Readable Stream` that represents the child process's `stdout`. - -If the child was not spawned with `stdio[1]` set to `'pipe'`, then this will -not be set. - -`child.stdout` is shorthand for `child.stdio[1]`. Both properties will refer -to the same object, or null. - -## Asynchronous Process Creation - -These methods follow the common async programming patterns (accepting a -callback or returning an EventEmitter). - -### child_process.exec(command[, options], callback) +### child_process.exec(command[, options][, callback]) * `command` {String} The command to run, with space-separated arguments * `options` {Object} @@ -376,43 +131,48 @@ callback or returning an EventEmitter). * `stderr` {Buffer} * Return: ChildProcess object -Runs a command in a shell and buffers the output. +Spawns a shell then executes the `command` within that shell, buffering any +generated output. - var exec = require('child_process').exec, - child; - - child = exec('cat *.js bad_file | wc -l', - function (error, stdout, stderr) { - console.log('stdout: ' + stdout); - console.log('stderr: ' + stderr); + const exec = require('child_process').exec; + const child = exec('cat *.js bad_file | wc -l', + (error, stdout, stderr) => { + console.log(`stdout: ${stdout}`); + console.log(`stderr: ${stderr}`); if (error !== null) { - console.log('exec error: ' + error); + console.log(`exec error: ${error}`); } }); -The callback gets the arguments `(error, stdout, stderr)`. On success, `error` -will be `null`. On error, `error` will be an instance of [`Error`][] and `error.code` -will be the exit code of the child process, and `error.signal` will be set to the -signal that terminated the process. +If a `callback` function is provided, it is called with the arguments +`(error, stdout, stderr)`. On success, `error` will be `null`. On error, +`error` will be an instance of [`Error`][]. The `error.code` property will be +the exit code of the child process while `error.signal` will be set to the +signal that terminated the process. Any exit code other than `0` is considered +to be an error. -There is a second optional argument to specify several options. The -default options are +The `options` argument may be passed as the second argument to customize how +the process is spawned. The default options are: - { encoding: 'utf8', + { + encoding: 'utf8', timeout: 0, maxBuffer: 200*1024, killSignal: 'SIGTERM', cwd: null, - env: null } + env: null + } + +If `timeout` is greater than `0`, the parent will send the the signal +identified by the `killSignal` property (the default is `'SIGTERM'`) if the +child runs longer than `timeout` milliseconds. -If `timeout` is greater than 0, then it will kill the child process -if it runs longer than `timeout` milliseconds. The child process is killed with -`killSignal` (default: `'SIGTERM'`). `maxBuffer` specifies the largest -amount of data (in bytes) allowed on stdout or stderr - if this value is -exceeded then the child process is killed. +The `maxBuffer` option specifies the largest amount of data (in bytes) allowed +on stdout or stderr - if this value is exceeded then the child process is +terminated. -*Note: Unlike the `exec()` POSIX system call, `child_process.exec()` does not replace -the existing process and uses a shell to execute the command.* +*Note: Unlike the `exec()` POSIX system call, `child_process.exec()` does not +replace the existing process and uses a shell to execute the command.* ### child_process.execFile(file[, args][, options][, callback]) @@ -434,10 +194,21 @@ the existing process and uses a shell to execute the command.* * `stderr` {Buffer} * Return: ChildProcess object -This is similar to [`child_process.exec()`][] except it does not execute a -subshell but rather the specified file directly. This makes it slightly -leaner than [`child_process.exec()`][]. It has the same options. - +The `child_process.execFile()` method is similar to [`child_process.exec()`][] +except that it does not first spawn a shell. Rather, the specified `command` is +spawned directly as a new process making it slightly more efficient than +[`child_process.exec()`][]. The same options are support by both +`child_process.exec()` and `child_process.execFile()`. + + const exec = require('child_process').execFile; + const child = execFile('cat *.js bad_file | wc -l', + (error, stdout, stderr) => { + console.log(`stdout: ${stdout}`); + console.log(`stderr: ${stderr}`); + if (error !== null) { + console.log(`exec error: ${error}`); + } + }); ### child_process.fork(modulePath[, args][, options]) @@ -457,23 +228,31 @@ leaner than [`child_process.exec()`][]. It has the same options. * `gid` {Number} Sets the group identity of the process. (See setgid(2).) * Return: ChildProcess object -This is a special case of the [`child_process.spawn()`][] functionality for -spawning Node.js processes. In addition to having all the methods in a normal -ChildProcess instance, the returned object has a communication channel built-in. -See [`ChildProcess#send()`][] for details. - -These child Node.js processes are still whole new instances of V8. Assume at -least 30ms startup and 10mb memory for each new Node.js. That is, you cannot -create many thousands of them. - -The `execPath` property in the `options` object allows for a process to be -created for the child rather than the current `node` executable. This should be -done with care and by default will talk over the fd represented an -environmental variable `NODE_CHANNEL_FD` on the child process. The input and +The `child_process.fork()` method is a special case of +[`child_process.spawn()`][] used specifically to spawn new Node.js processes. +Like `child_process.spawn()`, a `ChildProcess` object is returned. The returned +`ChildProcess` will have an additional communication channel built-in that +allows messages to be passed back and forth between the parent and child. See +[`ChildProcess#send()`][] for details. + +It is important to keep in mind that spawned Node.js child processes are +independent of the parent with exception of the IPC communication channel +that is established between the two. Each process has it's own memory, with +their own V8 instances. Because of the additional resource allocations +required, spawning a large number of child Node.js processes is not +recommended. + +By default, `child_process.fork()` will spawn new Node.js instances using the +`process.execPath` of the parent process. The `execPath` property in the +`options` object allows for an alternative execution path to be used. + +Node.js processes launched with a custom `execPath` will communicate with the +parent process using the file descriptor (fd) identified using the +environment variable `NODE_CHANNEL_FD` on the child process. The input and output on this fd is expected to be line delimited JSON objects. -*Note: Unlike the `fork()` POSIX system call, [`child_process.fork()`][] does not clone the -current process.* +*Note: Unlike the `fork()` POSIX system call, [`child_process.fork()`][] does +not clone the current process.* ### child_process.spawn(command[, args][, options]) @@ -491,12 +270,14 @@ current process.* * `gid` {Number} Sets the group identity of the process. (See setgid(2).) * return: {ChildProcess object} -Launches a new process with the given `command`, with command line arguments in -`args`. If omitted, `args` defaults to an empty Array. +The `child_process.spawn()` method spawns a new process using the given +`command`, with command line arguments in `args`. If omitted, `args` defaults +to an empty array. -The third argument is used to specify additional options, with these defaults: +A third argument may be used to specify additional options, with these defaults: - { cwd: undefined, + { + cwd: undefined, env: process.env } @@ -506,93 +287,97 @@ If not given, the default is to inherit the current working directory. Use `env` to specify environment variables that will be visible to the new process, the default is `process.env`. -Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the exit code: +Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the +exit code: - var spawn = require('child_process').spawn, - ls = spawn('ls', ['-lh', '/usr']); + const spawn = require('child_process').spawn; + const ls = spawn('ls', ['-lh', '/usr']); - ls.stdout.on('data', function (data) { - console.log('stdout: ' + data); + ls.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); }); - ls.stderr.on('data', function (data) { - console.log('stderr: ' + data); + ls.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); }); - ls.on('close', function (code) { - console.log('child process exited with code ' + code); + ls.on('close', (code) => { + console.log(`child process exited with code ${code}`); }); Example: A very elaborate way to run 'ps ax | grep ssh' - var spawn = require('child_process').spawn, - ps = spawn('ps', ['ax']), - grep = spawn('grep', ['ssh']); + const spawn = require('child_process').spawn; + const ps = spawn('ps', ['ax']); + const grep = spawn('grep', ['ssh']); - ps.stdout.on('data', function (data) { + ps.stdout.on('data', (data) => { grep.stdin.write(data); }); - ps.stderr.on('data', function (data) { - console.log('ps stderr: ' + data); + ps.stderr.on('data', (data) => { + console.log(`ps stderr: ${data}`); }); - ps.on('close', function (code) { + ps.on('close', (code) => { if (code !== 0) { - console.log('ps process exited with code ' + code); + console.log(`ps process exited with code ${code}`); } grep.stdin.end(); }); - grep.stdout.on('data', function (data) { - console.log('' + data); + grep.stdout.on('data', (data) => { + console.log(`${data}`); }); - grep.stderr.on('data', function (data) { - console.log('grep stderr: ' + data); + grep.stderr.on('data', (data) => { + console.log(`grep stderr: ${data}`); }); - grep.on('close', function (code) { + grep.on('close', (code) => { if (code !== 0) { - console.log('grep process exited with code ' + code); + console.log(`grep process exited with code ${code}`); } }); Example of checking for failed exec: - var spawn = require('child_process').spawn, - child = spawn('bad_command'); + const spawn = require('child_process').spawn; + const child = spawn('bad_command'); - child.on('error', function (err) { + child.on('error', (err) => { console.log('Failed to start child process.'); }); #### options.detached -On Windows, this makes it possible for the child to continue running after the -parent exits. The child will have a new console window (this cannot be -disabled). +On Windows, setting `options.detached` to `true` makes it possible for the +child process to continue running after the parent exits. The child will have +its own console window. *Once enabled for a child process, it cannot be +disabled*. -On non-Windows, if the `detached` option is set, the child process will be made -the leader of a new process group and session. Note that child processes may -continue running after the parent exits whether they are detached or not. See -`setsid(2)` for more information. +On non-Windows platforms, if `options.detached` is set to `true`, the child +process will be made the leader of a new process group and session. Note that +child processes may continue running after the parent exits regardless of +whether they are detached or not. See `setsid(2)` for more information. -By default, the parent will wait for the detached child to exit. To prevent -the parent from waiting for a given `child`, use the `child.unref()` method, -and the parent's event loop will not include the child in its reference count. +By default, the parent will wait for the detached child to exit. To prevent +the parent from waiting for a given `child`, use the `child.unref()` method. +Doing so will cause the parent's event loop to not include the child in its +reference count, allowing the parent to exit independently of the child, unless +there is an established IPC channel between the child and parent. Example of detaching a long-running process and redirecting its output to a file: - var fs = require('fs'), - spawn = require('child_process').spawn, - out = fs.openSync('./out.log', 'a'), - err = fs.openSync('./out.log', 'a'); + const fs = require('fs'); + const spawn = require('child_process').spawn; + const out = fs.openSync('./out.log', 'a'); + const err = fs.openSync('./out.log', 'a'); - var child = spawn('prg', [], { + const child = spawn('prg', [], { detached: true, stdio: [ 'ignore', out, err ] }); @@ -607,14 +392,23 @@ controlling terminal. #### options.stdio -As a shorthand, the `stdio` argument may be one of the following strings: +The `options.stdio` option is used to configure the pipes that are established +between the parent and child process. By default, the child's stdin, stdout, +and stderr are redirected to corresponding `child.stdin`, `child.stdout`, and +`child.stderr` streams on the `ChildProcess` object. This is equivalent to +setting the `options.stdio` equal to `['pipe', 'pipe', 'pipe']`. -* `'pipe'` - `['pipe', 'pipe', 'pipe']`, this is the default value -* `'ignore'` - `['ignore', 'ignore', 'ignore']` -* `'inherit'` - `[process.stdin, process.stdout, process.stderr]` or `[0,1,2]` +For convenience, `options.stdio` may be one of the following strings: -Otherwise, the `'stdio'` option to [`child_process.spawn()`][] is an array where each -index corresponds to a fd in the child. The value is one of the following: +* `'pipe'` - equivalent to `['pipe', 'pipe', 'pipe']` (the default) +* `'ignore'` - equivalent to `['ignore', 'ignore', 'ignore']` +* `'inherit'` - equivalent to `[process.stdin, process.stdout, process.stderr]` + or `[0,1,2]` + +Otherwise, the value of `option.stdio` is an array where each index corresponds +to an fd in the child. The fds 0, 1, and 2 correspond to stdin, stdout, +and stderr, respectively. Additional fds can be specified to create additional +pipes between the parent and child. The value is one of the following: 1. `'pipe'` - Create a pipe between the child process and the parent process. The parent end of the pipe is exposed to the parent as a property on the @@ -624,13 +418,15 @@ index corresponds to a fd in the child. The value is one of the following: 2. `'ipc'` - Create an IPC channel for passing messages/file descriptors between parent and child. A ChildProcess may have at most *one* IPC stdio file descriptor. Setting this option enables the ChildProcess.send() method. - If the child writes JSON messages to this file descriptor, then this will - trigger ChildProcess.on('message'). If the child is an Node.js program, then - the presence of an IPC channel will enable process.send() and - process.on('message'). -3. `'ignore'` - Do not set this file descriptor in the child. Note that Node.js - will always open fd 0 - 2 for the processes it spawns. When any of these is - ignored Node.js will open `/dev/null` and attach it to the child's fd. + If the child writes JSON messages to this file descriptor, the + `ChildProcess.on('message')` event handler will be triggered in the parent. + If the child is a Node.js process, the presence of an IPC channel will enable + `process.send()`, `process.disconnect()`, `process.on('disconnect')`, and + `process.on('message')` within the child. +3. `'ignore'` - Instructs Node.js to ignore the fd in the child. While Node.js + will always open fds 0 - 2 for the processes it spawns, setting the fd to + `'ignore'` will cause Node.js to open `/dev/null` and attach it to the + child's fd. 4. `Stream` object - Share a readable or writable stream that refers to a tty, file, socket, or a pipe with the child process. The stream's underlying file descriptor is duplicated in the child process to the fd that @@ -646,7 +442,7 @@ index corresponds to a fd in the child. The value is one of the following: Example: - var spawn = require('child_process').spawn; + const spawn = require('child_process').spawn; // Child will use parent's stdios spawn('prg', [], { stdio: 'inherit' }); @@ -654,16 +450,25 @@ Example: // Spawn child sharing only stderr spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] }); - // Open an extra fd=4, to interact with programs present a + // Open an extra fd=4, to interact with programs presenting a // startd-style interface. spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] }); +*It is worth noting that when an IPC channel is established between the +parent and child processes, and the child is a Node.js process, the child +is launched with the IPC channel unreferenced (using `unref()`) until the +child registers an event handler for the `process.on('disconnected')` event. +This allows the child to exit normally without the process being held open +by the open IPC channel.* + See also: [`child_process.exec()`][] and [`child_process.fork()`][] ## Synchronous Process Creation -These methods are **synchronous**, meaning they **WILL** block the event loop, -pausing execution of your code until the spawned process exits. +The `child_process.spawnSync()`, `child_process.execSync()`, and +`child_process.execFileSync()` methods are **synchronous** and **WILL** block +the Node.js event loop, pausing execution of any additional code until the +spawned process exits. Blocking calls like these are mostly useful for simplifying general purpose scripting tasks and for simplifying the loading/processing of application @@ -690,11 +495,13 @@ configuration at startup. * `encoding` {String} The encoding used for all stdio inputs and outputs. (Default: 'buffer') * return: {Buffer|String} The stdout from the command -`execFileSync` will not return until the child process has fully closed. When a -timeout has been encountered and `killSignal` is sent, the method won't return -until the process has completely exited. That is to say, if the process handles -the `SIGTERM` signal and doesn't exit, your process will wait until the child -process has exited. +The `child_process.execFileSync()` method is generally identical to +`child_process.execFile()` with the exception that the method will not return +until the child process has fully closed. When a timeout has been encountered +and `killSignal` is sent, the method won't return until the process has +completely exited. *Note that if the child process intercepts and handles +the `SIGTERM` signal and does not exit, the parent process will still wait +until the child process has exited.* If the process times out, or has a non-zero exit code, this method ***will*** throw. The [`Error`][] object will contain the entire result from @@ -724,11 +531,13 @@ throw. The [`Error`][] object will contain the entire result from * `encoding` {String} The encoding used for all stdio inputs and outputs. (Default: 'buffer') * return: {Buffer|String} The stdout from the command -`execSync` will not return until the child process has fully closed. When a -timeout has been encountered and `killSignal` is sent, the method won't return -until the process has completely exited. That is to say, if the process handles -the `SIGTERM` signal and doesn't exit, your process will wait until the child -process has exited. +The `child_process.execSync()` method is generally identical to +`child_process.exec()` with the exception that the method will not return until +the child process has fully closed. When a timeout has been encountered and +`killSignal` is sent, the method won't return until the process has completely +exited. *Note that if the child process intercepts and handles the `SIGTERM` +signal and doesn't exit, the parent process will wait until the child +process has exited.* If the process times out, or has a non-zero exit code, this method ***will*** throw. The [`Error`][] object will contain the entire result from @@ -760,26 +569,370 @@ throw. The [`Error`][] object will contain the entire result from * `signal` {String} The signal used to kill the child process * `error` {Error} The error object if the child process failed or timed out -`spawnSync` will not return until the child process has fully closed. When a -timeout has been encountered and `killSignal` is sent, the method won't return -until the process has completely exited. That is to say, if the process handles -the `SIGTERM` signal and doesn't exit, your process will wait until the child +The `child_process.spawnSync()` method is generally identical to +`child_process.spawn()` with the exception that the function will not return +until the child process has fully closed. When a timeout has been encountered +and `killSignal` is sent, the method won't return until the process has +completely exited. Note that if the process intercepts and handles the +`SIGTERM` signal and doesn't exit, the parent process will wait until the child process has exited. +## Class: ChildProcess + +Instances of the `ChildProcess` class are [`EventEmitters`][] that represent +spawned child processes. + +Instances of `ChildProcess` are not intended to be created directly. Rather, +use the [`child_process.spawn()`][], [`child_process.exec()`][], +[`child_process.execFile()`][], or [`child_process.fork()`][] methods to create +instances of `ChildProcess`. + +### Event: 'close' + +* `code` {Number} the exit code if the child exited on its own. +* `signal` {String} the signal by which the child process was terminated. + +The `'close'` event is emitted when the stdio streams of a child process have +been closed. This is distinct from the `'exit'` event, since multiple +processes might share the same stdio streams. + +### Event: 'disconnect' + +The `'disconnect'` event is emitted after calling the +`ChildProcess.disconnect()` method in the parent or child process. After +disconnecting it is no longer possible to send or receive messages, and the +`ChildProcess.connected` property is false. + +### Event: 'error' + +* `err` {Error Object} the error. + +The `'error'` event is emitted whenever: + +1. The process could not be spawned, or +2. The process could not be killed, or +3. Sending a message to the child process failed. + +Note that the `'exit'` event may or may not fire after an error has occurred. +If you are listening to both the `'exit'` and `'error'` events, it is important +to guard against accidentally invoking handler functions multiple times. + +See also [`ChildProcess#kill()`][] and [`ChildProcess#send()`][]. + +### Event: 'exit' + +* `code` {Number} the exit code if the child exited on its own. +* `signal` {String} the signal by which the child process was terminated. + +The `'exit'` event is emitted after the child process ends. If the process +exited, `code` is the final exit code of the process, otherwise `null`. If the +process terminated due to receipt of a signal, `signal` is the string name of +the signal, otherwise `null`. One of the two will always be non-null. + +Note that when the `'exit'` event is triggered, child process stdio streams +might still be open. + +Also, note that Node.js establishes signal handlers for `SIGINT` and +`SIGTERM` and Node.js processes will not terminate immediately due to receipt +of those signals. Rather, Node.js will perform a sequence of cleanup actions +and then will re-raise the handled signal. + +See `waitpid(2)`. + +### Event: 'message' + +* `message` {Object} a parsed JSON object or primitive value. +* `sendHandle` {Handle object} a [`net.Socket`][] or [`net.Server`][] object, or + undefined. + +The `'message'` event is triggered when a child process uses `process.send()` +to send messages. + +### child.connected + +* {Boolean} Set to false after `.disconnect` is called + +The `child.connected` property indicates whether it is still possible to send +and receive messages from a child process. When `child.connected` is false, it +is no longer possible to send or receive messages. + +### child.disconnect() + +Closes the IPC channel between parent and child, allowing the child to exit +gracefully once there are no other connections keeping it alive. After calling +this method the `child.connected` and `process.connected` properties in both +the parent and child (respectively) will be set to `false`, and it will be no +longer possible to pass messages between the processes. + +The `'disconnect'` event will be emitted when there are no messages in the +process of being received. This will most often be triggered immediately after +calling `child.disconnect()`. + +Note that when the child process is a Node.js instance (e.g. spawned using +[`child_process.fork()`]), the `process.disconnect()` method can be invoked +within the child process to close the IPC channel as well. + +### child.kill([signal]) + +* `signal` {String} + +The `child.kill()` methods sends a signal to the child process. If no argument +is given, the process will be sent the `'SIGTERM'` signal. See `signal(7)` for +a list of available signals. + + const spawn = require('child_process').spawn; + const grep = spawn('grep', ['ssh']); + + grep.on('close', (code, signal) => { + console.log( + `child process terminated due to receipt of signal ${signal}`); + }); + + // Send SIGHUP to process + grep.kill('SIGHUP'); + +The `ChildProcess` object may emit an `'error'` event if the signal cannot be +delivered. Sending a signal to a child process that has already exited is not +an error but may have unforeseen consequences. Specifically, if the process +identifier (PID) has been reassigned to another process, the signal will be +delivered to that process instead which can have unexpected results. + +Note that while the function is called `kill`, the signal delivered to the +child process may not actually terminate the process. + +See `kill(2)` + +### child.pid + +* {Integer} + +Returns the process identifier (PID) of the child process. + +Example: + + const spawn = require('child_process').spawn; + const grep = spawn('grep', ['ssh']); + + console.log(`Spawned child pid: ${grep.pid}`); + grep.stdin.end(); + +### child.send(message[, sendHandle][, callback]) + +* `message` {Object} +* `sendHandle` {Handle object} +* `callback` {Function} +* Return: Boolean + +When an IPC channel has been established between the parent and child ( +i.e. when using [`child_process.fork()`][]), the `child.send()` method can be +used to send messages to the child process. When the child process is a Node.js +instance, these messages can be received via the `process.on('message')` event. + +For example, in the parent script: + + const cp = require('child_process'); + const n = cp.fork(`${__dirname}/sub.js`); + + n.on('message', (m) => { + console.log('PARENT got message:', m); + }); + + n.send({ hello: 'world' }); + +And then the child script, `'sub.js'` might look like this: + + process.on('message', (m) => { + console.log('CHILD got message:', m); + }); + + process.send({ foo: 'bar' }); + +Child Node.js processes will have a `process.send()` method of their own that +allows the child to send messages back to the parent. + +There is a special case when sending a `{cmd: 'NODE_foo'}` message. All messages +containing a `NODE_` prefix in its `cmd` property are considered to be reserved +for use within Node.js core and will not be emitted in the child's +`process.on('message')` event. Rather, such messages are emitted using the +`process.on('internalMessage')` event and are consumed internally by Node.js. +Applications should avoid using such messages or listening for +`'internalMessage'` events as it is subject to change without notice. + +The optional `sendHandle` argument that may be passed to `child.send()` is for +passing a TCP server or socket object to the child process. The child will +receive the object as the second argument passed to the callback function +registered on the `process.on('message')` event. + +The optional `callback` is a function that is invoked after the message is +sent but before the child may have received it. The function is called with a +single argument: `null` on success, or an [`Error`][] object on failure. + +If no `callback` function is provided and the message cannot be sent, an +`'error'` event will be emitted by the `ChildProcess` object. This can happen, +for instance, when the child process has already exited. + +`child.send()` will return `false` if the channel has closed or when the +backlog of unsent messages exceeds a threshold that makes it unwise to send +more. Otherwise, the method returns `true`. The `callback` function can be +used to implement flow control. + +#### Example: sending a server object + +The `sendHandle` argument can be used, for instance, to pass the handle of +a TSCP server object to the child process as illustrated in the example below: + + const child = require('child_process').fork('child.js'); + + // Open up the server object and send the handle. + const server = require('net').createServer(); + server.on('connection', (socket) => { + socket.end('handled by parent'); + }); + server.listen(1337, () => { + child.send('server', server); + }); + +The child would then receive the server object as: + + process.on('message', (m, server) => { + if (m === 'server') { + server.on('connection', (socket) => { + socket.end('handled by child'); + }); + } + }); + +Once the server is now shared between the parent and child, some connections +can be handled by the parent and some by the child. + +While the example above uses a server created using the `net` module, `dgram` +module servers use exactly the same workflow with the exceptions of listening on +a `'message'` event instead of `'connection'` and using `server.bind` instead of +`server.listen`. This is, however, currently only supported on UNIX platforms. + +#### Example: sending a socket object + +Similarly, the `sendHandler` argument can be used to pass the handle of a +socket to the child process. The example below spawns two children that each +handle connections with "normal" or "special" priority: + + const normal = require('child_process').fork('child.js', ['normal']); + const special = require('child_process').fork('child.js', ['special']); + + // Open up the server and send sockets to child + const server = require('net').createServer(); + server.on('connection', (socket) => { + + // If this is special priority + if (socket.remoteAddress === '74.125.127.100') { + special.send('socket', socket); + return; + } + // This is normal priority + normal.send('socket', socket); + }); + server.listen(1337); + +The `child.js` would receive the socket handle as the second argument passed +to the event callback function: + + process.on('message', (m, socket) => { + if (m === 'socket') { + socket.end(`Request handled with ${process.argv[2]} priority`); + } + }); + +Once a socket has been passed to a child, the parent is no longer capable of +tracking when the socket is destroyed. To indicate this, the `.connections` +property becomes `null`. It is recommended not to use `.maxConnections` when +this occurs. + +### child.stderr + +* {Stream object} + +A `Readable Stream` that represents the child process's `stderr`. + +If the child was spawned with `stdio[2]` set to anything other than `'pipe'`, +then this will be `undefined`. + +`child.stderr` is an alias for `child.stdio[2]`. Both properties will refer to +the same value. + +### child.stdin + +* {Stream object} + +A `Writable Stream` that represents the child process's `stdin`. + +*Note that if a child process waits to read all of its input, the child will not +continue until this stream has been closed via `end()`.* + +If the child was spawned with `stdio[0]` set to anything other than `'pipe'`, +then this will be `undefined`. + +`child.stdin` is an alias for `child.stdio[0]`. Both properties will refer to +the same value. + +### child.stdio + +* {Array} + +A sparse array of pipes to the child process, corresponding with positions in +the [`stdio`][] option passed to [`child_process.spawn()`][] that have been set +to the value `'pipe'`. Note that `child.stdio[0]`, `child.stdio[1]`, and +`child.stdio[2]` are also available as `child.stdin`, `child.stdout`, and +`child.stderr`, respectively. + +In the following example, only the child's fd `1` (stdout) is configured as a +pipe, so only the parent's `child.stdio[1]` is a stream, all other values in +the array are `null`. + + const assert = require('assert'); + const fs = require('fs'); + const child_process = require('child_process'); + + const child = child_process.spawn('ls', { + stdio: [ + 0, // Use parents stdin for child + 'pipe', // Pipe child's stdout to parent + fs.openSync('err.out', 'w') // Direct child's stderr to a file + ] + }); + + assert.equal(child.stdio[0], null); + assert.equal(child.stdio[0], child.stdin); + + assert(child.stdout); + assert.equal(child.stdio[1], child.stdout); + + assert.equal(child.stdio[2], null); + assert.equal(child.stdio[2], child.stderr); + +### child.stdout + +* {Stream object} + +A `Readable Stream` that represents the child process's `stdout`. + +If the child was spawned with `stdio[1]` set to anything other than `'pipe'`, +then this will be `undefined`. + +`child.stdout` is an alias for `child.stdio[1]`. Both properties will refer +to the same value. + +[`popen(3)`]: http://linux.die.net/man/3/popen [`child_process.exec()`]: #child_process_child_process_exec_command_options_callback +[`child_process.execFile()`]: #child_process_child_process_execfile_file_args_options_callback [`child_process.fork()`]: #child_process_child_process_fork_modulepath_args_options [`child_process.spawn()`]: #child_process_child_process_spawn_command_args_options [`child_process.spawnSync()`]: #child_process_child_process_spawnsync_command_args_options [`ChildProcess#kill()`]: #child_process_child_kill_signal [`ChildProcess#send()`]: #child_process_child_send_message_sendhandle_callback [`Error`]: errors.html#errors_class_error -[`EventEmitter`]: events.html#events_class_events_eventemitter -[`exec()`]: #child_process_child_process_exec_command_options_callback -[`execFile()`]: #child_process_child_process_execfile_file_args_options_callback -[`fork()`]: #child_process_child_process_fork_modulepath_args_options +[`EventEmitters`]: events.html#events_class_events_eventemitter [`net.Server`]: net.html#net_class_net_server [`net.Socket`]: net.html#net_class_net_socket -[`spawn()`]: #child_process_child_process_spawn_command_args_options [`stdio`]: #child_process_options_stdio [below]: #child_process_asynchronous_process_creation [synchronous counterparts]: #child_process_synchronous_process_creation diff --git a/doc/api/cluster.markdown b/doc/api/cluster.markdown index d300b274a162..b29c13694b00 100644 --- a/doc/api/cluster.markdown +++ b/doc/api/cluster.markdown @@ -9,9 +9,9 @@ processes to handle the load. The cluster module allows you to easily create child processes that all share server ports. - var cluster = require('cluster'); - var http = require('http'); - var numCPUs = require('os').cpus().length; + const cluster = require('cluster'); + const http = require('http'); + const numCPUs = require('os').cpus().length; if (cluster.isMaster) { // Fork workers. @@ -19,15 +19,15 @@ all share server ports. cluster.fork(); } - cluster.on('exit', function(worker, code, signal) { - console.log('worker ' + worker.process.pid + ' died'); + cluster.on('exit', (worker, code, signal) => { + console.log(`worker ${worker.process.pid} died`); }); } else { // Workers can share any TCP connection // In this case it is an HTTP server - http.createServer(function(req, res) { + http.createServer((req, res) => { res.writeHead(200); - res.end("hello world\n"); + res.end('hello world\n'); }).listen(8000); } @@ -113,7 +113,7 @@ it can be obtained using `cluster.worker`. Similar to the `cluster.on('disconnect')` event, but specific to this worker. - cluster.fork().on('disconnect', function() { + cluster.fork().on('disconnect', () => { // Worker has disconnected }); @@ -131,14 +131,14 @@ In a worker you can also use `process.on('error')`. Similar to the `cluster.on('exit')` event, but specific to this worker. - var worker = cluster.fork(); - worker.on('exit', function(code, signal) { + const worker = cluster.fork(); + worker.on('exit', (code, signal) => { if( signal ) { - console.log("worker was killed by signal: "+signal); + console.log(`worker was killed by signal: ${signal}`); } else if( code !== 0 ) { - console.log("worker exited with error code: "+code); + console.log(`worker exited with error code: ${code}`); } else { - console.log("worker success!"); + console.log('worker success!'); } }); @@ -148,7 +148,7 @@ Similar to the `cluster.on('exit')` event, but specific to this worker. Similar to the `cluster.on('listening')` event, but specific to this worker. - cluster.fork().on('listening', function(address) { + cluster.fork().on('listening', (address) => { // Worker is listening }); @@ -167,15 +167,15 @@ In a worker you can also use `process.on('message')`. As an example, here is a cluster that keeps count of the number of requests in the master process using the message system: - var cluster = require('cluster'); - var http = require('http'); + const cluster = require('cluster'); + const http = require('http'); if (cluster.isMaster) { // Keep track of http requests var numReqs = 0; - setInterval(function() { - console.log("numReqs =", numReqs); + setInterval(() => { + console.log('numReqs =', numReqs); }, 1000); // Count requests @@ -186,21 +186,21 @@ in the master process using the message system: } // Start workers and listen for messages containing notifyRequest - var numCPUs = require('os').cpus().length; + const numCPUs = require('os').cpus().length; for (var i = 0; i < numCPUs; i++) { cluster.fork(); } - Object.keys(cluster.workers).forEach(function(id) { + Object.keys(cluster.workers).forEach((id) => { cluster.workers[id].on('message', messageHandler); }); } else { // Worker processes have a http server. - http.Server(function(req, res) { + http.Server((req, res) => { res.writeHead(200); - res.end("hello world\n"); + res.end('hello world\n'); // notify master about the request process.send({ cmd: 'notifyRequest' }); @@ -211,7 +211,7 @@ in the master process using the message system: Similar to the `cluster.on('online')` event, but specific to this worker. - cluster.fork().on('online', function() { + cluster.fork().on('online', () => { // Worker is online }); @@ -249,27 +249,27 @@ the `'disconnect'` event has not been emitted after some time. var worker = cluster.fork(); var timeout; - worker.on('listening', function(address) { + worker.on('listening', (address) => { worker.send('shutdown'); worker.disconnect(); - timeout = setTimeout(function() { + timeout = setTimeout(() => { worker.kill(); }, 2000); }); - worker.on('disconnect', function() { + worker.on('disconnect', () => { clearTimeout(timeout); }); } else if (cluster.isWorker) { - var net = require('net'); - var server = net.createServer(function(socket) { + const net = require('net'); + var server = net.createServer((socket) => { // connections never end }); server.listen(8000); - process.on('message', function(msg) { + process.on('message', (msg) => { if(msg === 'shutdown') { // initiate graceful close of any connections to server } @@ -349,7 +349,7 @@ This example will echo back all messages from the master: worker.send('hi there'); } else if (cluster.isWorker) { - process.on('message', function(msg) { + process.on('message', (msg) => { process.send(msg); }); } @@ -363,7 +363,7 @@ Set by calling `.kill()` or `.disconnect()`, until then it is `undefined`. The boolean `worker.suicide` lets you distinguish between voluntary and accidental exit, the master may choose not to respawn a worker based on this value. - cluster.on('exit', function(worker, code, signal) { + cluster.on('exit', (worker, code, signal) => { if (worker.suicide === true) { console.log('Oh, it was just suicide\' – no need to worry'). } @@ -384,8 +384,8 @@ There may be a delay between the `'disconnect'` and `'exit'` events. These even can be used to detect if the process is stuck in a cleanup or if there are long-living connections. - cluster.on('disconnect', function(worker) { - console.log('The worker #' + worker.id + ' has disconnected'); + cluster.on('disconnect', (worker) => { + console.log(`The worker #${worker.id} has disconnected`); }); ## Event: 'exit' @@ -399,7 +399,7 @@ When any of the workers die the cluster module will emit the `'exit'` event. This can be used to restart the worker by calling `.fork()` again. - cluster.on('exit', function(worker, code, signal) { + cluster.on('exit', (worker, code, signal) => { console.log('worker %d died (%s). restarting...', worker.process.pid, signal || code); cluster.fork(); @@ -416,16 +416,16 @@ This can be used to log worker activity, and create your own timeout. var timeouts = []; function errorMsg() { - console.error("Something must be wrong with the connection ..."); + console.error('Something must be wrong with the connection ...'); } - cluster.on('fork', function(worker) { + cluster.on('fork', (worker) => { timeouts[worker.id] = setTimeout(errorMsg, 2000); }); - cluster.on('listening', function(worker, address) { + cluster.on('listening', (worker, address) => { clearTimeout(timeouts[worker.id]); }); - cluster.on('exit', function(worker, code, signal) { + cluster.on('exit', (worker, code, signal) => { clearTimeout(timeouts[worker.id]); errorMsg(); }); @@ -443,8 +443,9 @@ object and the `address` object contains the following connection properties: `address`, `port` and `addressType`. This is very useful if the worker is listening on more than one address. - cluster.on('listening', function(worker, address) { - console.log("A worker is now connected to " + address.address + ":" + address.port); + cluster.on('listening', (worker, address) => { + console.log( + `A worker is now connected to ${address.address}:${address.port}`); }); The `addressType` is one of: @@ -472,8 +473,8 @@ When the master receives an online message it will emit this event. The difference between `'fork'` and `'online'` is that fork is emitted when the master forks a worker, and 'online' is emitted when the worker is running. - cluster.on('online', function(worker) { - console.log("Yay, the worker responded after it was forked"); + cluster.on('online', (worker) => { + console.log('Yay, the worker responded after it was forked'); }); ## Event: 'setup' @@ -584,7 +585,7 @@ Note that: Example: - var cluster = require('cluster'); + const cluster = require('cluster'); cluster.setupMaster({ exec: 'worker.js', args: ['--use', 'https'], @@ -604,14 +605,14 @@ This can only be called from the master process. A reference to the current worker object. Not available in the master process. - var cluster = require('cluster'); + const cluster = require('cluster'); if (cluster.isMaster) { console.log('I am master'); cluster.fork(); cluster.fork(); } else if (cluster.isWorker) { - console.log('I am worker #' + cluster.worker.id); + console.log(`I am worker #${cluster.worker.id}`); } ## cluster.workers @@ -633,14 +634,14 @@ before last `'disconnect'` or `'exit'` event is emitted. callback(cluster.workers[id]); } } - eachWorker(function(worker) { + eachWorker((worker) => { worker.send('big announcement to all workers'); }); Should you wish to reference a worker over a communication channel, using the worker's unique id is the easiest way to find the worker. - socket.on('data', function(id) { + socket.on('data', (id) => { var worker = cluster.workers[id]; }); diff --git a/doc/api/console.markdown b/doc/api/console.markdown index 6343ca781c3d..5c2596fe605f 100644 --- a/doc/api/console.markdown +++ b/doc/api/console.markdown @@ -2,79 +2,114 @@ Stability: 2 - Stable -The module defines a `Console` class and exports a `console` object. +The `console` module provides a simple debugging console that is similar to the +JavaScript console mechanism provided by web browsers. -The `console` object is a special instance of `Console` whose output is -sent to stdout or stderr. +The module exports two specific components: -For ease of use, `console` is defined as a global object and can be used -directly without `require`. +* A `Console` class with methods such as `console.log()`, `console.error()` and + `console.warn()` that can be used to write to any Node.js stream. +* A global `console` instance configured to write to `stdout` and `stderr`. + Because this object is global, it can be used without calling + `require('console')`. + +Example using the global `console`: + + console.log('hello world'); + // Prints: hello world, to stdout + console.log('hello %s', 'world'); + // Prints: hello world, to stdout + console.error(new Error('Whoops, something bad happened')); + // Prints: [Error: Whoops, something bad happened], to stderr + + const name = 'Will Robinson'; + console.warn(`Danger ${name}! Danger!`); + // Prints: Danger Will Robinson! Danger!, to stderr + +Example using the `Console` class: + + const out = getStreamSomehow(); + const err = getStreamSomehow(); + const myConsole = new console.Console(out, err); + + myConsole.log('hello world'); + // Prints: hello world, to out + myConsole.log('hello %s', 'world'); + // Prints: hello world, to out + myConsole.error(new Error('Whoops, something bad happened')); + // Prints: [Error: Whoops, something bad happened], to err + + const name = 'Will Robinson'; + myConsole.warn(`Danger ${name}! Danger!`); + // Prints: Danger Will Robinson! Danger!, to err + +While the API for the `Console` class is designed fundamentally around the +Web browser `console` object, the `Console` is Node.js is *not* intended to +duplicate the browsers functionality exactly. + +## Asynchronous vs Synchronous Consoles + +The console functions are synchronous when the destination is a terminal or +a file (to avoid lost messages in case of premature exit) and asynchronous +when the destination is a pipe (to avoid blocking for long periods of time). + +In the following example, stdout is non-blocking while stderr is blocking: + + $ node script.js 2> error.log | tee info.log + +Typically, the distinction between blocking/non-blocking is not important +unless an application is logging significant amounts of data. High volume +logging *should* use a `Console` instance that writes to a pipe. ## Class: Console -Use `require('console').Console` or `console.Console` to access this class. +The `Console` class can be used to create a simple logger with configurable +output streams and can be accessed using either `require('console').Console` +or `console.Console`: - var Console = require('console').Console; - var Console = console.Console; - -You can use the `Console` class to create a simple logger like `console` but -with different output streams. + const Console = require('console').Console; + const Console = console.Console; ### new Console(stdout[, stderr]) -Create a new `Console` by passing one or two writable stream instances. +Creates a new `Console` by passing one or two writable stream instances. `stdout` is a writable stream to print log or info output. `stderr` is used for warning or error output. If `stderr` isn't passed, the warning and error output will be sent to the `stdout`. - var output = fs.createWriteStream('./stdout.log'); - var errorOutput = fs.createWriteStream('./stderr.log'); + const output = fs.createWriteStream('./stdout.log'); + const errorOutput = fs.createWriteStream('./stderr.log'); // custom simple logger - var logger = new Console(output, errorOutput); + const logger = new Console(output, errorOutput); // use it like console var count = 5; logger.log('count: %d', count); // in stdout.log: count 5 The global `console` is a special `Console` whose output is sent to -`process.stdout` and `process.stderr`: +`process.stdout` and `process.stderr`. It is equivalent to calling: new Console(process.stdout, process.stderr); -## console - -* {Object} - - - -For printing to stdout and stderr. Similar to the console object functions -provided by most web browsers, here the output is sent to stdout or stderr. - -The console functions are synchronous when the destination is a terminal or -a file (to avoid lost messages in case of premature exit) and asynchronous -when it's a pipe (to avoid blocking for long periods of time). - -That is, in the following example, stdout is non-blocking while stderr -is blocking: - - $ node script.js 2> error.log | tee info.log - -Typically, the blocking/non-blocking dichotomy is not something you should -worry about unless you log huge amounts of data. - ### console.assert(value[, message][, ...]) -Similar to [`assert.ok()`][], but the error message is formatted as -`util.format(message...)`. +A simple assertion test that verifies whether `value` is truthy. If it is not, +an `AssertionError` is throw. If provided, the error `message` is formatted +using [`util.format()`][] and used as the error message. + + console.assert(true, 'does nothing'); + // OK + console.assert(false, 'Whoops %s', 'didn\'t work'); + // AssertionError: Whoops didn't work ### console.dir(obj[, options]) Uses [`util.inspect()`][] on `obj` and prints the resulting string to stdout. -This function bypasses any custom `inspect()` function on `obj`. An optional -`options` object may be passed that alters certain aspects of the formatted -string: +This function bypasses any custom `inspect()` function defined on `obj`. An +optional `options` object may be passed that alters certain aspects of the +formatted string: - `showHidden` - if `true` then the object's non-enumerable and symbol properties will be shown too. Defaults to `false`. @@ -89,36 +124,53 @@ Defaults to `false`. Colors are customizable; see ### console.error([data][, ...]) -Same as [`console.log()`][] but prints to stderr. +Prints to stderr with newline. Multiple arguments can be passed, with the first +used as the primary message and all additional used as substitution +values similar to `printf()` (the arguments are all passed to +[`util.format()`][]). + + const code = 5; + console.error('error #%d', code); + // Prints: error #5, to stderr + console.error('error', code); + // Prints: error 5, to stderr + +If formatting elements (e.g. `%d`) are not found in the first string then +[`util.inspect()`][] is called on each argument and the resulting string +values are concatenated. See [`util.format()`][] for more information. ### console.info([data][, ...]) -Same as [`console.log()`][]. +The `console.info()` function is an alias for [`console.log()`][]. ### console.log([data][, ...]) -Prints to stdout with newline. This function can take multiple arguments in a -`printf()`-like way: +Prints to stdout with newline. Multiple arguments can be passed, with the first +used as the primary message and all additional used as substitution +values similar to `printf()` (the arguments are all passed to +[`util.format()`][]). var count = 5; console.log('count: %d', count); - // prints 'count: 5' + // Prints: count: 5, to stdout + console.log('count: ', count); + // Prints: count: 5, to stdout -If formatting elements are not found in the first string then -[`util.inspect()`][] is used on each argument. See [`util.format()`][] for more -information. +If formatting elements (e.g. `%d`) are not found in the first string then +[`util.inspect()`][] is called on each argument and the resulting string +values are concatenated. See [`util.format()`][] for more information. ### console.time(label) Starts a timer that can be used to compute the duration of an operation. Timers -are identified by a unique name. Use the same name when you call +are identified by a unique `label`. Use the same `label` when you call [`console.timeEnd()`][] to stop the timer and output the elapsed time in -milliseconds. Timer durations are accurate to the sub-millisecond. +milliseconds to stdout. Timer durations are accurate to the sub-millisecond. ### console.timeEnd(label) Stops a timer that was previously started by calling [`console.time()`][] and -prints the result to the console: +prints the result to stdout: console.time('100-elements'); for (var i = 0; i < 100; i++) { @@ -129,18 +181,30 @@ prints the result to the console: ### console.trace(message[, ...]) -Print to stderr `'Trace :'`, followed by the formatted message and stack trace -to the current position. +Prints to stderr the string `'Trace :'`, followed by the [`util.format()`][] +formatted message and stack trace to the current position in the code. + + console.trace('Show me'); + // Prints: (stack trace will vary based on where trace is called) + // Trace: Show me + // at repl:2:9 + // at REPLServer.defaultEval (repl.js:248:27) + // at bound (domain.js:287:14) + // at REPLServer.runBound [as eval] (domain.js:300:12) + // at REPLServer. (repl.js:412:12) + // at emitOne (events.js:82:20) + // at REPLServer.emit (events.js:169:7) + // at REPLServer.Interface._onLine (readline.js:210:10) + // at REPLServer.Interface._line (readline.js:549:8) + // at REPLServer.Interface._ttyWrite (readline.js:826:14) ### console.warn([data][, ...]) -Same as [`console.error()`][]. +The `console.warn()` function is an alias for [`console.error()`][]. -[`assert.ok()`]: assert.html#assert_assert_value_message_assert_ok_value_message [`console.error()`]: #console_console_error_data [`console.log()`]: #console_console_log_data [`console.time()`]: #console_console_time_label [`console.timeEnd()`]: #console_console_timeend_label [`util.format()`]: util.html#util_util_format_format [`util.inspect()`]: util.html#util_util_inspect_object_options -[customizing `util.inspect()` colors]: util.html#util_customizing_util_inspect_colors diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown index f90ec1c429a8..a731d979ac88 100644 --- a/doc/api/crypto.markdown +++ b/doc/api/crypto.markdown @@ -280,9 +280,9 @@ associated with the private key being set. Example (obtaining a shared secret): - var crypto = require('crypto'); - var alice = crypto.createECDH('secp256k1'); - var bob = crypto.createECDH('secp256k1'); + const crypto = require('crypto'); + const alice = crypto.createECDH('secp256k1'); + const bob = crypto.createECDH('secp256k1'); // Note: This is a shortcut way to specify one of Alice's previous private // keys. It would be unwise to use such a predictable private key in a real @@ -294,8 +294,8 @@ Example (obtaining a shared secret): // Bob uses a newly generated cryptographically strong pseudorandom key pair bob.generateKeys(); - var alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); - var bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); + const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); + const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); // alice_secret and bob_secret should be the same shared secret value console.log(alice_secret === bob_secret); @@ -535,20 +535,20 @@ algorithms. Example: this program that takes the sha256 sum of a file - var filename = process.argv[2]; - var crypto = require('crypto'); - var fs = require('fs'); + const filename = process.argv[2]; + const crypto = require('crypto'); + const fs = require('fs'); - var shasum = crypto.createHash('sha256'); + const shasum = crypto.createHash('sha256'); - var s = fs.ReadStream(filename); - s.on('data', function(d) { + const s = fs.ReadStream(filename); + s.on('data', (d) => { shasum.update(d); }); - s.on('end', function() { + s.on('end', () => { var d = shasum.digest('hex'); - console.log(d + ' ' + filename); + console.log(`${d} ${filename}`); }); ## crypto.createHmac(algorithm, key) @@ -581,7 +581,7 @@ Returns an array with the names of the supported ciphers. Example: - var ciphers = crypto.getCiphers(); + const ciphers = crypto.getCiphers(); console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...] ## crypto.getCurves() @@ -590,7 +590,7 @@ Returns an array with the names of the supported elliptic curves. Example: - var curves = crypto.getCurves(); + const curves = crypto.getCurves(); console.log(curves); // ['secp256k1', 'secp384r1', ...] ## crypto.getDiffieHellman(group_name) @@ -608,15 +608,15 @@ and communication time. Example (obtaining a shared secret): - var crypto = require('crypto'); - var alice = crypto.getDiffieHellman('modp14'); - var bob = crypto.getDiffieHellman('modp14'); + const crypto = require('crypto'); + const alice = crypto.getDiffieHellman('modp14'); + const bob = crypto.getDiffieHellman('modp14'); alice.generateKeys(); bob.generateKeys(); - var alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); - var bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); + const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); + const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); /* alice_secret and bob_secret should be the same */ console.log(alice_secret == bob_secret); @@ -627,7 +627,7 @@ Returns an array with the names of the supported hash algorithms. Example: - var hashes = crypto.getHashes(); + const hashes = crypto.getHashes(); console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...] ## crypto.pbkdf2(password, salt, iterations, keylen[, digest], callback) @@ -711,7 +711,7 @@ NOTE: All paddings are defined in `constants` module. Generates cryptographically strong pseudo-random data. Usage: // async - crypto.randomBytes(256, function(ex, buf) { + crypto.randomBytes(256, (ex, buf) => { if (ex) throw ex; console.log('Have %d bytes of random data: %s', buf.length, buf); }); diff --git a/doc/api/debugger.markdown b/doc/api/debugger.markdown index 7154b7ae50db..1f9d6703b7e0 100644 --- a/doc/api/debugger.markdown +++ b/doc/api/debugger.markdown @@ -4,9 +4,10 @@ -V8 comes with an extensive debugger which is accessible out-of-process via a -simple [TCP protocol][]. Node.js has a built-in client for this debugger. To -use this, start Node.js with the `debug` argument; a prompt will appear: +Node.js includes a full-featured out-of-process debugging utility accessible +via a simple [TCP-based protocol][] and built-in debugging client. To use it, +start Node.js with the `debug` argument followed by the path to the script to +debug; a prompt will be displayed indicating successful launch of the debugger: % node debug myscript.js < debugger listening on port 5858 @@ -17,21 +18,23 @@ use this, start Node.js with the `debug` argument; a prompt will appear: 3 debugger; debug> -Node.js's debugger client doesn't support the full range of commands, but -simple step and inspection is possible. By putting the statement `debugger;` -into the source code of your script, you will enable a breakpoint. +Node.js's debugger client does not yet support the full range of commands, but +simple step and inspection are possible. -For example, suppose `myscript.js` looked like this: +Inserting the statement `debugger;` into the source code of a script will +enable a breakpoint at that position in the code. + +For example, suppose `myscript.js` is written as: // myscript.js x = 5; setTimeout(function () { debugger; - console.log("world"); + console.log('world'); }, 1000); - console.log("hello"); + console.log('hello'); -Then once the debugger is run, it will break on line 4. +Once the debugger is run, a breakpoint will occur at line 4: % node debug myscript.js < debugger listening on port 5858 @@ -46,15 +49,15 @@ Then once the debugger is run, it will break on line 4. 1 x = 5; 2 setTimeout(function () { 3 debugger; - 4 console.log("world"); + 4 console.log('world'); 5 }, 1000); debug> next break in /home/indutny/Code/git/indutny/myscript.js:4 2 setTimeout(function () { 3 debugger; - 4 console.log("world"); + 4 console.log('world'); 5 }, 1000); - 6 console.log("hello"); + 6 console.log('hello'); debug> repl Press Ctrl + C to leave debug repl > x @@ -65,28 +68,28 @@ Then once the debugger is run, it will break on line 4. < world break in /home/indutny/Code/git/indutny/myscript.js:5 3 debugger; - 4 console.log("world"); + 4 console.log('world'); 5 }, 1000); - 6 console.log("hello"); + 6 console.log('hello'); 7 debug> quit % -The `repl` command allows you to evaluate code remotely. The `next` command -steps over to the next line. There are a few other commands available and more -to come. Type `help` to see others. +The `repl` command allows code to be evaluated remotely. The `next` command +steps over to the next line. Type `help` to see what other commands are +available. ## Watchers -You can watch expression and variable values while debugging your code. -On every breakpoint each expression from the watchers list will be evaluated -in the current context and displayed just before the breakpoint's source code -listing. +It is possible to watch expression and variable values while debugging. On +every breakpoint, each expression from the watchers list will be evaluated +in the current context and displayed immediately before the breakpoint's +source code listing. -To start watching an expression, type `watch("my_expression")`. `watchers` -prints the active watchers. To remove a watcher, type -`unwatch("my_expression")`. +To begin watching an expression, type `watch('my_expression')`. The command +`watchers` will print the active watchers. To remove a watcher, type +`unwatch('my_expression')`. ## Commands reference @@ -154,19 +157,20 @@ breakpoint) ### Various * `scripts` - List all loaded scripts -* `version` - Display v8's version +* `version` - Display V8's version ## Advanced Usage -The V8 debugger can be enabled and accessed either by starting Node.js with -the `--debug` command-line flag or by signaling an existing Node.js process -with `SIGUSR1`. +An alternative way of enabling and accessing the debugger is to start +Node.js with the `--debug` command-line flag or by signaling an existing +Node.js process with `SIGUSR1`. -Once a process has been set in debug mode with this it can be connected to -with the Node.js debugger. Either connect to the `pid` or the URI to the -debugger. The syntax is: +Once a process has been set in debug mode this way, it can be connected to +using the Node.js debugger by either connecting to the `pid` of the running +process or via URI reference to the listening debugger: * `node debug -p ` - Connects to the process via the `pid` -* `node debug ` - Connects to the process via the URI such as localhost:5858 +* `node debug ` - Connects to the process via the URI such as +localhost:5858 -[TCP protocol]: https://github.com/v8/v8/wiki/Debugging-Protocol +[TCP-based protocol]: https://github.com/v8/v8/wiki/Debugging-Protocol diff --git a/doc/api/dgram.markdown b/doc/api/dgram.markdown index 71c59db3bf74..78bf3c2210bf 100644 --- a/doc/api/dgram.markdown +++ b/doc/api/dgram.markdown @@ -4,52 +4,64 @@ -Datagram sockets are available through `require('dgram')`. +The `dgram` module provides an implementation of UDP Datagram sockets. -Important note: the behavior of [`dgram.Socket#bind()`][] has changed in v0.10 -and is always asynchronous now. If you have code that looks like this: + const dgram = require('dgram'); + const server = dgram.createSocket('udp4'); - var s = dgram.createSocket('udp4'); - s.bind(1234); - s.addMembership('224.0.0.114'); + server.on('error', (err) => { + console.log(`server error:\n${err.stack}`); + server.close(); + }); -You have to change it to this: + server.on('message', (msg, rinfo) => { + console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); + }); - var s = dgram.createSocket('udp4'); - s.bind(1234, function() { - s.addMembership('224.0.0.114'); + server.on('listening', () => { + var address = server.address(); + console.log(`server listening ${address.address}:${address.port}`); }); + server.bind(41234); + // server listening 0.0.0.0:41234 + ## Class: dgram.Socket -The dgram Socket class encapsulates the datagram functionality. It -should be created via [`dgram.createSocket(...)`][] +The `dgram.Socket` object is an [`EventEmitter`][] that encapsulates the +datagram functionality. + +New instances of `dgram.Socket` are created using [`dgram.createSocket()`][]. +The `new` keyword is not to be used to create `dgram.Socket` instances. ### Event: 'close' -Emitted after a socket is closed with [`close()`][]. No new `'message'` events will be emitted -on this socket. +The `'close'` event is emitted after a socket is closed with [`close()`][]. +Once triggered, no new `'message'` events will be emitted on this socket. ### Event: 'error' * `exception` Error object -Emitted when an error occurs. +The `'error'` event is emitted whenever any error occurs. The event handler +function is passed a single Error object. ### Event: 'listening' -Emitted when a socket starts listening for datagrams. This happens as soon as UDP sockets -are created. +The `'listening'` event is emitted whenever a socket begins listening for +datagram messages. This occurs as soon as UDP sockets are created. ### Event: 'message' * `msg` Buffer object. The message * `rinfo` Object. Remote address information -Emitted when a new datagram is available on a socket. `msg` is a `Buffer` and -`rinfo` is an object with the sender's address information: +The `'message'` event is emitted when a new datagram is available on a socket. +The event handler function is passed two arguments: `msg` and `rinfo`. The +`msg` argument is a [`Buffer`][] and `rinfo` is an object with the sender's +address information provided by the `address`, `family` and `port` properties: - socket.on('message', function(msg, rinfo) { + socket.on('message', (msg, rinfo) => { console.log('Received %d bytes from %s:%d\n', msg.length, rinfo.address, rinfo.port); }); @@ -59,57 +71,58 @@ Emitted when a new datagram is available on a socket. `msg` is a `Buffer` and * `multicastAddress` String * `multicastInterface` String, Optional -Tells the kernel to join a multicast group with `IP_ADD_MEMBERSHIP` socket option. - -If `multicastInterface` is not specified, the OS will try to add membership to all valid -interfaces. +Tells the kernel to join a multicast group at the given `multicastAddress` +using the `IP_ADD_MEMBERSHIP` socket option. If the `multicastInterface` +argument is not specified, the operating system will try to add membership to +all valid networking interfaces. ### socket.address() -Returns an object containing the address information for a socket. For UDP sockets, -this object will contain `address` , `family` and `port`. +Returns an object containing the address information for a socket. +For UDP sockets, this object will contain `address`, `family` and `port` +properties. -### socket.bind([port][, address][, callback]) +### [socket.bind([port][, address][, callback])] * `port` Integer, Optional * `address` String, Optional -* `callback` Function with no parameters, Optional. Callback when - binding is done. - -For UDP sockets, listen for datagrams on a named `port` and optional -`address`. If `port` is not specified, the OS will try to bind to a random -port. If `address` is not specified, the OS will try to listen on -all addresses. After binding is done, a `'listening'` event is emitted -and the `callback`(if specified) is called. Specifying both a -`'listening'` event listener and `callback` is not harmful but not very +* `callback` Function with no parameters, Optional. Called when + binding is complete. + +For UDP sockets, causes the `dgram.Socket` to listen for datagram messages on a +named `port` and optional `address`. If `port` is not specified, the operating +system will attempt to bind to a random port. If `address` is not specified, +the operating system will attempt to listen on all addresses. Once binding is +complete, a `'listening'` event is emitted and the optional `callback` function +is called. + +Note that specifying both a `'listening'` event listener and passing a +`callback` to the `socket.bind()` method is not harmful but not very useful. A bound datagram socket keeps the Node.js process running to receive -datagrams. +datagram messages. If binding fails, an `'error'` event is generated. In rare case (e.g. -binding a closed socket), an [`Error`][] may be thrown by this method. +attempting to bind with a closed socket), an [`Error`][] may be thrown. Example of a UDP server listening on port 41234: - var dgram = require("dgram"); + const dgram = require('dgram'); + const server = dgram.createSocket('udp4'); - var server = dgram.createSocket("udp4"); - - server.on("error", function (err) { - console.log("server error:\n" + err.stack); + server.on('error', (err) => { + console.log(`server error:\n${err.stack}`); server.close(); }); - server.on("message", function (msg, rinfo) { - console.log("server got: " + msg + " from " + - rinfo.address + ":" + rinfo.port); + server.on('message', (msg, rinfo) => { + console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); }); - server.on("listening", function () { + server.on('listening', () => { var address = server.address(); - console.log("server listening " + - address.address + ":" + address.port); + console.log(`server listening ${address.address}:${address.port}`); }); server.bind(41234); @@ -123,15 +136,22 @@ Example of a UDP server listening on port 41234: * `exclusive` {Boolean} - Optional. * `callback` {Function} - Optional. -The `port` and `address` properties of `options`, as well as the optional -callback function, behave as they do on a call to -[`socket.bind(port, \[address\], \[callback\])`][]. +For UDP sockets, causes the `dgram.Socket` to listen for datagram messages on a +named `port` and optional `address` that are passed as properties of an +`options` object passed as the first argument. If `port` is not specified, the +operating system will attempt to bind to a random port. If `address` is not +specified, the operating system will attempt to listen on all addresses. Once +binding is complete, a `'listening'` event is emitted and the optional +`callback` function is called. + +The `options` object may contain an additional `exclusive` property that is +use when using `dgram.Socket` objects with the [`cluster`] module. When +`exclusive` is set to `false` (the default), cluster workers will use the same +underlying socket handle allowing connection handling duties to be shared. +When `exclusive` is `true`, however, the handle is not shared and attempted +port sharing results in an error. -If `exclusive` is `false` (default), then cluster workers will use the same -underlying handle, allowing connection handling duties to be shared. When -`exclusive` is `true`, the handle is not shared, and attempted port sharing -results in an error. An example which listens on an exclusive port is -shown below. +An example socket listening on an exclusive port is shown below. socket.bind({ address: 'localhost', @@ -149,13 +169,13 @@ provided, it is added as a listener for the [`'close'`][] event. * `multicastAddress` String * `multicastInterface` String, Optional -Opposite of [`addMembership()`][] - tells the kernel to leave a multicast group with -`IP_DROP_MEMBERSHIP` socket option. This is automatically called by the kernel -when the socket is closed or process terminates, so most apps will never need to call -this. +Instructs the kernel to leave a multicast group at `multicastAddress` using the +`IP_DROP_MEMBERSHIP` socket option. This method is automatically called by the +kernel when the socket is closed or the process terminates, so most apps will +never have reason to call this. -If `multicastInterface` is not specified, the OS will try to drop membership to all valid -interfaces. +If `multicastInterface` is not specified, the operating system will attempt to +drop membership on all valid interfaces. ### socket.send(buf, offset, length, port, address[, callback]) @@ -166,135 +186,178 @@ interfaces. * `address` String. Destination hostname or IP address. * `callback` Function. Called when the message has been sent. Optional. -For UDP sockets, the destination port and address must be specified. A string -may be supplied for the `address` parameter, and it will be resolved with DNS. +Broadcasts a datagram on the socket. The destination `port` and `address` must +be specified. + +The `buf` argument is a [`Buffer`] object containing the message. The `offset` +and `length` specify the offset within the `Buffer` where the message begins +and the number of bytes in the message, respectively. With messages that +contain multi-byte characters, `offset` and `length` will be calculated with +respect to [byte length][] and not the character position. -If the address is omitted or is an empty string, `'0.0.0.0'` or `'::0'` is used -instead. Depending on the network configuration, those defaults may or may not -work; it's best to be explicit about the destination address. +The `address` argument is a string. If the value of `address` is a host name, +DNS will be used to resolve the address of the host. If the `address` is not +specified or is an empty string, `'0.0.0.0'` or `'::0'` will be used instead. +It is possible, depending on the network configuration, that these defaults +may not work; accordingly, it is best to be explicit about the destination +address. -If the socket has not been previously bound with a call to `bind`, it gets -assigned a random port number and is bound to the "all interfaces" address +If the socket has not been previously bound with a call to `bind`, the socket +is assigned a random port number and is bound to the "all interfaces" address (`'0.0.0.0'` for `udp4` sockets, `'::0'` for `udp6` sockets.) -An optional callback may be specified to detect DNS errors or for determining -when it's safe to reuse the `buf` object. Note that DNS lookups delay the time -to send for at least one tick. The only way to know for sure that the datagram -has been sent is by using a callback. If an error occurs and a callback is -given, the error will be the first argument to the callback. If a callback is -not given, the error is emitted as an `'error'` event on the `socket` object. +An optional `callback` function may be specified to as a way of reporting +DNS errors or for determining when it is safe to reuse the `buf` object. +Note that DNS lookups delay the time to send for at least one tick of the +Node.js event loop. -With consideration for multi-byte characters, `offset` and `length` will -be calculated with respect to [byte length][] and not the character position. +The only way to know for sure that the datagram has been sent is by using a +`callback`. If an error occurs and a `callback` is given, the error will be +passed as the first argument to the `callback`. If a `callback` is not given, +the error is emitted as an `'error'` event on the `socket` object. Example of sending a UDP packet to a random port on `localhost`; - var dgram = require('dgram'); - var message = new Buffer("Some bytes"); - var client = dgram.createSocket("udp4"); - client.send(message, 0, message.length, 41234, "localhost", function(err) { + const dgram = require('dgram'); + const message = new Buffer('Some bytes'); + const client = dgram.createSocket('udp4'); + client.send(message, 0, message.length, 41234, 'localhost', (err) => { client.close(); }); **A Note about UDP datagram size** -The maximum size of an `IPv4/v6` datagram depends on the `MTU` (_Maximum Transmission Unit_) -and on the `Payload Length` field size. +The maximum size of an `IPv4/v6` datagram depends on the `MTU` +(_Maximum Transmission Unit_) and on the `Payload Length` field size. -- The `Payload Length` field is `16 bits` wide, which means that a normal payload - cannot be larger than 64K octets including internet header and data +- The `Payload Length` field is `16 bits` wide, which means that a normal + payload exceed 64K octets _including_ the internet header and data (65,507 bytes = 65,535 − 8 bytes UDP header − 20 bytes IP header); - this is generally true for loopback interfaces, but such long datagrams - are impractical for most hosts and networks. + this is generally true for loopback interfaces, but such long datagram + messages are impractical for most hosts and networks. -- The `MTU` is the largest size a given link layer technology can support for datagrams. - For any link, `IPv4` mandates a minimum `MTU` of `68` octets, while the recommended `MTU` - for IPv4 is `576` (typically recommended as the `MTU` for dial-up type applications), - whether they arrive whole or in fragments. +- The `MTU` is the largest size a given link layer technology can support for + datagram messages. For any link, `IPv4` mandates a minimum `MTU` of `68` + octets, while the recommended `MTU` for IPv4 is `576` (typically recommended + as the `MTU` for dial-up type applications), whether they arrive whole or in + fragments. For `IPv6`, the minimum `MTU` is `1280` octets, however, the mandatory minimum - fragment reassembly buffer size is `1500` octets. - The value of `68` octets is very small, since most current link layer technologies have - a minimum `MTU` of `1500` (like Ethernet). + fragment reassembly buffer size is `1500` octets. The value of `68` octets is + very small, since most current link layer technologies, like Ethernet, have a + minimum `MTU` of `1500`. -Note that it's impossible to know in advance the MTU of each link through which -a packet might travel, and that generally sending a datagram greater than -the (receiver) `MTU` won't work (the packet gets silently dropped, without -informing the source that the data did not reach its intended recipient). +It is impossible to know in advance the MTU of each link through which +a packet might travel. Sending a datagram greater than the receiver `MTU` will +not work because the packet will get silently dropped without informing the +source that the data did not reach its intended recipient. ### socket.setBroadcast(flag) * `flag` Boolean -Sets or clears the `SO_BROADCAST` socket option. When this option is set, UDP packets -may be sent to a local interface's broadcast address. +Sets or clears the `SO_BROADCAST` socket option. When set to `true`, UDP +packets may be sent to a local interface's broadcast address. ### socket.setMulticastLoopback(flag) * `flag` Boolean -Sets or clears the `IP_MULTICAST_LOOP` socket option. When this option is set, multicast -packets will also be received on the local interface. +Sets or clears the `IP_MULTICAST_LOOP` socket option. When set to `true`, +multicast packets will also be received on the local interface. ### socket.setMulticastTTL(ttl) * `ttl` Integer -Sets the `IP_MULTICAST_TTL` socket option. TTL stands for "Time to Live", but in this -context it specifies the number of IP hops that a packet is allowed to go through, -specifically for multicast traffic. Each router or gateway that forwards a packet -decrements the TTL. If the TTL is decremented to 0 by a router, it will not be forwarded. +Sets the `IP_MULTICAST_TTL` socket option. While TTL generally stands for +"Time to Live", in this context it specifies the number of IP hops that a +packet is allowed to travel through, specifically for multicast traffic. Each +router or gateway that forwards a packet decrements the TTL. If the TTL is +decremented to 0 by a router, it will not be forwarded. -The argument to `setMulticastTTL()` is a number of hops between 0 and 255. The default on most -systems is 1. +The argument passed to to `socket.setMulticastTTL()` is a number of hops +between 0 and 255. The default on most systems is `1` but can vary. ### socket.setTTL(ttl) * `ttl` Integer -Sets the `IP_TTL` socket option. TTL stands for "Time to Live", but in this context it -specifies the number of IP hops that a packet is allowed to go through. Each router or -gateway that forwards a packet decrements the TTL. If the TTL is decremented to 0 by a -router, it will not be forwarded. Changing TTL values is typically done for network -probes or when multicasting. +Sets the `IP_TTL` socket option. While TTL generally stands for "Time to Live", +in this context it specifies the number of IP hops that a packet is allowed to +travel through. Each router or gateway that forwards a packet decrements the +TTL. If the TTL is decremented to 0 by a router, it will not be forwarded. +Changing TTL values is typically done for network probes or when multicasting. -The argument to `setTTL()` is a number of hops between 1 and 255. The default -on most systems is 64. +The argument to `socket.setTTL()` is a number of hops between 1 and 255. +The default on most systems is 64 but can vary. ### socket.ref() -Opposite of `unref`, calling `ref` on a previously `unref`d socket will *not* -let the program exit if it's the only socket left (the default behavior). If -the socket is `ref`d calling `ref` again will have no effect. +By default, binding a socket will cause it to block the Node.js process from +exiting as long as the socket is open. The `socket.unref()` method can be used +to exclude the socket from the reference counting that keeps the Node.js +process active. The `socket.ref()` method adds the socket back to the reference +counting and restores the default behavior. -Returns `socket`. +Calling `socket.ref()` multiples times will have no additional effect. + +The `socket.ref()` method returns a reference to the socket so calls can be +chained. ### socket.unref() -Calling `unref` on a socket will allow the program to exit if this is the only -active socket in the event system. If the socket is already `unref`d calling -`unref` again will have no effect. +By default, binding a socket will cause it to block the Node.js process from +exiting as long as the socket is open. The `socket.unref()` method can be used +to exclude the socket from the reference counting that keeps the Node.js +process active, allowing the process to exit even if the socket is still +listening. + +Calling `socket.unref()` multiple times will have no addition effect. + +The `socket.unref()` method returns a reference to the socket so calls can be +chained. + +### Change to asynchronous `socket.bind()` behavior + +As of Node.js v0.10, [`dgram.Socket#bind()`][] changed to an asynchronous +execution model. Legacy code that assumes synchronous behavior, as in the +following example: + + const s = dgram.createSocket('udp4'); + s.bind(1234); + s.addMembership('224.0.0.114'); + +Must be changed to pass a callback function to the [`dgram.Socket#bind()`][] +function: -Returns `socket`. + const s = dgram.createSocket('udp4'); + s.bind(1234, () => { + s.addMembership('224.0.0.114'); + }); -## dgram.createSocket(options[, callback]) +## `dgram` module functions + +### dgram.createSocket(options[, callback]) * `options` Object * `callback` Function. Attached as a listener to `'message'` events. * Returns: Socket object -The `options` object should contain a `type` field of either `udp4` or `udp6` -and an optional boolean `reuseAddr` field. +Creates a `dgram.Socket` object. The `options` argument is an object that +should contain a `type` field of either `udp4` or `udp6` and an optional +boolean `reuseAddr` field. When `reuseAddr` is `true` [`socket.bind()`][] will reuse the address, even if another process has already bound a socket on it. `reuseAddr` defaults to -`false`. - -Takes an optional callback which is added as a listener for `'message'` events. +`false`. An optional `callback` function can be passed specified which is added +as a listener for `'message'` events. -Call [`socket.bind()`][] if you want to receive datagrams. [`socket.bind()`][] will -bind to the "all interfaces" address on a random port (it does the right thing -for both `udp4` and `udp6` sockets). You can then retrieve the address and port -with [`socket.address().address`][] and [`socket.address().port`][]. +Once the socket is created, calling [`socket.bind()`][] will instruct the +socket to begin listening for datagram messages. When `address` and `port` are +not passed to [`socket.bind()`][] the method will bind the socket to the "all +interfaces" address on a random port (it does the right thing for both `udp4` +and `udp6` sockets). The bound address and port can be retrieved using +[`socket.address().address`][] and [`socket.address().port`][]. ## dgram.createSocket(type[, callback]) @@ -303,24 +366,26 @@ with [`socket.address().address`][] and [`socket.address().port`][]. Optional * Returns: Socket object -Creates a datagram Socket of the specified types. Valid types are `udp4` -and `udp6`. - -Takes an optional callback which is added as a listener for `'message'` events. +Creates a `dgram.Socket` object of the specified `type`. The `type` argument +can be either `udp4` or `udp6`. An optional `callback` function can be passed +which is added as a listener for `'message'` events. -Call [`socket.bind()`][] if you want to receive datagrams. [`socket.bind()`][] will -bind to the "all interfaces" address on a random port (it does the right thing -for both `udp4` and `udp6` sockets). You can then retrieve the address and port -with [`socket.address().address`][] and [`socket.address().port`][]. +Once the socket is created, calling [`socket.bind()`][] will instruct the +socket to begin listening for datagram messages. When `address` and `port` are +not passed to [`socket.bind()`][] the method will bind the socket to the "all +interfaces" address on a random port (it does the right thing for both `udp4` +and `udp6` sockets). The bound address and port can be retrieved using +[`socket.address().address`][] and [`socket.address().port`][]. +[`EventEmitter`]: events.html +[`Buffer`]: buffer.html [`'close'`]: #dgram_event_close [`addMembership()`]: #dgram_socket_addmembership_multicastaddress_multicastinterface [`close()`]: #dgram_socket_close_callback -[`dgram.createSocket(...)`]: #dgram_dgram_createsocket_options_callback +[`dgram.createSocket()`]: #dgram_dgram_createsocket_options_callback [`dgram.Socket#bind()`]: #dgram_socket_bind_options_callback [`Error`]: errors.html#errors_class_error [`socket.address().address`]: #dgram_socket_address [`socket.address().port`]: #dgram_socket_address [`socket.bind()`]: #dgram_socket_bind_port_address_callback -[`socket.bind(port, \[address\], \[callback\])`]: #dgram_socket_bind_port_address_callback [byte length]: buffer.html#buffer_class_method_buffer_bytelength_string_encoding diff --git a/doc/api/dns.markdown b/doc/api/dns.markdown index ef68b93b8afa..86bee2164876 100644 --- a/doc/api/dns.markdown +++ b/doc/api/dns.markdown @@ -2,67 +2,63 @@ Stability: 2 - Stable -Use `require('dns')` to access this module. - -This module contains functions that belong to two different categories: +The `dns` module contains functions belonging to two different categories: 1) Functions that use the underlying operating system facilities to perform -name resolution, and that do not necessarily do any network communication. -This category contains only one function: [`dns.lookup()`][]. __Developers looking -to perform name resolution in the same way that other applications on the same -operating system behave should use [`dns.lookup()`][].__ +name resolution, and that do not necessarily perform any network communication. +This category contains only one function: [`dns.lookup()`][]. __Developers +looking to perform name resolution in the same way that other applications on +the same operating system behave should use [`dns.lookup()`][].__ -Here is an example that does a lookup of `www.google.com`. +For example, looking up `nodejs.org`. - var dns = require('dns'); + const dns = require('dns'); - dns.lookup('www.google.com', function onLookup(err, addresses, family) { + dns.lookup('nodejs.org', (err, addresses, family) => { console.log('addresses:', addresses); }); 2) Functions that connect to an actual DNS server to perform name resolution, and that _always_ use the network to perform DNS queries. This category -contains all functions in the `dns` module but [`dns.lookup()`][]. These functions -do not use the same set of configuration files than what [`dns.lookup()`][] uses. -For instance, _they do not use the configuration from `/etc/hosts`_. These -functions should be used by developers who do not want to use the underlying -operating system's facilities for name resolution, and instead want to -_always_ perform DNS queries. +contains all functions in the `dns` module _except_ [`dns.lookup()`][]. These +functions do not use the same set of configuration files used by +[`dns.lookup()`][] (e.g. `/etc/hosts`). These functions should be used by +developers who do not want to use the underlying operating system's facilities +for name resolution, and instead want to _always_ perform DNS queries. -Here is an example which resolves `'www.google.com'` then reverse -resolves the IP addresses which are returned. +Below is an example that resolves `'nodejs.org'` then reverse resolves the IP +addresses that are returned. - var dns = require('dns'); + const dns = require('dns'); - dns.resolve4('www.google.com', function (err, addresses) { + dns.resolve4('nodejs.org', (err, addresses) => { if (err) throw err; - console.log('addresses: ' + JSON.stringify(addresses)); + console.log(`addresses: ${JSON.stringify(addresses)}`); - addresses.forEach(function (a) { - dns.reverse(a, function (err, hostnames) { + addresses.forEach((a) => { + dns.reverse(a, (err, hostnames) => { if (err) { throw err; } - - console.log('reverse for ' + a + ': ' + JSON.stringify(hostnames)); + console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`); }); }); }); -There are subtle consequences in choosing one or another, please consult the -[Implementation considerations section][] for more information. +There are subtle consequences in choosing one over the other, please consult +the [Implementation considerations section][] for more information. ## dns.getServers() -Returns an array of IP addresses as strings that are currently being used for -resolution +Returns an array of IP address strings that are being used for name +resolution. ## dns.lookup(hostname[, options], callback) -Resolves a hostname (e.g. `'google.com'`) into the first found A (IPv4) or +Resolves a hostname (e.g. `'nodejs.org'`) into the first found A (IPv4) or AAAA (IPv6) record. `options` can be an object or integer. If `options` is -not provided, then IP v4 and v6 addresses are both valid. If `options` is +not provided, then IPv4 and IPv6 addresses are both valid. If `options` is an integer, then it must be `4` or `6`. Alternatively, `options` can be an object containing these properties: @@ -80,153 +76,193 @@ Alternatively, `options` can be an object containing these properties: All properties are optional. An example usage of options is shown below. -``` -{ - family: 4, - hints: dns.ADDRCONFIG | dns.V4MAPPED, - all: false -} -``` + { + family: 4, + hints: dns.ADDRCONFIG | dns.V4MAPPED, + all: false + } -The callback has arguments `(err, address, family)`. `address` is a string -representation of an IP v4 or v6 address. `family` is either the integer 4 or 6 -and denotes the family of `address` (not necessarily the value initially passed -to `lookup`). +The `callback` function has arguments `(err, address, family)`. `address` is a +string representation of an IPv4 or IPv6 address. `family` is either the +integer `4` or `6` and denotes the family of `address` (not necessarily the +value initially passed to `lookup`). -With the `all` option set, the arguments change to `(err, addresses)`, with -`addresses` being an array of objects with the properties `address` and -`family`. +With the `all` option set to `true`, the arguments change to +`(err, addresses)`, with `addresses` being an array of objects with the +properties `address` and `family`. On error, `err` is an [`Error`][] object, where `err.code` is the error code. Keep in mind that `err.code` will be set to `'ENOENT'` not only when the hostname does not exist but also when the lookup fails in other ways such as no available file descriptors. -`dns.lookup()` doesn't necessarily have anything to do with the DNS protocol. -It's only an operating system facility that can associate name with addresses, -and vice versa. +`dns.lookup()` does not necessarily have anything to do with the DNS protocol. +The implementation uses an operating system facility that can associate names +with addresses, and vice versa. This implementation can have subtle but +important consequences on the behavior of any Node.js program. Please take some +time to consult the [Implementation considerations section][] before using +`dns.lookup()`. -Its implementation can have subtle but important consequences on the behavior -of any Node.js program. Please take some time to consult the [Implementation -considerations section][] before using it. +### Supported getaddrinfo flags + +The following flags can be passed as hints to [`dns.lookup()`][]. + +- `dns.ADDRCONFIG`: Returned address types are determined by the types +of addresses supported by the current system. For example, IPv4 addresses +are only returned if the current system has at least one IPv4 address +configured. Loopback addresses are not considered. +- `dns.V4MAPPED`: If the IPv6 family was specified, but no IPv6 addresses were +found, then return IPv4 mapped IPv6 addresses. Note that it is not supported +on some operating systems (e.g FreeBSD 10.1). ## dns.lookupService(address, port, callback) -Resolves the given address and port into a hostname and service using -`getnameinfo`. +Resolves the given `address` and `port` into a hostname and service using +the operating system's underlying `getnameinfo` implementation. The callback has arguments `(err, hostname, service)`. The `hostname` and `service` arguments are strings (e.g. `'localhost'` and `'http'` respectively). On error, `err` is an [`Error`][] object, where `err.code` is the error code. + const dns = require('dns'); + dns.lookupService('127.0.0.1', 22, (err, hostname, service) => { + console.log(hostname, service); + // Prints: localhost ssh + }); ## dns.resolve(hostname[, rrtype], callback) -Resolves a hostname (e.g. `'google.com'`) into an array of the record types -specified by rrtype. +Uses the DNS protocol to resolve a hostname (e.g. `'nodejs.org'`) into an +array of the record types specified by `rrtype`. -Valid rrtypes are: +Valid values for `rrtype` are: - * `'A'` (IPV4 addresses, default) - * `'AAAA'` (IPV6 addresses) - * `'MX'` (mail exchange records) - * `'TXT'` (text records) - * `'SRV'` (SRV records) - * `'PTR'` (used for reverse IP lookups) - * `'NS'` (name server records) - * `'CNAME'` (canonical name records) - * `'SOA'` (start of authority record) + * `'A'` - IPV4 addresses, default + * `'AAAA'` - IPV6 addresses + * `'MX'` - mail exchange records + * `'TXT'` - text records + * `'SRV'` - SRV records + * `'PTR'` - used for reverse IP lookups + * `'NS'` - name server records + * `'CNAME'` - canonical name records + * `'SOA'` - start of authority record -The callback has arguments `(err, addresses)`. The type of each item -in `addresses` is determined by the record type, and described in the -documentation for the corresponding lookup methods below. +The `callback` function has arguments `(err, addresses)`. When successful, +`addresses` will be an array. The type of each item in `addresses` is +determined by the record type, and described in the documentation for the +corresponding lookup methods below. On error, `err` is an [`Error`][] object, where `err.code` is one of the error codes listed below. - ## dns.resolve4(hostname, callback) -The same as [`dns.resolve()`][], but only for IPv4 queries (`A` records). -`addresses` is an array of IPv4 addresses (e.g. +Uses the DNS protocol to resolve a IPv4 addresses (`A` records) for the +`hostname`. The `addresses` argument passed to the `callback` function +will contain an array of IPv4 addresses (e.g. `['74.125.79.104', '74.125.79.105', '74.125.79.106']`). ## dns.resolve6(hostname, callback) -The same as [`dns.resolve4()`][] except for IPv6 queries (an `AAAA` query). +Uses the DNS protocol to resolve a IPv6 addresses (`AAAA` records) for the +`hostname`. The `addresses` argument passed to the `callback` function +will contain an array of IPv6 addresses. ## dns.resolveCname(hostname, callback) -The same as [`dns.resolve()`][], but only for canonical name records (`CNAME` -records). `addresses` is an array of the canonical name records available for -`hostname` (e.g., `['bar.example.com']`). +Uses the DNS protocol to resolve `CNAME` records for the `hostname`. The +`addresses` argument passed to the `callback` function +will contain an of canonical name records available for the `hostname` +(e.g. `['bar.example.com']`). ## dns.resolveMx(hostname, callback) -The same as [`dns.resolve()`][], but only for mail exchange queries (`MX` records). - -`addresses` is an array of MX records, each with a priority and an exchange -attribute (e.g. `[{'priority': 10, 'exchange': 'mx.example.com'},...]`). +Uses the DNS protocol to resolve mail exchange records (`MX` records) for the +`hostname`. The `addresses` argument passed to the `callback` function will +contain an array of objects containing both a `priority` and `exchange` +property (e.g. `[{priority: 10, exchange: 'mx.example.com'}, ...]`). ## dns.resolveNs(hostname, callback) -The same as [`dns.resolve()`][], but only for name server records (`NS` records). -`addresses` is an array of the name server records available for `hostname` +Uses the DNS protocol to resolve name server records (`NS` records) for the +`hostname`. The `addresses` argument passed to the `callback` function will +contain an array of name server records available for `hostname` (e.g., `['ns1.example.com', 'ns2.example.com']`). ## dns.resolveSoa(hostname, callback) -The same as [`dns.resolve()`][], but only for start of authority record queries -(`SOA` record). +Uses the DNS protocol to resolve a start of authority record (`SOA` record) for +the `hostname`. The `addresses` argument passed to the `callback` function will +be an object with the following properties: + +* `nsname` +* `hostmaster` +* `serial` +* `refresh` +* `retry` +* `expire` +* `minttl` + + { + nsname: 'ns.example.com', + hostmaster: 'root.example.com', + serial: 2013101809, + refresh: 10000, + retry: 2400, + expire: 604800, + minttl: 3600 + } -`addresses` is an object with the following structure: +## dns.resolveSrv(hostname, callback) -``` -{ - nsname: 'ns.example.com', - hostmaster: 'root.example.com', - serial: 2013101809, - refresh: 10000, - retry: 2400, - expire: 604800, - minttl: 3600 -} -``` +Uses the DNS protocol to resolve service records (`SRV` records) for the +`hostname`. The `addresses` argument passed to the `callback` function will +be an array of objects with the following properties: -## dns.resolveSrv(hostname, callback) +* `priority` +* `weight` +* `port` +* `name` -The same as [`dns.resolve()`][], but only for service records (`SRV` records). -`addresses` is an array of the SRV records available for `hostname`. Properties -of SRV records are priority, weight, port, and name (e.g., -`[{'priority': 10, 'weight': 5, 'port': 21223, 'name': 'service.example.com'}, ...]`). + { + priority: 10, + weight: 5, + port: 21223, + name: 'service.example.com' + } ## dns.resolveTxt(hostname, callback) -The same as [`dns.resolve()`][], but only for text queries (`TXT` records). -`addresses` is a 2-d array of the text records available for `hostname` (e.g., +Uses the DNS protocol to resolve text queries (`TXT` records) for the +`hostname`. The `addresses` argument passed to the `callback` function is +is a two-dimentional array of the text records available for `hostname` (e.g., `[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]`). Each sub-array contains TXT chunks of -one record. Depending on the use case, the could be either joined together or +one record. Depending on the use case, these could be either joined together or treated separately. ## dns.reverse(ip, callback) -Reverse resolves an ip address to an array of hostnames. +Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an +array of hostnames. -The callback has arguments `(err, hostnames)`. +The `callback` function has arguments `(err, hostnames)`, where `hostnames` +is an array of resolved hostnames for the given `ip`. On error, `err` is an [`Error`][] object, where `err.code` is one of the error codes listed below. ## dns.setServers(servers) -Given an array of IP addresses as strings, set them as the servers to use for -resolving +Sets the IP addresses of the servers to be used when resolving. The `servers` +argument is an array of IPv4 or IPv6 addresses. -If you specify a port with the address it will be stripped, as the underlying -library doesn't support that. +If a port specified on the address it will be removed. -This will throw if you pass invalid input. +An error will be thrown if an invalid address is provided. + +The `dns.setServers()` method must not be called while a DNS query is in +progress. ## Error codes @@ -257,52 +293,41 @@ Each DNS query can return one of the following error codes: - `dns.ADDRGETNETWORKPARAMS`: Could not find GetNetworkParams function. - `dns.CANCELLED`: DNS query cancelled. -## Supported getaddrinfo flags - -The following flags can be passed as hints to [`dns.lookup()`][]. - -- `dns.ADDRCONFIG`: Returned address types are determined by the types -of addresses supported by the current system. For example, IPv4 addresses -are only returned if the current system has at least one IPv4 address -configured. Loopback addresses are not considered. -- `dns.V4MAPPED`: If the IPv6 family was specified, but no IPv6 addresses were -found, then return IPv4 mapped IPv6 addresses. Note that it is not supported -on some operating systems (e.g FreeBSD 10.1). - ## Implementation considerations -Although [`dns.lookup()`][] and `dns.resolve*()/dns.reverse()` functions have the same -goal of associating a network name with a network address (or vice versa), -their behavior is quite different. These differences can have subtle but -significant consequences on the behavior of Node.js programs. - -### dns.lookup - -Under the hood, [`dns.lookup()`][] uses the same operating system facilities as most -other programs. For instance, [`dns.lookup()`][] will almost always resolve a given -name the same way as the `ping` command. On most POSIX-like operating systems, -the behavior of the [`dns.lookup()`][] function can be tweaked by changing settings -in `nsswitch.conf(5)` and/or `resolv.conf(5)`, but be careful that changing -these files will change the behavior of all other programs running on the same -operating system. - -Though the call will be asynchronous from JavaScript's perspective, it is -implemented as a synchronous call to `getaddrinfo(3)` that runs on libuv's -threadpool. Because libuv's threadpool has a fixed size, it means that if for -whatever reason the call to `getaddrinfo(3)` takes a long time, other -operations that could run on libuv's threadpool (such as filesystem +Although [`dns.lookup()`][] and the various `dns.resolve*()/dns.reverse()` +functions have the same goal of associating a network name with a network +address (or vice versa), their behavior is quite different. These differences +can have subtle but significant consequences on the behavior of Node.js +programs. + +### `dns.lookup()` + +Under the hood, [`dns.lookup()`][] uses the same operating system facilities +as most other programs. For instance, [`dns.lookup()`][] will almost always +resolve a given name the same way as the `ping` command. On most POSIX-like +operating systems, the behavior of the [`dns.lookup()`][] function can be +modified by changing settings in `nsswitch.conf(5)` and/or `resolv.conf(5)`, +but note that changing these files will change the behavior of _all other +programs running on the same operating system_. + +Though the call to `dns.lookup()` will be asynchronous from JavaScript's +perspective, it is implemented as a synchronous call to `getaddrinfo(3)` that +runs on libuv's threadpool. Because libuv's threadpool has a fixed size, it +means that if for whatever reason the call to `getaddrinfo(3)` takes a long +time, other operations that could run on libuv's threadpool (such as filesystem operations) will experience degraded performance. In order to mitigate this issue, one potential solution is to increase the size of libuv's threadpool by -setting the 'UV_THREADPOOL_SIZE' environment variable to a value greater than -4 (its current default value). For more information on libuv's threadpool, see +setting the `'UV_THREADPOOL_SIZE'` environment variable to a value greater than +`4` (its current default value). For more information on libuv's threadpool, see [the official libuv documentation][]. -### dns.resolve, functions starting with dns.resolve and dns.reverse +### `dns.resolve()`, `dns.resolve*()` and `dns.reverse()` -These functions are implemented quite differently than [`dns.lookup()`][]. They do -not use `getaddrinfo(3)` and they _always_ perform a DNS query on the network. -This network communication is always done asynchronously, and does not use -libuv's threadpool. +These functions are implemented quite differently than [`dns.lookup()`][]. They +do not use `getaddrinfo(3)` and they _always_ perform a DNS query on the +network. This network communication is always done asynchronously, and does not +use libuv's threadpool. As a result, these functions cannot have the same negative impact on other processing that happens on libuv's threadpool that [`dns.lookup()`][] can have. diff --git a/doc/api/domain.markdown b/doc/api/domain.markdown index 16854d46acce..410a74498dde 100644 --- a/doc/api/domain.markdown +++ b/doc/api/domain.markdown @@ -48,15 +48,15 @@ For example, this is not a good idea: // XXX WARNING! BAD IDEA! var d = require('domain').create(); -d.on('error', function(er) { +d.on('error', (er) => { // The error won't crash the process, but what it does is worse! // Though we've prevented abrupt process restarting, we are leaking // resources like crazy if this ever happens. // This is no better than process.on('uncaughtException')! console.log('error, but oh well', er.message); }); -d.run(function() { - require('http').createServer(function(req, res) { +d.run(() => { + require('http').createServer((req, res) => { handleRequest(req, res); }).listen(PORT); }); @@ -69,8 +69,8 @@ appropriately, and handle errors with much greater safety. ```javascript // Much better! -var cluster = require('cluster'); -var PORT = +process.env.PORT || 1337; +const cluster = require('cluster'); +const PORT = +process.env.PORT || 1337; if (cluster.isMaster) { // In real life, you'd probably use more than just 2 workers, @@ -88,7 +88,7 @@ if (cluster.isMaster) { cluster.fork(); cluster.fork(); - cluster.on('disconnect', function(worker) { + cluster.on('disconnect', (worker) => { console.error('disconnect!'); cluster.fork(); }); @@ -98,14 +98,14 @@ if (cluster.isMaster) { // // This is where we put our bugs! - var domain = require('domain'); + const domain = require('domain'); // See the cluster documentation for more details about using // worker processes to serve requests. How it works, caveats, etc. - var server = require('http').createServer(function(req, res) { + const server = require('http').createServer((req, res) => { var d = domain.create(); - d.on('error', function(er) { + d.on('error', (er) => { console.error('error', er.stack); // Note: we're in dangerous territory! @@ -115,7 +115,7 @@ if (cluster.isMaster) { try { // make sure we close down within 30 seconds - var killtimer = setTimeout(function() { + var killtimer = setTimeout(() => { process.exit(1); }, 30000); // But don't keep the process open just for that! @@ -146,7 +146,7 @@ if (cluster.isMaster) { d.add(res); // Now run the handler function in the domain. - d.run(function() { + d.run(() => { handleRequest(req, res); }); }); @@ -159,7 +159,7 @@ function handleRequest(req, res) { switch(req.url) { case '/error': // We do some async stuff, and then... - setTimeout(function() { + setTimeout(() => { // Whoops! flerb.bark(); }); @@ -229,18 +229,20 @@ For example: ``` // create a top-level domain for the server -var serverDomain = domain.create(); +const domain = require('domain'); +const http = require('http'); +const serverDomain = domain.create(); -serverDomain.run(function() { +serverDomain.run(() => { // server is created in the scope of serverDomain - http.createServer(function(req, res) { + http.createServer((req, res) => { // req and res are also created in the scope of serverDomain // however, we'd prefer to have a separate domain for each request. // create it first thing, and add req and res to it. var reqd = domain.create(); reqd.add(req); reqd.add(res); - reqd.on('error', function(er) { + reqd.on('error', (er) => { console.error('Error', er, req.url); try { res.writeHead(500); @@ -281,14 +283,16 @@ This is the most basic way to use a domain. Example: ``` -var d = domain.create(); -d.on('error', function(er) { +const domain = require('domain'); +const fs = require('fs'); +const d = domain.create(); +d.on('error', (er) => { console.error('Caught error!', er); }); -d.run(function() { - process.nextTick(function() { - setTimeout(function() { // simulating some various async stuff - fs.open('non-existent file', 'r', function(er, fd) { +d.run(() => { + process.nextTick(() => { + setTimeout(() => { // simulating some various async stuff + fs.open('non-existent file', 'r', (er, fd) => { if (er) throw er; // proceed... }); @@ -341,7 +345,7 @@ thrown will be routed to the domain's `'error'` event. #### Example - var d = domain.create(); + const d = domain.create(); function readSomeFile(filename, cb) { fs.readFile(filename, 'utf8', d.bind(function(er, data) { @@ -350,7 +354,7 @@ thrown will be routed to the domain's `'error'` event. })); } - d.on('error', function(er) { + d.on('error', (er) => { // an error occurred somewhere. // if we throw it now, it will crash the program // with the normal line number and stack message. @@ -370,7 +374,7 @@ with a single error handler in a single place. #### Example - var d = domain.create(); + const d = domain.create(); function readSomeFile(filename, cb) { fs.readFile(filename, 'utf8', d.intercept(function(data) { @@ -386,7 +390,7 @@ with a single error handler in a single place. })); } - d.on('error', function(er) { + d.on('error', (er) => { // an error occurred somewhere. // if we throw it now, it will crash the program // with the normal line number and stack message. diff --git a/doc/api/errors.markdown b/doc/api/errors.markdown index a12489fdc141..823e9361901c 100644 --- a/doc/api/errors.markdown +++ b/doc/api/errors.markdown @@ -2,222 +2,257 @@ -Errors generated by Node.js fall into two categories: JavaScript errors and system -errors. All errors inherit from or are instances of JavaScript's [`Error`][] -class and are guaranteed to provide *at least* the attributes available on that -class. - -When an operation is not permitted due to language-syntax or -language-runtime-level reasons, a **JavaScript error** is generated and thrown -as an **exception**. If an operation is not allowed due to system-level -restrictions, a **system error** is generated. Client code is then given the -opportunity to **intercept** this error based on how the API **propagates** it. - -The style of API called determines how generated errors are handed back, or -**propagated**, to client code, which in turn informs how the client may **intercept** -the error. Exceptions can be intercepted using the [`try / catch` construct][]; -other propagation strategies are covered [below][]. +Applications running in Node.js will generally experience four categories of +errors: + +- Standard JavaScript errors such as: + - [`EvalError`][]: thrown when a call to `eval()` fails. + - [`SyntaxError`][]: thrown in response to improper JavaScript language + syntax. + - [`RangeError`][]: thrown when a value is not within an expected range + - [`ReferenceError`][]: thrown when using undefined variables + - [`TypeError`][]: thrown when passing arguments of the wrong type + - [`URIError`][]: thrown when a global URI handling function is misused. +- System errors triggered by underlying operating system constraints such + as attempting to open a file that does not exist, attempting to send data + over a closed socket, etc; +- And User-specified errors triggered by application code. +- Assertion Errors are a special class of error that can be triggered whenever + Node.js detects an exceptional logic violation that should never occur. These + are raised typically by the `assert` module. + +All JavaScript and System errors raised by Node.js inherit from, or are +instances of, the standard JavaScript [`Error`][] class and are guaranteed +to provide *at least* the properties available on that class. ## Error Propagation and Interception -All Node.js APIs will treat invalid arguments as exceptional -- that is, if passed -invalid arguments, they will *immediately* generate and throw the error as an -exception, even if they are an otherwise asynchronous API. - -Synchronous APIs (like [`fs.readFileSync`][]) will throw the error. The act of -*throwing* a value (in this case, the error) turns the value into an **exception**. -Exceptions may be caught using the [`try { } catch(err) { }`][] construct. +Node.js supports several mechanisms for propagating and handling errors that +occur while an application is running. How these errors are reported and +handled depends entirely on the type of Error and the style of the API that is +called. + +All JavaScript errors are handled as exceptions that *immediately* generate +and throw an error using the standard JavaScript `throw` mechanism. These +are handled using the [`try / catch` construct][] provided by the JavaScript +language. + + // Throws with a ReferenceError because z is undefined + try { + const m = 1; + const n = m + z; + } catch (err) { + // Handle the error here. + } -Asynchronous APIs have **two** mechanisms for error propagation; one mechanism -for APIs that represent a single operation, and one for APIs that represent -multiple operations over time. +Any use of the JavaScript `throw` mechanism will raise an exception that +*must* be handled using `try / catch` or the Node.js process will exit +immediately. -### Error events +With few exceptions, _Synchronous_ APIs (any blocking method that does not +accept a `callback` function, such as [`fs.readFileSync`][]), will use `throw` +to report errors. - +Errors that occur within _Asynchronous APIs_ may be reported in multiple ways: -The other mechanism for providing errors is the `'error'` event. This is -typically used by [stream-based][] and [event emitter-based][] APIs, which -themselves represent a series of asynchronous operations over time (versus a -single operation that may pass or fail). If no `'error'` event handler is -attached to the source of the error, the error will be thrown. At this point, -it will crash the process as an unhandled exception unless [domains][] are -employed appropriately or [`process.on('uncaughtException')`][] has a handler. +- Most asynchronous methods that accept a `callback` function will accept an + `Error` object passed as the first argument to that function. If that first + argument is not `null` and is an instance of `Error`, then an error occurred + that should be handled. -```javascript -var net = require('net'); + ``` + const fs = require('fs'); + fs.readFile('a file that does not exist', (err, data) => { + if (err) { + console.error('There was an error reading the file!', err); + return; + } + // Otherwise handle the data + }); + ``` +- When an asynchronous method is called on an object that is an `EventEmitter`, + errors can be routed to that object's `'error'` event. + + ``` + const net = require('net'); + const connection = net.connect('localhost'); + + // Adding an 'error' event handler to a stream: + connection.on('error', (err) => { + // If the connection is reset by the server, or if it can't + // connect at all, or on any sort of error encountered by + // the connection, the error will be sent here. + console.error(err); + }); -var connection = net.connect('localhost'); + connection.pipe(process.stdout); + ``` -// adding an 'error' event handler to a stream: -connection.on('error', function(err) { - // if the connection is reset by the server, or if it can't - // connect at all, or on any sort of error encountered by - // the connection, the error will be sent here. - console.error(err); -}); +- A handful of typically asynchronous methods in the Node.js API may still + use the `throw` mechanism to raise exceptions that must be handled using + `try / catch`. There is no comprehensive list of such methods; please + refer to the documentation of each method to determine the appropriate + error handling mechanism required. -connection.pipe(process.stdout); -``` +The use of the `'error'` event mechanism is most common for [stream-based][] +and [event emitter-based][] APIs, which themselves represent a series of +asynchronous operations over time (as opposed to a single operation that may +pass or fail). -The "throw when no error handlers are attached behavior" is not limited to APIs -provided by Node.js -- even user created event emitters and streams will throw -errors when no error handlers are attached. An example: +For *all* `EventEmitter` objects, if an `'error'` event handler is not +provided, the error will be thrown, causing the Node.js process to report an +unhandled exception and crash unless either: The [`domain`][] module is used +appropriately or a handler has been registered for the +[`process.on('uncaughtException')`][] event. -```javascript -var EventEmitter = require('events'); + const EventEmitter = require('events'); + const ee = new EventEmitter(); -var ee = new EventEmitter(); + setImmediate(() => { + // This will crash the process because no 'error' event + // handler has been added. + ee.emit('error', new Error('This will crash')); + }); -setImmediate(function() { - // this will crash the process because no 'error' event - // handler has been added. - ee.emit('error', new Error('This will crash')); -}); -``` +Errors generated in this way *cannot* be intercepted using `try / catch` as +they are thrown *after* the calling code has already exited. -As with node style callbacks, errors generated this way *cannot* be intercepted -by `try { } catch(err) { }` -- they happen *after* the calling code has already -exited. +Developers must refer to the documentation for each method to determine +exactly how errors raised by those methods are propagated. -### Node style callbacks +### Node.js style callbacks -Single operation APIs take "node style callbacks" -- a -function provided to the API as an argument. The node style callback takes -at least **one** argument -- `error` -- that will either be `null` (if no error -was encountered) or an `Error` instance. For instance: - -```javascript -var fs = require('fs'); - -fs.readFile('/some/file/that/does-not-exist', function nodeStyleCallback(err, data) { - console.log(err) // Error: ENOENT - console.log(data) // undefined / null -}); - -fs.readFile('/some/file/that/does-exist', function(err, data) { - console.log(err) // null - console.log(data) // -}) -``` - -Note that `try { } catch(err) { }` **cannot** intercept errors generated by -asynchronous APIs. A common mistake for beginners is to try to use `throw` -inside their node style callback: - -```javascript -// THIS WILL NOT WORK: -var fs = require('fs'); - -try { - fs.readFile('/some/file/that/does-not-exist', function(err, data) { - // mistaken assumption: throwing here... - if (err) { - throw err; +Most asynchronous methods exposed by the Node.js core API follow an idiomatic +pattern referred to as a "Node.js style callback". With this pattern, a +callback function is passed to the method as an argument. When the operation +either completes or an error is raised, the callback function is called with +the Error object (if any) passed as the first argument. If no error was raised, +the first argument will be passed as `null`. + + const fs = require('fs'); + + function nodeStyleCallback(err, data) { + if (err) { + console.error('There was an error', err); + return; + } + console.log(data); } - }); -} catch(err) { - // ... will be caught here -- this is incorrect! - console.log(err); // Error: ENOENT -} -``` - -This will not work! By the time the node style callback has been called, the -surrounding code (including the `try { } catch(err) { }` will have already -exited. Throwing an error inside a node style callback **will crash the process** in most cases. -If [domains][] are enabled, they may intercept the thrown error; similarly, if a -handler has been added to `process.on('uncaughtException')`, it will intercept -the error. -## JavaScript Errors - - + fs.readFile('/some/file/that/does-not-exist', nodeStyleCallback); + fs.readFile('/some/file/that/does-exist', nodeStyleCallback) + +The JavaScript `try / catch` mechanism **cannot** be used to intercept errors +generated by asynchronous APIs. A common mistake for beginners is to try to +use `throw` inside a Node.js style callback: + + // THIS WILL NOT WORK: + const fs = require('fs'); + + try { + fs.readFile('/some/file/that/does-not-exist', (err, data) => { + // mistaken assumption: throwing here... + if (err) { + throw err; + } + }); + } catch(err) { + // This will not catch the throw! + console.log(err); + } -JavaScript errors typically denote that an API is being used incorrectly, or that -there is a problem with the program as written. +This will not work because the callback function passed to `fs.readFile()` is +called asynchronously. By the time the callback has been called, the +surrounding code (including the `try { } catch(err) { }` block will have +already exited. Throwing an error inside the callback **can crash the Node.js +process** in most cases. If [domains][] are enabled, or a handler has been +registered with `process.on('uncaughtException')`, such errors can be +intercepted. -### Class: Error +## Class: Error -A general error object. Unlike other error objects, `Error` instances do not -denote any specific circumstance of why the error occurred. Errors capture a -"stack trace" detailing the point in the program at which they were -instantiated, and may provide a description of the error. +A generic JavaScript `Error` object that does not denote any specific +circumstance of why the error occurred. `Error` objects capture a "stack trace" +detailing the point in the code at which the `Error` was instantiated, and may +provide a text description of the error. -**Note**: Node.js will generate this class of error to encapsulate system -errors as well as plain JavaScript errors. +All errors generated by Node.js, including all System and JavaScript errors, +will either be instances of, or inherit from, the `Error` class. -#### new Error(message) +### new Error(message) -Instantiates a new `Error` object and sets its `.message` property to the provided -message. Its `.stack` will represent the point in the program at which `new Error` -was called. Stack traces are subject to [V8's stack trace API][]. -Stack traces only extend to the beginning of synchronous code execution, *or* a number of frames given by -`Error.stackTraceLimit`, whichever is smaller. +Creates a new `Error` object and sets the `error.message` property to the +provided text message. If an object is passed as `message`, the text message +is generated by calling `message.toString()`. The `error.stack` property will +represent the point in the code at which `new Error()` was called. Stack traces +are dependent on [V8's stack trace API][]. Stack traces extend only to either +(a) the beginning of *synchronous code execution*, or (b) the number of frames +given by the property `Error.stackTraceLimit`, whichever is smaller. -#### Error.captureStackTrace(targetObject[, constructorOpt]) +### Error.captureStackTrace(targetObject[, constructorOpt]) Creates a `.stack` property on `targetObject`, which when accessed returns -a string representing the location in the program at which `Error.captureStackTrace` -was called. +a string representing the location in the code at which +`Error.captureStackTrace()` was called. -```javascript -var myObject = {}; - -Error.captureStackTrace(myObject); - -myObject.stack // similar to `new Error().stack` -``` + const myObject = {}; + Error.captureStackTrace(myObject); + myObject.stack // similar to `new Error().stack` The first line of the trace, instead of being prefixed with `ErrorType: -message`, will be the result of `targetObject.toString()`. - -`constructorOpt` optionally accepts a function. If given, all frames above -`constructorOpt`, including `constructorOpt`, will be omitted from the generated -stack trace. +message`, will be the result of calling `targetObject.toString()`. -This is useful for hiding implementation details of error generation from the -end user. A common way of using this parameter is to pass the current Error -constructor to it: +The optional `constructorOpt` argument accepts a function. If given, all frames +above `constructorOpt`, including `constructorOpt`, will be omitted from the +generated stack trace. -```javascript +The `constructorOpt` argument is useful for hiding implementation +details of error generation from an end user. For instance: -function MyError() { - Error.captureStackTrace(this, MyError); -} + function MyError() { + Error.captureStackTrace(this, MyError); + } -// without passing MyError to captureStackTrace, the MyError -// frame would should up in the .stack property. by passing -// the constructor, we omit that frame and all frames above it. -new MyError().stack + // Without passing MyError to captureStackTrace, the MyError + // frame would should up in the .stack property. by passing + // the constructor, we omit that frame and all frames above it. + new MyError().stack -``` +### Error.stackTraceLimit -#### Error.stackTraceLimit +The `Error.stackTraceLimit` property specifies the number of stack frames +collected by a stack trace (whether generated by `new Error().stack` or +`Error.captureStackTrace(obj)`). -Property that determines the number of stack frames collected by a stack trace -(whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). +The default value is `10` but may be set to any valid JavaScript number. Changes +will affect any stack trace captured *after* the value has been changed. -The initial value is `10`. It may be set to any valid JavaScript number, which -will affect any stack trace captured *after* the value has been changed. If set -to a non-number value, stack traces will not capture any frames and will report -`undefined` on access. +If set to a non-number value, or set to a negative number, stack traces will +not capture any frames. #### error.message -A string of the value passed to `Error()` upon instantiation. The message will -also appear in the first line of the stack trace of the error. Changing this -property *may not* change the first line of the stack trace. +Returns the string description of error as set by calling `new Error(message)`. +The `message` passed to the constructor will also appear in the first line of +the stack trace of the `Error`, however changing this property after the +`Error` object is created *may not* change the first line of the stack trace. + + const err = new Error('The message'); + console.log(err.message); + // Prints: The message #### error.stack -A property that, when **accessed**, returns a string representing the point in the program -at which this error was instantiated. An example stacktrace follows: +Returns a string describing the point in the code at which the `Error` was +instantiated. + +For example: Error: Things keep happening! at /home/gbusey/file.js:525:2 @@ -225,103 +260,107 @@ at which this error was instantiated. An example stacktrace follows: at Actor. (/home/gbusey/actors.js:400:8) at increaseSynergy (/home/gbusey/actors.js:701:6) -The first line is formatted as `: `, and it is followed -by a series of stack frames (each line beginning with "at "). Each frame describes -a call site in the program that lead to the error being generated. V8 attempts to -display a name for each function (by variable name, function name, or object -method name), but occasionally it will not be able to find a suitable name. If -V8 cannot determine a name for the function, only location information will be -displayed for that frame. Otherwise, the determined function name will be displayed -with location information appended in parentheses. - -Frames are **only** generated for JavaScript functions. If, for example, execution -synchronously passes through a C++ addon function called `cheetahify`, which itself -calls a JavaScript function, the frame representing the `cheetahify` call will **not** -be present in stacktraces: - -```javascript -var cheetahify = require('./native-binding.node'); - -function makeFaster() { - // cheetahify *synchronously* calls speedy. - cheetahify(function speedy() { - throw new Error('oh no!'); - }); -} - -makeFaster(); // will throw: -// /home/gbusey/file.js:6 -// throw new Error('oh no!'); -// ^ -// Error: oh no! -// at speedy (/home/gbusey/file.js:6:11) -// at makeFaster (/home/gbusey/file.js:5:3) -// at Object. (/home/gbusey/file.js:10:1) -// at Module._compile (module.js:456:26) -// at Object.Module._extensions..js (module.js:474:10) -// at Module.load (module.js:356:32) -// at Function.Module._load (module.js:312:12) -// at Function.Module.runMain (module.js:497:10) -// at startup (node.js:119:16) -// at node.js:906:3 -``` +The first line is formatted as `: `, and +is followed by a series of stack frames (each line beginning with "at "). +Each frame describes a call site within the code that lead to the error being +generated. V8 attempts to display a name for each function (by variable name, +function name, or object method name), but occasionally it will not be able to +find a suitable name. If V8 cannot determine a name for the function, only +location information will be displayed for that frame. Otherwise, the +determined function name will be displayed with location information appended +in parentheses. + +It is important to note that frames are **only** generated for JavaScript +functions. If, for example, execution synchronously passes through a C++ addon +function called `cheetahify`, which itself calls a JavaScript function, the +frame representing the `cheetahify` call will **not** be present in the stack +traces: + + const cheetahify = require('./native-binding.node'); + + function makeFaster() { + // cheetahify *synchronously* calls speedy. + cheetahify(function speedy() { + throw new Error('oh no!'); + }); + } + + makeFaster(); // will throw: + // /home/gbusey/file.js:6 + // throw new Error('oh no!'); + // ^ + // Error: oh no! + // at speedy (/home/gbusey/file.js:6:11) + // at makeFaster (/home/gbusey/file.js:5:3) + // at Object. (/home/gbusey/file.js:10:1) + // at Module._compile (module.js:456:26) + // at Object.Module._extensions..js (module.js:474:10) + // at Module.load (module.js:356:32) + // at Function.Module._load (module.js:312:12) + // at Function.Module.runMain (module.js:497:10) + // at startup (node.js:119:16) + // at node.js:906:3 The location information will be one of: * `native`, if the frame represents a call internal to V8 (as in `[].forEach`). -* `plain-filename.js:line:column`, if the frame represents a call internal to Node.js. -* `/absolute/path/to/file.js:line:column`, if the frame represents a call in a user program, or its dependencies. +* `plain-filename.js:line:column`, if the frame represents a call internal + to Node.js. +* `/absolute/path/to/file.js:line:column`, if the frame represents a call in + a user program, or its dependencies. -It is important to note that the string representing the stacktrace is only -generated on **access**: it is lazily generated. +The string representing the stack trace is lazily generated when the +`error.stack` property is **accessed**. The number of frames captured by the stack trace is bounded by the smaller of `Error.stackTraceLimit` or the number of available frames on the current event loop tick. -System-level errors are generated as augmented `Error` instances, which are detailed -[below](#errors_system_errors). +System-level errors are generated as augmented `Error` instances, which are +detailed [below](#errors_system_errors). -### Class: RangeError +## Class: RangeError A subclass of `Error` that indicates that a provided argument was not within the -set or range of acceptable values for a function; whether that be a numeric -range, or outside the set of options for a given function parameter. An example: +set or range of acceptable values for a function; whether that is a numeric +range, or outside the set of options for a given function parameter. + +For example: -```javascript -require('net').connect(-1); // throws RangeError, port should be > 0 && < 65536 -``` + require('net').connect(-1); + // throws RangeError, port should be > 0 && < 65536 -Node.js will generate and throw `RangeError` instances *immediately* -- they are a form +Node.js will generate and throw `RangeError` instances *immediately* as a form of argument validation. -### Class: ReferenceError +## Class: ReferenceError -A subclass of `Error` that indicates that an attempt is being made to access a variable -that is not defined. Most commonly it indicates a typo, or an otherwise broken program. -While client code may generate and propagate these errors, in practice only V8 will do -so. +A subclass of `Error` that indicates that an attempt is being made to access a +variable that is not defined. Such errors commonly indicate typos in code, or +an otherwise broken program. -```javascript -doesNotExist; // throws ReferenceError, doesNotExist is not a variable in this program. -``` +While client code may generate and propagate these errors, in practice, only V8 +will do so. -`ReferenceError` instances will have an `.arguments` member that is an array containing -one element -- a string representing the variable that was not defined. + doesNotExist; + // throws ReferenceError, doesNotExist is not a variable in this program. -```javascript -try { - doesNotExist; -} catch(err) { - err.arguments[0] === 'doesNotExist'; -} -``` +`ReferenceError` instances will have an `error.arguments` property whose value +is an array containing a single element: a string representing the variable +that was not defined. -Unless the userland program is dynamically generating and running code, -ReferenceErrors should always be considered a bug in the program, or its -dependencies. + const assert = require('assert'); + try { + doesNotExist; + } catch(err) { + assert(err.arguments[0], 'doesNotExist'); + } + +Unless an application is dynamically generating and running code, +`ReferenceError` instances should always be considered a bug in the code +or its dependencies. -### Class: SyntaxError +## Class: SyntaxError A subclass of `Error` that indicates that a program is not valid JavaScript. These errors may only be generated and propagated as a result of code @@ -329,144 +368,129 @@ evaluation. Code evaluation may happen as a result of `eval`, `Function`, `require`, or [vm][]. These errors are almost always indicative of a broken program. -```javascript -try { - require("vm").runInThisContext("binary ! isNotOk"); -} catch(err) { - // err will be a SyntaxError -} -``` + try { + require('vm').runInThisContext('binary ! isNotOk'); + } catch(err) { + // err will be a SyntaxError + } -SyntaxErrors are unrecoverable from the context that created them – they may only be caught -by other contexts. +`SyntaxError` instances are unrecoverable in the context that created them – +they may only be caught by other contexts. -### Class: TypeError +## Class: TypeError -A subclass of `Error` that indicates that a provided argument is not an allowable -type. For example, passing a function to a parameter which expects a string would -be considered a TypeError. +A subclass of `Error` that indicates that a provided argument is not an +allowable type. For example, passing a function to a parameter which expects a +string would be considered a TypeError. -```javascript -require('url').parse(function() { }); // throws TypeError, since it expected a string -``` + require('url').parse(function() { }); + // throws TypeError, since it expected a string -Node.js will generate and throw `TypeError` instances *immediately* -- they are a form +Node.js will generate and throw `TypeError` instances *immediately* as a form of argument validation. -### Exceptions vs. Errors +## Exceptions vs. Errors -A JavaScript exception is a value that is thrown as a result of an invalid operation or -as the target of a `throw` statement. While it is not required that these values are instances of -`Error` or classes which inherit from `Error`, all exceptions thrown by Node.js or the JavaScript -runtime *will* be instances of Error. +A JavaScript exception is a value that is thrown as a result of an invalid +operation or as the target of a `throw` statement. While it is not required +that these values are instances of `Error` or classes which inherit from +`Error`, all exceptions thrown by Node.js or the JavaScript runtime *will* be +instances of Error. -Some exceptions are *unrecoverable* at the JavaScript layer. These exceptions will always bring -down the process. These are usually failed `assert()` checks or `abort()` calls in the C++ layer. +Some exceptions are *unrecoverable* at the JavaScript layer. Such exceptions +will *always* cause the Node.js process to crash. Examples include `assert()` +checks or `abort()` calls in the C++ layer. ## System Errors -System errors are generated in response to a program's runtime environment. -Ideally, they represent operational errors that the program needs to be able to -react to. They are generated at the syscall level: an exhaustive list of error -codes and their meanings is available by running `man 2 intro` or `man 3 errno` -on most Unices; or [online][]. +System errors are generated when exceptions occur within the program's +runtime environment. Typically, these are operational errors that occur +when an application violates an operating system constraint such as attempting +to read a file that does not exist or when the user does not have sufficient +permissions. + +System errors are typically generated at the syscall level: an exhaustive list +of error codes and their meanings is available by running `man 2 intro` or +`man 3 errno` on most Unices; or [online][]. -In Node.js, system errors are represented as augmented `Error` objects -- not full -subclasses, but instead an error instance with added members. +In Node.js, system errors are represented as augmented `Error` objects with +added properties. ### Class: System Error #### error.code #### error.errno -A string representing the error code, which is always `E` followed by capital -letters, and may be referenced in `man 2 intro`. +Returns a string representing the error code, which is always `E` followed by +a sequence of capital letters, and may be referenced in `man 2 intro`. + +The properties `error.code` and `error.errno` are aliases of one another and +return the same value. #### error.syscall -A string representing the [syscall][] that failed. +Returns a string describing the [syscall][] that failed. ### Common System Errors -This list is **not exhaustive**, but enumerates many of the common system errors when -writing a Node.js program. An exhaustive list may be found [here][online]. - -#### EACCES: Permission denied - -An attempt was made to access a file in a way forbidden by its file access -permissions. - -#### EADDRINUSE: Address already in use - -An attempt to bind a server ([`net`][], [`http`][], or [`https`][]) to a local -address failed due to another server on the local system already occupying -that address. - -#### ECONNREFUSED: Connection refused - -No connection could be made because the target machine actively refused -it. This usually results from trying to connect to a service that is inactive -on the foreign host. - -#### ECONNRESET: Connection reset by peer - -A connection was forcibly closed by a peer. This normally results -from a loss of the connection on the remote socket due to a timeout -or reboot. Commonly encountered via the [`http`][] and [`net`][] modules. - -#### EEXIST: File exists - -An existing file was the target of an operation that required that the target -not exist. - -#### EISDIR: Is a directory - -An operation expected a file, but the given pathname was a directory. - -#### EMFILE: Too many open files in system - -Maximum number of [file descriptors][] allowable on the system has -been reached, and requests for another descriptor cannot be fulfilled until -at least one has been closed. +This list is **not exhaustive**, but enumerates many of the common system +errors encountered when writing a Node.js program. An exhaustive list may be +found [here][online]. -Commonly encountered when opening many files at once in parallel, especially -on systems (in particular, OS X) where there is a low file descriptor limit -for processes. To remedy a low limit, run `ulimit -n 2048` in the same shell -that will run the Node.js process. +- `EACCES` (Permission denied): An attempt was made to access a file in a way + forbidden by its file access permissions. -#### ENOENT: No such file or directory +- `EADDRINUSE` (Address already in use): An attempt to bind a server + ([`net`][], [`http`][], or [`https`][]) to a local address failed due to + another server on the local system already occupying that address. -Commonly raised by [`fs`][] operations; a component of the specified pathname -does not exist -- no entity (file or directory) could be found by the given path. +- `ECONNREFUSED` (Connection refused): No connection could be made because the + target machine actively refused it. This usually results from trying to + connect to a service that is inactive on the foreign host. -#### ENOTDIR: Not a directory +- `ECONNRESET` (Connection reset by peer): A connection was forcibly closed by + a peer. This normally results from a loss of the connection on the remote + socket due to a timeout or reboot. Commonly encountered via the [`http`][] + and [`net`][] modules. -A component of the given pathname existed, but was not a directory as expected. -Commonly raised by [`fs.readdir`][]. +- `EEXIST` (File exists): An existing file was the target of an operation that + required that the target not exist. -#### ENOTEMPTY: Directory not empty +- `EISDIR` (Is a directory): An operation expected a file, but the given + pathname was a directory. -A directory with entries was the target of an operation that requires -an empty directory -- usually [`fs.unlink`][]. +- `EMFILE` (Too many open files in system): Maximum number of + [file descriptors][] allowable on the system has been reached, and + requests for another descriptor cannot be fulfilled until at least one + has been closed. This is encountered when opening many files at once in + parallel, especially on systems (in particular, OS X) where there is a low + file descriptor limit for processes. To remedy a low limit, run + `ulimit -n 2048` in the same shell that will run the Node.js process. -#### EPERM: Operation not permitted +- `ENOENT` (No such file or directory): Commonly raised by [`fs`][] operations + to indicate that a component of the specified pathname does not exist -- no + entity (file or directory) could be found by the given path. -An attempt was made to perform an operation that requires appropriate -privileges. +- `ENOTDIR` (Not a directory): A component of the given pathname existed, but + was not a directory as expected. Commonly raised by [`fs.readdir`][]. -#### EPIPE: Broken pipe +- `ENOTEMPTY` (Directory not empty): A directory with entries was the target + of an operation that requires an empty directory -- usually [`fs.unlink`][]. -A write on a pipe, socket, or FIFO for which there is no process to read the -data. Commonly encountered at the [`net`][] and [`http`][] layers, indicative that -the remote side of the stream being written to has been closed. +- `EPERM` (Operation not permitted): An attempt was made to perform an + operation that requires elevated privileges. -#### ETIMEDOUT: Operation timed out +- `EPIPE` (Broken pipe): A write on a pipe, socket, or FIFO for which there is + no process to read the data. Commonly encountered at the [`net`][] and + [`http`][] layers, indicative that the remote side of the stream being + written to has been closed. -A connect or send request failed because the connected party did not properly -respond after a period of time. Usually encountered by [`http`][] or [`net`][] -- -often a sign that a connected socket was not `.end()`'d appropriately. +- `ETIMEDOUT` (Operation timed out): A connect or send request failed because + the connected party did not properly respond after a period of time. Usually + encountered by [`http`][] or [`net`][] -- often a sign that a `socket.end()` + was not properly called. [`Error`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error [`fs.readdir`]: fs.html#fs_fs_readdir_path_callback @@ -488,3 +512,7 @@ often a sign that a connected socket was not `.end()`'d appropriately. [syscall]: http://man7.org/linux/man-pages/man2/syscall.2.html [V8's stack trace API]: https://github.com/v8/v8/wiki/Stack-Trace-API [vm]: vm.html +[`SyntaxError`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError +[`ReferenceError`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError +[`TypeError`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError +[`domain`]: domain.html diff --git a/doc/api/events.markdown b/doc/api/events.markdown index 92bec1363268..0fdfc0787490 100644 --- a/doc/api/events.markdown +++ b/doc/api/events.markdown @@ -4,88 +4,257 @@ -Many objects in Node.js emit events: a [`net.Server`][] emits an event each -time a peer connects to it, a [`fs.ReadStream`][] emits an event when the file -is opened. All objects which emit events are instances of `events.EventEmitter`. -You can access this module by doing: `require("events");` +Much of the Node.js core API is built around an idiomatic asynchronous +event-driven architecture in which certain kinds of objects (called "emitters") +periodically emit named events that cause Function objects ("listeners") to be +called. -Typically, event names are represented by a camel-cased string, however, -there aren't any strict restrictions on that, as any valid property key will be -accepted. +For instance: a [`net.Server`][] object emits an event each time a peer +connects to it; a [`fs.ReadStream`][] emits an event when the file is opened; +a [stream][] emits an event whenever data is available to be read. -Functions can then be attached to objects, to be executed when an event -is emitted. These functions are called _listeners_. Inside a listener -function, `this` refers to the `EventEmitter` that the listener was -attached to. +All objects that emit events are instances of the `EventEmitter` class. These +objects expose an `eventEmitter.on()` function that allows one or more +Functions to be attached to named events emitted by the object. Typically, +event names are camel-cased strings but any valid JavaScript property key +can be used. +When the `EventEmitter` object emits an event, all of the Functions attached +to that specific event are called _synchronously_. Any values returned by the +called listeners are _ignored_ and will be discarded. -## Class: events.EventEmitter +The following example shows a simple `EventEmitter` instance with a single +listener. The `eventEmitter.on()` method is used to register listeners, while +the `eventEmitter.emit()` method is used to trigger the event. -Use `require('events')` to access the EventEmitter class. + const EventEmitter = require('events'); + const util = require('util'); + + function MyEmitter() { + EventEmitter.call(this); + } + util.inherits(MyEmitter, EventEmitter); -```javascript -var EventEmitter = require('events'); -``` + const myEmitter = new MyEmitter(); + myEmitter.on('event', function() { + console.log('an event occurred!'); + }); + myEmitter.emit('event'); -When an `EventEmitter` instance experiences an error, the typical action is -to emit an `'error'` event. Error events are treated as a special case in -Node.js. If there is no listener for it, then the default action is to print -a stack trace and exit the program. +Any object can become an `EventEmitter` through inheritance. The example above +uses the traditional Node.js style prototypical inheritance using +the `util.inherits()` method. It is, however, possible to use ES6 classes as +well: -All EventEmitters emit the event `'newListener'` when new listeners are -added and `'removeListener'` when a listener is removed. + const EventEmitter = require('events'); -### Inheriting from 'EventEmitter' + class MyEmitter extends EventEmitter {} -Inheriting from `EventEmitter` is no different from inheriting from any other -constructor function. For example: + const myEmitter = new MyEmitter(); + myEmitter.on('event', function() { + console.log('an event occurred!'); + }); + myEmitter.emit('event'); + +## Passing arguments and `this` to listeners + +The `eventEmitter.emit()` method allows an arbitrary set of arguments to be +passed to the listener functions. It is important to keep in mind that when an +ordinary listener function is called by the `EventEmitter`, the standard `this` +keyword is intentionally set to reference the `EventEmitter` to which the +listener is attached. + + const myEmitter = new MyEmitter(); + myEmitter.on('event', function(a, b) { + console.log(a, b, this); + // Prints: + // a b MyEmitter { + // domain: null, + // _events: { event: [Function] }, + // _eventsCount: 1, + // _maxListeners: undefined } + }); + myEmitter.emit('event', 'a', 'b'); - 'use strict'; - const util = require('util'); - const EventEmitter = require('events'); +It is possible to use ES6 Arrow Functions as listeners, however, when doing so, +the `this` keyword will no longer reference the `EventEmitter` instance: - function MyEventEmitter() { - // Initialize necessary properties from `EventEmitter` in this instance - EventEmitter.call(this); - } + const myEmitter = new MyEmitter(); + myEmitter.on('event', (a, b) => { + console.log(a, b, this); + // Prints: a b {} + }); + myEmitter.emit('event', 'a', 'b'); + +## Asynchronous vs. Synchronous + +The `EventListener` calls all listeners synchronously in the order in which +they were registered. This is important to ensure the proper sequencing of +events and to avoid race conditions or logic errors. When appropriate, +listener functions can switch to an asynchronous mode of operation using +the `setImmediate()` or `process.nextTick()` methods: + + const myEmitter = new MyEmitter(); + myEmitter.on('event', (a, b) => { + setImmediate(() => { + console.log('this happens asynchronously'); + }); + }); + myEmitter.emit('event', 'a', 'b'); + +## Handling events only once + +When a listener is registered using the `eventEmitter.on()` method, that +listener will be invoked _every time_ the named event is emitted. + + const myEmitter = new MyEmitter(); + var m = 0; + myEmitter.on('event', () => { + console.log(++m); + }); + myEmitter.emit('event'); + // Prints: 1 + myEmitter.emit('event'); + // Prints: 2 + +Using the `eventEmitter.once()` method, it is possible to register a listener +that is immediately unregistered after it is called. + + const myEmitter = new MyEmitter(); + var m = 0; + myEmitter.once('event', () => { + console.log(++m); + }); + myEmitter.emit('event'); + // Prints: 1 + myEmitter.emit('event'); + // Ignored + +## Error events + +When an error occurs within an `EventEmitter` instance, the typical action is +for an `'error'` event to be emitted. These are treated as a special case +within Node.js. + +If an `EventEmitter` does _not_ have at least one listener registered for the +`'error'` event, and an `'error'` event is emitted, the error is thrown, a +stack trace is printed, and the Node.js process exits. + + const myEmitter = new MyEmitter(); + myEmitter.emit('error', new Error('whoops!')); + // Throws and crashes Node.js + +To guard against crashing the Node.js process, developers can either register +a listener for the `process.on('uncaughtException')` event or use the +[`domain`][] module (_Note, however, that the `domain` module has been +deprecated_). + + const myEmitter = new MyEmitter(); - // Inherit functions from `EventEmitter`'s prototype - util.inherits(MyEventEmitter, EventEmitter); + process.on('uncaughtException', (err) => { + console.log('whoops! there was an error'); + }); + + myEmitter.emit('error', new Error('whoops!')); + // Prints: whoops! there was an error + +As a best practice, developers should always register listeners for the +`'error'` event: + + const myEmitter = new MyEmitter(); + myEmitter.on('error', (err) => { + console.log('whoops! there was an error'); + }); + myEmitter.emit('error', new Error('whoops!')); + // Prints: whoops! there was an error + +## Class: EventEmitter -### Class Method: EventEmitter.listenerCount(emitter, event) +The `EventEmitter` class is defined and exposed by the `events` module: - Stability: 0 - Deprecated: Use [emitter.listenerCount][] instead. + const EventEmitter = require('events'); -Returns the number of listeners for a given event. +All EventEmitters emit the event `'newListener'` when new listeners are +added and `'removeListener'` when a listener is removed. ### Event: 'newListener' * `event` {String|Symbol} The event name * `listener` {Function} The event handler function -This event is emitted *before* a listener is added. When this event is -triggered, the listener has not been added to the array of listeners for the -`event`. Any listeners added to the event `name` in the newListener event -callback will be added *before* the listener that is in the process of being -added. +The `EventEmitter` instance will emit it's own `'newListener'` event *before* +a listener is added to it's internal array of listeners. + +Listeners registered for the `'newListener'` event will be passed the event +name and a reference to the listener being added. + +The fact that the event is triggered before adding the listener has a subtle +but important side effect: any *additional* listeners registered to the same +`name` *within* the `'newListener'` callback will be inserted *before* the +listener that is in the process of being added. + + const myEmitter = new MyEmitter(); + // Only do this once so we don't loop forever + myEmitter.once('newListener', (event, listener) => { + if (event === 'event') { + // Insert a new listener in front + myEmitter.on('event', () => { + console.log('B'); + }); + } + }); + myEmitter.on('event', () => { + console.log('A'); + }); + myEmitter.emit('event'); + // Prints: + // B + // A ### Event: 'removeListener' * `event` {String|Symbol} The event name * `listener` {Function} The event handler function -This event is emitted *after* a listener is removed. When this event is -triggered, the listener has been removed from the array of listeners for the -`event`. +The `'removeListener'` event is emitted *after* a listener is removed. + +### EventEmitter.listenerCount(emitter, event) + + Stability: 0 - Deprecated: Use [`emitter.listenerCount()`][] instead. + +A class method that returns the number of listeners for the given `event` +registered on the given `emitter`. + + const myEmitter = new MyEmitter(); + myEmitter.on('event', () => {}); + myEmitter.on('event', () => {}); + console.log(EventEmitter.listenerCount(myEmitter, 'event')); + // Prints: 2 ### EventEmitter.defaultMaxListeners -[`emitter.setMaxListeners(n)`][] sets the maximum on a per-instance basis. -This class property lets you set it for *all* `EventEmitter` instances, -current and future, effective immediately. Use with care. +By default, a maximum of `10` listeners can be registered for any single +event. This limit can be changed for individual `EventEmitter` instances +using the [`emitter.setMaxListeners(n)`][] method. To change the default +for *all* `EventEmitter` instances, the `EventEmitter.defaultMaxListeners` +property can be used. -Note that [`emitter.setMaxListeners(n)`][] still has precedence over -`EventEmitter.defaultMaxListeners`. +Take caution when setting the `EventEmitter.defaultMaxListeners` because the +change effects *all* `EventEmitter` instances, including those created before +the change is made. However, calling [`emitter.setMaxListeners(n)`][] still has +precedence over `EventEmitter.defaultMaxListeners`. + +Note that this is not a hard limit. The `EventEmitter` instance will allow +more listeners to be added but will output a trace warning to stderr indicating +that a `possible EventEmitter memory leak` has been detected. For any single +`EventEmitter`, the `emitter.getMaxListeners()` and `emitter.setMaxListeners()` +methods can be used to temporarily avoid this warning: + + emitter.setMaxListeners(emitter.getMaxListeners() + 1); + emitter.once('event', () => { + // do stuff + emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0)); + }); ### emitter.addListener(event, listener) @@ -93,77 +262,72 @@ Alias for `emitter.on(event, listener)`. ### emitter.emit(event[, arg1][, arg2][, ...]) -Calls each of the listeners in order with the supplied arguments. +Synchronously calls each of the listeners registered for `event`, in the order +they were registered, passing the supplied arguments to each. Returns `true` if event had listeners, `false` otherwise. ### emitter.getMaxListeners() -Returns the current max listener value for the emitter which is either set by -[`emitter.setMaxListeners(n)`][] or defaults to +Returns the current max listener value for the `EventEmitter` which is either +set by [`emitter.setMaxListeners(n)`][] or defaults to [`EventEmitter.defaultMaxListeners`][]. -This can be useful to increment/decrement max listeners to avoid the warning -while not being irresponsible and setting a too big number. +### emitter.listenerCount(event) - emitter.setMaxListeners(emitter.getMaxListeners() + 1); - emitter.once('event', function () { - // do stuff - emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0)); - }); - -### emitter.listenerCount(type) - -* `type` {Value} The type of event +* `event` {Value} The type of event -Returns the number of listeners listening to the `type` of event. +Returns the number of listeners listening to the `event` type. ### emitter.listeners(event) -Returns a copy of the array of listeners for the specified event. +Returns a copy of the array of listeners for the specified `event`. - server.on('connection', function (stream) { + server.on('connection', (stream) => { console.log('someone connected!'); }); - console.log(util.inspect(server.listeners('connection'))); // [ [Function] ] + console.log(util.inspect(server.listeners('connection'))); + // Prints: [ [Function] ] ### emitter.on(event, listener) -Adds a listener to the end of the listeners array for the specified `event`. -No checks are made to see if the `listener` has already been added. Multiple -calls passing the same combination of `event` and `listener` will result in the -`listener` being added multiple times. +Adds the `listener` function to the end of the listeners array for the +specified `event`. No checks are made to see if the `listener` has already +been added. Multiple calls passing the same combination of `event` and +`listener` will result in the `listener` being added, and called, multiple +times. - server.on('connection', function (stream) { + server.on('connection', (stream) => { console.log('someone connected!'); }); -Returns emitter, so calls can be chained. +Returns a reference to the `EventEmitter` so calls can be chained. ### emitter.once(event, listener) -Adds a **one time** listener for the event. This listener is -invoked only the next time the event is fired, after which -it is removed. +Adds a **one time** `listener` function for the `event`. This listener is +invoked only the next time `event` is triggered, after which it is removed. - server.once('connection', function (stream) { + server.once('connection', (stream) => { console.log('Ah, we have our first user!'); }); -Returns emitter, so calls can be chained. +Returns a reference to the `EventEmitter` so calls can be chained. ### emitter.removeAllListeners([event]) -Removes all listeners, or those of the specified event. It's not a good idea to -remove listeners that were added elsewhere in the code, especially when it's on -an emitter that you didn't create (e.g. sockets or file streams). +Removes all listeners, or those of the specified `event`. -Returns emitter, so calls can be chained. +Note that it is bad practice to remove listeners added elsewhere in the code, +particularly when the `EventEmitter` instance was created by some other +component or module (e.g. sockets or file streams). + +Returns a reference to the `EventEmitter` so calls can be chained. ### emitter.removeListener(event, listener) -Removes a listener from the listener array for the specified event. -**Caution**: changes array indices in the listener array behind the listener. +Removes the specified `listener` from the listener array for the specified +`event`. var callback = function(stream) { console.log('someone connected!'); @@ -177,19 +341,29 @@ listener array. If any single listener has been added multiple times to the listener array for the specified `event`, then `removeListener` must be called multiple times to remove each instance. -Returns emitter, so calls can be chained. +Because listeners are managed using an internal array, calling this will +change the position indices of any listener registered *after* the listener +being removed. This will not impact the order in which listeners are called, +but it will means that any copies of the listener array as returned by +the `emitter.listeners()` method will need to be recreated. + +Returns a reference to the `EventEmitter` so calls can be chained. ### emitter.setMaxListeners(n) -By default EventEmitters will print a warning if more than 10 listeners are -added for a particular event. This is a useful default which helps finding -memory leaks. Obviously not all Emitters should be limited to 10. This function -allows that to be increased. Set to `Infinity` (or `0`) for unlimited. +By default EventEmitters will print a warning if more than `10` listeners are +added for a particular event. This is a useful default that helps finding +memory leaks. Obviously, not all events should be limited to just 10 listeners. +The `emitter.setMaxListeners()` method allows the limit to be modified for this +specific `EventEmitter` instance. The value can be set to `Infinity` (or `0`) +for to indicate an unlimited number of listeners. -Returns emitter, so calls can be chained. +Returns a reference to the `EventEmitter` so calls can be chained. [`net.Server`]: net.html#net_class_net_server [`fs.ReadStream`]: fs.html#fs_class_fs_readstream [`emitter.setMaxListeners(n)`]: #events_emitter_setmaxlisteners_n [`EventEmitter.defaultMaxListeners`]: #events_eventemitter_defaultmaxlisteners -[emitter.listenerCount]: #events_emitter_listenercount_type +[`emitter.listenerCount()`]: #events_emitter_listenercount_event +[`domain`]: domain.html +[stream]: stream.html diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index 82f10d9ca16e..6b505dcadfa3 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -18,16 +18,16 @@ You can use try/catch to handle exceptions or allow them to bubble up. Here is an example of the asynchronous version: - var fs = require('fs'); + const fs = require('fs'); - fs.unlink('/tmp/hello', function (err) { + fs.unlink('/tmp/hello', (err) => { if (err) throw err; console.log('successfully deleted /tmp/hello'); }); Here is the synchronous version: - var fs = require('fs'); + const fs = require('fs'); fs.unlinkSync('/tmp/hello'); console.log('successfully deleted /tmp/hello'); @@ -35,23 +35,23 @@ Here is the synchronous version: With the asynchronous methods there is no guaranteed ordering. So the following is prone to error: - fs.rename('/tmp/hello', '/tmp/world', function (err) { + fs.rename('/tmp/hello', '/tmp/world', (err) => { if (err) throw err; console.log('renamed complete'); }); - fs.stat('/tmp/world', function (err, stats) { + fs.stat('/tmp/world', (err, stats) => { if (err) throw err; - console.log('stats: ' + JSON.stringify(stats)); + console.log(`stats: ${JSON.stringify(stats)}`); }); It could be that `fs.stat` is executed before `fs.rename`. The correct way to do this is to chain the callbacks. - fs.rename('/tmp/hello', '/tmp/world', function (err) { + fs.rename('/tmp/hello', '/tmp/world', (err) => { if (err) throw err; - fs.stat('/tmp/world', function (err, stats) { + fs.stat('/tmp/world', (err, stats) => { if (err) throw err; - console.log('stats: ' + JSON.stringify(stats)); + console.log(`stats: ${JSON.stringify(stats)}`); }); }); @@ -240,7 +240,7 @@ Asynchronously append data to a file, creating the file if it does not yet exist Example: - fs.appendFile('message.txt', 'data to append', function (err) { + fs.appendFile('message.txt', 'data to append', (err) => { if (err) throw err; console.log('The "data to append" was appended to file!'); }); @@ -355,8 +355,8 @@ If `options` is a string, then it specifies the encoding. Test whether or not the given path exists by checking with the file system. Then call the `callback` argument with either true or false. Example: - fs.exists('/etc/passwd', function (exists) { - console.log(exists ? "it's there" : 'no passwd!'); + fs.exists('/etc/passwd', (exists) => { + console.log(exists ? 'it\'s there' : 'no passwd!'); }); `fs.exists()` should not be used to check if a file exists before calling @@ -579,7 +579,7 @@ Synchronous readdir(3). Returns an array of filenames excluding `'.'` and Asynchronously reads the entire contents of a file. Example: - fs.readFile('/etc/passwd', function (err, data) { + fs.readFile('/etc/passwd', (err, data) => { if (err) throw err; console.log(data); }); @@ -623,7 +623,7 @@ resolution or avoid additional `fs.stat` calls for known real paths. Example: var cache = {'/etc':'/private/etc'}; - fs.realpath('/etc/passwd', cache, function (err, resolvedPath) { + fs.realpath('/etc/passwd', cache, (err, resolvedPath) => { if (err) throw err; console.log(resolvedPath); }); @@ -790,10 +790,10 @@ Windows. Even on supported platforms, `filename` is not always guaranteed to be provided. Therefore, don't assume that `filename` argument is always provided in the callback, and have some fallback logic if it is null. - fs.watch('somedir', function (event, filename) { - console.log('event is: ' + event); + fs.watch('somedir', (event, filename) => { + console.log(`event is: ${event}`); if (filename) { - console.log('filename provided: ' + filename); + console.log(`filename provided: ${filename}`); } else { console.log('filename not provided'); } @@ -814,9 +814,9 @@ target should be polled in milliseconds. The default is The `listener` gets two arguments the current stat object and the previous stat object: - fs.watchFile('message.text', function (curr, prev) { - console.log('the current mtime is: ' + curr.mtime); - console.log('the previous mtime was: ' + prev.mtime); + fs.watchFile('message.text', (curr, prev) => { + console.log(`the current mtime is: ${curr.mtime}`); + console.log(`the previous mtime was: ${prev.mtime}`); }); These stat objects are instances of `fs.Stat`. @@ -900,7 +900,7 @@ to `'utf8'`. Example: - fs.writeFile('message.txt', 'Hello Node.js', function (err) { + fs.writeFile('message.txt', 'Hello Node.js', (err) => { if (err) throw err; console.log('It\'s saved!'); }); diff --git a/doc/api/http.markdown b/doc/api/http.markdown index fb2cbae8914e..aedc35208f6d 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -64,10 +64,10 @@ a `'close'` event or a special `'agentRemove'` event. This means that if you intend to keep one HTTP request open for a long time and don't want it to stay in the pool you can do something along the lines of: - http.get(options, function(res) { + http.get(options, (res) => { // Do stuff - }).on("socket", function (socket) { - socket.emit("agentRemove"); + }).on('socket', (socket) => { + socket.emit('agentRemove'); }); Alternatively, you could just opt out of pooling entirely using @@ -78,7 +78,7 @@ Alternatively, you could just opt out of pooling entirely using port: 80, path: '/', agent: false // create a new agent just for this one request - }, function (res) { + }, (res) => { // Do stuff with response }) @@ -103,7 +103,7 @@ of these values set to their respective defaults. To configure any of them, you must create your own [`http.Agent`][] object. ```javascript -var http = require('http'); +const http = require('http'); var keepAliveAgent = new http.Agent({ keepAlive: true }); options.agent = keepAliveAgent; http.request(options, onResponseCallback); @@ -202,19 +202,19 @@ their connections closed. A client server pair that show you how to listen for the `'connect'` event. - var http = require('http'); - var net = require('net'); - var url = require('url'); + const http = require('http'); + const net = require('net'); + const url = require('url'); // Create an HTTP tunneling proxy - var proxy = http.createServer(function (req, res) { + var proxy = http.createServer( (req, res) => { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('okay'); }); - proxy.on('connect', function(req, cltSocket, head) { + proxy.on('connect', (req, cltSocket, head) => { // connect to an origin server - var srvUrl = url.parse('http://' + req.url); - var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, function() { + var srvUrl = url.parse(`http://${req.url}`); + var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => { cltSocket.write('HTTP/1.1 200 Connection Established\r\n' + 'Proxy-agent: Node.js-Proxy\r\n' + '\r\n'); @@ -225,7 +225,7 @@ A client server pair that show you how to listen for the `'connect'` event. }); // now that proxy is running - proxy.listen(1337, '127.0.0.1', function() { + proxy.listen(1337, '127.0.0.1', () => { // make a request to a tunneling proxy var options = { @@ -238,7 +238,7 @@ A client server pair that show you how to listen for the `'connect'` event. var req = http.request(options); req.end(); - req.on('connect', function(res, socket, head) { + req.on('connect', (res, socket, head) => { console.log('got connected!'); // make a request over an HTTP tunnel @@ -246,10 +246,10 @@ A client server pair that show you how to listen for the `'connect'` event. 'Host: www.google.com:80\r\n' + 'Connection: close\r\n' + '\r\n'); - socket.on('data', function(chunk) { + socket.on('data', (chunk) => { console.log(chunk.toString()); }); - socket.on('end', function() { + socket.on('end', () => { proxy.close(); }); }); @@ -292,14 +292,14 @@ their connections closed. A client server pair that show you how to listen for the `'upgrade'` event. - var http = require('http'); + const http = require('http'); // Create an HTTP server - var srv = http.createServer(function (req, res) { + var srv = http.createServer( (req, res) => { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('okay'); }); - srv.on('upgrade', function(req, socket, head) { + srv.on('upgrade', (req, socket, head) => { socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' + 'Upgrade: WebSocket\r\n' + 'Connection: Upgrade\r\n' + @@ -309,7 +309,7 @@ A client server pair that show you how to listen for the `'upgrade'` event. }); // now that server is running - srv.listen(1337, '127.0.0.1', function() { + srv.listen(1337, '127.0.0.1', () => { // make a request var options = { @@ -324,7 +324,7 @@ A client server pair that show you how to listen for the `'upgrade'` event. var req = http.request(options); req.end(); - req.on('upgrade', function(res, socket, upgradeHead) { + req.on('upgrade', (res, socket, upgradeHead) => { console.log('got upgraded!'); socket.end(); process.exit(0); @@ -375,6 +375,9 @@ Once a socket is assigned to this request and is connected Once a socket is assigned to this request and is connected [`socket.setTimeout()`][] will be called. +* `timeout` {Number} Milliseconds before a request is considered to be timed out. +* `callback` {Function} Optional function to be called when a timeout occurs. Same as binding to the `timeout` event. + ### request.write(chunk[, encoding][, callback]) Sends a chunk of the body. By calling this method @@ -395,7 +398,7 @@ Returns `request`. ## Class: http.Server -This is an [`EventEmitter`][] with the following events: +This class inherits from [`net.Server`][] and has the following additional events: ### Event: 'checkContinue' @@ -606,7 +609,7 @@ emit trailers, with a list of the header fields in its value. E.g., response.writeHead(200, { 'Content-Type': 'text/plain', 'Trailer': 'Content-MD5' }); response.write(fileData); - response.addTrailers({'Content-MD5': "7895bf4b8828b55ceaf47747b4bca667"}); + response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'}); response.end(); Attempting to set a trailer field name that contains invalid characters will @@ -649,7 +652,7 @@ Removes a header that's queued for implicit sending. Example: - response.removeHeader("Content-Encoding"); + response.removeHeader('Content-Encoding'); ### response.sendDate @@ -667,11 +670,11 @@ here if you need to send multiple headers with the same name. Example: - response.setHeader("Content-Type", "text/html"); + response.setHeader('Content-Type', 'text/html'); or - response.setHeader("Set-Cookie", ["type=ninja", "language=javascript"]); + response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']); Attempting to set a header field name that contains invalid characters will result in a [`TypeError`][] being thrown. @@ -964,12 +967,12 @@ is that it sets the method to GET and calls `req.end()` automatically. Example: - http.get("http://www.google.com/index.html", function(res) { - console.log("Got response: " + res.statusCode); + http.get('http://www.google.com/index.html', (res) => { + console.log(`Got response: ${res.statusCode}`); // consume response body res.resume(); - }).on('error', function(e) { - console.log("Got error: " + e.message); + }).on('error', (e) => { + console.log(`Got error: ${e.message}`); }); ## http.globalAgent @@ -1037,20 +1040,20 @@ Example: } }; - var req = http.request(options, function(res) { - console.log('STATUS: ' + res.statusCode); - console.log('HEADERS: ' + JSON.stringify(res.headers)); + var req = http.request(options, (res) => { + console.log(`STATUS: ${res.statusCode}`); + console.log(`HEADERS: ${JSON.stringify(res.headers)}`); res.setEncoding('utf8'); - res.on('data', function (chunk) { - console.log('BODY: ' + chunk); + res.on('data', (chunk) => { + console.log(`BODY: ${chunk}`); }); - res.on('end', function() { + res.on('end', () => { console.log('No more data in response.') }) }); - req.on('error', function(e) { - console.log('problem with request: ' + e.message); + req.on('error', (e) => { + console.log(`problem with request: ${e.message}`); }); // write data to request body @@ -1096,6 +1099,7 @@ There are a few special headers that should be noted. [`http.Server`]: #http_class_http_server [`http.ServerResponse`]: #http_class_http_serverresponse [`message.headers`]: #http_message_headers +[`net.Server`]: net.html#net_class_net_server [`net.Server.close()`]: net.html#net_server_close_callback [`net.Server.listen()`]: net.html#net_server_listen_handle_callback [`net.Server.listen(path)`]: net.html#net_server_listen_path_callback diff --git a/doc/api/https.markdown b/doc/api/https.markdown index aab07b9ce35b..93416633747f 100644 --- a/doc/api/https.markdown +++ b/doc/api/https.markdown @@ -32,31 +32,31 @@ automatically added to the `'request'` event. Example: // curl -k https://localhost:8000/ - var https = require('https'); - var fs = require('fs'); + const https = require('https'); + const fs = require('fs'); - var options = { + const options = { key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') }; - https.createServer(options, function (req, res) { + https.createServer(options, (req, res) => { res.writeHead(200); - res.end("hello world\n"); + res.end('hello world\n'); }).listen(8000); Or - var https = require('https'); - var fs = require('fs'); + const https = require('https'); + const fs = require('fs'); - var options = { + const options = { pfx: fs.readFileSync('server.pfx') }; - https.createServer(options, function (req, res) { + https.createServer(options, (req, res) => { res.writeHead(200); - res.end("hello world\n"); + res.end('hello world\n'); }).listen(8000); ### server.close([callback]) @@ -78,17 +78,17 @@ automatically parsed with [`url.parse()`][]. Example: - var https = require('https'); + const https = require('https'); - https.get('https://encrypted.google.com/', function(res) { - console.log("statusCode: ", res.statusCode); - console.log("headers: ", res.headers); + https.get('https://encrypted.google.com/', (res) => { + console.log('statusCode: ', res.statusCode); + console.log('headers: ', res.headers); - res.on('data', function(d) { + res.on('data', (d) => { process.stdout.write(d); }); - }).on('error', function(e) { + }).on('error', (e) => { console.error(e); }); @@ -107,7 +107,7 @@ All options from [`http.request()`][] are valid. Example: - var https = require('https'); + const https = require('https'); var options = { hostname: 'encrypted.google.com', @@ -116,17 +116,17 @@ Example: method: 'GET' }; - var req = https.request(options, function(res) { - console.log("statusCode: ", res.statusCode); - console.log("headers: ", res.headers); + var req = https.request(options, (res) => { + console.log('statusCode: ', res.statusCode); + console.log('headers: ', res.headers); - res.on('data', function(d) { + res.on('data', (d) => { process.stdout.write(d); }); }); req.end(); - req.on('error', function(e) { + req.on('error', (e) => { console.error(e); }); @@ -192,7 +192,7 @@ Example: }; options.agent = new https.Agent(options); - var req = https.request(options, function(res) { + var req = https.request(options, (res) => { ... } @@ -210,7 +210,7 @@ Example: agent: false }; - var req = https.request(options, function(res) { + var req = https.request(options, (res) => { ... } diff --git a/doc/api/modules.markdown b/doc/api/modules.markdown index 00c1c77915c9..aa1f0b074e50 100644 --- a/doc/api/modules.markdown +++ b/doc/api/modules.markdown @@ -10,13 +10,12 @@ in one-to-one correspondence. As an example, `foo.js` loads the module The contents of `foo.js`: - var circle = require('./circle.js'); - console.log( 'The area of a circle of radius 4 is ' - + circle.area(4)); + const circle = require('./circle.js'); + console.log( `The area of a circle of radius 4 is ${circle.area(4)}`); The contents of `circle.js`: - var PI = Math.PI; + const PI = Math.PI; exports.area = function (r) { return PI * r * r; @@ -40,9 +39,9 @@ instead of `exports`. Below, `bar.js` makes use of the `square` module, which exports a constructor: - var square = require('./square.js'); + const square = require('./square.js'); var mySquare = square(2); - console.log('The area of my square is ' + mySquare.area()); + console.log(`The area of my square is ${mySquare.area()}`); The `square` module is defined in `square.js`: @@ -233,7 +232,7 @@ Consider this situation: console.log('a starting'); exports.done = false; - var b = require('./b.js'); + const b = require('./b.js'); console.log('in a, b.done = %j', b.done); exports.done = true; console.log('a done'); @@ -242,7 +241,7 @@ Consider this situation: console.log('b starting'); exports.done = false; - var a = require('./a.js'); + const a = require('./a.js'); console.log('in b, a.done = %j', a.done); exports.done = true; console.log('b done'); @@ -250,8 +249,8 @@ Consider this situation: `main.js`: console.log('main starting'); - var a = require('./a.js'); - var b = require('./b.js'); + const a = require('./a.js'); + const b = require('./b.js'); console.log('in main, a.done=%j, b.done=%j', a.done, b.done); When `main.js` loads `a.js`, then `a.js` in turn loads `b.js`. At that @@ -425,20 +424,20 @@ which is probably not what you want to do. For example suppose we were making a module called `a.js` - var EventEmitter = require('events'); + const EventEmitter = require('events'); module.exports = new EventEmitter(); // Do some work, and after some time emit // the 'ready' event from the module itself. - setTimeout(function() { + setTimeout(() => { module.exports.emit('ready'); }, 1000); Then in another file we could do - var a = require('./a'); - a.on('ready', function() { + const a = require('./a'); + a.on('ready', () => { console.log('module a is ready'); }); @@ -448,13 +447,13 @@ done in any callbacks. This does not work: x.js: - setTimeout(function() { - module.exports = { a: "hello" }; + setTimeout(() => { + module.exports = { a: 'hello' }; }, 0); y.js: - var x = require('./x'); + const x = require('./x'); console.log(x.a); #### exports alias diff --git a/doc/api/net.markdown b/doc/api/net.markdown index 32d2218982db..7e898596f5a1 100644 --- a/doc/api/net.markdown +++ b/doc/api/net.markdown @@ -45,14 +45,14 @@ Returns an object with three properties, e.g. Example: - var server = net.createServer(function (socket) { - socket.end("goodbye\n"); + var server = net.createServer((socket) => { + socket.end('goodbye\n'); }); // grab a random port. - server.listen(function() { + server.listen(() => { address = server.address(); - console.log("opened server on %j", address); + console.log('opened server on %j', address); }); Don't call `server.address()` until the `'listening'` event has been emitted. @@ -184,10 +184,10 @@ One issue some users run into is getting `EADDRINUSE` errors. This means that another server is already running on the requested port. One way of handling this would be to wait a second and then try again. This can be done with - server.on('error', function (e) { + server.on('error', (e) => { if (e.code == 'EADDRINUSE') { console.log('Address in use, retrying...'); - setTimeout(function () { + setTimeout(() => { server.close(); server.listen(PORT, HOST); }, 1000); @@ -512,24 +512,23 @@ The `connectListener` parameter will be added as a listener for the Here is an example of a client of the previously described echo server: - var net = require('net'); - var client = net.connect({port: 8124}, - function() { //'connect' listener + const net = require('net'); + const client = net.connect({port: 8124}, () => { //'connect' listener console.log('connected to server!'); client.write('world!\r\n'); }); - client.on('data', function(data) { + client.on('data', (data) => { console.log(data.toString()); client.end(); }); - client.on('end', function() { + client.on('end', () => { console.log('disconnected from server'); }); To connect on the socket `/tmp/echo.sock` the second line would just be changed to - var client = net.connect({path: '/tmp/echo.sock'}); + const client = net.connect({path: '/tmp/echo.sock'}); ## net.connect(path[, connectListener]) @@ -562,24 +561,24 @@ The `connectListener` parameter will be added as a listener for the Here is an example of a client of the previously described echo server: - var net = require('net'); - var client = net.connect({port: 8124}, - function() { //'connect' listener + const net = require('net'); + const client = net.connect({port: 8124}, + () => { //'connect' listener console.log('connected to server!'); client.write('world!\r\n'); }); - client.on('data', function(data) { + client.on('data', (data) => { console.log(data.toString()); client.end(); }); - client.on('end', function() { + client.on('end', () => { console.log('disconnected from server'); }); To connect on the socket `/tmp/echo.sock` the second line would just be changed to - var client = net.connect({path: '/tmp/echo.sock'}); + const client = net.connect({path: '/tmp/echo.sock'}); ## net.createConnection(path[, connectListener]) @@ -624,16 +623,16 @@ original process. To begin reading data from a paused socket, call [`resume()`][ Here is an example of an echo server which listens for connections on port 8124: - var net = require('net'); - var server = net.createServer(function(c) { //'connection' listener + const net = require('net'); + const server = net.createServer((c) => { //'connection' listener console.log('client connected'); - c.on('end', function() { + c.on('end', () => { console.log('client disconnected'); }); c.write('hello\r\n'); c.pipe(c); }); - server.listen(8124, function() { //'listening' listener + server.listen(8124, () => { //'listening' listener console.log('server bound'); }); @@ -644,7 +643,7 @@ Test this by using `telnet`: To listen on the socket `/tmp/echo.sock` the third line from the last would just be changed to - server.listen('/tmp/echo.sock', function() { //'listening' listener + server.listen('/tmp/echo.sock', () => { //'listening' listener Use `nc` to connect to a UNIX domain socket server: diff --git a/doc/api/process.markdown b/doc/api/process.markdown index 73724b39b96f..bdc71590f41c 100644 --- a/doc/api/process.markdown +++ b/doc/api/process.markdown @@ -29,9 +29,9 @@ implicitly by the event loop draining. Example of listening for `'exit'`: - process.on('exit', function(code) { + process.on('exit', (code) => { // do *NOT* do this - setTimeout(function() { + setTimeout(() => { console.log('This will not run'); }, 0); console.log('About to exit with code:', code); @@ -71,11 +71,11 @@ event tells you when the list of unhandled rejections shrinks. For example using the rejection detection hooks in order to keep a map of all the rejected promise reasons at a given time: - var unhandledRejections = new Map(); - process.on('unhandledRejection', function(reason, p) { + const unhandledRejections = new Map(); + process.on('unhandledRejection', (reason, p) => { unhandledRejections.set(p, reason); }); - process.on('rejectionHandled', function(p) { + process.on('rejectionHandled', (p) => { unhandledRejections.delete(p); }); @@ -93,11 +93,11 @@ a stack trace and exit) will not occur. Example of listening for `'uncaughtException'`: - process.on('uncaughtException', function(err) { - console.log('Caught exception: ' + err); + process.on('uncaughtException', (err) => { + console.log(`Caught exception: ${err}`); }); - setTimeout(function() { + setTimeout(() => { console.log('This will still run.'); }, 500); @@ -138,7 +138,7 @@ instance). Here is an example that logs every unhandled rejection to the console - process.on('unhandledRejection', function(reason, p) { + process.on('unhandledRejection', (reason, p) => { console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason); // application specific logging, throwing an error, or other logic here }); @@ -146,8 +146,8 @@ Here is an example that logs every unhandled rejection to the console For example, here is a rejection that will trigger the `'unhandledRejection'` event: - somePromise.then(function(res) { - return reportToUser(JSON.pasre(res)); // note the typo + somePromise.then((res) => { + return reportToUser(JSON.parse(res)); // note the typo }); // no `.catch` or `.then` Here is an example of a coding pattern that will also trigger @@ -226,7 +226,7 @@ Example of listening for `SIGINT`: // Start reading from stdin so we don't exit. process.stdin.resume(); - process.on('SIGINT', function() { + process.on('SIGINT', () => { console.log('Got SIGINT. Press Control-D to exit.'); }); @@ -285,8 +285,8 @@ An array containing the command line arguments. The first element will be next elements will be any additional command line arguments. // print process.argv - process.argv.forEach(function(val, index, array) { - console.log(index + ': ' + val); + process.argv.forEach((val, index, array) => { + console.log(`${index}: ${val}`); }); This will generate: @@ -302,13 +302,13 @@ This will generate: Changes the current working directory of the process or throws an exception if that fails. - console.log('Starting directory: ' + process.cwd()); + console.log(`Starting directory: ${process.cwd()}`); try { process.chdir('/tmp'); - console.log('New directory: ' + process.cwd()); + console.log(`New directory: ${process.cwd()}`); } catch (err) { - console.log('chdir: ' + err); + console.log(`chdir: ${err}`); } ## process.config @@ -340,7 +340,7 @@ An example of the possible output looks like: target_arch: 'x64', v8_use_snapshot: 'true' } } -### process.connected +## process.connected * {Boolean} Set to false after `process.disconnect()` is called @@ -350,7 +350,7 @@ If `process.connected` is false, it is no longer possible to send messages. Returns the current working directory of the process. - console.log('Current directory: ' + process.cwd()); + console.log(`Current directory: ${process.cwd()}`); ## process.disconnect() @@ -450,7 +450,7 @@ Gets the effective group identity of the process. (See getegid(2).) This is the numerical group id, not the group name. if (process.getegid) { - console.log('Current gid: ' + process.getegid()); + console.log(`Current gid: ${process.getegid()}`); } @@ -463,7 +463,7 @@ Gets the effective user identity of the process. (See geteuid(2).) This is the numerical userid, not the username. if (process.geteuid) { - console.log('Current uid: ' + process.geteuid()); + console.log(`Current uid: ${process.geteuid()}`); } ## process.getgid() @@ -475,7 +475,7 @@ Gets the group identity of the process. (See getgid(2).) This is the numerical group id, not the group name. if (process.getgid) { - console.log('Current gid: ' + process.getgid()); + console.log(`Current gid: ${process.getgid()}`); } ## process.getgroups() @@ -495,7 +495,7 @@ Gets the user identity of the process. (See getuid(2).) This is the numerical userid, not the username. if (process.getuid) { - console.log('Current uid: ' + process.getuid()); + console.log(`Current uid: ${process.getuid()}`); } ## process.hrtime() @@ -511,7 +511,7 @@ a diff reading, useful for benchmarks and measuring intervals: var time = process.hrtime(); // [ 1800216, 25 ] - setTimeout(function() { + setTimeout(() => { var diff = process.hrtime(time); // [ 1, 552 ] @@ -556,11 +556,11 @@ something other than kill the target process. Example of sending a signal to yourself: - process.on('SIGHUP', function() { + process.on('SIGHUP', () => { console.log('Got SIGHUP signal.'); }); - setTimeout(function() { + setTimeout(() => { console.log('Exiting.'); process.exit(0); }, 100); @@ -584,7 +584,7 @@ As with `require.main`, it will be `undefined` if there was no entry script. Returns an object describing the memory usage of the Node.js process measured in bytes. - var util = require('util'); + const util = require('util'); console.log(util.inspect(process.memoryUsage())); @@ -609,7 +609,7 @@ efficient. It runs before any additional I/O events (including timers) fire in subsequent ticks of the event loop. console.log('start'); - process.nextTick(function() { + process.nextTick(() => { console.log('nextTick callback'); }); console.log('scheduled'); @@ -625,7 +625,7 @@ but before any I/O has occurred. function MyThing(options) { this.setupOptions(options); - process.nextTick(function() { + process.nextTick(() => { this.startDoingStuff(); }.bind(this)); } @@ -677,14 +677,14 @@ happening, just like a `while(true);` loop. The PID of the process. - console.log('This process is pid ' + process.pid); + console.log(`This process is pid ${process.pid}`); ## process.platform What platform you're running on: `'darwin'`, `'freebsd'`, `'linux'`, `'sunos'` or `'win32'` - console.log('This platform is ' + process.platform); + console.log(`This platform is ${process.platform}`); ## process.release @@ -738,13 +738,13 @@ This accepts either a numerical ID or a groupname string. If a groupname is specified, this method blocks while resolving it to a numerical ID. if (process.getegid && process.setegid) { - console.log('Current gid: ' + process.getegid()); + console.log(`Current gid: ${process.getegid()}`); try { process.setegid(501); - console.log('New gid: ' + process.getegid()); + console.log(`New gid: ${process.getegid()}`); } catch (err) { - console.log('Failed to set gid: ' + err); + console.log(`Failed to set gid: ${err}`); } } @@ -758,13 +758,13 @@ This accepts either a numerical ID or a username string. If a username is specified, this method blocks while resolving it to a numerical ID. if (process.geteuid && process.seteuid) { - console.log('Current uid: ' + process.geteuid()); + console.log(`Current uid: ${process.geteuid()}`); try { process.seteuid(501); - console.log('New uid: ' + process.geteuid()); + console.log(`New uid: ${process.geteuid()}`); } catch (err) { - console.log('Failed to set uid: ' + err); + console.log(`Failed to set uid: ${err}`); } } @@ -778,13 +778,13 @@ a numerical ID or a groupname string. If a groupname is specified, this method blocks while resolving it to a numerical ID. if (process.getgid && process.setgid) { - console.log('Current gid: ' + process.getgid()); + console.log(`Current gid: ${process.getgid()}`); try { process.setgid(501); - console.log('New gid: ' + process.getgid()); + console.log(`New gid: ${process.getgid()}`); } catch (err) { - console.log('Failed to set gid: ' + err); + console.log(`Failed to set gid: ${err}`); } } @@ -808,13 +808,13 @@ a numerical ID or a username string. If a username is specified, this method blocks while resolving it to a numerical ID. if (process.getuid && process.setuid) { - console.log('Current uid: ' + process.getuid()); + console.log(`Current uid: ${process.getuid()}`); try { process.setuid(501); - console.log('New uid: ' + process.getuid()); + console.log(`New uid: ${process.getuid()}`); } catch (err) { - console.log('Failed to set uid: ' + err); + console.log(`Failed to set uid: ${err}`); } } @@ -836,14 +836,14 @@ Example of opening standard input and listening for both events: process.stdin.setEncoding('utf8'); - process.stdin.on('readable', function() { + process.stdin.on('readable', () => { var chunk = process.stdin.read(); if (chunk !== null) { - process.stdout.write('data: ' + chunk); + process.stdout.write(`data: ${chunk}`); } }); - process.stdin.on('end', function() { + process.stdin.on('end', () => { process.stdout.write('end'); }); @@ -865,7 +865,7 @@ A `Writable Stream` to `stdout` (on fd `1`). For example, a `console.log` equivalent could look like this: console.log = function(msg) { - process.stdout.write(msg + '\n'); + process.stdout.write(`${msg}\n`); }; `process.stderr` and `process.stdout` are unlike other streams in Node.js in @@ -891,7 +891,7 @@ See [the tty docs][] for more information. ## process.title -Getter/setter to set what is displayed in `ps. +Getter/setter to set what is displayed in `ps`. When used as a setter, the maximum length is platform-specific and probably short. @@ -909,11 +909,11 @@ Sets or reads the process's file mode creation mask. Child processes inherit the mask from the parent process. Returns the old mask if `mask` argument is given, otherwise returns the current mask. - var oldmask, newmask = 0022; - - oldmask = process.umask(newmask); - console.log('Changed umask from: ' + oldmask.toString(8) + - ' to ' + newmask.toString(8)); + const newmask = 0o022; + const oldmask = process.umask(newmask); + console.log( + `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}` + ); ## process.uptime() @@ -924,7 +924,7 @@ Number of seconds Node.js has been running. A compiled-in property that exposes `NODE_VERSION`. - console.log('Version: ' + process.version); + console.log(`Version: ${process.version}`); ## process.versions diff --git a/doc/api/readline.markdown b/doc/api/readline.markdown index cdf424339ed0..5d98f501f68c 100644 --- a/doc/api/readline.markdown +++ b/doc/api/readline.markdown @@ -9,16 +9,16 @@ Note that once you've invoked this module, your Node.js program will not terminate until you've closed the interface. Here's how to allow your program to gracefully exit: - var readline = require('readline'); + const readline = require('readline'); - var rl = readline.createInterface({ + const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); - rl.question("What do you think of Node.js? ", function(answer) { + rl.question('What do you think of Node.js? ', (answer) => { // TODO: Log the answer in a database - console.log("Thank you for your valuable feedback:", answer); + console.log('Thank you for your valuable feedback:', answer); rl.close(); }); @@ -66,8 +66,8 @@ nothing is displayed. Example usage: - interface.question('What is your favorite food?', function(answer) { - console.log('Oh, so your favorite food is ' + answer); + interface.question('What is your favorite food?', (answer) => { + console.log(`Oh, so your favorite food is ${answer}`); }); ### rl.resume() @@ -117,8 +117,8 @@ user hits enter, or return. This is a good hook to listen for user input. Example of listening for `'line'`: - rl.on('line', function (cmd) { - console.log('You just typed: '+cmd); + rl.on('line', (cmd) => { + console.log(`You just typed: ${cmd}`); }); ### Event: 'pause' @@ -132,7 +132,7 @@ Also emitted whenever the `input` stream is not paused and receives the Example of listening for `'pause'`: - rl.on('pause', function() { + rl.on('pause', () => { console.log('Readline paused.'); }); @@ -144,7 +144,7 @@ Emitted whenever the `input` stream is resumed. Example of listening for `'resume'`: - rl.on('resume', function() { + rl.on('resume', () => { console.log('Readline resumed.'); }); @@ -161,7 +161,7 @@ background. Example of listening for `SIGCONT`: - rl.on('SIGCONT', function() { + rl.on('SIGCONT', () => { // `prompt` will automatically resume the stream rl.prompt(); }); @@ -176,8 +176,8 @@ stream receives a `SIGINT`, `pause` will be triggered. Example of listening for `SIGINT`: - rl.on('SIGINT', function() { - rl.question('Are you sure you want to exit?', function(answer) { + rl.on('SIGINT', () => { + rl.question('Are you sure you want to exit?', (answer) => { if (answer.match(/^y(es)?$/i)) rl.pause(); }); }); @@ -200,7 +200,7 @@ before the program was sent to the background. Example of listening for `SIGTSTP`: - rl.on('SIGTSTP', function() { + rl.on('SIGTSTP', () => { // This will override SIGTSTP and prevent the program from going to the // background. console.log('Caught SIGTSTP.'); @@ -211,13 +211,13 @@ Example of listening for `SIGTSTP`: Here's an example of how to use all these together to craft a tiny command line interface: - var readline = require('readline'), - rl = readline.createInterface(process.stdin, process.stdout); + const readline = require('readline'); + const rl = readline.createInterface(process.stdin, process.stdout); rl.setPrompt('OHAI> '); rl.prompt(); - rl.on('line', function(line) { + rl.on('line', (line) => { switch(line.trim()) { case 'hello': console.log('world!'); @@ -227,7 +227,7 @@ line interface: break; } rl.prompt(); - }).on('close', function() { + }).on('close', () => { console.log('Have a great day!'); process.exit(0); }); @@ -277,7 +277,7 @@ Example: function completer(line) { var completions = '.help .error .exit .quit .q'.split(' ') - var hits = completions.filter(function(c) { return c.indexOf(line) == 0 }) + var hits = completions.filter((c) => { return c.indexOf(line) == 0 }) // show all completions if none found return [hits.length ? hits : completions, line] } @@ -291,8 +291,8 @@ Also `completer` can be run in async mode if it accepts two arguments: `createInterface` is commonly used with [`process.stdin`][] and [`process.stdout`][] in order to accept user input: - var readline = require('readline'); - var rl = readline.createInterface({ + const readline = require('readline'); + const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); diff --git a/doc/api/repl.markdown b/doc/api/repl.markdown index d5d4ec62ec75..99e9d0e26d87 100644 --- a/doc/api/repl.markdown +++ b/doc/api/repl.markdown @@ -85,8 +85,8 @@ a variable to the REPL explicitly by assigning it to the `context` object associated with each `REPLServer`. For example: // repl_test.js - var repl = require('repl'), - msg = 'message'; + const repl = require('repl'); + var msg = 'message'; repl.start('> ').context.m = msg; @@ -152,7 +152,7 @@ to signal `'end'` on the `input` stream. Example of listening for `exit`: - replServer.on('exit', function () { + replServer.on('exit', () => { console.log('Got "exit" event from repl!'); process.exit(); }); @@ -173,7 +173,7 @@ Example of listening for `reset`: someExtension.extend(r.context); // When a new context is created extend it as well. - replServer.on('reset', function (context) { + replServer.on('reset', (context) => { console.log('repl has a new context'); someExtension.extend(context); }); @@ -196,13 +196,13 @@ If a function is provided instead of an object for `cmd`, it is treated as the Example of defining a command: // repl_test.js - var repl = require('repl'); + const repl = require('repl'); var replServer = repl.start(); replServer.defineCommand('sayhello', { help: 'Say hello', action: function(name) { - this.write('Hello, ' + name + '!\n'); + this.write(`Hello, ${name}!\n'); this.displayPrompt(); } }); @@ -277,9 +277,9 @@ will share the same global object but will have unique I/O. Here is an example that starts a REPL on stdin, a Unix socket, and a TCP socket: - var net = require('net'), - repl = require('repl'), - connections = 0; + const net = require('net'); + const repl = require('repl'); + var connections = 0; repl.start({ prompt: 'Node.js via stdin> ', @@ -287,24 +287,24 @@ Here is an example that starts a REPL on stdin, a Unix socket, and a TCP socket: output: process.stdout }); - net.createServer(function (socket) { + net.createServer((socket) => { connections += 1; repl.start({ prompt: 'Node.js via Unix socket> ', input: socket, output: socket - }).on('exit', function() { + }).on('exit', () => { socket.end(); }) }).listen('/tmp/node-repl-sock'); - net.createServer(function (socket) { + net.createServer((socket) => { connections += 1; repl.start({ prompt: 'Node.js via TCP socket> ', input: socket, output: socket - }).on('exit', function() { + }).on('exit', () => { socket.end(); }); }).listen(5001); diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index b76ef0093e18..76d96233ac4b 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -50,9 +50,9 @@ Almost all Node.js programs, no matter how simple, use Streams in some way. Here is an example of using Streams in an Node.js program: ```javascript -var http = require('http'); +const http = require('http'); -var server = http.createServer(function (req, res) { +var server = http.createServer( (req, res) => { // req is an http.IncomingMessage, which is a Readable Stream // res is an http.ServerResponse, which is a Writable Stream @@ -62,18 +62,18 @@ var server = http.createServer(function (req, res) { req.setEncoding('utf8'); // Readable streams emit 'data' events once a listener is added - req.on('data', function (chunk) { + req.on('data', (chunk) => { body += chunk; }); // the end event tells you that you have entire body - req.on('end', function () { + req.on('end', () => { try { var data = JSON.parse(body); } catch (er) { // uh oh! bad json! res.statusCode = 400; - return res.end('error: ' + er.message); + return res.end(`error: ${er.message}`); } // write back something interesting to the user: @@ -176,7 +176,7 @@ possible, this is the best way to do so. ```javascript var readable = getReadableStreamSomehow(); -readable.on('data', function(chunk) { +readable.on('data', (chunk) => { console.log('got %d bytes of data', chunk.length); }); ``` @@ -191,10 +191,10 @@ or by calling `read()` repeatedly until you get to the end. ```javascript var readable = getReadableStreamSomehow(); -readable.on('data', function(chunk) { +readable.on('data', (chunk) => { console.log('got %d bytes of data', chunk.length); }); -readable.on('end', function() { +readable.on('end', () => { console.log('there will be no more data.'); }); ``` @@ -216,7 +216,7 @@ hadn't already. ```javascript var readable = getReadableStreamSomehow(); -readable.on('readable', function() { +readable.on('readable', () => { // there is some data to read now }); ``` @@ -234,12 +234,12 @@ In the former case, `.read()` will return that data. In the latter case, is an empty file: ```javascript -var fs = require('fs'); +const fs = require('fs'); var rr = fs.createReadStream('foo.txt'); -rr.on('readable', function() { +rr.on('readable', () => { console.log('readable:', rr.read()); }); -rr.on('end', function() { +rr.on('end', () => { console.log('end'); }); ``` @@ -280,11 +280,11 @@ available will remain in the internal buffer. ```javascript var readable = getReadableStreamSomehow(); -readable.on('data', function(chunk) { +readable.on('data', (chunk) => { console.log('got %d bytes of data', chunk.length); readable.pause(); console.log('there will be no more data for 1 second'); - setTimeout(function() { + setTimeout(() => { console.log('now data will start flowing again'); readable.resume(); }, 1000); @@ -335,7 +335,7 @@ end. ```javascript reader.pipe(writer, { end: false }); -reader.on('end', function() { +reader.on('end', () => { writer.end('Goodbye\n'); }); ``` @@ -366,7 +366,7 @@ drained. ```javascript var readable = getReadableStreamSomehow(); -readable.on('readable', function() { +readable.on('readable', () => { var chunk; while (null !== (chunk = readable.read())) { console.log('got %d bytes of data', chunk.length); @@ -395,7 +395,7 @@ data. ```javascript var readable = getReadableStreamSomehow(); readable.resume(); -readable.on('end', function() { +readable.on('end', () => { console.log('got to the end, but did not read anything'); }); ``` @@ -420,7 +420,7 @@ as strings, always use this method. ```javascript var readable = getReadableStreamSomehow(); readable.setEncoding('utf8'); -readable.on('data', function(chunk) { +readable.on('data', (chunk) => { assert.equal(typeof chunk, 'string'); console.log('got %d characters of string data', chunk.length); }); @@ -443,7 +443,7 @@ var writable = fs.createWriteStream('file.txt'); // All the data from readable goes into 'file.txt', // but only for the first second readable.pipe(writable); -setTimeout(function() { +setTimeout(() => { console.log('stop writing to file.txt'); readable.unpipe(writable); console.log('manually close the file stream'); @@ -471,7 +471,7 @@ for Stream Implementors, below.) // Pull off a header delimited by \n\n // use unshift() if we get too much // Call the callback with (error, header, stream) -var StringDecoder = require('string_decoder').StringDecoder; +const StringDecoder = require('string_decoder').StringDecoder; function parseHeader(stream, callback) { stream.on('error', callback); stream.on('readable', onReadable); @@ -528,12 +528,12 @@ as a convenience for interacting with old Node.js programs and libraries. For example: ```javascript -var OldReader = require('./old-api-module.js').OldReader; -var oreader = new OldReader; -var Readable = require('stream').Readable; -var myReader = new Readable().wrap(oreader); +const OldReader = require('./old-api-module.js').OldReader; +const Readable = require('stream').Readable; +const oreader = new OldReader; +const myReader = new Readable().wrap(oreader); -myReader.on('readable', function() { +myReader.on('readable', () => { myReader.read(); // etc. }); ``` @@ -615,10 +615,10 @@ to the underlying system, this event is emitted. ```javascript var writer = getWritableStreamSomehow(); for (var i = 0; i < 100; i ++) { - writer.write('hello, #' + i + '!\n'); + writer.write('hello, #${i}!\n'); } writer.end('this is the end\n'); -writer.on('finish', function() { +writer.on('finish', () => { console.error('all writes are now complete.'); }); ``` @@ -633,7 +633,7 @@ stream, adding this writable to its set of destinations. ```javascript var writer = getWritableStreamSomehow(); var reader = getReadableStreamSomehow(); -writer.on('pipe', function(src) { +writer.on('pipe', (src) => { console.error('something is piping into the writer'); assert.equal(src, reader); }); @@ -650,7 +650,7 @@ readable stream, removing this writable from its set of destinations. ```javascript var writer = getWritableStreamSomehow(); var reader = getReadableStreamSomehow(); -writer.on('unpipe', function(src) { +writer.on('unpipe', (src) => { console.error('something has stopped piping into the writer'); assert.equal(src, reader); }); @@ -723,7 +723,7 @@ To implement any sort of stream, the pattern is the same: [`util.inherits`][] method is particularly helpful for this.) 2. Call the appropriate parent class constructor in your constructor, to be sure that the internal mechanisms are set up properly. -2. Implement one or more specific methods, as detailed below. +3. Implement one or more specific methods, as detailed below. The class to extend and the method(s) to implement depend on the sort of stream class you are writing: @@ -761,7 +761,7 @@ of stream class you are writing:

[Writable](#stream_class_stream_writable_1)

-

[_write][], _writev

+

[_write][], [_writev][]

@@ -772,7 +772,7 @@ of stream class you are writing:

[Duplex](#stream_class_stream_duplex_1)

-

[_read][], [_write][], _writev

+

[_read][], [_write][], [_writev][]

@@ -783,7 +783,7 @@ of stream class you are writing:

[Transform](#stream_class_stream_transform_1)

-

_transform, _flush

+

[_transform][], [_flush][]

@@ -955,8 +955,8 @@ This is a basic example of a Readable stream. It emits the numerals from 1 to 1,000,000 in ascending order, and then ends. ```javascript -var Readable = require('stream').Readable; -var util = require('util'); +const Readable = require('stream').Readable; +const util = require('util'); util.inherits(Counter, Readable); function Counter(opt) { @@ -995,8 +995,8 @@ below for a better implementation. // Using Readable directly for this is sub-optimal. See the // alternative example below under the Transform section. -var Readable = require('stream').Readable; -var util = require('util'); +const Readable = require('stream').Readable; +const util = require('util'); util.inherits(SimpleProtocol, Readable); @@ -1012,13 +1012,13 @@ function SimpleProtocol(source, options) { this._source = source; var self = this; - source.on('end', function() { + source.on('end', () => { self.push(null); }); // give it a kick whenever the source is readable // read(0) will not consume any bytes - source.on('readable', function() { + source.on('readable', () => { self.read(0); }); @@ -1210,8 +1210,8 @@ would be piped into the parser, which is a more idiomatic Node.js stream approach. ```javascript -var util = require('util'); -var Transform = require('stream').Transform; +const util = require('util'); +const Transform = require('stream').Transform; util.inherits(SimpleProtocol, Transform); function SimpleProtocol(options) { @@ -1518,10 +1518,10 @@ For example, consider the following code: ```javascript // WARNING! BROKEN! -net.createServer(function(socket) { +net.createServer((socket) => { // we add an 'end' method, but never consume the data - socket.on('end', function() { + socket.on('end', () => { // It will never get here. socket.end('I got your message (but didnt read it)\n'); }); @@ -1538,9 +1538,9 @@ start the flow of data: ```javascript // Workaround -net.createServer(function(socket) { +net.createServer((socket) => { - socket.on('end', function() { + socket.on('end', () => { socket.end('I got your message (but didnt read it)\n'); }); @@ -1589,9 +1589,9 @@ respectively. These options can be used to implement parsers and serializers with Transform streams. ```javascript -var util = require('util'); -var StringDecoder = require('string_decoder').StringDecoder; -var Transform = require('stream').Transform; +const util = require('util'); +const StringDecoder = require('string_decoder').StringDecoder; +const Transform = require('stream').Transform; util.inherits(JSONParseStream, Transform); // Gets \n-delimited JSON string data, and emits the parsed objects @@ -1728,3 +1728,12 @@ horribly wrong. [Writable]: #stream_class_stream_writable [zlib streams]: zlib.html [zlib]: zlib.html +[_transform]: #stream_transform_transform_chunk_encoding_callback +[`_transform()`]: #stream_transform_transform_chunk_encoding_callback +[`_transform(chunk, encoding, callback)`]: #stream_transform_transform_chunk_encoding_callback +[_flush]: #stream_transform_flush_callback +[`_flush()`]: #stream_transform_flush_callback +[`_flush(callback)`]: #stream_transform_flush_callback +[_writev]: #stream_writable_writev_chunks_callback +[`_writev()`]: #stream_writable_writev_chunks_callback +[`_writev(chunks, callback)`]: #stream_writable_writev_chunks_callback diff --git a/doc/api/string_decoder.markdown b/doc/api/string_decoder.markdown index b58bcd2cf422..8bcba2cfbd51 100644 --- a/doc/api/string_decoder.markdown +++ b/doc/api/string_decoder.markdown @@ -6,13 +6,13 @@ To use this module, do `require('string_decoder')`. StringDecoder decodes a buffer to a string. It is a simple interface to `buffer.toString()` but provides additional support for utf8. - var StringDecoder = require('string_decoder').StringDecoder; - var decoder = new StringDecoder('utf8'); + const StringDecoder = require('string_decoder').StringDecoder; + const decoder = new StringDecoder('utf8'); - var cent = new Buffer([0xC2, 0xA2]); + const cent = new Buffer([0xC2, 0xA2]); console.log(decoder.write(cent)); - var euro = new Buffer([0xE2, 0x82, 0xAC]); + const euro = new Buffer([0xE2, 0x82, 0xAC]); console.log(decoder.write(euro)); ## Class: StringDecoder diff --git a/doc/api/synopsis.markdown b/doc/api/synopsis.markdown index 347b22e3cad2..4a051013c4a6 100644 --- a/doc/api/synopsis.markdown +++ b/doc/api/synopsis.markdown @@ -5,9 +5,9 @@ An example of a [web server][] written with Node.js which responds with `'Hello World'`: - var http = require('http'); + const http = require('http'); - http.createServer(function (request, response) { + http.createServer( (request, response) => { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n'); }).listen(8124); diff --git a/doc/api/timers.markdown b/doc/api/timers.markdown index 4d5caf2e0ee0..cf2f24ae938a 100644 --- a/doc/api/timers.markdown +++ b/doc/api/timers.markdown @@ -49,14 +49,14 @@ milliseconds (approximately 25 days) or less than 1, Node.js will use 1 as the ## setTimeout(callback, delay[, arg][, ...]) -To schedule execution of a one-time `callback` after `delay` milliseconds. Returns a -`timeoutObject` for possible use with `clearTimeout()`. Optionally you can -also pass arguments to the callback. +To schedule execution of a one-time `callback` after `delay` milliseconds. +Returns a `timeoutObject` for possible use with `clearTimeout()`. Optionally you +can also pass arguments to the callback. -It is important to note that your callback will probably not be called in exactly -`delay` milliseconds - Node.js makes no guarantees about the exact timing of when -the callback will fire, nor of the ordering things will fire in. The callback will -be called as close as possible to the time specified. +The callback will likely not be invoked in precisely `delay` milliseconds. +Node.js makes no guarantees about the exact timing of when callbacks will fire, +nor of their ordering. The callback will be called as close as possible to the +time specified. To follow browser behavior, when using delays larger than 2147483647 milliseconds (approximately 25 days) or less than 1, the timeout is executed @@ -64,10 +64,11 @@ immediately, as if the `delay` was set to 1. ## unref() -The opaque value returned by [`setTimeout`][] and [`setInterval`][] also has the method -`timer.unref()` which will allow you to create a timer that is active but if -it is the only item left in the event loop, it won't keep the program running. -If the timer is already `unref`d calling `unref` again will have no effect. +The opaque value returned by [`setTimeout`][] and [`setInterval`][] also has the +method `timer.unref()` which will allow you to create a timer that is active but +if it is the only item left in the event loop, it won't keep the program +running. If the timer is already `unref`d calling `unref` again will have no +effect. In the case of `setTimeout` when you `unref` you create a separate timer that will wakeup the event loop, creating too many of these may adversely effect diff --git a/doc/api/tls.markdown b/doc/api/tls.markdown index f7fbf1ee72a9..97d7388a2910 100644 --- a/doc/api/tls.markdown +++ b/doc/api/tls.markdown @@ -243,11 +243,11 @@ established after addition of event listener. Here's an example for using TLS session resumption: var tlsSessionStore = {}; - server.on('newSession', function(id, data, cb) { + server.on('newSession', (id, data, cb) => { tlsSessionStore[id.toString('hex')] = data; cb(); }); - server.on('resumeSession', function(id, cb) { + server.on('resumeSession', (id, cb) => { cb(null, tlsSessionStore[id.toString('hex')] || null); }); @@ -598,7 +598,7 @@ Creates a new client connection to the given `port` and `host` (old API) or OpenSSL and are defined in the constant [SSL_METHODS][]. - `secureContext`: An optional TLS context object from - `tls.createSecureContext( ... )`. Could it be used for caching client + `tls.createSecureContext( ... )`. It could be used for caching client certificates, key, and CA certificates. - `session`: A `Buffer` instance, containing TLS session. @@ -615,10 +615,10 @@ The `callback` parameter will be added as a listener for the Here is an example of a client of echo server as described previously: - var tls = require('tls'); - var fs = require('fs'); + const tls = require('tls'); + const fs = require('fs'); - var options = { + const options = { // These are necessary only if using the client certificate authentication key: fs.readFileSync('client-key.pem'), cert: fs.readFileSync('client-cert.pem'), @@ -627,40 +627,40 @@ Here is an example of a client of echo server as described previously: ca: [ fs.readFileSync('server-cert.pem') ] }; - var socket = tls.connect(8000, options, function() { + var socket = tls.connect(8000, options, () => { console.log('client connected', socket.authorized ? 'authorized' : 'unauthorized'); process.stdin.pipe(socket); process.stdin.resume(); }); socket.setEncoding('utf8'); - socket.on('data', function(data) { + socket.on('data', (data) => { console.log(data); }); - socket.on('end', function() { + socket.on('end', () => { server.close(); }); Or - var tls = require('tls'); - var fs = require('fs'); + const tls = require('tls'); + const fs = require('fs'); - var options = { + const options = { pfx: fs.readFileSync('client.pfx') }; - var socket = tls.connect(8000, options, function() { + var socket = tls.connect(8000, options, () => { console.log('client connected', socket.authorized ? 'authorized' : 'unauthorized'); process.stdin.pipe(socket); process.stdin.resume(); }); socket.setEncoding('utf8'); - socket.on('data', function(data) { + socket.on('data', (data) => { console.log(data); }); - socket.on('end', function() { + socket.on('end', () => { server.close(); }); @@ -856,10 +856,10 @@ automatically set as a listener for the [`'secureConnection'`][] event. The Here is a simple example echo server: - var tls = require('tls'); - var fs = require('fs'); + const tls = require('tls'); + const fs = require('fs'); - var options = { + const options = { key: fs.readFileSync('server-key.pem'), cert: fs.readFileSync('server-cert.pem'), @@ -870,23 +870,23 @@ Here is a simple example echo server: ca: [ fs.readFileSync('client-cert.pem') ] }; - var server = tls.createServer(options, function(socket) { + var server = tls.createServer(options, (socket) => { console.log('server connected', socket.authorized ? 'authorized' : 'unauthorized'); - socket.write("welcome!\n"); + socket.write('welcome!\n'); socket.setEncoding('utf8'); socket.pipe(socket); }); - server.listen(8000, function() { + server.listen(8000, () => { console.log('server bound'); }); Or - var tls = require('tls'); - var fs = require('fs'); + const tls = require('tls'); + const fs = require('fs'); - var options = { + const options = { pfx: fs.readFileSync('server.pfx'), // This is necessary only if using the client certificate authentication. @@ -894,14 +894,14 @@ Or }; - var server = tls.createServer(options, function(socket) { + var server = tls.createServer(options, (socket) => { console.log('server connected', socket.authorized ? 'authorized' : 'unauthorized'); - socket.write("welcome!\n"); + socket.write('welcome!\n'); socket.setEncoding('utf8'); socket.pipe(socket); }); - server.listen(8000, function() { + server.listen(8000, () => { console.log('server bound'); }); You can test this server by connecting to it with `openssl s_client`: diff --git a/doc/api/tty.markdown b/doc/api/tty.markdown index 251742a0e1b8..f01cedd702da 100644 --- a/doc/api/tty.markdown +++ b/doc/api/tty.markdown @@ -45,9 +45,9 @@ ever created (and only when `isatty(1)` is true). Emitted by `refreshSize()` when either of the `columns` or `rows` properties has changed. - process.stdout.on('resize', function() { + process.stdout.on('resize', () => { console.log('screen size has changed!'); - console.log(process.stdout.columns + 'x' + process.stdout.rows); + console.log(`${process.stdout.columns}x${process.stdout.rows}`); }); ### ws.columns diff --git a/doc/api/util.markdown b/doc/api/util.markdown index 03386aefb5b7..4574ae452b23 100644 --- a/doc/api/util.markdown +++ b/doc/api/util.markdown @@ -53,7 +53,7 @@ comma. For example, `NODE_DEBUG=fs,net,tls`. Marks that a method should not be used any more. - var util = require('util'); + const util = require('util'); exports.puts = util.deprecate(function() { for (var i = 0, len = arguments.length; i < len; ++i) { @@ -123,8 +123,8 @@ prototype of `constructor` will be set to a new object created from As an additional convenience, `superConstructor` will be accessible through the `constructor.super_` property. - var util = require("util"); - var EventEmitter = require("events"); + const util = require('util'); + const EventEmitter = require('events'); function MyStream() { EventEmitter.call(this); @@ -133,7 +133,7 @@ through the `constructor.super_` property. util.inherits(MyStream, EventEmitter); MyStream.prototype.write = function(data) { - this.emit("data", data); + this.emit('data', data); } var stream = new MyStream(); @@ -141,10 +141,10 @@ through the `constructor.super_` property. console.log(stream instanceof EventEmitter); // true console.log(MyStream.super_ === EventEmitter); // true - stream.on("data", function(data) { - console.log('Received data: "' + data + '"'); + stream.on('data', (data) => { + console.log(`Received data: "${data}"`); }) - stream.write("It works!"); // Received data: "It works!" + stream.write('It works!'); // Received data: "It works!" ## util.inspect(object[, options]) @@ -168,7 +168,7 @@ formatted string: Example of inspecting all properties of the `util` object: - var util = require('util'); + const util = require('util'); console.log(util.inspect(util, { showHidden: true, depth: null })); @@ -207,11 +207,11 @@ There are also `bold`, `italic`, `underline` and `inverse` codes. Objects also may define their own `inspect(depth)` function which `util.inspect()` will invoke and use the result of when inspecting the object: - var util = require('util'); + const util = require('util'); var obj = { name: 'nate' }; obj.inspect = function(depth) { - return '{' + this.name + '}'; + return `{${this.name}}`; }; util.inspect(obj); @@ -237,7 +237,7 @@ Internal alias for [`Array.isArray`][]. Returns `true` if the given "object" is an `Array`. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isArray([]) // true @@ -252,7 +252,7 @@ Returns `true` if the given "object" is an `Array`. `false` otherwise. Returns `true` if the given "object" is a `Boolean`. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isBoolean(1) // false @@ -269,7 +269,7 @@ Use `Buffer.isBuffer()` instead. Returns `true` if the given "object" is a `Buffer`. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isBuffer({ length: 0 }) // false @@ -284,7 +284,7 @@ Returns `true` if the given "object" is a `Buffer`. `false` otherwise. Returns `true` if the given "object" is a `Date`. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isDate(new Date()) // true @@ -299,7 +299,7 @@ Returns `true` if the given "object" is a `Date`. `false` otherwise. Returns `true` if the given "object" is an [`Error`][]. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isError(new Error()) // true @@ -314,7 +314,7 @@ Returns `true` if the given "object" is an [`Error`][]. `false` otherwise. Returns `true` if the given "object" is a `Function`. `false` otherwise. - var util = require('util'); + const util = require('util'); function Foo() {} var Bar = function() {}; @@ -332,7 +332,7 @@ Returns `true` if the given "object" is a `Function`. `false` otherwise. Returns `true` if the given "object" is strictly `null`. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isNull(0) // false @@ -347,7 +347,7 @@ Returns `true` if the given "object" is strictly `null`. `false` otherwise. Returns `true` if the given "object" is `null` or `undefined`. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isNullOrUndefined(0) // false @@ -362,7 +362,7 @@ Returns `true` if the given "object" is `null` or `undefined`. `false` otherwise Returns `true` if the given "object" is a `Number`. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isNumber(false) // false @@ -380,7 +380,7 @@ Returns `true` if the given "object" is a `Number`. `false` otherwise. Returns `true` if the given "object" is strictly an `Object` __and__ not a `Function`. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isObject(5) // false @@ -397,7 +397,7 @@ Returns `true` if the given "object" is strictly an `Object` __and__ not a Returns `true` if the given "object" is a primitive type. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isPrimitive(5) // true @@ -424,7 +424,7 @@ Returns `true` if the given "object" is a primitive type. `false` otherwise. Returns `true` if the given "object" is a `RegExp`. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isRegExp(/some regexp/) // true @@ -439,7 +439,7 @@ Returns `true` if the given "object" is a `RegExp`. `false` otherwise. Returns `true` if the given "object" is a `String`. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isString('') // true @@ -456,7 +456,7 @@ Returns `true` if the given "object" is a `String`. `false` otherwise. Returns `true` if the given "object" is a `Symbol`. `false` otherwise. - var util = require('util'); + const util = require('util'); util.isSymbol(5) // false @@ -471,7 +471,7 @@ Returns `true` if the given "object" is a `Symbol`. `false` otherwise. Returns `true` if the given "object" is `undefined`. `false` otherwise. - var util = require('util'); + const util = require('util'); var foo; util.isUndefined(5) diff --git a/doc/api/v8.markdown b/doc/api/v8.markdown index 1cee348ba1ca..70abd6c6473f 100644 --- a/doc/api/v8.markdown +++ b/doc/api/v8.markdown @@ -35,7 +35,7 @@ Usage: ``` // Print GC events to stdout for one minute. -var v8 = require('v8'); +const v8 = require('v8'); v8.setFlagsFromString('--trace_gc'); setTimeout(function() { v8.setFlagsFromString('--notrace_gc'); }, 60e3); ``` diff --git a/doc/api/vm.markdown b/doc/api/vm.markdown index fd36c6b21f7e..07e99ac73567 100644 --- a/doc/api/vm.markdown +++ b/doc/api/vm.markdown @@ -6,7 +6,7 @@ You can access this module with: - var vm = require('vm'); + const vm = require('vm'); JavaScript code can be compiled and run immediately or compiled, saved, and run later. @@ -48,8 +48,8 @@ and returns the result. Running code does not have access to local scope. Example: compile code that increments a global variable and sets one, then execute the code multiple times. These globals are contained in the sandbox. - var util = require('util'); - var vm = require('vm'); + const util = require('util'); + const vm = require('vm'); var sandbox = { animal: 'cat', @@ -85,14 +85,14 @@ Example: compile code that sets a global variable, then execute the code multiple times in different contexts. These globals are set on and contained in the sandboxes. - var util = require('util'); - var vm = require('vm'); + const util = require('util'); + const vm = require('vm'); - var sandboxes = [{}, {}, {}]; + const sandboxes = [{}, {}, {}]; - var script = new vm.Script('globalVar = "set"'); + const script = new vm.Script('globalVar = "set"'); - sandboxes.forEach(function (sandbox) { + sandboxes.forEach((sandbox) => { script.runInNewContext(sandbox); }); @@ -114,11 +114,11 @@ current `global` object. Example of using `script.runInThisContext` to compile code once and run it multiple times: - var vm = require('vm'); + const vm = require('vm'); global.globalVar = 0; - var script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' }); + const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' }); for (var i = 0; i < 1000; ++i) { script.runInThisContext(); @@ -176,10 +176,10 @@ returns the result. Running code does not have access to local scope. The Example: compile and execute different scripts in a single existing context. - var util = require('util'); - var vm = require('vm'); + const util = require('util'); + const vm = require('vm'); - var sandbox = { globalVar: 1 }; + const sandbox = { globalVar: 1 }; vm.createContext(sandbox); for (var i = 0; i < 10; ++i) { @@ -198,7 +198,7 @@ separate process. `vm.runInDebugContext` compiles and executes `code` inside the V8 debug context. The primary use case is to get access to the V8 debug object: - var Debug = vm.runInDebugContext('Debug'); + const Debug = vm.runInDebugContext('Debug'); Debug.scripts().forEach(function(script) { console.log(script.name); }); Note that the debug context and object are intrinsically tied to V8's debugger @@ -217,10 +217,10 @@ the sandbox as the global object and returns the result. Example: compile and execute code that increments a global variable and sets a new one. These globals are contained in the sandbox. - var util = require('util'); - var vm = require('vm'); + const util = require('util'); + const vm = require('vm'); - var sandbox = { + const sandbox = { animal: 'cat', count: 2 }; @@ -242,14 +242,14 @@ code does not have access to local scope, but does have access to the current Example of using `vm.runInThisContext` and `eval` to run the same code: - var vm = require('vm'); + const vm = require('vm'); var localVar = 'initial value'; - var vmResult = vm.runInThisContext('localVar = "vm";'); + const vmResult = vm.runInThisContext('localVar = "vm";'); console.log('vmResult: ', vmResult); console.log('localVar: ', localVar); - var evalResult = eval('localVar = "eval";'); + const evalResult = eval('localVar = "eval";'); console.log('evalResult: ', evalResult); console.log('localVar: ', localVar); diff --git a/doc/api/zlib.markdown b/doc/api/zlib.markdown index 5b1cf407820d..5f238be5bff8 100644 --- a/doc/api/zlib.markdown +++ b/doc/api/zlib.markdown @@ -4,7 +4,7 @@ You can access this module with: - var zlib = require('zlib'); + const zlib = require('zlib'); This provides bindings to Gzip/Gunzip, Deflate/Inflate, and DeflateRaw/InflateRaw classes. Each class takes the same options, and @@ -15,24 +15,24 @@ is a readable/writable Stream. Compressing or decompressing a file can be done by piping an fs.ReadStream into a zlib stream, then into an fs.WriteStream. - var gzip = zlib.createGzip(); - var fs = require('fs'); - var inp = fs.createReadStream('input.txt'); - var out = fs.createWriteStream('input.txt.gz'); + const gzip = zlib.createGzip(); + const fs = require('fs'); + const inp = fs.createReadStream('input.txt'); + const out = fs.createWriteStream('input.txt.gz'); inp.pipe(gzip).pipe(out); Compressing or decompressing data in one step can be done by using the convenience methods. - var input = '.................................'; + const input = '.................................'; zlib.deflate(input, function(err, buffer) { if (!err) { console.log(buffer.toString('base64')); } }); - var buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64'); + const buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64'); zlib.unzip(buffer, function(err, buffer) { if (!err) { console.log(buffer.toString()); @@ -48,14 +48,14 @@ ought to be cached. See [Memory Usage Tuning][] below for more information on the speed/memory/compression tradeoffs involved in zlib usage. // client request example - var zlib = require('zlib'); - var http = require('http'); - var fs = require('fs'); - var request = http.get({ host: 'izs.me', + const zlib = require('zlib'); + const http = require('http'); + const fs = require('fs'); + const request = http.get({ host: 'izs.me', path: '/', port: 80, headers: { 'accept-encoding': 'gzip,deflate' } }); - request.on('response', function(response) { + request.on('response', (response) => { var output = fs.createWriteStream('izs.me_index.html'); switch (response.headers['content-encoding']) { @@ -75,10 +75,10 @@ on the speed/memory/compression tradeoffs involved in zlib usage. // server example // Running a gzip operation on every request is quite expensive. // It would be much more efficient to cache the compressed buffer. - var zlib = require('zlib'); - var http = require('http'); - var fs = require('fs'); - http.createServer(function(request, response) { + const zlib = require('zlib'); + const http = require('http'); + const fs = require('fs'); + http.createServer((request, response) => { var raw = fs.createReadStream('index.html'); var acceptEncoding = request.headers['accept-encoding']; if (!acceptEncoding) { diff --git a/doc/releases.md b/doc/releases.md index 2adbdcbcd2d7..57e95c266f4f 100644 --- a/doc/releases.md +++ b/doc/releases.md @@ -1,11 +1,11 @@ Node.js Release Process ===================== -This document describes the technical aspects of the node.js release process. The intended audience is those who have been authorized by the Node.js Foundation Technical Steering Committee (TSC) to create, promote and sign official release builds for node.js, hosted on . +This document describes the technical aspects of the Node.js release process. The intended audience is those who have been authorized by the Node.js Foundation Technical Steering Committee (TSC) to create, promote, and sign official release builds for Node.js, hosted on . ## Who can make a release? -Release authorization is given by the node.js TSC. Once authorized, an individual must be have the following: +Release authorization is given by the Node.js TSC. Once authorized, an individual must be have the following: ### 1. Jenkins Release Access @@ -17,23 +17,23 @@ There are three relevant Jenkins jobs that should be used for a release flow: **c.** **Release builds:** **[iojs+release](https://ci.nodejs.org/job/iojs+release/)** does all of the work to build all required release assets. Promotion of the release files is a manual step once they are ready (see below). -The [Node.js build team](https://github.com/nodejs/build) is able to provide this access to individuals authorized by the TC. +The [Node.js build team](https://github.com/nodejs/build) is able to provide this access to individuals authorized by the TSC. ### 2. Access -The _dist_ user on nodejs.org controls the assets available in (note that is an alias for ). +The _dist_ user on nodejs.org controls the assets available in . is an alias for . -The Jenkins release build slaves upload their artifacts to the web server as the _staging_ user, the _dist_ user has access to move these assets to public access (the _staging_ user does not, for security purposes). +The Jenkins release build slaves upload their artifacts to the web server as the _staging_ user. The _dist_ user has access to move these assets to public access while, for security, the _staging_ user does not. Nightly builds are promoted automatically on the server by a cron task for the _dist_ user. -Release builds require manual promotion by an individual with SSH access to the server as the _dist_ user. The [Node.js build team](https://github.com/nodejs/build) is able to provide this access to individuals authorized by the TC. +Release builds require manual promotion by an individual with SSH access to the server as the _dist_ user. The [Node.js build team](https://github.com/nodejs/build) is able to provide this access to individuals authorized by the TSC. ### 3. A Publicly Listed GPG Key -A SHASUMS256.txt file is produced for every promoted build, nightly and releases. Additionally for releases, this file is signed by the individual responsible for that release. In order to be able to verify downloaded binaries, the public should be able to check that the SHASUMS256.txt file has been signed by someone who has been authorized to create a release. +A SHASUMS256.txt file is produced for every promoted build, nightly, and releases. Additionally for releases, this file is signed by the individual responsible for that release. In order to be able to verify downloaded binaries, the public should be able to check that the SHASUMS256.txt file has been signed by someone who has been authorized to create a release. -The GPG keys should be fetchable from a known third-party keyserver, currently the SKS Keyservers at are recommended. Use the [submission](https://sks-keyservers.net/i/#submit) form to submit a new GPG key. Keys should be fetchable via: +The GPG keys should be fetchable from a known third-party keyserver. The SKS Keyservers at are recommended. Use the [submission](https://sks-keyservers.net/i/#submit) form to submit a new GPG key. Keys should be fetchable via: ``` gpg --keyserver pool.sks-keyservers.net --recv-keys @@ -48,7 +48,7 @@ Additionally, full GPG key fingerprints for individuals authorized to release sh Notes: - Dates listed below as _"YYYY-MM-DD"_ should be the date of the release **as UTC**. Use `date -u +'%Y-%m-%d'` to find out what this is. - - Version strings are listed below as _"vx.y.z"_, substitute for the release version. + - Version strings are listed below as _"vx.y.z"_. Substitute for the release version. ### 1. Ensure that HEAD Is Stable @@ -56,7 +56,7 @@ Run a **[node-test-pull-request](https://ci.nodejs.org/job/node-test-pull-reques ### 2. Produce a Nightly Build _(optional)_ -If there is a reason to produce a test release for the purpose of having others try out installers or specifics of builds, produce a nightly build using **[iojs+release](https://ci.nodejs.org/job/iojs+release/)** and wait for it to drop in . Follow the directions and enter a proper length commit sha, a date string and select "nightly" for "disttype". +If there is a reason to produce a test release for the purpose of having others try out installers or specifics of builds, produce a nightly build using **[iojs+release](https://ci.nodejs.org/job/iojs+release/)** and wait for it to drop in . Follow the directions and enter a proper length commit SHA, enter a date string, and select "nightly" for "disttype". This is particularly recommended if there has been recent work relating to the OS X or Windows installers as they are not tested in any way by CI. @@ -123,7 +123,7 @@ This macro is used to signal an ABI version for native addons. It currently has The general rule is to bump this version when there are _breaking ABI_ changes and also if there are non-trivial API changes. The rules are not yet strictly defined, so if in doubt, please confer with someone that will have a more informed perspective, such as a member of the NAN team. -**Note** that it is current TSC policy to bump major version when ABI changes. If you see a need to bump `NODE_MODULE_VERSION` then you should consult the TSC, commits may need to be reverted or a major version bump may need to happen. +**Note** that it is current TSC policy to bump major version when ABI changes. If you see a need to bump `NODE_MODULE_VERSION` then you should consult the TSC. Commits may need to be reverted or a major version bump may need to happen. ### 5. Create Release Commit @@ -141,7 +141,7 @@ Notable changes: ### 6. Push to GitHub -Note that it is not essential that the release builds be created from the Node.js repository, they may be created from your own fork if you desire. It is preferable, but not essential that the commits remain the same between that used to build and the tagged commit in the Node.js repository. +Note that it is not essential that the release builds be created from the Node.js repository. They may be created from your own fork if you desire. It is preferable, but not essential, that the commits remain the same between that used to build and the tagged commit in the Node.js repository. ### 7. Produce Release Builds @@ -149,11 +149,11 @@ Use **[iojs+release](https://ci.nodejs.org/job/iojs+release/)** to produce relea Artifacts from each slave are uploaded to Jenkins and are available if further testing is required. Use this opportunity particularly to test OS X and Windows installers if there are any concerns. Click through to the individual slaves for a run to find the artifacts. -All release slaves should achieve "SUCCESS" (and be green, not red). A release with failures should not be promoted, there are likely problems to be investigated. +All release slaves should achieve "SUCCESS" (and be green, not red). A release with failures should not be promoted as there are likely problems to be investigated. You can rebuild the release as many times as you need prior to promoting them if you encounter problems. -Note that you do not have to wait for the ARM builds if they are take longer than the others. It is only necessary to have the main Linux (x64 and x86), OS X .pkg and .tar.gz, Windows (x64 and x86) .msi and .exe, source, headers and docs (both produced currently by an OS X slave). i.e. the slaves with "arm" in their name don't need to have finished to progress to the next step. However, **if you promote builds _before_ ARM builds have finished, you must repeat the promotion step for the ARM builds when they are ready**. +Note that you do not have to wait for the ARM builds if they take longer than the others. It is only necessary to have the main Linux (x64 and x86), OS X .pkg and .tar.gz, Windows (x64 and x86) .msi and .exe, source, headers and docs (both produced currently by an OS X slave). That is, the slaves with "arm" in their name don't need to have finished to progress to the next step. However, **if you promote builds _before_ ARM builds have finished, you must repeat the promotion step for the ARM builds when they are ready**. ### 8. Tag and Sign the Release Commit @@ -188,29 +188,29 @@ This sets up the branch so that nightly builds are produced with the next versio **It is important that the same individual who signed the release tag be the one to promote the builds as the SHASUMS256.txt file needs to be signed with the same GPG key!** -When you are confident that the build slaves have properly produced usable artifacts and uploaded them to the web server you can promote them to release status. This is done by interacting with the web server via the _dist_ user. +When you are confident that the build slaves have properly produced usable artifacts and uploaded them to the web server, you can promote them to release status. This is done by interacting with the web server via the _dist_ user. The _tools/release.sh_ script should be used to promote and sign the build. When run, it will perform the following actions: -**a.** Select a GPG key from your private keys, it will use a command similar to: `gpg --list-secret-keys` to list your keys. If you don't have any keys, it will bail (why are you releasing? Your tag should be signed!). If you have only one key, it will use that. If you have more than one key it will ask you to select one from the list. Be sure to use the same key that you signed your git tag with. +**a.** Select a GPG key from your private keys. It will use a command similar to: `gpg --list-secret-keys` to list your keys. If you don't have any keys, it will bail. (Why are you releasing? Your tag should be signed!) If you have only one key, it will use that. If you have more than one key it will ask you to select one from the list. Be sure to use the same key that you signed your git tag with. **b.** Log in to the server via SSH and check for releases that can be promoted, along with the list of artifacts. It will use the `dist-promotable` command on the server to find these. You will be asked, for each promotable release, whether you want to proceed. If there is more than one release to promote (there shouldn't be), be sure to only promote the release you are responsible for. **c.** Log in to the server via SSH and run the promote script for the given release. The command on the server will be similar to: `dist-promote vx.y.z`. After this step, the release artifacts will be available for download and a SHASUMS256.txt file will be present. The release will still be unsigned, however. -**d.** Download SHASUMS256.txt to your computer using SCP into a temporary directory. +**d.** Use `scp` to download SHASUMS256.txt to a temporary directory on your computer. -**e.** Sign the SHASUMS256.txt file using a command similar to: `gpg --default-key YOURKEY --clearsign /path/to/SHASUMS256.txt`. You will be prompted by GPG for your password for this to work. The signed file will be named SHASUMS256.txt.asc. +**e.** Sign the SHASUMS256.txt file using a command similar to: `gpg --default-key YOURKEY --clearsign /path/to/SHASUMS256.txt`. You will be prompted by GPG for your password. The signed file will be named SHASUMS256.txt.asc. -**f.** Output an ASCII armored version of your public GPG key, using a command similar to: `gpg --default-key YOURKEY --armor --export --output /path/to/SHASUMS256.txt.gpg`. This does not require your password and is mainly a convenience for users although not the recommended way to get a copy of your key. +**f.** Output an ASCII armored version of your public GPG key using a command similar to: `gpg --default-key YOURKEY --armor --export --output /path/to/SHASUMS256.txt.gpg`. This does not require your password and is mainly a convenience for users, although not the recommended way to get a copy of your key. **g.** Upload the SHASUMS256.txt\* files back to the server into the release directory. -If you didn't wait for ARM builds in the previous step before promoting the release, you should re-run _tools/release.sh_ after the ARM builds have finished and it will move the ARM artifacts into the correct location and you will be prompted to re-sign SHASUMS256.txt. +If you didn't wait for ARM builds in the previous step before promoting the release, you should re-run _tools/release.sh_ after the ARM builds have finished. That will move the ARM artifacts into the correct location. You will be prompted to re-sign SHASUMS256.txt. ### 11. Check the Release -Your release should be available at and also . Check that the appropriate files are in place, you may also want to check that the binaries are working as appropriate and have the right internal version strings. Check that the API docs are available at . Check that the release catalog files are correct at and . +Your release should be available at and . Check that the appropriate files are in place. You may want to check that the binaries are working as appropriate and have the right internal version strings. Check that the API docs are available at . Check that the release catalog files are correct at and . ### 12. Announce diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 305baa2cbd2f..ddb1c5bfff9b 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -58,7 +58,7 @@ function Agent(options) { if (req && req.shouldKeepAlive && !socket.destroyed && - self.options.keepAlive) { + self.keepAlive) { var freeSockets = self.freeSockets[name]; var freeLen = freeSockets ? freeSockets.length : 0; var count = freeLen; @@ -66,7 +66,6 @@ function Agent(options) { count += self.sockets[name].length; if (count > self.maxSockets || freeLen >= self.maxFreeSockets) { - self.removeSocket(socket, options); socket.destroy(); } else { freeSockets = freeSockets || []; @@ -78,7 +77,6 @@ function Agent(options) { freeSockets.push(socket); } } else { - self.removeSocket(socket, options); socket.destroy(); } } diff --git a/lib/_http_client.js b/lib/_http_client.js index 02d6e7ed374a..1361e2a6e0ec 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -3,7 +3,6 @@ const util = require('util'); const net = require('net'); const url = require('url'); -const EventEmitter = require('events'); const HTTPParser = process.binding('http_parser').HTTPParser; const assert = require('assert').ok; const common = require('_http_common'); @@ -283,6 +282,13 @@ function socketErrorListener(err) { socket.destroy(); } +function freeSocketErrorListener(err) { + var socket = this; + debug('SOCKET ERROR on FREE socket:', err.message, err.stack); + socket.destroy(); + socket.emit('agentRemove'); +} + function socketOnEnd() { var socket = this; var req = this._httpMessage; @@ -449,6 +455,7 @@ function responseOnEnd() { } socket.removeListener('close', socketCloseListener); socket.removeListener('error', socketErrorListener); + socket.once('error', freeSocketErrorListener); // Mark this socket as available, AFTER user-added end // handlers have a chance to run. process.nextTick(emitFreeNT, socket); @@ -483,6 +490,7 @@ function tickOnSocket(req, socket) { } parser.onIncoming = parserOnIncomingClient; + socket.removeListener('error', freeSocketErrorListener); socket.on('error', socketErrorListener); socket.on('data', socketOnData); socket.on('end', socketOnEnd); diff --git a/lib/_http_incoming.js b/lib/_http_incoming.js index 5377c84d5d3c..581f62f129f1 100644 --- a/lib/_http_incoming.js +++ b/lib/_http_incoming.js @@ -165,7 +165,7 @@ IncomingMessage.prototype._addHeaderLine = function(field, value, dest) { default: // make comma-separated list - if (dest[field] !== undefined) { + if (typeof dest[field] === 'string') { dest[field] += ', ' + value; } else { dest[field] = value; diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index e3a258b1cddd..72c5374f7b12 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -572,7 +572,7 @@ OutgoingMessage.prototype.end = function(data, encoding, callback) { var ret; if (data) { // Normal body write. - ret = this.write(data, encoding); + this.write(data, encoding); } if (this._hasBody && this.chunkedEncoding) { diff --git a/lib/_http_server.js b/lib/_http_server.js index e2221b759bd0..f524790fb2b1 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -65,6 +65,7 @@ const STATUS_CODES = exports.STATUS_CODES = { 428 : 'Precondition Required', // RFC 6585 429 : 'Too Many Requests', // RFC 6585 431 : 'Request Header Fields Too Large',// RFC 6585 + 451 : 'Unavailable For Legal Reasons', 500 : 'Internal Server Error', 501 : 'Not Implemented', 502 : 'Bad Gateway', diff --git a/lib/assert.js b/lib/assert.js index 11733493450b..3e52ab45f661 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -170,6 +170,11 @@ function _deepEqual(actual, expected, strict) { (expected === null || typeof expected !== 'object')) { return strict ? actual === expected : actual == expected; + // If both values are instances of typed arrays, wrap them in + // a Buffer each to increase performance + } else if (ArrayBuffer.isView(actual) && ArrayBuffer.isView(expected)) { + return compare(new Buffer(actual), new Buffer(expected)) === 0; + // 7.5 For all other Object pairs, including Array objects, equivalence is // determined by having the same number of owned properties (as verified // with Object.prototype.hasOwnProperty.call), the same set of keys diff --git a/lib/buffer.js b/lib/buffer.js index d9f0a5fad4c6..2daebb5e301e 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -19,13 +19,17 @@ binding.setupBufferJS(Buffer.prototype, bindingObj); const flags = bindingObj.flags; const kNoZeroFill = 0; +function createBuffer(size) { + const ui8 = new Uint8Array(size); + Object.setPrototypeOf(ui8, Buffer.prototype); + return ui8; +} function createPool() { poolSize = Buffer.poolSize; if (poolSize > 0) flags[kNoZeroFill] = 1; - allocPool = new Uint8Array(poolSize); - Object.setPrototypeOf(allocPool, Buffer.prototype); + allocPool = createBuffer(poolSize); poolOffset = 0; } createPool(); @@ -67,9 +71,7 @@ function SlowBuffer(length) { length = 0; if (length > 0) flags[kNoZeroFill] = 1; - const ui8 = new Uint8Array(+length); - Object.setPrototypeOf(ui8, Buffer.prototype); - return ui8; + return createBuffer(+length); } Object.setPrototypeOf(SlowBuffer.prototype, Uint8Array.prototype); @@ -78,9 +80,7 @@ Object.setPrototypeOf(SlowBuffer, Uint8Array); function allocate(size) { if (size === 0) { - const ui8 = new Uint8Array(size); - Object.setPrototypeOf(ui8, Buffer.prototype); - return ui8; + return createBuffer(size); } if (size < (Buffer.poolSize >>> 1)) { if (size > (poolSize - poolOffset)) @@ -95,9 +95,7 @@ function allocate(size) { // being zero filled. if (size > 0) flags[kNoZeroFill] = 1; - const ui8 = new Uint8Array(size); - Object.setPrototypeOf(ui8, Buffer.prototype); - return ui8; + return createBuffer(size); } } @@ -123,6 +121,10 @@ function fromString(string, encoding) { function fromObject(obj) { if (obj instanceof Buffer) { var b = allocate(obj.length); + + if (b.length === 0) + return b; + obj.copy(b, 0, 0, obj.length); return b; } diff --git a/lib/https.js b/lib/https.js index 6f97991f98c8..8e79d295bf5e 100644 --- a/lib/https.js +++ b/lib/https.js @@ -130,6 +130,10 @@ Agent.prototype.getName = function(options) { if (options.rejectUnauthorized !== undefined) name += options.rejectUnauthorized; + name += ':'; + if (options.servername && options.servername !== options.host) + name += options.servername; + return name; }; diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index 04bd270b1859..64def982c980 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -675,6 +675,9 @@ function setupChannel(target, channel) { const INTERNAL_PREFIX = 'NODE_'; function handleMessage(target, message, handle) { + if (!target._channel) + return; + var eventName = 'message'; if (message !== null && typeof message === 'object' && diff --git a/lib/internal/repl.js b/lib/internal/repl.js index 1a62414a49e9..e6b41fbdd89b 100644 --- a/lib/internal/repl.js +++ b/lib/internal/repl.js @@ -14,12 +14,6 @@ module.exports.createInternalRepl = createRepl; // The debounce is to guard against code pasted into the REPL. const kDebounceHistoryMS = 15; -// XXX(chrisdickinson): hack to make sure that the internal debugger -// uses the original repl. -function replStart() { - return REPL.start.apply(REPL, arguments); -} - function createRepl(env, opts, cb) { if (typeof opts === 'function') { cb = opts; @@ -120,7 +114,15 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) { if (data) { repl.history = data.split(/[\n\r]+/, repl.historySize); - } else if (oldHistoryPath) { + } else if (oldHistoryPath === historyPath) { + // If pre-v3.0, the user had set NODE_REPL_HISTORY_FILE to + // ~/.node_repl_history, warn the user about it and proceed. + repl._writeToOutput( + '\nThe old repl history file has the same name and location as ' + + `the new one i.e., ${historyPath} and is empty.\nUsing it as is.\n`); + repl._refreshLine(); + + } else if (oldHistoryPath) { // Grab data from the older pre-v3.0 JSON NODE_REPL_HISTORY_FILE format. repl._writeToOutput( '\nConverting old JSON repl history to line-separated history.\n' + @@ -128,7 +130,13 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) { repl._refreshLine(); try { - repl.history = JSON.parse(fs.readFileSync(oldHistoryPath, 'utf8')); + // Pre-v3.0, repl history was stored as JSON. + // Try and convert it to line separated history. + const oldReplJSONHistory = fs.readFileSync(oldHistoryPath, 'utf8'); + + // Only attempt to use the history if there was any. + if (oldReplJSONHistory) repl.history = JSON.parse(oldReplJSONHistory); + if (!Array.isArray(repl.history)) { throw new Error('Expected array, got ' + typeof repl.history); } diff --git a/lib/internal/v8_prof_polyfill.js b/lib/internal/v8_prof_polyfill.js index 1beae0e4e4b5..755f8f0d65d1 100644 --- a/lib/internal/v8_prof_polyfill.js +++ b/lib/internal/v8_prof_polyfill.js @@ -26,40 +26,42 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Node polyfill -var fs = require('fs'); -var os = { +const fs = require('fs'); +const cp = require('child_process'); +const os = { system: function(name, args) { if (process.platform === 'linux' && name === 'nm') { // Filter out vdso and vsyscall entries. - var arg = args[args.length - 1]; + const arg = args[args.length - 1]; if (arg === '[vdso]' || arg == '[vsyscall]' || /^[0-9a-f]+-[0-9a-f]+$/.test(arg)) { return ''; } + } else if (process.platform === 'darwin') { + args.unshift('-c', name); + name = '/bin/sh'; } - return require('child_process').execFileSync( - name, args, {encoding: 'utf8'}); + return cp.spawnSync(name, args).stdout.toString(); } }; -var print = console.log; +const print = console.log; function read(fileName) { return fs.readFileSync(fileName, 'utf8'); } -arguments = process.argv.slice(2); -var quit = process.exit; +const quit = process.exit; // Polyfill "readline()". -var logFile = arguments[arguments.length - 1]; +const logFile = arguments[arguments.length - 1]; try { fs.accessSync(logFile); } catch(e) { console.error('Please provide a valid isolate file as the final argument.'); process.exit(1); } -var fd = fs.openSync(logFile, 'r'); -var buf = new Buffer(4096); -var dec = new (require('string_decoder').StringDecoder)('utf-8'); +const fd = fs.openSync(logFile, 'r'); +const buf = new Buffer(4096); +const dec = new (require('string_decoder').StringDecoder)('utf-8'); var line = ''; versionCheck(); function readline() { @@ -85,7 +87,7 @@ function versionCheck() { var firstLine = readline(); line = firstLine + '\n' + line; firstLine = firstLine.split(','); - var curVer = process.versions.v8.split('.'); + const curVer = process.versions.v8.split('.'); if (firstLine.length !== 6 && firstLine[0] !== 'v8-version') { console.log('Unable to read v8-version from log file.'); return; diff --git a/lib/internal/v8_prof_processor.js b/lib/internal/v8_prof_processor.js index 543f977d4ae4..05452c180849 100644 --- a/lib/internal/v8_prof_processor.js +++ b/lib/internal/v8_prof_processor.js @@ -1,9 +1,4 @@ -'use strict'; -var cp = require('child_process'); -var fs = require('fs'); -var path = require('path'); - -var scriptFiles = [ +const scriptFiles = [ 'internal/v8_prof_polyfill', 'v8/tools/splaytree', 'v8/tools/codemap', @@ -16,29 +11,19 @@ var scriptFiles = [ 'v8/tools/SourceMap', 'v8/tools/tickprocessor-driver' ]; -var tempScript = 'tick-processor-tmp-' + process.pid; -var tempNm = 'mac-nm-' + process.pid; +var script = ''; -process.on('exit', function() { - try { fs.unlinkSync(tempScript); } catch (e) {} - try { fs.unlinkSync(tempNm); } catch (e) {} -}); -process.on('uncaughtException', function(err) { - try { fs.unlinkSync(tempScript); } catch (e) {} - try { fs.unlinkSync(tempNm); } catch (e) {} - throw err; +scriptFiles.forEach(function(s) { + script += process.binding('natives')[s] + '\n'; }); -scriptFiles.forEach(function(script) { - fs.appendFileSync(tempScript, process.binding('natives')[script]); -}); -var tickArguments = [tempScript]; +var tickArguments = []; if (process.platform === 'darwin') { - fs.writeFileSync(tempNm, process.binding('natives')['v8/tools/mac-nm'], - { mode: 0o555 }); - tickArguments.push('--mac', '--nm=' + path.join(process.cwd(), tempNm)); + const nm = 'foo() { nm "$@" | (c++filt -p -i || cat) }; foo $@'; + tickArguments.push('--mac', '--nm=' + nm); } else if (process.platform === 'win32') { tickArguments.push('--windows'); } tickArguments.push.apply(tickArguments, process.argv.slice(1)); -cp.spawn(process.execPath, tickArguments, { stdio: 'inherit' }); +script = 'arguments = ' + JSON.stringify(tickArguments) + ';\n' + script; +eval(script); diff --git a/lib/os.js b/lib/os.js index 2d537f53840a..ddf7cee9d487 100644 --- a/lib/os.js +++ b/lib/os.js @@ -1,7 +1,6 @@ 'use strict'; const binding = process.binding('os'); -const util = require('util'); const internalUtil = require('internal/util'); const isWindows = process.platform === 'win32'; diff --git a/lib/repl.js b/lib/repl.js index 76c7487b7bf3..de6f56223831 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -568,7 +568,8 @@ REPLServer.prototype.displayPrompt = function(preserveCursor) { var prompt = this._initialPrompt; if (this.bufferedCommand.length) { prompt = '...'; - var levelInd = new Array(this.lines.level.length).join('..'); + const len = this.lines.level.length ? this.lines.level.length - 1 : 0; + const levelInd = '..'.repeat(len); prompt += levelInd + ' '; } @@ -920,7 +921,8 @@ REPLServer.prototype.memory = function memory(cmd) { // save the line so I can do magic later if (cmd) { // TODO should I tab the level? - self.lines.push(new Array(self.lines.level.length).join(' ') + cmd); + const len = self.lines.level.length ? self.lines.level.length - 1 : 0; + self.lines.push(' '.repeat(len) + cmd); } else { // I don't want to not change the format too much... self.lines.push(''); diff --git a/lib/url.js b/lib/url.js index 45155fee936b..6489d6327d0e 100644 --- a/lib/url.js +++ b/lib/url.js @@ -586,7 +586,7 @@ Url.prototype.resolveObject = function(relative) { // Put this after the other two cases because it simplifies the booleans if (psychotic) { result.hostname = result.host = srcPath.shift(); - //occationaly the auth can get stuck only in host + //occasionally the auth can get stuck only in host //this especially happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? @@ -668,7 +668,7 @@ Url.prototype.resolveObject = function(relative) { if (psychotic) { result.hostname = result.host = isAbsolute ? '' : srcPath.length ? srcPath.shift() : ''; - //occationaly the auth can get stuck only in host + //occasionally the auth can get stuck only in host //this especially happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? diff --git a/lib/util.js b/lib/util.js index aa75950c217f..5b3166150749 100644 --- a/lib/util.js +++ b/lib/util.js @@ -163,9 +163,10 @@ function stylizeNoColor(str, styleType) { function arrayToHash(array) { var hash = Object.create(null); - array.forEach(function(val) { + for (var i = 0; i < array.length; i++) { + var val = array[i]; hash[val] = true; - }); + } return hash; } diff --git a/node.gyp b/node.gyp index 9a4f91a95ce3..c59e8fec36df 100644 --- a/node.gyp +++ b/node.gyp @@ -91,7 +91,6 @@ 'deps/v8/tools/tickprocessor.js', 'deps/v8/tools/SourceMap.js', 'deps/v8/tools/tickprocessor-driver.js', - 'deps/v8/tools/mac-nm', ], }, diff --git a/src/debug-agent.cc b/src/debug-agent.cc index 3409fb2603ae..06ede7fdef4a 100644 --- a/src/debug-agent.cc +++ b/src/debug-agent.cc @@ -321,6 +321,8 @@ void Agent::EnqueueMessage(AgentMessage* message) { void Agent::MessageHandler(const v8::Debug::Message& message) { Isolate* isolate = message.GetIsolate(); Environment* env = Environment::GetCurrent(isolate); + if (env == nullptr) + return; // Called from a non-node context. Agent* a = env->debugger_agent(); CHECK_NE(a, nullptr); CHECK_EQ(isolate, a->parent_env()->isolate()); diff --git a/src/env.h b/src/env.h index 0c616ddef214..6151c57069ad 100644 --- a/src/env.h +++ b/src/env.h @@ -38,6 +38,12 @@ namespace node { #define NODE_ISOLATE_SLOT 3 #endif +// The number of items passed to push_values_to_array_function has diminishing +// returns around 8. This should be used at all call sites using said function. +#ifndef NODE_PUSH_VAL_TO_ARRAY_MAX +#define NODE_PUSH_VAL_TO_ARRAY_MAX 8 +#endif + // Strings are per-isolate primitives but Environment proxies them // for the sake of convenience. Strings should be ASCII-only. #define PER_ISOLATE_STRING_PROPERTIES(V) \ @@ -231,12 +237,11 @@ namespace node { V(zero_return_string, "ZERO_RETURN") \ #define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) \ - V(add_properties_by_index_function, v8::Function) \ V(as_external, v8::External) \ + V(async_hooks_destroy_function, v8::Function) \ V(async_hooks_init_function, v8::Function) \ - V(async_hooks_pre_function, v8::Function) \ V(async_hooks_post_function, v8::Function) \ - V(async_hooks_destroy_function, v8::Function) \ + V(async_hooks_pre_function, v8::Function) \ V(binding_cache_object, v8::Object) \ V(buffer_constructor_function, v8::Function) \ V(buffer_prototype_object, v8::Object) \ @@ -250,6 +255,7 @@ namespace node { V(pipe_constructor_template, v8::FunctionTemplate) \ V(process_object, v8::Object) \ V(promise_reject_function, v8::Function) \ + V(push_values_to_array_function, v8::Function) \ V(script_context_constructor_template, v8::FunctionTemplate) \ V(script_data_constructor_function, v8::Function) \ V(secure_context_constructor_template, v8::FunctionTemplate) \ diff --git a/src/node.cc b/src/node.cc index 49cfc8a06053..3a780b5d5f29 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1063,7 +1063,7 @@ void SetupProcessObject(const FunctionCallbackInfo& args) { CHECK(args[0]->IsFunction()); - env->set_add_properties_by_index_function(args[0].As()); + env->set_push_values_to_array_function(args[0].As()); env->process_object()->Delete( FIXED_ONE_BYTE_STRING(env->isolate(), "_setupProcessObject")); } @@ -1607,28 +1607,22 @@ static void GetActiveRequests(const FunctionCallbackInfo& args) { Local ary = Array::New(args.GetIsolate()); Local ctx = env->context(); - Local fn = env->add_properties_by_index_function(); - static const size_t argc = 8; - Local argv[argc]; - size_t i = 0; + Local fn = env->push_values_to_array_function(); + Local argv[NODE_PUSH_VAL_TO_ARRAY_MAX]; + size_t idx = 0; for (auto w : *env->req_wrap_queue()) { - if (w->persistent().IsEmpty() == false) { - argv[i++ % argc] = w->object(); - if ((i % argc) == 0) { - HandleScope scope(env->isolate()); - fn->Call(ctx, ary, argc, argv).ToLocalChecked(); - for (auto&& arg : argv) { - arg = Local(); - } - } + if (w->persistent().IsEmpty()) + continue; + argv[idx] = w->object(); + if (++idx >= ARRAY_SIZE(argv)) { + fn->Call(ctx, ary, idx, argv).ToLocalChecked(); + idx = 0; } } - const size_t remainder = i % argc; - if (remainder > 0) { - HandleScope scope(env->isolate()); - fn->Call(ctx, ary, remainder, argv).ToLocalChecked(); + if (idx > 0) { + fn->Call(ctx, ary, idx, argv).ToLocalChecked(); } args.GetReturnValue().Set(ary); @@ -1641,7 +1635,10 @@ void GetActiveHandles(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Local ary = Array::New(env->isolate()); - int i = 0; + Local ctx = env->context(); + Local fn = env->push_values_to_array_function(); + Local argv[NODE_PUSH_VAL_TO_ARRAY_MAX]; + size_t idx = 0; Local owner_sym = env->owner_string(); @@ -1652,7 +1649,14 @@ void GetActiveHandles(const FunctionCallbackInfo& args) { Local owner = object->Get(owner_sym); if (owner->IsUndefined()) owner = object; - ary->Set(i++, owner); + argv[idx] = owner; + if (++idx >= ARRAY_SIZE(argv)) { + fn->Call(ctx, ary, idx, argv).ToLocalChecked(); + idx = 0; + } + } + if (idx > 0) { + fn->Call(ctx, ary, idx, argv).ToLocalChecked(); } args.GetReturnValue().Set(ary); @@ -2124,26 +2128,17 @@ void Kill(const FunctionCallbackInfo& args) { // and nanoseconds, to avoid any integer overflow possibility. // Pass in an Array from a previous hrtime() call to instead get a time diff. void Hrtime(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - uint64_t t = uv_hrtime(); - if (args.Length() > 0) { - // return a time diff tuple - if (!args[0]->IsArray()) { - return env->ThrowTypeError( - "process.hrtime() only accepts an Array tuple."); - } - Local inArray = Local::Cast(args[0]); - uint64_t seconds = inArray->Get(0)->Uint32Value(); - uint64_t nanos = inArray->Get(1)->Uint32Value(); - t -= (seconds * NANOS_PER_SEC) + nanos; - } + Local ab = args[0].As()->Buffer(); + uint32_t* fields = static_cast(ab->GetContents().Data()); - Local tuple = Array::New(env->isolate(), 2); - tuple->Set(0, Integer::NewFromUnsigned(env->isolate(), t / NANOS_PER_SEC)); - tuple->Set(1, Integer::NewFromUnsigned(env->isolate(), t % NANOS_PER_SEC)); - args.GetReturnValue().Set(tuple); + // These three indices will contain the values for the hrtime tuple. The + // seconds value is broken into the upper/lower 32 bits and stored in two + // uint32 fields to be converted back in JS. + fields[0] = (t / NANOS_PER_SEC) >> 32; + fields[1] = (t / NANOS_PER_SEC) & 0xffffffff; + fields[2] = t % NANOS_PER_SEC; } extern "C" void node_module_register(void* m) { @@ -2555,23 +2550,35 @@ static void EnvDeleter(Local property, static void EnvEnumerator(const PropertyCallbackInfo& info) { - Isolate* isolate = info.GetIsolate(); + Environment* env = Environment::GetCurrent(info); + Isolate* isolate = env->isolate(); + Local ctx = env->context(); + Local fn = env->push_values_to_array_function(); + Local argv[NODE_PUSH_VAL_TO_ARRAY_MAX]; + size_t idx = 0; + #ifdef __POSIX__ int size = 0; while (environ[size]) size++; - Local envarr = Array::New(isolate, size); + Local envarr = Array::New(isolate); for (int i = 0; i < size; ++i) { const char* var = environ[i]; const char* s = strchr(var, '='); const int length = s ? s - var : strlen(var); - Local name = String::NewFromUtf8(isolate, - var, - String::kNormalString, - length); - envarr->Set(i, name); + argv[idx] = String::NewFromUtf8(isolate, + var, + String::kNormalString, + length); + if (++idx >= ARRAY_SIZE(argv)) { + fn->Call(ctx, envarr, idx, argv).ToLocalChecked(); + idx = 0; + } + } + if (idx > 0) { + fn->Call(ctx, envarr, idx, argv).ToLocalChecked(); } #else // _WIN32 WCHAR* environment = GetEnvironmentStringsW(); @@ -2579,7 +2586,6 @@ static void EnvEnumerator(const PropertyCallbackInfo& info) { return; // This should not happen. Local envarr = Array::New(isolate); WCHAR* p = environment; - int i = 0; while (*p) { WCHAR *s; if (*p == L'=') { @@ -2594,13 +2600,19 @@ static void EnvEnumerator(const PropertyCallbackInfo& info) { } const uint16_t* two_byte_buffer = reinterpret_cast(p); const size_t two_byte_buffer_len = s - p; - Local value = String::NewFromTwoByte(isolate, - two_byte_buffer, - String::kNormalString, - two_byte_buffer_len); - envarr->Set(i++, value); + argv[idx] = String::NewFromTwoByte(isolate, + two_byte_buffer, + String::kNormalString, + two_byte_buffer_len); + if (++idx >= ARRAY_SIZE(argv)) { + fn->Call(ctx, envarr, idx, argv).ToLocalChecked(); + idx = 0; + } p = s + wcslen(s) + 1; } + if (idx > 0) { + fn->Call(ctx, envarr, idx, argv).ToLocalChecked(); + } FreeEnvironmentStringsW(environment); #endif diff --git a/src/node.js b/src/node.js index 34aae9395442..d63ffac8b705 100644 --- a/src/node.js +++ b/src/node.js @@ -181,12 +181,35 @@ } startup.setupProcessObject = function() { - process._setupProcessObject(setPropByIndex); + const _hrtime = process.hrtime; + const hrValues = new Uint32Array(3); - function setPropByIndex() { + process._setupProcessObject(pushValueToArray); + + function pushValueToArray() { for (var i = 0; i < arguments.length; i++) this.push(arguments[i]); } + + process.hrtime = function hrtime(ar) { + _hrtime(hrValues); + + if (typeof ar !== 'undefined') { + if (Array.isArray(ar)) { + return [ + (hrValues[0] * 0x100000000 + hrValues[1]) - ar[0], + hrValues[2] - ar[1] + ]; + } + + throw new TypeError('process.hrtime() only accepts an Array tuple'); + } + + return [ + hrValues[0] * 0x100000000 + hrValues[1], + hrValues[2] + ]; + }; }; startup.globalVariables = function() { diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 63d767a1f4cd..35a0687b9f95 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -116,21 +116,6 @@ static X509_NAME *cnnic_ev_name = d2i_X509_NAME(nullptr, &cnnic_ev_p, sizeof(CNNIC_EV_ROOT_CA_SUBJECT_DATA)-1); -// Forcibly clear OpenSSL's error stack on return. This stops stale errors -// from popping up later in the lifecycle of crypto operations where they -// would cause spurious failures. It's a rather blunt method, though. -// ERR_clear_error() isn't necessarily cheap either. -struct ClearErrorOnReturn { - ~ClearErrorOnReturn() { ERR_clear_error(); } -}; - -// Pop errors from OpenSSL's error stack that were added -// between when this was constructed and destructed. -struct MarkPopErrorOnReturn { - MarkPopErrorOnReturn() { ERR_set_mark(); } - ~MarkPopErrorOnReturn() { ERR_pop_to_mark(); } -}; - static uv_mutex_t* locks; const char* const root_certs[] = { @@ -517,46 +502,35 @@ int SSL_CTX_get_issuer(SSL_CTX* ctx, X509* cert, X509** issuer) { } -// Read a file that contains our certificate in "PEM" format, -// possibly followed by a sequence of CA certificates that should be -// sent to the peer in the Certificate message. -// -// Taken from OpenSSL - editted for style. int SSL_CTX_use_certificate_chain(SSL_CTX* ctx, - BIO* in, + X509* x, + STACK_OF(X509)* extra_certs, X509** cert, X509** issuer) { - int ret = 0; - X509* x = nullptr; + CHECK_EQ(*issuer, nullptr); + CHECK_EQ(*cert, nullptr); - x = PEM_read_bio_X509_AUX(in, nullptr, CryptoPemCallback, nullptr); - - if (x == nullptr) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); - goto end; - } - - ret = SSL_CTX_use_certificate(ctx, x); + int ret = SSL_CTX_use_certificate(ctx, x); if (ret) { // If we could set up our certificate, now proceed to // the CA certificates. - X509 *ca; int r; - unsigned long err; if (ctx->extra_certs != nullptr) { sk_X509_pop_free(ctx->extra_certs, X509_free); ctx->extra_certs = nullptr; } - while ((ca = PEM_read_bio_X509(in, nullptr, CryptoPemCallback, nullptr))) { + for (int i = 0; i < sk_X509_num(extra_certs); i++) { + X509* ca = sk_X509_value(extra_certs, i); + // NOTE: Increments reference count on `ca` r = SSL_CTX_add1_chain_cert(ctx, ca); if (!r) { - X509_free(ca); ret = 0; + *issuer = nullptr; goto end; } // Note that we must not free r if it was successfully @@ -567,17 +541,8 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx, // Find issuer if (*issuer != nullptr || X509_check_issued(ca, x) != X509_V_OK) continue; - *issuer = ca; - } - // When the while loop ends, it's usually just EOF. - err = ERR_peek_last_error(); - if (ERR_GET_LIB(err) == ERR_LIB_PEM && - ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { - ERR_clear_error(); - } else { - // some real error - ret = 0; + *issuer = ca; } } @@ -590,13 +555,88 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx, // no need to free `store` } else { // Increment issuer reference count - CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509); + *issuer = X509_dup(*issuer); + if (*issuer == nullptr) { + ret = 0; + goto end; + } } } end: + if (ret && x != nullptr) { + *cert = X509_dup(x); + if (*cert == nullptr) + ret = 0; + } + return ret; +} + + +// Read a file that contains our certificate in "PEM" format, +// possibly followed by a sequence of CA certificates that should be +// sent to the peer in the Certificate message. +// +// Taken from OpenSSL - edited for style. +int SSL_CTX_use_certificate_chain(SSL_CTX* ctx, + BIO* in, + X509** cert, + X509** issuer) { + X509* x = nullptr; + + // Just to ensure that `ERR_peek_last_error` below will return only errors + // that we are interested in + ERR_clear_error(); + + x = PEM_read_bio_X509_AUX(in, nullptr, CryptoPemCallback, nullptr); + + if (x == nullptr) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); + return 0; + } + + X509* extra = nullptr; + int ret = 0; + unsigned long err = 0; + + // Read extra certs + STACK_OF(X509)* extra_certs = sk_X509_new_null(); + if (extra_certs == nullptr) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_MALLOC_FAILURE); + goto done; + } + + while ((extra = PEM_read_bio_X509(in, nullptr, CryptoPemCallback, nullptr))) { + if (sk_X509_push(extra_certs, extra)) + continue; + + // Failure, free all certs + goto done; + } + extra = nullptr; + + // When the while loop ends, it's usually just EOF. + err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_PEM && + ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { + ERR_clear_error(); + } else { + // some real error + goto done; + } + + ret = SSL_CTX_use_certificate_chain(ctx, x, extra_certs, cert, issuer); + if (!ret) + goto done; + + done: + if (extra_certs != nullptr) + sk_X509_pop_free(extra_certs, X509_free); + if (extra != nullptr) + X509_free(extra); if (x != nullptr) - *cert = x; + X509_free(x); + return ret; } @@ -614,6 +654,16 @@ void SecureContext::SetCert(const FunctionCallbackInfo& args) { if (!bio) return; + // Free previous certs + if (sc->issuer_ != nullptr) { + X509_free(sc->issuer_); + sc->issuer_ = nullptr; + } + if (sc->cert_ != nullptr) { + X509_free(sc->cert_); + sc->cert_ = nullptr; + } + int rv = SSL_CTX_use_certificate_chain(sc->ctx_, bio, &sc->cert_, @@ -888,7 +938,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { PKCS12* p12 = nullptr; EVP_PKEY* pkey = nullptr; X509* cert = nullptr; - STACK_OF(X509)* extraCerts = nullptr; + STACK_OF(X509)* extra_certs = nullptr; char* pass = nullptr; bool ret = false; @@ -913,28 +963,33 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { pass[passlen] = '\0'; } + // Free previous certs + if (sc->issuer_ != nullptr) { + X509_free(sc->issuer_); + sc->issuer_ = nullptr; + } + if (sc->cert_ != nullptr) { + X509_free(sc->cert_); + sc->cert_ = nullptr; + } + if (d2i_PKCS12_bio(in, &p12) && - PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) && - SSL_CTX_use_certificate(sc->ctx_, cert) && + PKCS12_parse(p12, pass, &pkey, &cert, &extra_certs) && + SSL_CTX_use_certificate_chain(sc->ctx_, + cert, + extra_certs, + &sc->cert_, + &sc->issuer_) && SSL_CTX_use_PrivateKey(sc->ctx_, pkey)) { - // set extra certs - while (X509* x509 = sk_X509_pop(extraCerts)) { - if (!sc->ca_store_) { - sc->ca_store_ = X509_STORE_new(); - SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_); - } - - X509_STORE_add_cert(sc->ca_store_, x509); - SSL_CTX_add_client_CA(sc->ctx_, x509); - X509_free(x509); - } + ret = true; + } + if (pkey != nullptr) EVP_PKEY_free(pkey); + if (cert != nullptr) X509_free(cert); - sk_X509_free(extraCerts); - - ret = true; - } + if (extra_certs != nullptr) + sk_X509_free(extra_certs); PKCS12_free(p12); BIO_free_all(in); diff --git a/src/node_crypto.h b/src/node_crypto.h index d3d66e32dd13..aaadc904dd39 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -39,6 +39,21 @@ namespace node { namespace crypto { +// Forcibly clear OpenSSL's error stack on return. This stops stale errors +// from popping up later in the lifecycle of crypto operations where they +// would cause spurious failures. It's a rather blunt method, though. +// ERR_clear_error() isn't necessarily cheap either. +struct ClearErrorOnReturn { + ~ClearErrorOnReturn() { ERR_clear_error(); } +}; + +// Pop errors from OpenSSL's error stack that were added +// between when this was constructed and destructed. +struct MarkPopErrorOnReturn { + MarkPopErrorOnReturn() { ERR_set_mark(); } + ~MarkPopErrorOnReturn() { ERR_pop_to_mark(); } +}; + enum CheckResult { CHECK_CERT_REVOKED = 0, CHECK_OK = 1 diff --git a/src/node_file.cc b/src/node_file.cc index b6ef7d5b78f7..5c1b39864c55 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -214,6 +214,9 @@ static void After(uv_fs_t *req) { { int r; Local names = Array::New(env->isolate(), 0); + Local fn = env->push_values_to_array_function(); + Local name_argv[NODE_PUSH_VAL_TO_ARRAY_MAX]; + size_t name_idx = 0; for (int i = 0; ; i++) { uv_dirent_t ent; @@ -229,9 +232,19 @@ static void After(uv_fs_t *req) { break; } - Local name = String::NewFromUtf8(env->isolate(), - ent.name); - names->Set(i, name); + name_argv[name_idx++] = + String::NewFromUtf8(env->isolate(), ent.name); + + if (name_idx >= ARRAY_SIZE(name_argv)) { + fn->Call(env->context(), names, name_idx, name_argv) + .ToLocalChecked(); + name_idx = 0; + } + } + + if (name_idx > 0) { + fn->Call(env->context(), names, name_idx, name_argv) + .ToLocalChecked(); } argv[1] = names; @@ -811,6 +824,9 @@ static void ReadDir(const FunctionCallbackInfo& args) { CHECK_GE(SYNC_REQ.result, 0); int r; Local names = Array::New(env->isolate(), 0); + Local fn = env->push_values_to_array_function(); + Local name_v[NODE_PUSH_VAL_TO_ARRAY_MAX]; + size_t name_idx = 0; for (int i = 0; ; i++) { uv_dirent_t ent; @@ -821,9 +837,18 @@ static void ReadDir(const FunctionCallbackInfo& args) { if (r != 0) return env->ThrowUVException(r, "readdir", "", *path); - Local name = String::NewFromUtf8(env->isolate(), - ent.name); - names->Set(i, name); + + name_v[name_idx++] = String::NewFromUtf8(env->isolate(), ent.name); + + if (name_idx >= ARRAY_SIZE(name_v)) { + fn->Call(env->context(), names, name_idx, name_v) + .ToLocalChecked(); + name_idx = 0; + } + } + + if (name_idx > 0) { + fn->Call(env->context(), names, name_idx, name_v).ToLocalChecked(); } args.GetReturnValue().Set(names); diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index ff3dfb26e529..28322f95c409 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -632,12 +632,23 @@ class Parser : public BaseObject { Local CreateHeaders() { // num_values_ is either -1 or the entry # of the last header // so num_values_ == 0 means there's a single header - Local headers = Array::New(env()->isolate(), 2 * num_values_); - - for (int i = 0; i < num_values_; ++i) { - headers->Set(2 * i, fields_[i].ToString(env())); - headers->Set(2 * i + 1, values_[i].ToString(env())); - } + Local headers = Array::New(env()->isolate()); + Local fn = env()->push_values_to_array_function(); + Local argv[NODE_PUSH_VAL_TO_ARRAY_MAX * 2]; + int i = 0; + + do { + size_t j = 0; + while (i < num_values_ && j < ARRAY_SIZE(argv) / 2) { + argv[j * 2] = fields_[i].ToString(env()); + argv[j * 2 + 1] = values_[i].ToString(env()); + i++; + j++; + } + if (j > 0) { + fn->Call(env()->context(), headers, j * 2, argv).ToLocalChecked(); + } + } while (i < num_values_); return headers; } diff --git a/src/node_os.cc b/src/node_os.cc index a10009074855..92f53a9c407f 100644 --- a/src/node_os.cc +++ b/src/node_os.cc @@ -200,7 +200,7 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo& args) { ret = Object::New(env->isolate()); if (err == UV_ENOSYS) { - args.GetReturnValue().Set(ret); + return args.GetReturnValue().Set(ret); } else if (err) { return env->ThrowUVException(err, "uv_interface_addresses"); } diff --git a/src/node_version.h b/src/node_version.h index 763f3e3cf75e..cd2203b79ede 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -2,7 +2,7 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 5 -#define NODE_MINOR_VERSION 3 +#define NODE_MINOR_VERSION 4 #define NODE_PATCH_VERSION 1 #define NODE_VERSION_IS_RELEASE 0 diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 94f70eba5de6..d7bf4ed8bee7 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -31,7 +31,6 @@ using v8::Object; using v8::String; using v8::Value; - TLSWrap::TLSWrap(Environment* env, Kind kind, StreamBase* stream, @@ -401,6 +400,8 @@ void TLSWrap::ClearOut() { if (ssl_ == nullptr) return; + crypto::MarkPopErrorOnReturn mark_pop_error_on_return; + char out[kClearOutChunkSize]; int read; for (;;) { @@ -462,6 +463,8 @@ bool TLSWrap::ClearIn() { if (ssl_ == nullptr) return false; + crypto::MarkPopErrorOnReturn mark_pop_error_on_return; + int written = 0; while (clear_in_->Length() > 0) { size_t avail = 0; @@ -589,6 +592,8 @@ int TLSWrap::DoWrite(WriteWrap* w, if (ssl_ == nullptr) return UV_EPROTO; + crypto::MarkPopErrorOnReturn mark_pop_error_on_return; + int written = 0; for (i = 0; i < count; i++) { written = SSL_write(ssl_, bufs[i].base, bufs[i].len); @@ -704,8 +709,11 @@ void TLSWrap::DoRead(ssize_t nread, int TLSWrap::DoShutdown(ShutdownWrap* req_wrap) { + crypto::MarkPopErrorOnReturn mark_pop_error_on_return; + if (ssl_ != nullptr && SSL_shutdown(ssl_) == 0) SSL_shutdown(ssl_); + shutdown_ = true; EncOut(); return stream_->DoShutdown(req_wrap); diff --git a/test/addons/at-exit/test.js b/test/addons/at-exit/test.js index 32264a6604ee..c94453cb3b05 100644 --- a/test/addons/at-exit/test.js +++ b/test/addons/at-exit/test.js @@ -1,3 +1,3 @@ 'use strict'; require('../../common'); -var binding = require('./build/Release/binding'); +require('./build/Release/binding'); diff --git a/test/addons/buffer-free-callback/test.js b/test/addons/buffer-free-callback/test.js index 6ee328d52220..a70931d81e89 100644 --- a/test/addons/buffer-free-callback/test.js +++ b/test/addons/buffer-free-callback/test.js @@ -2,7 +2,6 @@ // Flags: --expose-gc require('../../common'); -var assert = require('assert'); var binding = require('./build/Release/binding'); function check(size) { diff --git a/test/addons/repl-domain-abort/test.js b/test/addons/repl-domain-abort/test.js index bbd0c737eeba..5591b4f2b38e 100644 --- a/test/addons/repl-domain-abort/test.js +++ b/test/addons/repl-domain-abort/test.js @@ -46,4 +46,4 @@ var options = { }; // Run commands from fake REPL. -var dummy = repl.start(options); +repl.start(options); diff --git a/test/common.js b/test/common.js index 3bb5d51f0127..32200b9e6a97 100644 --- a/test/common.js +++ b/test/common.js @@ -8,6 +8,8 @@ var child_process = require('child_process'); const stream = require('stream'); const util = require('util'); +const testRoot = path.resolve(process.env.NODE_TEST_DIR || + path.dirname(__filename)); exports.testDir = path.dirname(__filename); exports.fixturesDir = path.join(exports.testDir, 'fixtures'); @@ -69,18 +71,28 @@ exports.refreshTmpDir = function() { }; if (process.env.TEST_THREAD_ID) { - // Distribute ports in parallel tests - if (!process.env.NODE_COMMON_PORT) - exports.PORT += +process.env.TEST_THREAD_ID * 100; - + exports.PORT += process.env.TEST_THREAD_ID * 100; exports.tmpDirName += '.' + process.env.TEST_THREAD_ID; } -exports.tmpDir = path.join(exports.testDir, exports.tmpDirName); +exports.tmpDir = path.join(testRoot, exports.tmpDirName); var opensslCli = null; var inFreeBSDJail = null; var localhostIPv4 = null; +exports.localIPv6Hosts = [ + // Debian/Ubuntu + 'ip6-localhost', + 'ip6-loopback', + + // SUSE + 'ipv6-localhost', + 'ipv6-loopback', + + // Typically universal + 'localhost', +]; + Object.defineProperty(exports, 'inFreeBSDJail', { get: function() { if (inFreeBSDJail !== null) return inFreeBSDJail; @@ -155,21 +167,13 @@ Object.defineProperty(exports, 'hasFipsCrypto', { if (exports.isWindows) { exports.PIPE = '\\\\.\\pipe\\libuv-test'; + if (process.env.TEST_THREAD_ID) { + exports.PIPE += '.' + process.env.TEST_THREAD_ID; + } } else { exports.PIPE = exports.tmpDir + '/test.sock'; } -if (process.env.NODE_COMMON_PIPE) { - exports.PIPE = process.env.NODE_COMMON_PIPE; - // Remove manually, the test runner won't do it - // for us like it does for files in test/tmp. - try { - fs.unlinkSync(exports.PIPE); - } catch (e) { - // Ignore. - } -} - if (exports.isWindows) { exports.faketimeCli = false; } else { @@ -242,6 +246,9 @@ exports.spawnPwd = function(options) { }; exports.platformTimeout = function(ms) { + if (process.config.target_defaults.default_configuration === 'Debug') + ms = 2 * ms; + if (process.arch !== 'arm') return ms; diff --git a/test/debugger/test-debugger-pid.js b/test/debugger/test-debugger-pid.js index 14a281ab3ce4..6a977d7cfa72 100644 --- a/test/debugger/test-debugger-pid.js +++ b/test/debugger/test-debugger-pid.js @@ -1,16 +1,9 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; -var port = common.PORT + 1337; var buffer = ''; -var expected = []; -var scriptToDebug = common.fixturesDir + '/empty.js'; - -function fail() { - assert(0); // `--debug-brk script.js` should not quit -} // connect to debug agent var interfacer = spawn(process.execPath, ['debug', '-p', '655555']); diff --git a/test/debugger/test-debugger-remote.js b/test/debugger/test-debugger-remote.js index 81ed8b41ab01..f5232dce9c8d 100644 --- a/test/debugger/test-debugger-remote.js +++ b/test/debugger/test-debugger-remote.js @@ -3,9 +3,7 @@ var common = require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; -var port = common.PORT + 1337; var buffer = ''; -var expected = []; var scriptToDebug = common.fixturesDir + '/empty.js'; function fail() { diff --git a/test/fixtures/.empty-repl-history-file b/test/fixtures/.empty-repl-history-file new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/fixtures/keys/Makefile b/test/fixtures/keys/Makefile index 143986274a6b..1148e529cd95 100644 --- a/test/fixtures/keys/Makefile +++ b/test/fixtures/keys/Makefile @@ -79,6 +79,14 @@ agent1-cert.pem: agent1-csr.pem ca1-cert.pem ca1-key.pem -CAcreateserial \ -out agent1-cert.pem +agent1-pfx.pem: agent1-cert.pem agent1-key.pem ca1-cert.pem + openssl pkcs12 -export \ + -in agent1-cert.pem \ + -inkey agent1-key.pem \ + -certfile ca1-cert.pem \ + -out agent1-pfx.pem \ + -password pass:sample + agent1-verify: agent1-cert.pem ca1-cert.pem openssl verify -CAfile ca1-cert.pem agent1-cert.pem diff --git a/test/fixtures/keys/agent1-pfx.pem b/test/fixtures/keys/agent1-pfx.pem new file mode 100644 index 000000000000..a36e746a72e0 Binary files /dev/null and b/test/fixtures/keys/agent1-pfx.pem differ diff --git a/test/gc/test-http-client-onerror.js b/test/gc/test-http-client-onerror.js index 98d046e180f1..7e50683c6633 100644 --- a/test/gc/test-http-client-onerror.js +++ b/test/gc/test-http-client-onerror.js @@ -22,7 +22,7 @@ console.log('We should do ' + todo + ' requests'); var http = require('http'); var server = http.createServer(serverHandler); -server.listen(PORT, getall); +server.listen(PORT, runTest); function getall() { if (count >= todo) @@ -51,8 +51,10 @@ function getall() { setImmediate(getall); } -for (var i = 0; i < 10; i++) - getall(); +function runTest() { + for (var i = 0; i < 10; i++) + getall(); +} function afterGC() { countGC ++; diff --git a/test/internet/test-dns-ipv4.js b/test/internet/test-dns-ipv4.js index 04befca6370e..bdca60d1b4fd 100644 --- a/test/internet/test-dns-ipv4.js +++ b/test/internet/test-dns-ipv4.js @@ -3,9 +3,7 @@ var common = require('../common'); var assert = require('assert'), dns = require('dns'), net = require('net'), - isIP = net.isIP, isIPv4 = net.isIPv4; -var util = require('util'); var expected = 0, completed = 0, diff --git a/test/internet/test-dns-ipv6.js b/test/internet/test-dns-ipv6.js index 27547edcd84b..d7c50a1e86b6 100644 --- a/test/internet/test-dns-ipv6.js +++ b/test/internet/test-dns-ipv6.js @@ -3,9 +3,7 @@ var common = require('../common'); var assert = require('assert'), dns = require('dns'), net = require('net'), - isIP = net.isIP, isIPv6 = net.isIPv6; -var util = require('util'); var expected = 0, completed = 0, diff --git a/test/internet/test-dns-txt-sigsegv.js b/test/internet/test-dns-txt-sigsegv.js index eba5c66c4649..4c2f12f7a97c 100644 --- a/test/internet/test-dns-txt-sigsegv.js +++ b/test/internet/test-dns-txt-sigsegv.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var dns = require('dns'); diff --git a/test/internet/test-dns.js b/test/internet/test-dns.js index 2a423f97dee7..6448ad7c76b0 100644 --- a/test/internet/test-dns.js +++ b/test/internet/test-dns.js @@ -1,9 +1,8 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'), dns = require('dns'), net = require('net'), - isIP = net.isIP, isIPv4 = net.isIPv4, isIPv6 = net.isIPv6; var util = require('util'); @@ -48,7 +47,7 @@ TEST(function test_reverse_bogus(done) { var error; try { - var req = dns.reverse('bogus ip', function() { + dns.reverse('bogus ip', function() { assert.ok(false); }); } catch (e) { @@ -369,7 +368,7 @@ console.log('looking up nodejs.org...'); var cares = process.binding('cares_wrap'); var req = new cares.GetAddrInfoReqWrap(); -var err = cares.getaddrinfo(req, 'nodejs.org', 4); +cares.getaddrinfo(req, 'nodejs.org', 4); req.oncomplete = function(err, domains) { assert.strictEqual(err, 0); diff --git a/test/internet/test-http-dns-fail.js b/test/internet/test-http-dns-fail.js index 151597de14cb..7e2f8cd402d6 100644 --- a/test/internet/test-http-dns-fail.js +++ b/test/internet/test-http-dns-fail.js @@ -4,7 +4,7 @@ * should trigger the error event after each attempt. */ -var common = require('../common'); +require('../common'); var assert = require('assert'); var http = require('http'); diff --git a/test/internet/test-net-connect-timeout.js b/test/internet/test-net-connect-timeout.js index b92d23485296..fd78a2936bd8 100644 --- a/test/internet/test-net-connect-timeout.js +++ b/test/internet/test-net-connect-timeout.js @@ -3,7 +3,7 @@ // https://groups.google.com/forum/#!topic/nodejs/UE0ZbfLt6t8 // https://groups.google.com/forum/#!topic/nodejs-dev/jR7-5UDqXkw -var common = require('../common'); +require('../common'); var net = require('net'); var assert = require('assert'); diff --git a/test/internet/test-net-connect-unref.js b/test/internet/test-net-connect-unref.js index a712490d31f5..ad24683b34d4 100644 --- a/test/internet/test-net-connect-unref.js +++ b/test/internet/test-net-connect-unref.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var net = require('net'); diff --git a/test/message/2100bytes.js b/test/message/2100bytes.js index b05f5e9e1d71..0f696806be03 100644 --- a/test/message/2100bytes.js +++ b/test/message/2100bytes.js @@ -1,7 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var util = require('util'); +require('../common'); console.log([ '_______________________________________________50', diff --git a/test/message/core_line_numbers.js b/test/message/core_line_numbers.js index ab86eb1e38f7..221001ed8952 100644 --- a/test/message/core_line_numbers.js +++ b/test/message/core_line_numbers.js @@ -1,5 +1,5 @@ 'use strict'; -const common = require('../common'); +require('../common'); const punycode = require('punycode'); // This test verifies that line numbers in core modules are reported correctly. diff --git a/test/message/error_exit.js b/test/message/error_exit.js index 7805fd219353..18d9dfb4ee99 100644 --- a/test/message/error_exit.js +++ b/test/message/error_exit.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); process.on('exit', function(code) { diff --git a/test/message/eval_messages.js b/test/message/eval_messages.js index 0b17bf5f97ae..bb1569601c88 100644 --- a/test/message/eval_messages.js +++ b/test/message/eval_messages.js @@ -1,7 +1,6 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); var spawn = require('child_process').spawn; diff --git a/test/message/hello_world.js b/test/message/hello_world.js index 1e6b030393c6..187bbd2cfcf7 100644 --- a/test/message/hello_world.js +++ b/test/message/hello_world.js @@ -1,5 +1,4 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); console.log('hello world'); diff --git a/test/message/max_tick_depth.js b/test/message/max_tick_depth.js index cacd79581060..1d2ec175c5d9 100644 --- a/test/message/max_tick_depth.js +++ b/test/message/max_tick_depth.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); process.maxTickDepth = 10; var i = 20; diff --git a/test/message/nexttick_throw.js b/test/message/nexttick_throw.js index 3c0e2d8e379f..22f61a36f947 100644 --- a/test/message/nexttick_throw.js +++ b/test/message/nexttick_throw.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); process.nextTick(function() { process.nextTick(function() { diff --git a/test/message/stack_overflow.js b/test/message/stack_overflow.js index 7d1033c3ab2b..cef53bfb3d35 100644 --- a/test/message/stack_overflow.js +++ b/test/message/stack_overflow.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); Error.stackTraceLimit = 0; diff --git a/test/message/stdin_messages.js b/test/message/stdin_messages.js index e99c08553a91..6e1ced4124f2 100644 --- a/test/message/stdin_messages.js +++ b/test/message/stdin_messages.js @@ -1,7 +1,6 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); var spawn = require('child_process').spawn; diff --git a/test/message/throw_custom_error.js b/test/message/throw_custom_error.js index bb5dae05a9b0..8866ca8514de 100644 --- a/test/message/throw_custom_error.js +++ b/test/message/throw_custom_error.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); // custom error throwing throw ({ name: 'MyCustomError', message: 'This is a custom message' }); diff --git a/test/message/throw_custom_error.out b/test/message/throw_custom_error.out index ef73c52c889d..401581f31d5c 100644 --- a/test/message/throw_custom_error.out +++ b/test/message/throw_custom_error.out @@ -1,4 +1,4 @@ -*test*message*throw_custom_error.js:6 +*test*message*throw_custom_error.js:5 throw ({ name: 'MyCustomError', message: 'This is a custom message' }); ^ MyCustomError: This is a custom message diff --git a/test/message/throw_in_line_with_tabs.js b/test/message/throw_in_line_with_tabs.js index 50c69ca68101..3bb403feb322 100644 --- a/test/message/throw_in_line_with_tabs.js +++ b/test/message/throw_in_line_with_tabs.js @@ -1,7 +1,6 @@ /* eslint-disable indent */ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); console.error('before'); diff --git a/test/message/throw_in_line_with_tabs.out b/test/message/throw_in_line_with_tabs.out index e83b05768433..d245cca4941a 100644 --- a/test/message/throw_in_line_with_tabs.out +++ b/test/message/throw_in_line_with_tabs.out @@ -1,5 +1,5 @@ before -*test*message*throw_in_line_with_tabs.js:10 +*test*message*throw_in_line_with_tabs.js:9 throw ({ foo: 'bar' }); ^ [object Object] diff --git a/test/message/throw_non_error.js b/test/message/throw_non_error.js index a1046b725e93..d4dae642af88 100644 --- a/test/message/throw_non_error.js +++ b/test/message/throw_non_error.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); // custom error throwing throw ({ foo: 'bar' }); diff --git a/test/message/throw_non_error.out b/test/message/throw_non_error.out index 15f95fcc1169..b98edc46ae2a 100644 --- a/test/message/throw_non_error.out +++ b/test/message/throw_non_error.out @@ -1,4 +1,4 @@ -*test*message*throw_non_error.js:6 +*test*message*throw_non_error.js:5 throw ({ foo: 'bar' }); ^ [object Object] diff --git a/test/message/throw_null.js b/test/message/throw_null.js index ab8fb565a61e..9b17aa68f186 100644 --- a/test/message/throw_null.js +++ b/test/message/throw_null.js @@ -1,5 +1,4 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); throw null; diff --git a/test/message/throw_null.out b/test/message/throw_null.out index eb3eeb1294e7..5d2c677240d1 100644 --- a/test/message/throw_null.out +++ b/test/message/throw_null.out @@ -1,5 +1,5 @@ -*test*message*throw_null.js:5 +*test*message*throw_null.js:4 throw null; ^ null diff --git a/test/message/throw_undefined.js b/test/message/throw_undefined.js index f855cdd2f7da..18c27dbac877 100644 --- a/test/message/throw_undefined.js +++ b/test/message/throw_undefined.js @@ -1,5 +1,4 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); throw undefined; diff --git a/test/message/throw_undefined.out b/test/message/throw_undefined.out index c23dac051fa5..32a71f0486e4 100644 --- a/test/message/throw_undefined.out +++ b/test/message/throw_undefined.out @@ -1,5 +1,5 @@ -*test*message*throw_undefined.js:5 +*test*message*throw_undefined.js:4 throw undefined; ^ undefined diff --git a/test/message/timeout_throw.js b/test/message/timeout_throw.js index aaf3fbc8d2f4..5c345ac8c0c3 100644 --- a/test/message/timeout_throw.js +++ b/test/message/timeout_throw.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); setTimeout(function() { undefined_reference_error_maker; diff --git a/test/message/undefined_reference_in_new_context.js b/test/message/undefined_reference_in_new_context.js index 7256c0d8e360..73821ae53d4f 100644 --- a/test/message/undefined_reference_in_new_context.js +++ b/test/message/undefined_reference_in_new_context.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); var vm = require('vm'); console.error('before'); diff --git a/test/message/vm_display_runtime_error.js b/test/message/vm_display_runtime_error.js index d01ab0b540b3..a7ca99074441 100644 --- a/test/message/vm_display_runtime_error.js +++ b/test/message/vm_display_runtime_error.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); var vm = require('vm'); console.error('beginning'); diff --git a/test/message/vm_display_syntax_error.js b/test/message/vm_display_syntax_error.js index 179263478b84..23525c14d822 100644 --- a/test/message/vm_display_syntax_error.js +++ b/test/message/vm_display_syntax_error.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); var vm = require('vm'); console.error('beginning'); diff --git a/test/message/vm_dont_display_runtime_error.js b/test/message/vm_dont_display_runtime_error.js index 6b4c824cbe5e..19d0120a90ab 100644 --- a/test/message/vm_dont_display_runtime_error.js +++ b/test/message/vm_dont_display_runtime_error.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); var vm = require('vm'); console.error('beginning'); diff --git a/test/message/vm_dont_display_syntax_error.js b/test/message/vm_dont_display_syntax_error.js index 42b1ab14cba7..bff0433a144b 100644 --- a/test/message/vm_dont_display_syntax_error.js +++ b/test/message/vm_dont_display_syntax_error.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); var vm = require('vm'); console.error('beginning'); diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status index b4d449a6f57e..0fe1bf9027f5 100644 --- a/test/parallel/parallel.status +++ b/test/parallel/parallel.status @@ -7,15 +7,10 @@ prefix parallel [true] # This section applies to all platforms [$system==win32] -test-child-process-fork-regr-gh-2847 : PASS,FLAKY -test-cluster-net-send : PASS,FLAKY -test-cluster-shared-leak : PASS,FLAKY +test-debug-no-context : PASS,FLAKY test-tls-ticket-cluster : PASS,FLAKY [$system==linux] -test-http-client-timeout-event : PASS,FLAKY -test-child-process-buffering : PASS,FLAKY -test-child-process-exit-code : PASS,FLAKY [$system==macos] diff --git a/test/parallel/test-assert-typedarray-deepequal.js b/test/parallel/test-assert-typedarray-deepequal.js new file mode 100644 index 000000000000..68edefdc1753 --- /dev/null +++ b/test/parallel/test-assert-typedarray-deepequal.js @@ -0,0 +1,41 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const a = require('assert'); + +function makeBlock(f) { + var args = Array.prototype.slice.call(arguments, 1); + return function() { + return f.apply(this, args); + }; +} + +const equalArrayPairs = [ + [new Uint8Array(1e5), new Uint8Array(1e5)], + [new Uint16Array(1e5), new Uint16Array(1e5)], + [new Uint32Array(1e5), new Uint32Array(1e5)], + [new Uint8ClampedArray(1e5), new Uint8ClampedArray(1e5)], + [new Int8Array(1e5), new Int8Array(1e5)], + [new Int16Array(1e5), new Int16Array(1e5)], + [new Int32Array(1e5), new Int32Array(1e5)], + [new Float32Array(1e5), new Float32Array(1e5)], + [new Float64Array(1e5), new Float64Array(1e5)] +]; + +const notEqualArrayPairs = [ + [new Uint8Array(2), new Uint8Array(3)], + [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])], + [new Uint8ClampedArray([300, 2, 3]), new Uint8Array([300, 2, 3])] +]; + +equalArrayPairs.forEach((arrayPair) => { + assert.deepEqual(arrayPair[0], arrayPair[1]); +}); + +notEqualArrayPairs.forEach((arrayPair) => { + assert.throws( + makeBlock(a.deepEqual, arrayPair[0], arrayPair[1]), + a.AssertionError + ); +}); diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index b6d695f5e815..e9c01fda773d 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -271,8 +271,6 @@ assert.throws(makeBlock(a.deepStrictEqual, new Boolean(true), {}), function thrower(errorConstructor) { throw new errorConstructor('test'); } -var aethrow = makeBlock(thrower, a.AssertionError); -aethrow = makeBlock(thrower, a.AssertionError); // the basic calls work assert.throws(makeBlock(thrower, a.AssertionError), diff --git a/test/parallel/test-async-wrap-throw-no-init.js b/test/parallel/test-async-wrap-throw-no-init.js index b2f60f3215e8..768e38e8eff3 100644 --- a/test/parallel/test-async-wrap-throw-no-init.js +++ b/test/parallel/test-async-wrap-throw-no-init.js @@ -1,6 +1,6 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const async_wrap = process.binding('async_wrap'); diff --git a/test/parallel/test-beforeexit-event.js b/test/parallel/test-beforeexit-event.js index f3bd127b408b..8e5d66f5f5d7 100644 --- a/test/parallel/test-beforeexit-event.js +++ b/test/parallel/test-beforeexit-event.js @@ -1,7 +1,6 @@ 'use strict'; var assert = require('assert'); var net = require('net'); -var util = require('util'); var common = require('../common'); var revivals = 0; var deaths = 0; diff --git a/test/parallel/test-buffer-arraybuffer.js b/test/parallel/test-buffer-arraybuffer.js index c25de262ea97..522d97ece196 100644 --- a/test/parallel/test-buffer-arraybuffer.js +++ b/test/parallel/test-buffer-arraybuffer.js @@ -1,6 +1,6 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const Buffer = require('buffer').Buffer; diff --git a/test/parallel/test-buffer-ascii.js b/test/parallel/test-buffer-ascii.js index efc3a72c6625..94ba85a22761 100644 --- a/test/parallel/test-buffer-ascii.js +++ b/test/parallel/test-buffer-ascii.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // ASCII conversion in node.js simply masks off the high bits, diff --git a/test/parallel/test-buffer-bytelength.js b/test/parallel/test-buffer-bytelength.js index b292970f9418..32ed6dbd6761 100644 --- a/test/parallel/test-buffer-bytelength.js +++ b/test/parallel/test-buffer-bytelength.js @@ -1,6 +1,6 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Buffer = require('buffer').Buffer; diff --git a/test/parallel/test-buffer-concat.js b/test/parallel/test-buffer-concat.js index 8d0c0eebbd14..07f763a76dc4 100644 --- a/test/parallel/test-buffer-concat.js +++ b/test/parallel/test-buffer-concat.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var zero = []; diff --git a/test/parallel/test-buffer-fakes.js b/test/parallel/test-buffer-fakes.js index d473d16e9215..1a1d9c0c494b 100644 --- a/test/parallel/test-buffer-fakes.js +++ b/test/parallel/test-buffer-fakes.js @@ -1,9 +1,8 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const Buffer = require('buffer').Buffer; -const Bp = Buffer.prototype; function FakeBuffer() { } FakeBuffer.__proto__ = Buffer; diff --git a/test/parallel/test-buffer-includes.js b/test/parallel/test-buffer-includes.js index be002bb7f26d..8eaf2d479761 100644 --- a/test/parallel/test-buffer-includes.js +++ b/test/parallel/test-buffer-includes.js @@ -1,5 +1,5 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const Buffer = require('buffer').Buffer; diff --git a/test/parallel/test-buffer-indexof.js b/test/parallel/test-buffer-indexof.js index d358749f8efc..aac5b18f718c 100644 --- a/test/parallel/test-buffer-indexof.js +++ b/test/parallel/test-buffer-indexof.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Buffer = require('buffer').Buffer; diff --git a/test/parallel/test-buffer-inheritance.js b/test/parallel/test-buffer-inheritance.js index eb2f4a531d0b..ea61e50bf5f0 100644 --- a/test/parallel/test-buffer-inheritance.js +++ b/test/parallel/test-buffer-inheritance.js @@ -1,6 +1,6 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); diff --git a/test/parallel/test-buffer-inspect.js b/test/parallel/test-buffer-inspect.js index 35da378631ae..6d44389de735 100644 --- a/test/parallel/test-buffer-inspect.js +++ b/test/parallel/test-buffer-inspect.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var util = require('util'); diff --git a/test/parallel/test-buffer-iterator.js b/test/parallel/test-buffer-iterator.js index 05371d6d793f..ad135a911362 100644 --- a/test/parallel/test-buffer-iterator.js +++ b/test/parallel/test-buffer-iterator.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var buffer = new Buffer([1, 2, 3, 4, 5]); diff --git a/test/parallel/test-buffer-slow.js b/test/parallel/test-buffer-slow.js index d7b4f486e214..cf1a3fd8eb20 100644 --- a/test/parallel/test-buffer-slow.js +++ b/test/parallel/test-buffer-slow.js @@ -1,6 +1,6 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const buffer = require('buffer'); const Buffer = buffer.Buffer; diff --git a/test/parallel/test-child-process-buffering.js b/test/parallel/test-child-process-buffering.js index a37e1dbbbd75..1efa5a65f9ce 100644 --- a/test/parallel/test-child-process-buffering.js +++ b/test/parallel/test-child-process-buffering.js @@ -2,8 +2,6 @@ var common = require('../common'); var assert = require('assert'); -var spawn = require('child_process').spawn; - var pwd_called = false; var childClosed = false; var childExited = false; diff --git a/test/parallel/test-child-process-constructor.js b/test/parallel/test-child-process-constructor.js index 89db9cf81fdd..6980810485c9 100644 --- a/test/parallel/test-child-process-constructor.js +++ b/test/parallel/test-child-process-constructor.js @@ -1,7 +1,7 @@ 'use strict'; +require('../common'); var assert = require('assert'); -var common = require('../common'); var child_process = require('child_process'); var ChildProcess = child_process.ChildProcess; assert.equal(typeof ChildProcess, 'function'); diff --git a/test/parallel/test-child-process-cwd.js b/test/parallel/test-child-process-cwd.js index e0e83b6007a8..f13da684fbdf 100644 --- a/test/parallel/test-child-process-cwd.js +++ b/test/parallel/test-child-process-cwd.js @@ -1,8 +1,6 @@ 'use strict'; var common = require('../common'); var assert = require('assert'); -var spawn = require('child_process').spawn; -var path = require('path'); var returns = 0; diff --git a/test/parallel/test-child-process-detached.js b/test/parallel/test-child-process-detached.js index 25b811a8caa9..711c5d227d6b 100644 --- a/test/parallel/test-child-process-detached.js +++ b/test/parallel/test-child-process-detached.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var path = require('path'); diff --git a/test/parallel/test-child-process-exec-buffer.js b/test/parallel/test-child-process-exec-buffer.js index 0ab05080a2cb..a381af9631e0 100644 --- a/test/parallel/test-child-process-exec-buffer.js +++ b/test/parallel/test-child-process-exec-buffer.js @@ -9,7 +9,7 @@ var success_count = 0; var str = 'hello'; // default encoding -var child = exec('echo ' + str, function(err, stdout, stderr) { +exec('echo ' + str, function(err, stdout, stderr) { assert.ok('string', typeof(stdout), 'Expected stdout to be a string'); assert.ok('string', typeof(stderr), 'Expected stderr to be a string'); assert.equal(str + os.EOL, stdout); @@ -18,7 +18,7 @@ var child = exec('echo ' + str, function(err, stdout, stderr) { }); // no encoding (Buffers expected) -var child = exec('echo ' + str, { +exec('echo ' + str, { encoding: null }, function(err, stdout, stderr) { assert.ok(stdout instanceof Buffer, 'Expected stdout to be a Buffer'); diff --git a/test/parallel/test-child-process-exec-cwd.js b/test/parallel/test-child-process-exec-cwd.js index e253399b96ac..c259ffffda3d 100644 --- a/test/parallel/test-child-process-exec-cwd.js +++ b/test/parallel/test-child-process-exec-cwd.js @@ -16,7 +16,7 @@ if (common.isWindows) { dir = '/dev'; } -var child = exec(pwdcommand, {cwd: dir}, function(err, stdout, stderr) { +exec(pwdcommand, {cwd: dir}, function(err, stdout, stderr) { if (err) { error_count++; console.log('error!: ' + err.code); diff --git a/test/parallel/test-child-process-fork-and-spawn.js b/test/parallel/test-child-process-fork-and-spawn.js index d5255bf83ca8..5766dc865bc9 100644 --- a/test/parallel/test-child-process-fork-and-spawn.js +++ b/test/parallel/test-child-process-fork-and-spawn.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; var fork = require('child_process').fork; diff --git a/test/parallel/test-child-process-fork-dgram.js b/test/parallel/test-child-process-fork-dgram.js index f700960490cb..86cd6576c73b 100644 --- a/test/parallel/test-child-process-fork-dgram.js +++ b/test/parallel/test-child-process-fork-dgram.js @@ -25,7 +25,6 @@ if (common.isWindows) { } if (process.argv[2] === 'child') { - var childCollected = 0; var server; process.on('message', function removeMe(msg, clusterServer) { diff --git a/test/parallel/test-child-process-fork-exec-path.js b/test/parallel/test-child-process-fork-exec-path.js index 6a61bddd8a19..35a730b0da6c 100644 --- a/test/parallel/test-child-process-fork-exec-path.js +++ b/test/parallel/test-child-process-fork-exec-path.js @@ -1,6 +1,5 @@ 'use strict'; var assert = require('assert'); -var cp = require('child_process'); var fs = require('fs'); var path = require('path'); var common = require('../common'); diff --git a/test/parallel/test-child-process-fork-net2.js b/test/parallel/test-child-process-fork-net2.js index 95ec26a88d0d..dd89557b6112 100644 --- a/test/parallel/test-child-process-fork-net2.js +++ b/test/parallel/test-child-process-fork-net2.js @@ -117,47 +117,29 @@ if (process.argv[2] === 'child') { }); var closeEmitted = false; - server.on('close', function() { - console.error('[m] server close'); + server.on('close', common.mustCall(function() { closeEmitted = true; - console.error('[m] killing child processes'); child1.kill(); child2.kill(); child3.kill(); - }); + })); server.listen(common.PORT, '127.0.0.1'); - var timeElapsed = 0; var closeServer = function() { - console.error('[m] closeServer'); - var startTime = Date.now(); - server.on('close', function() { - console.error('[m] emit(close)'); - timeElapsed = Date.now() - startTime; - }); - - console.error('[m] calling server.close'); server.close(); setTimeout(function() { assert(!closeEmitted); - console.error('[m] sending close to children'); child1.send('close'); child2.send('close'); child3.disconnect(); }, 200); }; - var min = 190; - var max = common.platformTimeout(2000); process.on('exit', function() { assert.equal(disconnected, count); assert.equal(connected, count); - assert.ok(closeEmitted); - assert.ok(timeElapsed >= min && timeElapsed <= max, - `timeElapsed was not between ${min} and ${max} ms:` + - `${timeElapsed}`); }); } diff --git a/test/parallel/test-child-process-fork-ref.js b/test/parallel/test-child-process-fork-ref.js index b4066641bae9..de34f3eb8ae9 100644 --- a/test/parallel/test-child-process-fork-ref.js +++ b/test/parallel/test-child-process-fork-ref.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var fork = require('child_process').fork; diff --git a/test/parallel/test-child-process-fork-ref2.js b/test/parallel/test-child-process-fork-ref2.js index 8bc7e4c35541..42c43ed8882b 100644 --- a/test/parallel/test-child-process-fork-ref2.js +++ b/test/parallel/test-child-process-fork-ref2.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); var fork = require('child_process').fork; if (process.argv[2] === 'child') { diff --git a/test/parallel/test-child-process-fork-regr-gh-2847.js b/test/parallel/test-child-process-fork-regr-gh-2847.js index 27b4d72d2fc6..78856cb55ede 100644 --- a/test/parallel/test-child-process-fork-regr-gh-2847.js +++ b/test/parallel/test-child-process-fork-regr-gh-2847.js @@ -5,7 +5,6 @@ const assert = require('assert'); const cluster = require('cluster'); const net = require('net'); -const util = require('util'); var connectcount = 0; var sendcount = 0; @@ -19,6 +18,13 @@ if (!cluster.isMaster) { } var server = net.createServer(function(s) { + if (common.isWindows) { + s.on('error', function(err) { + // Prevent possible ECONNRESET errors from popping up + if (err.code !== 'ECONNRESET' || sendcount === 0) + throw err; + }); + } setTimeout(function() { s.destroy(); }, 100); diff --git a/test/parallel/test-child-process-internal.js b/test/parallel/test-child-process-internal.js index c39dc93293aa..03ea340236ad 100644 --- a/test/parallel/test-child-process-internal.js +++ b/test/parallel/test-child-process-internal.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); //messages diff --git a/test/parallel/test-child-process-set-blocking.js b/test/parallel/test-child-process-set-blocking.js index 3f09388265b8..6cdfbbc9a24c 100644 --- a/test/parallel/test-child-process-set-blocking.js +++ b/test/parallel/test-child-process-set-blocking.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var ch = require('child_process'); diff --git a/test/parallel/test-child-process-silent.js b/test/parallel/test-child-process-silent.js index 3714d3758d0f..c3705ab2a4d7 100644 --- a/test/parallel/test-child-process-silent.js +++ b/test/parallel/test-child-process-silent.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var childProcess = require('child_process'); diff --git a/test/parallel/test-child-process-spawn-error.js b/test/parallel/test-child-process-spawn-error.js index 1398dac16531..4eaa45ee7aef 100644 --- a/test/parallel/test-child-process-spawn-error.js +++ b/test/parallel/test-child-process-spawn-error.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var fs = require('fs'); var spawn = require('child_process').spawn; var assert = require('assert'); diff --git a/test/parallel/test-child-process-spawnsync-env.js b/test/parallel/test-child-process-spawnsync-env.js index 646097f9454c..4455b867e301 100644 --- a/test/parallel/test-child-process-spawnsync-env.js +++ b/test/parallel/test-child-process-spawnsync-env.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var cp = require('child_process'); diff --git a/test/parallel/test-child-process-spawnsync-timeout.js b/test/parallel/test-child-process-spawnsync-timeout.js index 34c69a1fc597..122a65825949 100644 --- a/test/parallel/test-child-process-spawnsync-timeout.js +++ b/test/parallel/test-child-process-spawnsync-timeout.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var spawnSync = require('child_process').spawnSync; diff --git a/test/parallel/test-child-process-stdin-ipc.js b/test/parallel/test-child-process-stdin-ipc.js index d2347849dd5b..79e60f333b9d 100644 --- a/test/parallel/test-child-process-stdin-ipc.js +++ b/test/parallel/test-child-process-stdin-ipc.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; diff --git a/test/parallel/test-child-process-stdin.js b/test/parallel/test-child-process-stdin.js index c12b24579375..4a371b83fb04 100644 --- a/test/parallel/test-child-process-stdin.js +++ b/test/parallel/test-child-process-stdin.js @@ -18,30 +18,20 @@ var response = ''; var exitStatus = -1; var closed = false; -var gotStdoutEOF = false; - cat.stdout.setEncoding('utf8'); cat.stdout.on('data', function(chunk) { console.log('stdout: ' + chunk); response += chunk; }); -cat.stdout.on('end', function() { - gotStdoutEOF = true; -}); - - -var gotStderrEOF = false; +cat.stdout.on('end', common.mustCall(function() {})); cat.stderr.on('data', function(chunk) { // shouldn't get any stderr output assert.ok(false); }); -cat.stderr.on('end', function(chunk) { - gotStderrEOF = true; -}); - +cat.stderr.on('end', common.mustCall(function() {})); cat.on('exit', function(status) { console.log('exit event'); diff --git a/test/parallel/test-child-process-stdio-big-write-end.js b/test/parallel/test-child-process-stdio-big-write-end.js index 5ae85acc54d9..bc414938b581 100644 --- a/test/parallel/test-child-process-stdio-big-write-end.js +++ b/test/parallel/test-child-process-stdio-big-write-end.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var BUFSIZE = 1024; diff --git a/test/parallel/test-child-process-stdio-inherit.js b/test/parallel/test-child-process-stdio-inherit.js index 8cf08a7bd5fa..409c0af7ca0d 100644 --- a/test/parallel/test-child-process-stdio-inherit.js +++ b/test/parallel/test-child-process-stdio-inherit.js @@ -31,5 +31,5 @@ function grandparent() { function parent() { // should not immediately exit. - var child = common.spawnCat({ stdio: 'inherit' }); + common.spawnCat({ stdio: 'inherit' }); } diff --git a/test/parallel/test-child-process-stdio.js b/test/parallel/test-child-process-stdio.js index 1ff6e4d914f7..d5fe6d43b64d 100644 --- a/test/parallel/test-child-process-stdio.js +++ b/test/parallel/test-child-process-stdio.js @@ -1,7 +1,6 @@ 'use strict'; var common = require('../common'); var assert = require('assert'); -var spawn = require('child_process').spawn; var options = {stdio: ['pipe']}; var child = common.spawnPwd(options); diff --git a/test/parallel/test-child-process-stdout-flush-exit.js b/test/parallel/test-child-process-stdout-flush-exit.js index 577a33a05082..b76a7cb5e5a8 100644 --- a/test/parallel/test-child-process-stdout-flush-exit.js +++ b/test/parallel/test-child-process-stdout-flush-exit.js @@ -1,7 +1,6 @@ 'use strict'; var common = require('../common'); var assert = require('assert'); -var path = require('path'); // if child process output to console and exit if (process.argv[2] === 'child') { diff --git a/test/parallel/test-child-process-validate-stdio.js b/test/parallel/test-child-process-validate-stdio.js index 289323002da4..0a12e4f54c53 100644 --- a/test/parallel/test-child-process-validate-stdio.js +++ b/test/parallel/test-child-process-validate-stdio.js @@ -1,8 +1,8 @@ 'use strict'; // Flags: --expose_internals +require('../common'); var assert = require('assert'); -var common = require('../common'); var _validateStdio = require('internal/child_process')._validateStdio; // should throw if string and not ignore, pipe, or inherit diff --git a/test/parallel/test-cluster-debug-port.js b/test/parallel/test-cluster-debug-port.js index 1a42850e9b2b..076a59108b09 100644 --- a/test/parallel/test-cluster-debug-port.js +++ b/test/parallel/test-cluster-debug-port.js @@ -1,5 +1,5 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const cluster = require('cluster'); diff --git a/test/parallel/test-cluster-dgram-2.js b/test/parallel/test-cluster-dgram-2.js index 0253cafcf497..6426e1c224be 100644 --- a/test/parallel/test-cluster-dgram-2.js +++ b/test/parallel/test-cluster-dgram-2.js @@ -2,7 +2,6 @@ var NUM_WORKERS = 4; var PACKETS_PER_WORKER = 10; -var assert = require('assert'); var cluster = require('cluster'); var common = require('../common'); var dgram = require('dgram'); diff --git a/test/parallel/test-cluster-disconnect-race.js b/test/parallel/test-cluster-disconnect-race.js new file mode 100644 index 000000000000..97d55a20b1ac --- /dev/null +++ b/test/parallel/test-cluster-disconnect-race.js @@ -0,0 +1,39 @@ +'use strict'; + +// This code triggers an AssertionError on Linux in Node.js 5.3.0 and earlier. +// Ref: https://github.com/nodejs/node/issues/4205 + +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); +const cluster = require('cluster'); + +if (common.isWindows) { + console.log('1..0 # Skipped: This test does not apply to Windows.'); + return; +} + +cluster.schedulingPolicy = cluster.SCHED_NONE; + +if (cluster.isMaster) { + var worker1, worker2; + + worker1 = cluster.fork(); + worker1.on('message', common.mustCall(function() { + worker2 = cluster.fork(); + worker1.disconnect(); + worker2.on('online', common.mustCall(worker2.disconnect)); + })); + + cluster.on('exit', common.mustCall(function(worker, code) { + assert.strictEqual(code, 0, 'worker exited with error'); + }, 2)); + + return; +} + +var server = net.createServer(); + +server.listen(common.PORT, function() { + process.send('listening'); +}); diff --git a/test/parallel/test-cluster-eaddrinuse.js b/test/parallel/test-cluster-eaddrinuse.js index 6ff68252d9d8..3821551f00a3 100644 --- a/test/parallel/test-cluster-eaddrinuse.js +++ b/test/parallel/test-cluster-eaddrinuse.js @@ -5,7 +5,6 @@ var common = require('../common'); var assert = require('assert'); -var cluster = require('cluster'); var fork = require('child_process').fork; var net = require('net'); diff --git a/test/parallel/test-cluster-fork-env.js b/test/parallel/test-cluster-fork-env.js index 7749e42f608c..fb58daee0cff 100644 --- a/test/parallel/test-cluster-fork-env.js +++ b/test/parallel/test-cluster-fork-env.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var cluster = require('cluster'); diff --git a/test/parallel/test-cluster-http-pipe.js b/test/parallel/test-cluster-http-pipe.js index 4c6dee347bb8..cb9b090f08e8 100644 --- a/test/parallel/test-cluster-http-pipe.js +++ b/test/parallel/test-cluster-http-pipe.js @@ -34,7 +34,6 @@ http.createServer(function(req, res) { res.writeHead(200); res.end('OK'); }).listen(common.PIPE, function() { - var self = this; http.get({ socketPath: common.PIPE, path: '/' }, function(res) { res.resume(); res.on('end', function(err) { diff --git a/test/parallel/test-cluster-net-send.js b/test/parallel/test-cluster-net-send.js index 6190fb517e4d..fe536b5f2a43 100644 --- a/test/parallel/test-cluster-net-send.js +++ b/test/parallel/test-cluster-net-send.js @@ -31,16 +31,22 @@ if (process.argv[2] !== 'child') { } else { console.error('[%d] worker', process.pid); + var socket; + var cbcalls = 0; + function socketConnected() { + if (++cbcalls === 2) + process.send('handle', socket); + } + var server = net.createServer(function(c) { process.once('message', function(msg) { assert.equal(msg, 'got'); c.end('hello'); }); + socketConnected(); }); server.listen(common.PORT, function() { - var socket = net.connect(common.PORT, '127.0.0.1', function() { - process.send('handle', socket); - }); + socket = net.connect(common.PORT, '127.0.0.1', socketConnected); }); process.on('disconnect', function() { diff --git a/test/parallel/test-cluster-rr-ref.js b/test/parallel/test-cluster-rr-ref.js index 474e4d69f225..95d121df875b 100644 --- a/test/parallel/test-cluster-rr-ref.js +++ b/test/parallel/test-cluster-rr-ref.js @@ -1,7 +1,6 @@ 'use strict'; const common = require('../common'); -const assert = require('assert'); const cluster = require('cluster'); const net = require('net'); diff --git a/test/parallel/test-cluster-setup-master-cumulative.js b/test/parallel/test-cluster-setup-master-cumulative.js index 0376546d286b..f0f98fbdbfb3 100644 --- a/test/parallel/test-cluster-setup-master-cumulative.js +++ b/test/parallel/test-cluster-setup-master-cumulative.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var cluster = require('cluster'); diff --git a/test/parallel/test-cluster-setup-master-emit.js b/test/parallel/test-cluster-setup-master-emit.js index 8b463ec97bff..ad15c084c592 100644 --- a/test/parallel/test-cluster-setup-master-emit.js +++ b/test/parallel/test-cluster-setup-master-emit.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var cluster = require('cluster'); diff --git a/test/parallel/test-cluster-setup-master-multiple.js b/test/parallel/test-cluster-setup-master-multiple.js index 8ee6d091cd52..5ceff2bddfaf 100644 --- a/test/parallel/test-cluster-setup-master-multiple.js +++ b/test/parallel/test-cluster-setup-master-multiple.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var cluster = require('cluster'); diff --git a/test/parallel/test-cluster-setup-master.js b/test/parallel/test-cluster-setup-master.js index c32b3ea6d3b1..561371afb027 100644 --- a/test/parallel/test-cluster-setup-master.js +++ b/test/parallel/test-cluster-setup-master.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var cluster = require('cluster'); diff --git a/test/parallel/test-cluster-shared-leak.js b/test/parallel/test-cluster-shared-leak.js index a4de1d33a29b..55df57c9831e 100644 --- a/test/parallel/test-cluster-shared-leak.js +++ b/test/parallel/test-cluster-shared-leak.js @@ -15,14 +15,16 @@ if (cluster.isMaster) { worker1 = cluster.fork(); worker1.on('message', common.mustCall(function() { worker2 = cluster.fork(); - conn = net.connect(common.PORT, common.mustCall(function() { - worker1.send('die'); - worker2.send('die'); - })); - conn.on('error', function(e) { - // ECONNRESET is OK - if (e.code !== 'ECONNRESET') - throw e; + worker2.on('online', function() { + conn = net.connect(common.PORT, common.mustCall(function() { + worker1.send('die'); + worker2.send('die'); + })); + conn.on('error', function(e) { + // ECONNRESET is OK + if (e.code !== 'ECONNRESET') + throw e; + }); }); })); diff --git a/test/parallel/test-cluster-uncaught-exception.js b/test/parallel/test-cluster-uncaught-exception.js index ec42773ef558..04eac2e8ce63 100644 --- a/test/parallel/test-cluster-uncaught-exception.js +++ b/test/parallel/test-cluster-uncaught-exception.js @@ -3,7 +3,7 @@ // one that the cluster module installs. // https://github.com/joyent/node/issues/2556 -var common = require('../common'); +require('../common'); var assert = require('assert'); var cluster = require('cluster'); var fork = require('child_process').fork; diff --git a/test/parallel/test-cluster-worker-constructor.js b/test/parallel/test-cluster-worker-constructor.js index e29dc0156190..2a96d24a8a34 100644 --- a/test/parallel/test-cluster-worker-constructor.js +++ b/test/parallel/test-cluster-worker-constructor.js @@ -2,7 +2,7 @@ // test-cluster-worker-constructor.js // validates correct behavior of the cluster.Worker constructor -var common = require('../common'); +require('../common'); var assert = require('assert'); var cluster = require('cluster'); var worker; diff --git a/test/parallel/test-cluster-worker-death.js b/test/parallel/test-cluster-worker-death.js index 88a0f887cc2c..65da9865b0dd 100644 --- a/test/parallel/test-cluster-worker-death.js +++ b/test/parallel/test-cluster-worker-death.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var cluster = require('cluster'); diff --git a/test/parallel/test-cluster-worker-forced-exit.js b/test/parallel/test-cluster-worker-forced-exit.js index 76f5cc69a9f7..ef9f7728bad3 100644 --- a/test/parallel/test-cluster-worker-forced-exit.js +++ b/test/parallel/test-cluster-worker-forced-exit.js @@ -2,7 +2,6 @@ require('../common'); var assert = require('assert'); var cluster = require('cluster'); -var net = require('net'); var SENTINEL = 42; diff --git a/test/parallel/test-cluster-worker-init.js b/test/parallel/test-cluster-worker-init.js index 38886af5279a..41f73e1255a7 100644 --- a/test/parallel/test-cluster-worker-init.js +++ b/test/parallel/test-cluster-worker-init.js @@ -3,7 +3,7 @@ // verifies that, when a child process is forked, the cluster.worker // object can receive messages as expected -var common = require('../common'); +require('../common'); var assert = require('assert'); var cluster = require('cluster'); var msg = 'foo'; diff --git a/test/parallel/test-cluster-worker-isconnected.js b/test/parallel/test-cluster-worker-isconnected.js index eb3c5892bb5e..985d15ce6475 100644 --- a/test/parallel/test-cluster-worker-isconnected.js +++ b/test/parallel/test-cluster-worker-isconnected.js @@ -2,7 +2,6 @@ require('../common'); var cluster = require('cluster'); var assert = require('assert'); -var util = require('util'); if (cluster.isMaster) { var worker = cluster.fork(); diff --git a/test/parallel/test-console-instance.js b/test/parallel/test-console-instance.js index a80c6e57e4b1..1ab038df48e4 100644 --- a/test/parallel/test-console-instance.js +++ b/test/parallel/test-console-instance.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Stream = require('stream'); var Console = require('console').Console; diff --git a/test/parallel/test-console-not-call-toString.js b/test/parallel/test-console-not-call-toString.js index 7846dbf2778b..f152e33e98f0 100644 --- a/test/parallel/test-console-not-call-toString.js +++ b/test/parallel/test-console-not-call-toString.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var func = function() {}; diff --git a/test/parallel/test-console.js b/test/parallel/test-console.js index f8a927398034..14025694dd26 100644 --- a/test/parallel/test-console.js +++ b/test/parallel/test-console.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); assert.ok(process.stdout.writable); diff --git a/test/parallel/test-crypto-binary-default.js b/test/parallel/test-crypto-binary-default.js index 806f5de18bbb..c4b8990beb2e 100644 --- a/test/parallel/test-crypto-binary-default.js +++ b/test/parallel/test-crypto-binary-default.js @@ -20,7 +20,6 @@ var fs = require('fs'); var path = require('path'); // Test Certificates -var caPem = fs.readFileSync(common.fixturesDir + '/test_ca.pem', 'ascii'); var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii'); var certPfx = fs.readFileSync(common.fixturesDir + '/test_cert.pfx'); var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii'); diff --git a/test/parallel/test-crypto-certificate.js b/test/parallel/test-crypto-certificate.js index 8286d58d1e44..9814b395552e 100644 --- a/test/parallel/test-crypto-certificate.js +++ b/test/parallel/test-crypto-certificate.js @@ -11,7 +11,6 @@ var crypto = require('crypto'); crypto.DEFAULT_ENCODING = 'buffer'; var fs = require('fs'); -var path = require('path'); // Test Certificates var spkacValid = fs.readFileSync(common.fixturesDir + '/spkac.valid'); diff --git a/test/parallel/test-crypto-verify-failure.js b/test/parallel/test-crypto-verify-failure.js index f315aed1a9f1..2bc4ce543373 100644 --- a/test/parallel/test-crypto-verify-failure.js +++ b/test/parallel/test-crypto-verify-failure.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); if (!common.hasCrypto) { console.log('1..0 # Skipped: missing crypto'); @@ -20,8 +19,6 @@ var options = { cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem') }; -var canSend = true; - var server = tls.Server(options, function(socket) { setImmediate(function() { console.log('sending'); @@ -32,17 +29,15 @@ var server = tls.Server(options, function(socket) { }); }); -var client; - function verify() { console.log('verify'); - var verified = crypto.createVerify('RSA-SHA1') - .update('Test') - .verify(certPem, 'asdfasdfas', 'base64'); + crypto.createVerify('RSA-SHA1') + .update('Test') + .verify(certPem, 'asdfasdfas', 'base64'); } server.listen(common.PORT, function() { - client = tls.connect({ + tls.connect({ port: common.PORT, rejectUnauthorized: false }, function() { diff --git a/test/parallel/test-debug-no-context.js b/test/parallel/test-debug-no-context.js new file mode 100644 index 000000000000..a143e67ac66c --- /dev/null +++ b/test/parallel/test-debug-no-context.js @@ -0,0 +1,24 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; + +const args = [`--debug`, `--debug-port=${common.PORT}`, `--interactive`]; +const proc = spawn(process.execPath, args, { stdio: 'pipe' }); +proc.stdin.write(` + util.inspect(Promise.resolve(42)); + util.inspect(Promise.resolve(1337)); + .exit +`); +proc.on('exit', common.mustCall((exitCode, signalCode) => { + assert.strictEqual(exitCode, 0); + assert.strictEqual(signalCode, null); +})); +let stdout = ''; +proc.stdout.setEncoding('utf8'); +proc.stdout.on('data', data => stdout += data); +process.on('exit', () => { + assert(stdout.includes('Promise { 42 }')); + assert(stdout.includes('Promise { 1337 }')); +}); diff --git a/test/parallel/test-debug-signal-cluster.js b/test/parallel/test-debug-signal-cluster.js index 6572ef50afe8..7a950458b872 100644 --- a/test/parallel/test-debug-signal-cluster.js +++ b/test/parallel/test-debug-signal-cluster.js @@ -10,7 +10,6 @@ var options = { stdio: ['inherit', 'inherit', 'pipe', 'ipc'] }; var child = spawn(process.execPath, args, options); var outputLines = []; -var outputTimerId; var waitingForDebuggers = false; var pids = null; diff --git a/test/parallel/test-delayed-require.js b/test/parallel/test-delayed-require.js index 5fa82f236c1d..7376e70ba780 100644 --- a/test/parallel/test-delayed-require.js +++ b/test/parallel/test-delayed-require.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var a; diff --git a/test/parallel/test-dgram-bind.js b/test/parallel/test-dgram-bind.js index 6d35534cb5eb..0bca97fb294f 100644 --- a/test/parallel/test-dgram-bind.js +++ b/test/parallel/test-dgram-bind.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var dgram = require('dgram'); diff --git a/test/parallel/test-dgram-bytes-length.js b/test/parallel/test-dgram-bytes-length.js index 9f8c39eb04da..c68b2fab70af 100644 --- a/test/parallel/test-dgram-bytes-length.js +++ b/test/parallel/test-dgram-bytes-length.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var dgram = require('dgram'); diff --git a/test/parallel/test-dgram-empty-packet.js b/test/parallel/test-dgram-empty-packet.js index ba6faa62d86c..66cdbb92ac8f 100644 --- a/test/parallel/test-dgram-empty-packet.js +++ b/test/parallel/test-dgram-empty-packet.js @@ -1,8 +1,6 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); -var fs = require('fs'); var dgram = require('dgram'); var callbacks = 0; var client; diff --git a/test/parallel/test-dgram-error-message-address.js b/test/parallel/test-dgram-error-message-address.js index e307a23e2451..005695654f95 100644 --- a/test/parallel/test-dgram-error-message-address.js +++ b/test/parallel/test-dgram-error-message-address.js @@ -20,7 +20,6 @@ socket_ipv4.bind(common.PORT, '1.1.1.1'); // IPv6 Test var socket_ipv6 = dgram.createSocket('udp6'); -var family_ipv6 = 'IPv6'; socket_ipv6.on('listening', common.fail); diff --git a/test/parallel/test-dgram-listen-after-bind.js b/test/parallel/test-dgram-listen-after-bind.js index 2aac7ae9cf75..498a17a0e5b0 100644 --- a/test/parallel/test-dgram-listen-after-bind.js +++ b/test/parallel/test-dgram-listen-after-bind.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var dgram = require('dgram'); diff --git a/test/parallel/test-dgram-pingpong.js b/test/parallel/test-dgram-pingpong.js index 29ab92757bd8..883085a9cdaa 100644 --- a/test/parallel/test-dgram-pingpong.js +++ b/test/parallel/test-dgram-pingpong.js @@ -11,7 +11,6 @@ function pingPongTest(port, host) { var callbacks = 0; var N = 500; var count = 0; - var sent_final_ping = false; var server = dgram.createSocket('udp4', function(msg, rinfo) { if (debug) console.log('server got: ' + msg + @@ -48,7 +47,6 @@ function pingPongTest(port, host) { if (count < N) { client.send(buf, 0, buf.length, port, 'localhost'); } else { - sent_final_ping = true; client.send(buf, 0, buf.length, port, 'localhost', function() { client.close(); }); diff --git a/test/parallel/test-dgram-ref.js b/test/parallel/test-dgram-ref.js index d689a45e36df..6505ce9b1ec8 100644 --- a/test/parallel/test-dgram-ref.js +++ b/test/parallel/test-dgram-ref.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var dgram = require('dgram'); // should not hang, see #1282 diff --git a/test/parallel/test-dgram-regress-4496.js b/test/parallel/test-dgram-regress-4496.js index fcb8d026bc54..4bdd0d6520d7 100644 --- a/test/parallel/test-dgram-regress-4496.js +++ b/test/parallel/test-dgram-regress-4496.js @@ -1,7 +1,7 @@ 'use strict'; // Remove this test once we support sending strings. -var common = require('../common'); +require('../common'); var assert = require('assert'); var dgram = require('dgram'); diff --git a/test/parallel/test-dgram-send-bad-arguments.js b/test/parallel/test-dgram-send-bad-arguments.js index ccd10e005553..ddaa162c8bff 100644 --- a/test/parallel/test-dgram-send-bad-arguments.js +++ b/test/parallel/test-dgram-send-bad-arguments.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var dgram = require('dgram'); diff --git a/test/parallel/test-dgram-send-callback-buffer-length.js b/test/parallel/test-dgram-send-callback-buffer-length.js index a34c5e2eb6b8..80c2d23e42ef 100644 --- a/test/parallel/test-dgram-send-callback-buffer-length.js +++ b/test/parallel/test-dgram-send-callback-buffer-length.js @@ -2,9 +2,7 @@ var common = require('../common'); var assert = require('assert'); -var fs = require('fs'); var dgram = require('dgram'); -var callbacks = 0; var client, timer, buf, len, offset; diff --git a/test/parallel/test-dgram-send-empty-buffer.js b/test/parallel/test-dgram-send-empty-buffer.js index 11f3d38d2ed0..a8ab4339d8a3 100644 --- a/test/parallel/test-dgram-send-empty-buffer.js +++ b/test/parallel/test-dgram-send-empty-buffer.js @@ -1,10 +1,7 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); -var fs = require('fs'); var dgram = require('dgram'); -var callbacks = 0; var client, timer, buf; if (process.platform === 'darwin') { diff --git a/test/parallel/test-dgram-udp4.js b/test/parallel/test-dgram-udp4.js index f81dec398f72..58c8b69839ff 100644 --- a/test/parallel/test-dgram-udp4.js +++ b/test/parallel/test-dgram-udp4.js @@ -2,8 +2,7 @@ var common = require('../common'); var assert = require('assert'); -var fs = require('fs'), - dgram = require('dgram'), server, client, +var dgram = require('dgram'), server, client, server_port = common.PORT, message_to_send = 'A message to send', timer; @@ -52,4 +51,4 @@ server.bind(server_port); timer = setTimeout(function() { throw new Error('Timeout'); -}, 200); +}, common.platformTimeout(200)); diff --git a/test/parallel/test-dgram-unref.js b/test/parallel/test-dgram-unref.js index 2add3d28c497..083dab6d2958 100644 --- a/test/parallel/test-dgram-unref.js +++ b/test/parallel/test-dgram-unref.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var dgram = require('dgram'); diff --git a/test/parallel/test-dh-padding.js b/test/parallel/test-dh-padding.js index cdb1fc75f942..7d482b78f63a 100644 --- a/test/parallel/test-dh-padding.js +++ b/test/parallel/test-dh-padding.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); try { diff --git a/test/parallel/test-dns-cares-domains.js b/test/parallel/test-dns-cares-domains.js index cb651c5f5afb..a1aa18a10f88 100644 --- a/test/parallel/test-dns-cares-domains.js +++ b/test/parallel/test-dns-cares-domains.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var dns = require('dns'); var domain = require('domain'); diff --git a/test/parallel/test-dns-lookup-cb-error.js b/test/parallel/test-dns-lookup-cb-error.js index 330dfb5d5709..4a3dd2694121 100644 --- a/test/parallel/test-dns-lookup-cb-error.js +++ b/test/parallel/test-dns-lookup-cb-error.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var cares = process.binding('cares_wrap'); diff --git a/test/parallel/test-dns-regress-7070.js b/test/parallel/test-dns-regress-7070.js index 1fbd7f07a9d5..e696327d4d5f 100644 --- a/test/parallel/test-dns-regress-7070.js +++ b/test/parallel/test-dns-regress-7070.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var dns = require('dns'); diff --git a/test/parallel/test-dns.js b/test/parallel/test-dns.js index abc7edbf5980..3362e8c534ea 100644 --- a/test/parallel/test-dns.js +++ b/test/parallel/test-dns.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var dns = require('dns'); diff --git a/test/parallel/test-domain-exit-dispose-again.js b/test/parallel/test-domain-exit-dispose-again.js index 6fe9f25fb0d8..e5b1affc0afb 100644 --- a/test/parallel/test-domain-exit-dispose-again.js +++ b/test/parallel/test-domain-exit-dispose-again.js @@ -1,39 +1,76 @@ 'use strict'; -const common = require('../common'); -const assert = require('assert'); -const domain = require('domain'); -// Use the same timeout value so that both timers' callbacks are called during -// the same invocation of the underlying native timer's callback (listOnTimeout -// in lib/timers.js). -setTimeout(err, 50); -setTimeout(common.mustCall(secondTimer), 50); +// This test makes sure that when a domain is disposed, timers that are +// attached to that domain are not fired, but timers that are _not_ attached +// to that domain, including those whose callbacks are called from within +// the same invocation of listOnTimeout, _are_ called. -function err() { +require('../common'); +var assert = require('assert'); +var domain = require('domain'); +var disposalFailed = false; + +// Repeatedly schedule a timer with a delay different than the timers attached +// to a domain that will eventually be disposed to make sure that they are +// called, regardless of what happens with those timers attached to domains +// that will eventually be disposed. +var a = 0; +log(); +function log() { + console.log(a++, process.domain); + if (a < 10) setTimeout(log, 20); +} + +var secondTimerRan = false; + +// Use the same timeout duration for both "firstTimer" and "secondTimer" +// callbacks so that they are called during the same invocation of the +// underlying native timer's callback (listOnTimeout in lib/timers.js). +const TIMEOUT_DURATION = 50; + +setTimeout(function firstTimer() { const d = domain.create(); - d.on('error', handleDomainError); - d.run(err2); - function err2() { - // this function doesn't exist, and throws an error as a result. + d.on('error', function handleError(err) { + // Dispose the domain on purpose, so that we can test that nestedTimer + // is not called since it's associated to this domain and a timer whose + // domain is diposed should not run. + d.dispose(); + console.error(err); + console.error('in domain error handler', + process.domain, process.domain === d); + }); + + d.run(function() { + // Create another nested timer that is by definition associated to the + // domain "d". Because an error is thrown before the timer's callback + // is called, and because the domain's error handler disposes the domain, + // this timer's callback should never run. + setTimeout(function nestedTimer() { + console.error('Nested timer should not run, because it is attached to ' + + 'a domain that should be disposed.'); + disposalFailed = true; + process.exit(1); + }); + + // Make V8 throw an unreferenced error. As a result, the domain's error + // handler is called, which disposes the domain "d" and should prevent the + // nested timer that is attached to it from running. err3(); - } + }); +}, TIMEOUT_DURATION); - function handleDomainError(e) { - // In the domain's error handler, the current active domain should be the - // domain within which the error was thrown. - assert.equal(process.domain, d); - } -} +// This timer expires in the same invocation of listOnTimeout than firstTimer, +// but because it's not attached to any domain, it must run regardless of +// domain "d" being disposed. +setTimeout(function secondTimer() { + console.log('In second timer'); + secondTimerRan = true; +}, TIMEOUT_DURATION); -function secondTimer() { - // secondTimer was scheduled before any domain had been created, so its - // callback should not have any active domain set when it runs. - // Do not use assert here, as it throws errors and if a domain with an error - // handler is active, then asserting wouldn't make the test fail. - if (process.domain !== null) { - console.log('process.domain should be null, but instead is:', - process.domain); - process.exit(1); - } -} +process.on('exit', function() { + assert.equal(a, 10); + assert.equal(disposalFailed, false); + assert(secondTimerRan); + console.log('ok'); +}); diff --git a/test/parallel/test-domain-exit-dispose.js b/test/parallel/test-domain-exit-dispose.js index 90e7210ce21a..2bddb01cbd8c 100644 --- a/test/parallel/test-domain-exit-dispose.js +++ b/test/parallel/test-domain-exit-dispose.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var domain = require('domain'); var disposalFailed = false; diff --git a/test/parallel/test-domain-from-timer.js b/test/parallel/test-domain-from-timer.js index 93661b419b0b..f0115018ec18 100644 --- a/test/parallel/test-domain-from-timer.js +++ b/test/parallel/test-domain-from-timer.js @@ -1,7 +1,7 @@ 'use strict'; // Simple tests of most basic domain functionality. -var common = require('../common'); +require('../common'); var assert = require('assert'); // timeouts call the callback directly from cc, so need to make sure the diff --git a/test/parallel/test-domain-http-server.js b/test/parallel/test-domain-http-server.js index 99dbf413e3a4..37dbc30f4234 100644 --- a/test/parallel/test-domain-http-server.js +++ b/test/parallel/test-domain-http-server.js @@ -9,7 +9,6 @@ objects.baz.asdf = objects; var serverCaught = 0; var clientCaught = 0; -var disposeEmit = 0; var server = http.createServer(function(req, res) { var dom = domain.create(); diff --git a/test/parallel/test-domain-implicit-fs.js b/test/parallel/test-domain-implicit-fs.js index fd21dcafe085..d0a468419b92 100644 --- a/test/parallel/test-domain-implicit-fs.js +++ b/test/parallel/test-domain-implicit-fs.js @@ -1,15 +1,13 @@ 'use strict'; // Simple tests of most basic domain functionality. -var common = require('../common'); +require('../common'); var assert = require('assert'); var domain = require('domain'); -var events = require('events'); var caught = 0; var expectCaught = 1; var d = new domain.Domain(); -var e = new events.EventEmitter(); d.on('error', function(er) { console.error('caught', er); diff --git a/test/parallel/test-domain-multi.js b/test/parallel/test-domain-multi.js index e5f9f6748b17..ac01d66deee5 100644 --- a/test/parallel/test-domain-multi.js +++ b/test/parallel/test-domain-multi.js @@ -4,7 +4,6 @@ var common = require('../common'); var assert = require('assert'); var domain = require('domain'); -var events = require('events'); var caughtA = false; var caughtB = false; diff --git a/test/parallel/test-domain-nested-throw.js b/test/parallel/test-domain-nested-throw.js index 0fba3001b543..69a80b7ab104 100644 --- a/test/parallel/test-domain-nested-throw.js +++ b/test/parallel/test-domain-nested-throw.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var domain = require('domain'); diff --git a/test/parallel/test-domain-stack.js b/test/parallel/test-domain-stack.js index f9b5648a6619..e30d3b21f3af 100644 --- a/test/parallel/test-domain-stack.js +++ b/test/parallel/test-domain-stack.js @@ -1,10 +1,8 @@ 'use strict'; // Make sure that the domain stack doesn't get out of hand. -var common = require('../common'); -var assert = require('assert'); +require('../common'); var domain = require('domain'); -var events = require('events'); var a = domain.create(); a.name = 'a'; diff --git a/test/parallel/test-domain-timers.js b/test/parallel/test-domain-timers.js index 7530c9edba40..a97b300da02d 100644 --- a/test/parallel/test-domain-timers.js +++ b/test/parallel/test-domain-timers.js @@ -1,7 +1,7 @@ 'use strict'; +require('../common'); var domain = require('domain'); var assert = require('assert'); -var common = require('../common'); var timeout_err, timeout, immediate_err; diff --git a/test/parallel/test-domain-top-level-error-handler-throw.js b/test/parallel/test-domain-top-level-error-handler-throw.js index 2b9e704e43c3..4bde30d17cb8 100644 --- a/test/parallel/test-domain-top-level-error-handler-throw.js +++ b/test/parallel/test-domain-top-level-error-handler-throw.js @@ -7,7 +7,7 @@ * top-level error handler, not the one from the previous error. */ -const common = require('../common'); +require('../common'); const domainErrHandlerExMessage = 'exception from domain error handler'; const internalExMessage = 'You should NOT see me'; @@ -36,10 +36,12 @@ if (process.argv[2] === 'child') { stderrOutput += data.toString(); }); - child.on('exit', function onChildExited(exitCode, signal) { + child.on('close', function onChildClosed() { assert(stderrOutput.indexOf(domainErrHandlerExMessage) !== -1); assert(stderrOutput.indexOf(internalExMessage) === -1); + }); + child.on('exit', function onChildExited(exitCode, signal) { var expectedExitCode = 7; var expectedSignal = null; diff --git a/test/parallel/test-domain-uncaught-exception.js b/test/parallel/test-domain-uncaught-exception.js index 8792eb1ce545..35632dbf5372 100644 --- a/test/parallel/test-domain-uncaught-exception.js +++ b/test/parallel/test-domain-uncaught-exception.js @@ -13,8 +13,6 @@ const assert = require('assert'); const domain = require('domain'); const child_process = require('child_process'); -const uncaughtExceptions = {}; - const tests = []; function test1() { diff --git a/test/parallel/test-domain-with-abort-on-uncaught-exception.js b/test/parallel/test-domain-with-abort-on-uncaught-exception.js index 1c4c7cd8085a..55133ba67347 100644 --- a/test/parallel/test-domain-with-abort-on-uncaught-exception.js +++ b/test/parallel/test-domain-with-abort-on-uncaught-exception.js @@ -31,7 +31,6 @@ const domainErrHandlerExMessage = 'exception from domain error handler'; if (process.argv[2] === 'child') { var domain = require('domain'); var d = domain.create(); - var triggeredProcessUncaughtException = false; process.on('uncaughtException', function onUncaughtException() { // The process' uncaughtException event must not be emitted when @@ -116,17 +115,7 @@ if (process.argv[2] === 'child') { var child = exec(cmdToExec); if (child) { - var childTriggeredOnUncaughtExceptionHandler = false; - child.on('message', function onChildMsg(msg) { - if (msg === 'triggeredProcessUncaughtEx') { - childTriggeredOnUncaughtExceptionHandler = true; - } - }); - child.on('exit', function onChildExited(exitCode, signal) { - var expectedExitCodes; - var expectedSignals; - // When throwing errors from the top-level domain error handler // outside of a try/catch block, the process should not exit gracefully if (!options.useTryCatch && options.throwInDomainErrHandler) { diff --git a/test/parallel/test-domain.js b/test/parallel/test-domain.js index 918e3288e8dc..bef5e942e057 100644 --- a/test/parallel/test-domain.js +++ b/test/parallel/test-domain.js @@ -1,7 +1,7 @@ 'use strict'; // Simple tests of most basic domain functionality. -var common = require('../common'); +require('../common'); var assert = require('assert'); var domain = require('domain'); var events = require('events'); diff --git a/test/parallel/test-dsa-fips-invalid-key.js b/test/parallel/test-dsa-fips-invalid-key.js index 0b5773411ee5..2d30ef689100 100644 --- a/test/parallel/test-dsa-fips-invalid-key.js +++ b/test/parallel/test-dsa-fips-invalid-key.js @@ -12,8 +12,6 @@ var fs = require('fs'); var input = 'hello'; -var dsapub = fs.readFileSync(common.fixturesDir + - '/keys/dsa_public_1025.pem'); var dsapri = fs.readFileSync(common.fixturesDir + '/keys/dsa_private_1025.pem'); var sign = crypto.createSign('DSS1'); diff --git a/test/parallel/test-eval-require.js b/test/parallel/test-eval-require.js index f966b5a98c80..4e2ddf42b6df 100644 --- a/test/parallel/test-eval-require.js +++ b/test/parallel/test-eval-require.js @@ -2,8 +2,6 @@ var common = require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; -var path = require('path'); -var fs = require('fs'); var options = { cwd: common.fixturesDir diff --git a/test/parallel/test-eval.js b/test/parallel/test-eval.js index d3a83fbd5a70..59b5d1a24086 100644 --- a/test/parallel/test-eval.js +++ b/test/parallel/test-eval.js @@ -10,7 +10,7 @@ var error_count = 0; var cmd = ['"' + process.execPath + '"', '-e', '"console.error(process.argv)"', 'foo', 'bar'].join(' '); var expected = util.format([process.execPath, 'foo', 'bar']) + '\n'; -var child = exec(cmd, function(err, stdout, stderr) { +exec(cmd, function(err, stdout, stderr) { if (err) { console.log(err.toString()); ++error_count; diff --git a/test/parallel/test-event-emitter-add-listeners.js b/test/parallel/test-event-emitter-add-listeners.js index cc30fd24add3..82acd65c5858 100644 --- a/test/parallel/test-event-emitter-add-listeners.js +++ b/test/parallel/test-event-emitter-add-listeners.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var events = require('events'); diff --git a/test/parallel/test-event-emitter-check-listener-leaks.js b/test/parallel/test-event-emitter-check-listener-leaks.js index 90f686b5422c..3c8260e78747 100644 --- a/test/parallel/test-event-emitter-check-listener-leaks.js +++ b/test/parallel/test-event-emitter-check-listener-leaks.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var events = require('events'); diff --git a/test/parallel/test-event-emitter-get-max-listeners.js b/test/parallel/test-event-emitter-get-max-listeners.js index 43a14db0cca3..34ffee3600e5 100644 --- a/test/parallel/test-event-emitter-get-max-listeners.js +++ b/test/parallel/test-event-emitter-get-max-listeners.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var EventEmitter = require('events'); diff --git a/test/parallel/test-event-emitter-listener-count.js b/test/parallel/test-event-emitter-listener-count.js index c5b75c819d17..ebfed8b2ee33 100644 --- a/test/parallel/test-event-emitter-listener-count.js +++ b/test/parallel/test-event-emitter-listener-count.js @@ -1,6 +1,6 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const EventEmitter = require('events'); diff --git a/test/parallel/test-event-emitter-listeners-side-effects.js b/test/parallel/test-event-emitter-listeners-side-effects.js index 23076128eddf..5b9f2f3ddf0f 100644 --- a/test/parallel/test-event-emitter-listeners-side-effects.js +++ b/test/parallel/test-event-emitter-listeners-side-effects.js @@ -1,8 +1,7 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); -var events = require('events'); var EventEmitter = require('events').EventEmitter; var assert = require('assert'); diff --git a/test/parallel/test-event-emitter-listeners.js b/test/parallel/test-event-emitter-listeners.js index 48a60609e7be..77c44907b62d 100644 --- a/test/parallel/test-event-emitter-listeners.js +++ b/test/parallel/test-event-emitter-listeners.js @@ -1,6 +1,6 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var events = require('events'); diff --git a/test/parallel/test-event-emitter-max-listeners.js b/test/parallel/test-event-emitter-max-listeners.js index 5e754698d0a0..7d80c7a32fe0 100644 --- a/test/parallel/test-event-emitter-max-listeners.js +++ b/test/parallel/test-event-emitter-max-listeners.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var events = require('events'); diff --git a/test/parallel/test-event-emitter-method-names.js b/test/parallel/test-event-emitter-method-names.js index a260aa779855..c1e6540f0184 100644 --- a/test/parallel/test-event-emitter-method-names.js +++ b/test/parallel/test-event-emitter-method-names.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var events = require('events'); diff --git a/test/parallel/test-event-emitter-modify-in-emit.js b/test/parallel/test-event-emitter-modify-in-emit.js index 85845cc4443b..cd1849201dfe 100644 --- a/test/parallel/test-event-emitter-modify-in-emit.js +++ b/test/parallel/test-event-emitter-modify-in-emit.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var events = require('events'); diff --git a/test/parallel/test-event-emitter-no-error-provided-to-error-event.js b/test/parallel/test-event-emitter-no-error-provided-to-error-event.js index e85361475f89..918ba195d4be 100644 --- a/test/parallel/test-event-emitter-no-error-provided-to-error-event.js +++ b/test/parallel/test-event-emitter-no-error-provided-to-error-event.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var events = require('events'); var domain = require('domain'); diff --git a/test/parallel/test-event-emitter-num-args.js b/test/parallel/test-event-emitter-num-args.js index 6c403cd2f294..51f57e89bc6e 100644 --- a/test/parallel/test-event-emitter-num-args.js +++ b/test/parallel/test-event-emitter-num-args.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var events = require('events'); diff --git a/test/parallel/test-event-emitter-once.js b/test/parallel/test-event-emitter-once.js index 1085e7942a59..d007ef663fde 100644 --- a/test/parallel/test-event-emitter-once.js +++ b/test/parallel/test-event-emitter-once.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var events = require('events'); diff --git a/test/parallel/test-event-emitter-remove-listeners.js b/test/parallel/test-event-emitter-remove-listeners.js index 8993aadf51a4..396979a923d1 100644 --- a/test/parallel/test-event-emitter-remove-listeners.js +++ b/test/parallel/test-event-emitter-remove-listeners.js @@ -15,11 +15,6 @@ function listener2() { count++; } -function listener3() { - console.log('listener3'); - count++; -} - function remove1() { assert(0); } diff --git a/test/parallel/test-event-emitter-set-max-listeners-side-effects.js b/test/parallel/test-event-emitter-set-max-listeners-side-effects.js index f09f130ab489..11cfab0bb876 100644 --- a/test/parallel/test-event-emitter-set-max-listeners-side-effects.js +++ b/test/parallel/test-event-emitter-set-max-listeners-side-effects.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var events = require('events'); diff --git a/test/parallel/test-event-emitter-subclass.js b/test/parallel/test-event-emitter-subclass.js index fe915be34efc..023092415146 100644 --- a/test/parallel/test-event-emitter-subclass.js +++ b/test/parallel/test-event-emitter-subclass.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var EventEmitter = require('events').EventEmitter; var util = require('util'); diff --git a/test/parallel/test-exception-handler.js b/test/parallel/test-exception-handler.js index 9cc8106ea6f8..735daa510700 100644 --- a/test/parallel/test-exception-handler.js +++ b/test/parallel/test-exception-handler.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var MESSAGE = 'catch me if you can'; diff --git a/test/parallel/test-exception-handler2.js b/test/parallel/test-exception-handler2.js index 58e84ad21ba4..3ed2c9520461 100644 --- a/test/parallel/test-exception-handler2.js +++ b/test/parallel/test-exception-handler2.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); process.on('uncaughtException', function(err) { diff --git a/test/parallel/test-exec-max-buffer.js b/test/parallel/test-exec-max-buffer.js index 5cae35b69f95..15c6e7025978 100644 --- a/test/parallel/test-exec-max-buffer.js +++ b/test/parallel/test-exec-max-buffer.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var exec = require('child_process').exec; var assert = require('assert'); diff --git a/test/parallel/test-file-write-stream2.js b/test/parallel/test-file-write-stream2.js index 0044548b736d..e95760bc2d9a 100644 --- a/test/parallel/test-file-write-stream2.js +++ b/test/parallel/test-file-write-stream2.js @@ -4,7 +4,6 @@ var assert = require('assert'); var path = require('path'); var fs = require('fs'); -var util = require('util'); var filepath = path.join(common.tmpDir, 'write.txt'); diff --git a/test/parallel/test-file-write-stream3.js b/test/parallel/test-file-write-stream3.js index 1a88faa01fb8..a2552d95b215 100644 --- a/test/parallel/test-file-write-stream3.js +++ b/test/parallel/test-file-write-stream3.js @@ -3,8 +3,7 @@ var common = require('../common'); var assert = require('assert'); var path = require('path'), - fs = require('fs'), - util = require('util'); + fs = require('fs'); var filepath = path.join(common.tmpDir, 'write_pos.txt'); @@ -125,7 +124,7 @@ function run_test_2() { function run_test_3() { - var file, buffer, options; + var file, options; var data = '\u2026\u2026', // 3 bytes * 2 = 6 bytes in UTF-8 fileData; @@ -168,7 +167,7 @@ function run_test_3() { function run_test_4() { - var file, options; + var options; options = { start: -5, flags: 'r+' }; diff --git a/test/parallel/test-fs-empty-readStream.js b/test/parallel/test-fs-empty-readStream.js index 0863e0cdba4d..c5a016f9ea2c 100644 --- a/test/parallel/test-fs-empty-readStream.js +++ b/test/parallel/test-fs-empty-readStream.js @@ -15,15 +15,7 @@ fs.open(emptyFile, 'r', function(error, fd) { throw new Error('data event should not emit'); }); - var readEmit = false; - read.once('end', function() { - readEmit = true; - console.error('end event 1'); - }); - - setTimeout(function() { - assert.equal(readEmit, true); - }, common.platformTimeout(50)); + read.once('end', common.mustCall(function endEvent1() {})); }); fs.open(emptyFile, 'r', function(error, fd) { @@ -36,13 +28,11 @@ fs.open(emptyFile, 'r', function(error, fd) { throw new Error('data event should not emit'); }); - var readEmit = false; - read.once('end', function() { - readEmit = true; - console.error('end event 2'); + read.once('end', function endEvent2() { + throw new Error('end event should not emit'); }); setTimeout(function() { - assert.equal(readEmit, false); + assert.equal(read.isPaused(), true); }, common.platformTimeout(50)); }); diff --git a/test/parallel/test-fs-exists.js b/test/parallel/test-fs-exists.js index fcbd729a5ed8..3474fc4cb9ff 100644 --- a/test/parallel/test-fs-exists.js +++ b/test/parallel/test-fs-exists.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var fs = require('fs'); var f = __filename; diff --git a/test/parallel/test-fs-make-callback.js b/test/parallel/test-fs-make-callback.js index a15a16404df0..4fbe64437eaf 100644 --- a/test/parallel/test-fs-make-callback.js +++ b/test/parallel/test-fs-make-callback.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var fs = require('fs'); diff --git a/test/parallel/test-fs-open-flags.js b/test/parallel/test-fs-open-flags.js index c7d53117d587..667abb81765f 100644 --- a/test/parallel/test-fs-open-flags.js +++ b/test/parallel/test-fs-open-flags.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var constants = require('constants'); @@ -7,14 +7,9 @@ var fs = require('fs'); var O_APPEND = constants.O_APPEND || 0; var O_CREAT = constants.O_CREAT || 0; -var O_DIRECTORY = constants.O_DIRECTORY || 0; var O_EXCL = constants.O_EXCL || 0; -var O_NOCTTY = constants.O_NOCTTY || 0; -var O_NOFOLLOW = constants.O_NOFOLLOW || 0; var O_RDONLY = constants.O_RDONLY || 0; var O_RDWR = constants.O_RDWR || 0; -var O_SYMLINK = constants.O_SYMLINK || 0; -var O_SYNC = constants.O_SYNC || 0; var O_TRUNC = constants.O_TRUNC || 0; var O_WRONLY = constants.O_WRONLY || 0; diff --git a/test/parallel/test-fs-open.js b/test/parallel/test-fs-open.js index 59b605841b44..0818f2b7f63d 100644 --- a/test/parallel/test-fs-open.js +++ b/test/parallel/test-fs-open.js @@ -1,6 +1,5 @@ 'use strict'; -var constants = require('constants'); -var common = require('../common'); +require('../common'); var assert = require('assert'); var fs = require('fs'); diff --git a/test/parallel/test-fs-read-buffer-tostring-fail.js b/test/parallel/test-fs-read-buffer-tostring-fail.js index 3ec1491d2b47..f00df61ea731 100644 --- a/test/parallel/test-fs-read-buffer-tostring-fail.js +++ b/test/parallel/test-fs-read-buffer-tostring-fail.js @@ -6,7 +6,6 @@ const fs = require('fs'); const path = require('path'); const Buffer = require('buffer').Buffer; const kStringMaxLength = process.binding('buffer').kStringMaxLength; -const kMaxLength = process.binding('buffer').kMaxLength; var fd; diff --git a/test/parallel/test-fs-read-file-sync-hostname.js b/test/parallel/test-fs-read-file-sync-hostname.js index c5c5264c0dde..de1057379698 100644 --- a/test/parallel/test-fs-read-file-sync-hostname.js +++ b/test/parallel/test-fs-read-file-sync-hostname.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var fs = require('fs'); diff --git a/test/parallel/test-fs-readdir.js b/test/parallel/test-fs-readdir.js index b08f42b5c23f..9a9b85ecaccd 100644 --- a/test/parallel/test-fs-readdir.js +++ b/test/parallel/test-fs-readdir.js @@ -2,7 +2,6 @@ const common = require('../common'); const assert = require('assert'); -const path = require('path'); const fs = require('fs'); const readdirDir = common.tmpDir; diff --git a/test/parallel/test-fs-readfile-zero-byte-liar.js b/test/parallel/test-fs-readfile-zero-byte-liar.js index 2c9c6e3db9a5..a81b055494d3 100644 --- a/test/parallel/test-fs-readfile-zero-byte-liar.js +++ b/test/parallel/test-fs-readfile-zero-byte-liar.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var fs = require('fs'); diff --git a/test/parallel/test-fs-realpath.js b/test/parallel/test-fs-realpath.js index 12a4ce7b41b6..53312c6e8d71 100644 --- a/test/parallel/test-fs-realpath.js +++ b/test/parallel/test-fs-realpath.js @@ -37,11 +37,14 @@ function tmp(p) { return path.join(common.tmpDir, p); } -var fixturesAbsDir = common.fixturesDir; +var targetsAbsDir = path.join(common.tmpDir, 'targets'); var tmpAbsDir = common.tmpDir; -assert(fixturesAbsDir !== tmpAbsDir); -console.error('absolutes\n%s\n%s', fixturesAbsDir, tmpAbsDir); +// Set up targetsAbsDir and expected subdirectories +fs.mkdirSync(targetsAbsDir); +fs.mkdirSync(path.join(targetsAbsDir, 'nested-index')); +fs.mkdirSync(path.join(targetsAbsDir, 'nested-index', 'one')); +fs.mkdirSync(path.join(targetsAbsDir, 'nested-index', 'two')); function asynctest(testBlock, args, callback, assertBlock) { async_expected++; @@ -109,7 +112,7 @@ function test_simple_absolute_symlink(callback) { console.log('using type=%s', type); var entry = tmpAbsDir + '/symlink', - expected = fixturesAbsDir + '/nested-index/one'; + expected = common.fixturesDir + '/nested-index/one'; [ [entry, expected] ].forEach(function(t) { @@ -133,14 +136,15 @@ function test_deep_relative_file_symlink(callback) { } var expected = path.join(common.fixturesDir, 'cycles', 'root.js'); - var linkData1 = '../../cycles/root.js'; - var linkPath1 = path.join(common.fixturesDir, + var linkData1 = path.relative(path.join(targetsAbsDir, 'nested-index', 'one'), + expected); + var linkPath1 = path.join(targetsAbsDir, 'nested-index', 'one', 'symlink1.js'); try {fs.unlinkSync(linkPath1);} catch (e) {} fs.symlinkSync(linkData1, linkPath1, 'file'); var linkData2 = '../one/symlink1.js'; - var entry = path.join(common.fixturesDir, + var entry = path.join(targetsAbsDir, 'nested-index', 'two', 'symlink1-b.js'); try {fs.unlinkSync(entry);} catch (e) {} fs.symlinkSync(linkData2, entry, 'file'); @@ -160,14 +164,14 @@ function test_deep_relative_dir_symlink(callback) { return runNextTest(); } var expected = path.join(common.fixturesDir, 'cycles', 'folder'); - var linkData1b = '../../cycles/folder'; - var linkPath1b = path.join(common.fixturesDir, - 'nested-index', 'one', 'symlink1-dir'); + var path1b = path.join(targetsAbsDir, 'nested-index', 'one'); + var linkPath1b = path.join(path1b, 'symlink1-dir'); + var linkData1b = path.relative(path1b, expected); try {fs.unlinkSync(linkPath1b);} catch (e) {} fs.symlinkSync(linkData1b, linkPath1b, 'dir'); var linkData2b = '../one/symlink1-dir'; - var entry = path.join(common.fixturesDir, + var entry = path.join(targetsAbsDir, 'nested-index', 'two', 'symlink12-dir'); try {fs.unlinkSync(entry);} catch (e) {} fs.symlinkSync(linkData2b, entry, 'dir'); @@ -232,11 +236,10 @@ function test_relative_input_cwd(callback) { return runNextTest(); } - // we need to get the relative path to the tmp dir from cwd. - // When the test runner is running it, that will be .../node/test - // but it's more common to run `./node test/.../`, so detect it here. + // we need to calculate the relative path to the tmp dir from cwd var entrydir = process.cwd(); - var entry = common.tmpDir.substr(entrydir.length + 1) + '/cycles/realpath-3a'; + var entry = path.relative(entrydir, + path.join(common.tmpDir + '/cycles/realpath-3a')); var expected = common.tmpDir + '/cycles/root.js'; [ [entry, '../cycles/realpath-3b'], @@ -273,15 +276,15 @@ function test_deep_symlink_mix(callback) { } /* - /tmp/node-test-realpath-f1 -> ../tmp/node-test-realpath-d1/foo - /tmp/node-test-realpath-d1 -> ../node-test-realpath-d2 - /tmp/node-test-realpath-d2/foo -> ../node-test-realpath-f2 + /tmp/node-test-realpath-f1 -> $tmpDir/node-test-realpath-d1/foo + /tmp/node-test-realpath-d1 -> $tmpDir/node-test-realpath-d2 + /tmp/node-test-realpath-d2/foo -> $tmpDir/node-test-realpath-f2 /tmp/node-test-realpath-f2 - -> /node/test/fixtures/nested-index/one/realpath-c - /node/test/fixtures/nested-index/one/realpath-c - -> /node/test/fixtures/nested-index/two/realpath-c - /node/test/fixtures/nested-index/two/realpath-c -> ../../cycles/root.js - /node/test/fixtures/cycles/root.js (hard) + -> $tmpDir/targets/nested-index/one/realpath-c + $tmpDir/targets/nested-index/one/realpath-c + -> $tmpDir/targets/nested-index/two/realpath-c + $tmpDir/targets/nested-index/two/realpath-c -> $tmpDir/cycles/root.js + $tmpDir/targets/cycles/root.js (hard) */ var entry = tmp('node-test-realpath-f1'); try { fs.unlinkSync(tmp('node-test-realpath-d2/foo')); } catch (e) {} @@ -289,16 +292,16 @@ function test_deep_symlink_mix(callback) { fs.mkdirSync(tmp('node-test-realpath-d2'), 0o700); try { [ - [entry, '../' + common.tmpDirName + '/node-test-realpath-d1/foo'], + [entry, common.tmpDir + '/node-test-realpath-d1/foo'], [tmp('node-test-realpath-d1'), - '../' + common.tmpDirName + '/node-test-realpath-d2'], + common.tmpDir + '/node-test-realpath-d2'], [tmp('node-test-realpath-d2/foo'), '../node-test-realpath-f2'], - [tmp('node-test-realpath-f2'), fixturesAbsDir + - '/nested-index/one/realpath-c'], - [fixturesAbsDir + '/nested-index/one/realpath-c', fixturesAbsDir + - '/nested-index/two/realpath-c'], - [fixturesAbsDir + '/nested-index/two/realpath-c', - '../../../' + common.tmpDirName + '/cycles/root.js'] + [tmp('node-test-realpath-f2'), targetsAbsDir + + '/nested-index/one/realpath-c'], + [targetsAbsDir + '/nested-index/one/realpath-c', targetsAbsDir + + '/nested-index/two/realpath-c'], + [targetsAbsDir + '/nested-index/two/realpath-c', + common.tmpDir + '/cycles/root.js'] ].forEach(function(t) { try { fs.unlinkSync(t[0]); } catch (e) {} fs.symlinkSync(t[1], t[0]); diff --git a/test/parallel/test-fs-stat.js b/test/parallel/test-fs-stat.js index 123d6608b4bb..1affdec6260c 100644 --- a/test/parallel/test-fs-stat.js +++ b/test/parallel/test-fs-stat.js @@ -1,5 +1,5 @@ /* eslint-disable strict */ -var common = require('../common'); +require('../common'); var assert = require('assert'); var fs = require('fs'); var got_error = false; diff --git a/test/parallel/test-fs-symlink-dir-junction-relative.js b/test/parallel/test-fs-symlink-dir-junction-relative.js index dcc4e989cc1e..cb3e5a464fab 100644 --- a/test/parallel/test-fs-symlink-dir-junction-relative.js +++ b/test/parallel/test-fs-symlink-dir-junction-relative.js @@ -11,7 +11,7 @@ var expected_tests = 2; var linkPath1 = path.join(common.tmpDir, 'junction1'); var linkPath2 = path.join(common.tmpDir, 'junction2'); var linkTarget = path.join(common.fixturesDir); -var linkData = '../fixtures'; +var linkData = path.join(common.fixturesDir); common.refreshTmpDir(); @@ -42,4 +42,3 @@ function verifyLink(linkPath) { process.on('exit', function() { assert.equal(completed, expected_tests); }); - diff --git a/test/parallel/test-fs-sync-fd-leak.js b/test/parallel/test-fs-sync-fd-leak.js index 5f2b63125a1d..f7cfd25f4b9b 100644 --- a/test/parallel/test-fs-sync-fd-leak.js +++ b/test/parallel/test-fs-sync-fd-leak.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var fs = require('fs'); diff --git a/test/parallel/test-fs-utimes.js b/test/parallel/test-fs-utimes.js index 2ad6cea4379b..5d5cb40ec1ee 100644 --- a/test/parallel/test-fs-utimes.js +++ b/test/parallel/test-fs-utimes.js @@ -48,7 +48,7 @@ function expect_ok(syscall, resource, err, atime, mtime) { // would be even better though (node doesn't have such functionality yet) function runTest(atime, mtime, callback) { - var fd, err; + var fd; // // test synchronized code paths, these functions throw on failure // diff --git a/test/parallel/test-fs-write-file-sync.js b/test/parallel/test-fs-write-file-sync.js index 72c0a2b19b71..7ae9e122cae8 100644 --- a/test/parallel/test-fs-write-file-sync.js +++ b/test/parallel/test-fs-write-file-sync.js @@ -15,7 +15,7 @@ fs._closeSync = fs.closeSync; fs.closeSync = closeSync; // Reset the umask for testing -var mask = process.umask(0o000); +process.umask(0o000); // On Windows chmod is only able to manipulate read-only bit. Test if creating // the file in read-only mode works. diff --git a/test/parallel/test-fs-write-no-fd.js b/test/parallel/test-fs-write-no-fd.js index 5b38ce6ba814..eb0ed5caeb66 100644 --- a/test/parallel/test-fs-write-no-fd.js +++ b/test/parallel/test-fs-write-no-fd.js @@ -1,5 +1,5 @@ 'use strict'; -const common = require('../common'); +require('../common'); const fs = require('fs'); const assert = require('assert'); diff --git a/test/parallel/test-handle-wrap-close-abort.js b/test/parallel/test-handle-wrap-close-abort.js index 8e2388fa84d8..8572668f6668 100644 --- a/test/parallel/test-handle-wrap-close-abort.js +++ b/test/parallel/test-handle-wrap-close-abort.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); process.on('uncaughtException', function() { }); diff --git a/test/parallel/test-http-1.0-keep-alive.js b/test/parallel/test-http-1.0-keep-alive.js index eac0fe51e220..516a02031ef2 100644 --- a/test/parallel/test-http-1.0-keep-alive.js +++ b/test/parallel/test-http-1.0-keep-alive.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var http = require('http'); var net = require('net'); diff --git a/test/parallel/test-http-1.0.js b/test/parallel/test-http-1.0.js index 9989c9b969b8..f9c865f3e630 100644 --- a/test/parallel/test-http-1.0.js +++ b/test/parallel/test-http-1.0.js @@ -19,7 +19,7 @@ function test(handler, request_generator, response_validator) { server.close(); response_validator(server_response, client_got_eof, true); } - var timer = setTimeout(cleanup, 1000); + var timer = setTimeout(cleanup, common.platformTimeout(1000)); process.on('exit', cleanup); server.listen(port); diff --git a/test/parallel/test-http-304.js b/test/parallel/test-http-304.js index 06fd60f5572b..6ac1c68d0d36 100644 --- a/test/parallel/test-http-304.js +++ b/test/parallel/test-http-304.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var http = require('http'); var childProcess = require('child_process'); diff --git a/test/parallel/test-http-abort-client.js b/test/parallel/test-http-abort-client.js index e24ded11d1a7..4d7a32c1dfb2 100644 --- a/test/parallel/test-http-abort-client.js +++ b/test/parallel/test-http-abort-client.js @@ -14,7 +14,7 @@ var server = http.Server(function(req, res) { var responseClose = false; server.listen(common.PORT, function() { - var client = http.get({ + http.get({ port: common.PORT, headers: { connection: 'keep-alive' } diff --git a/test/parallel/test-http-after-connect.js b/test/parallel/test-http-after-connect.js index edd03b2178b2..ed18def86088 100644 --- a/test/parallel/test-http-after-connect.js +++ b/test/parallel/test-http-after-connect.js @@ -45,7 +45,7 @@ server.listen(common.PORT, function() { }); function doRequest(i) { - var req = http.get({ + http.get({ port: common.PORT, path: '/request' + i }, function(res) { diff --git a/test/parallel/test-http-agent-error-on-idle.js b/test/parallel/test-http-agent-error-on-idle.js new file mode 100644 index 000000000000..e3388ee0dcbd --- /dev/null +++ b/test/parallel/test-http-agent-error-on-idle.js @@ -0,0 +1,55 @@ +'use strict'; +var common = require('../common'); +var assert = require('assert'); +var http = require('http'); +var Agent = http.Agent; + +var agent = new Agent({ + keepAlive: true, +}); + +var requestParams = { + host: 'localhost', + port: common.PORT, + agent: agent, + path: '/' +}; + +var socketKey = agent.getName(requestParams); + +function get(callback) { + return http.get(requestParams, callback); +} + +var server = http.createServer(function(req, res) { + res.end('hello world'); +}); + +server.listen(common.PORT, function() { + get(function(res) { + assert.equal(res.statusCode, 200); + res.resume(); + res.on('end', function() { + process.nextTick(function() { + var freeSockets = agent.freeSockets[socketKey]; + assert.equal(freeSockets.length, 1, + 'expect a free socket on ' + socketKey); + + //generate a random error on the free socket + var freeSocket = freeSockets[0]; + freeSocket.emit('error', new Error('ECONNRESET: test')); + + get(done); + }); + }); + }); +}); + +function done() { + assert.equal(Object.keys(agent.freeSockets).length, 0, + 'expect the freeSockets pool to be empty'); + + agent.destroy(); + server.close(); + process.exit(0); +} diff --git a/test/parallel/test-http-agent-false.js b/test/parallel/test-http-agent-false.js index ad8de89f2038..96606028bf7a 100644 --- a/test/parallel/test-http-agent-false.js +++ b/test/parallel/test-http-agent-false.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var http = require('http'); diff --git a/test/parallel/test-http-agent-getname.js b/test/parallel/test-http-agent-getname.js index d8d30a8ddbc2..1b80b5c36e1e 100644 --- a/test/parallel/test-http-agent-getname.js +++ b/test/parallel/test-http-agent-getname.js @@ -1,8 +1,8 @@ 'use strict'; +require('../common'); var assert = require('assert'); var http = require('http'); -var common = require('../common'); var agent = new http.Agent(); diff --git a/test/parallel/test-http-agent-keepalive.js b/test/parallel/test-http-agent-keepalive.js index ef9553c83168..6800e893e329 100644 --- a/test/parallel/test-http-agent-keepalive.js +++ b/test/parallel/test-http-agent-keepalive.js @@ -1,27 +1,26 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var http = require('http'); -var Agent = require('_http_agent').Agent; -var EventEmitter = require('events').EventEmitter; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const Agent = require('_http_agent').Agent; -var agent = new Agent({ +const agent = new Agent({ keepAlive: true, keepAliveMsecs: 1000, maxSockets: 5, maxFreeSockets: 5 }); -var server = http.createServer(function(req, res) { +const server = http.createServer(function(req, res) { if (req.url === '/error') { res.destroy(); return; } else if (req.url === '/remote_close') { - // cache the socket, close it after 100ms - var socket = res.connection; - setTimeout(function() { + // cache the socket, close it after a short delay + const socket = res.connection; + setImmediate(function() { socket.end(); - }, 100); + }); } res.end('hello world'); }); @@ -35,7 +34,7 @@ function get(path, callback) { }, callback); } -var name = 'localhost:' + common.PORT + ':'; +const name = 'localhost:' + common.PORT + ':'; function checkDataAndSockets(body) { assert.equal(body.toString(), 'hello world'); @@ -77,7 +76,7 @@ function remoteClose() { assert.equal(agent.freeSockets[name], undefined, 'freeSockets is not empty'); remoteError(); - }, 200); + }, common.platformTimeout(200)); }); }); }); @@ -85,7 +84,7 @@ function remoteClose() { function remoteError() { // remove server will destroy ths socket - var req = get('/error', function(res) { + const req = get('/error', function(res) { throw new Error('should not call this function'); }); req.on('error', function(err) { @@ -98,7 +97,7 @@ function remoteError() { assert.equal(agent.sockets[name], undefined); assert.equal(agent.freeSockets[name], undefined); done(); - }, 1); + }, common.platformTimeout(1)); }); } diff --git a/test/parallel/test-http-agent-maxsockets-regress-4050.js b/test/parallel/test-http-agent-maxsockets-regress-4050.js new file mode 100644 index 000000000000..1cbe37cf0cc4 --- /dev/null +++ b/test/parallel/test-http-agent-maxsockets-regress-4050.js @@ -0,0 +1,43 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const MAX_SOCKETS = 2; + +const agent = new http.Agent({ + keepAlive: true, + keepAliveMsecs: 1000, + maxSockets: MAX_SOCKETS, + maxFreeSockets: 2 +}); + +const server = http.createServer(function(req, res) { + res.end('hello world'); +}); + +function get(path, callback) { + return http.get({ + host: 'localhost', + port: common.PORT, + agent: agent, + path: path + }, callback); +} + +server.listen(common.PORT, function() { + var finished = 0; + const num_requests = 6; + for (var i = 0; i < num_requests; i++) { + const request = get('/1', function() { + }); + request.on('response', function() { + request.abort(); + const sockets = agent.sockets[Object.keys(agent.sockets)[0]]; + assert(sockets.length <= MAX_SOCKETS); + if (++finished === num_requests) { + server.close(); + } + }); + } +}); diff --git a/test/parallel/test-http-agent-null.js b/test/parallel/test-http-agent-null.js index e118738f6640..29961ff3a5e8 100644 --- a/test/parallel/test-http-agent-null.js +++ b/test/parallel/test-http-agent-null.js @@ -2,7 +2,6 @@ var common = require('../common'); var assert = require('assert'); var http = require('http'); -var net = require('net'); var request = 0; var response = 0; diff --git a/test/parallel/test-http-buffer-sanity.js b/test/parallel/test-http-buffer-sanity.js index 4b120311d7da..98ce0f75b916 100644 --- a/test/parallel/test-http-buffer-sanity.js +++ b/test/parallel/test-http-buffer-sanity.js @@ -2,7 +2,6 @@ var common = require('../common'); var assert = require('assert'); var http = require('http'); -var util = require('util'); var bufferSize = 5 * 1024 * 1024; var measuredSize = 0; diff --git a/test/parallel/test-http-byteswritten.js b/test/parallel/test-http-byteswritten.js index 974f446dd436..fdc407aec667 100644 --- a/test/parallel/test-http-byteswritten.js +++ b/test/parallel/test-http-byteswritten.js @@ -1,7 +1,6 @@ 'use strict'; var common = require('../common'); var assert = require('assert'); -var fs = require('fs'); var http = require('http'); var body = 'hello world\n'; diff --git a/test/parallel/test-http-client-abort2.js b/test/parallel/test-http-client-abort2.js index 3f7ae98fa258..477d12b25827 100644 --- a/test/parallel/test-http-client-abort2.js +++ b/test/parallel/test-http-client-abort2.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var http = require('http'); var server = http.createServer(function(req, res) { diff --git a/test/parallel/test-http-client-encoding.js b/test/parallel/test-http-client-encoding.js index dd696f4dff60..baaef855b1e6 100644 --- a/test/parallel/test-http-client-encoding.js +++ b/test/parallel/test-http-client-encoding.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var http = require('http'); diff --git a/test/parallel/test-http-client-pipe-end.js b/test/parallel/test-http-client-pipe-end.js index efe241419397..715f8ccf79df 100644 --- a/test/parallel/test-http-client-pipe-end.js +++ b/test/parallel/test-http-client-pipe-end.js @@ -2,7 +2,6 @@ // see https://github.com/joyent/node/issues/3257 var common = require('../common'); -var assert = require('assert'); var http = require('http'); var server = http.createServer(function(req, res) { diff --git a/test/parallel/test-http-client-readable.js b/test/parallel/test-http-client-readable.js index ba9fdd658c38..8328afb01c64 100644 --- a/test/parallel/test-http-client-readable.js +++ b/test/parallel/test-http-client-readable.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var http = require('http'); var util = require('util'); diff --git a/test/parallel/test-http-default-port.js b/test/parallel/test-http-default-port.js index 457424ecfa93..e403b401fb60 100644 --- a/test/parallel/test-http-default-port.js +++ b/test/parallel/test-http-default-port.js @@ -57,7 +57,7 @@ if (common.hasCrypto) { res.end('ok'); this.close(); }).listen(SSLPORT, function() { - var req = https.get({ + https.get({ host: 'localhost', rejectUnauthorized: false, headers: { diff --git a/test/parallel/test-http-destroyed-socket-write2.js b/test/parallel/test-http-destroyed-socket-write2.js index 5bbb3bbc946f..9065939ccbd7 100644 --- a/test/parallel/test-http-destroyed-socket-write2.js +++ b/test/parallel/test-http-destroyed-socket-write2.js @@ -6,7 +6,6 @@ var assert = require('assert'); // where the server has ended the socket. var http = require('http'); -var net = require('net'); var server = http.createServer(function(req, res) { setImmediate(function() { res.destroy(); diff --git a/test/parallel/test-http-eof-on-connect.js b/test/parallel/test-http-eof-on-connect.js index e676643bab49..fc7dd1d9fe88 100644 --- a/test/parallel/test-http-eof-on-connect.js +++ b/test/parallel/test-http-eof-on-connect.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var net = require('net'); var http = require('http'); diff --git a/test/parallel/test-http-exceptions.js b/test/parallel/test-http-exceptions.js index dc2d5583ddba..922dc2095714 100644 --- a/test/parallel/test-http-exceptions.js +++ b/test/parallel/test-http-exceptions.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var http = require('http'); var server = http.createServer(function(req, res) { @@ -11,9 +10,8 @@ var server = http.createServer(function(req, res) { }); server.listen(common.PORT, function() { - var req; for (var i = 0; i < 4; i += 1) { - req = http.get({ port: common.PORT, path: '/busy/' + i }); + http.get({ port: common.PORT, path: '/busy/' + i }); } }); diff --git a/test/parallel/test-http-flush.js b/test/parallel/test-http-flush.js index cac1caf752be..8dc7ba7418dc 100644 --- a/test/parallel/test-http-flush.js +++ b/test/parallel/test-http-flush.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var http = require('http'); http.createServer(function(req, res) { diff --git a/test/parallel/test-http-head-request.js b/test/parallel/test-http-head-request.js index 5a6f90507cf3..faf2168e36d0 100644 --- a/test/parallel/test-http-head-request.js +++ b/test/parallel/test-http-head-request.js @@ -2,7 +2,6 @@ var common = require('../common'); var assert = require('assert'); var http = require('http'); -var util = require('util'); var body = 'hello world\n'; diff --git a/test/parallel/test-http-incoming-pipelined-socket-destroy.js b/test/parallel/test-http-incoming-pipelined-socket-destroy.js index 21cd3e69dfd7..1e5a910424d7 100644 --- a/test/parallel/test-http-incoming-pipelined-socket-destroy.js +++ b/test/parallel/test-http-incoming-pipelined-socket-destroy.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var http = require('http'); var net = require('net'); diff --git a/test/parallel/test-http-keep-alive-close-on-header.js b/test/parallel/test-http-keep-alive-close-on-header.js index 9ed6077b943a..83a0d0684cf6 100644 --- a/test/parallel/test-http-keep-alive-close-on-header.js +++ b/test/parallel/test-http-keep-alive-close-on-header.js @@ -2,7 +2,6 @@ var common = require('../common'); var assert = require('assert'); var http = require('http'); -var util = require('util'); var body = 'hello world\n'; var headers = {'connection': 'keep-alive'}; diff --git a/test/parallel/test-http-keep-alive.js b/test/parallel/test-http-keep-alive.js index f89f7698c46e..0d30bbe1da30 100644 --- a/test/parallel/test-http-keep-alive.js +++ b/test/parallel/test-http-keep-alive.js @@ -11,7 +11,6 @@ var server = http.createServer(function(req, res) { res.end(); }); -var connectCount = 0; var agent = new http.Agent({maxSockets: 1}); var headers = {'connection': 'keep-alive'}; var name = agent.getName({ port: common.PORT }); diff --git a/test/parallel/test-http-localaddress-bind-error.js b/test/parallel/test-http-localaddress-bind-error.js index 9a4bde26cd22..adaeba2b9459 100644 --- a/test/parallel/test-http-localaddress-bind-error.js +++ b/test/parallel/test-http-localaddress-bind-error.js @@ -17,7 +17,7 @@ var server = http.createServer(function(req, res) { }); server.listen(common.PORT, '127.0.0.1', function() { - var req = http.request({ + http.request({ host: 'localhost', port: common.PORT, path: '/', diff --git a/test/parallel/test-http-many-ended-pipelines.js b/test/parallel/test-http-many-ended-pipelines.js index 604dab7cc2c1..c415af64f9dc 100644 --- a/test/parallel/test-http-many-ended-pipelines.js +++ b/test/parallel/test-http-many-ended-pipelines.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); // no warnings should happen! var trace = console.trace; diff --git a/test/parallel/test-http-methods.js b/test/parallel/test-http-methods.js index 348fd2e519ef..62a4187841bd 100644 --- a/test/parallel/test-http-methods.js +++ b/test/parallel/test-http-methods.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var http = require('http'); var util = require('util'); diff --git a/test/parallel/test-http-no-content-length.js b/test/parallel/test-http-no-content-length.js index 5752e5e924cd..7a205dc07df3 100644 --- a/test/parallel/test-http-no-content-length.js +++ b/test/parallel/test-http-no-content-length.js @@ -10,7 +10,7 @@ var server = net.createServer(function(socket) { // Neither Content-Length nor Connection socket.end('HTTP/1.1 200 ok\r\n\r\nHello'); }).listen(common.PORT, function() { - var req = http.get({port: common.PORT}, function(res) { + http.get({port: common.PORT}, function(res) { res.setEncoding('utf8'); res.on('data', function(chunk) { body += chunk; diff --git a/test/parallel/test-http-parser-bad-ref.js b/test/parallel/test-http-parser-bad-ref.js index d409dc62d008..545a9c1fef11 100644 --- a/test/parallel/test-http-parser-bad-ref.js +++ b/test/parallel/test-http-parser-bad-ref.js @@ -4,7 +4,7 @@ // Flags: --expose_gc -var common = require('../common'); +require('../common'); var assert = require('assert'); var HTTPParser = process.binding('http_parser').HTTPParser; diff --git a/test/parallel/test-http-parser.js b/test/parallel/test-http-parser.js index bb004f864cf4..f10f3ac26b4b 100644 --- a/test/parallel/test-http-parser.js +++ b/test/parallel/test-http-parser.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var HTTPParser = process.binding('http_parser').HTTPParser; diff --git a/test/parallel/test-http-pipeline-regr-3508.js b/test/parallel/test-http-pipeline-regr-3508.js index 05639a2a42c5..74fe7586726c 100644 --- a/test/parallel/test-http-pipeline-regr-3508.js +++ b/test/parallel/test-http-pipeline-regr-3508.js @@ -1,6 +1,5 @@ 'use strict'; const common = require('../common'); -const assert = require('assert'); const http = require('http'); const net = require('net'); diff --git a/test/parallel/test-http-proxy.js b/test/parallel/test-http-proxy.js index fc8a753f2485..8a579cd69aa5 100644 --- a/test/parallel/test-http-proxy.js +++ b/test/parallel/test-http-proxy.js @@ -25,7 +25,7 @@ var backend = http.createServer(function(req, res) { var proxy = http.createServer(function(req, res) { console.error('proxy req headers: ' + JSON.stringify(req.headers)); - var proxy_req = http.get({ + http.get({ port: BACKEND_PORT, path: url.parse(req.url).pathname }, function(proxy_res) { @@ -56,7 +56,7 @@ function startReq() { nlistening++; if (nlistening < 2) return; - var client = http.get({ + http.get({ port: PROXY_PORT, path: '/test' }, function(res) { diff --git a/test/parallel/test-http-raw-headers.js b/test/parallel/test-http-raw-headers.js index 7ecaaa93cfb0..2042c0262a95 100644 --- a/test/parallel/test-http-raw-headers.js +++ b/test/parallel/test-http-raw-headers.js @@ -54,14 +54,6 @@ http.createServer(function(req, res) { ]); res.end('x f o o'); }).listen(common.PORT, function() { - var expectRawHeaders = [ - 'Date', - 'Tue, 06 Aug 2013 01:31:54 GMT', - 'Connection', - 'close', - 'Transfer-Encoding', - 'chunked' - ]; var req = http.request({ port: common.PORT, path: '/' }); req.addTrailers([ ['x-bAr', 'yOyOyOy'], diff --git a/test/parallel/test-http-regr-gh-2821.js b/test/parallel/test-http-regr-gh-2821.js index 4fdef2369bb1..8725111324a8 100644 --- a/test/parallel/test-http-regr-gh-2821.js +++ b/test/parallel/test-http-regr-gh-2821.js @@ -1,6 +1,5 @@ 'use strict'; const common = require('../common'); -const assert = require('assert'); const http = require('http'); const server = http.createServer(function(req, res) { diff --git a/test/parallel/test-http-res-write-after-end.js b/test/parallel/test-http-res-write-after-end.js index c8b3bf26e080..206f4273ec70 100644 --- a/test/parallel/test-http-res-write-after-end.js +++ b/test/parallel/test-http-res-write-after-end.js @@ -18,7 +18,7 @@ var server = http.Server(function(req, res) { }); server.listen(common.PORT, function() { - var req = http.get({port: common.PORT}, function(res) { + http.get({port: common.PORT}, function(res) { server.close(); }); }); diff --git a/test/parallel/test-http-response-multiheaders.js b/test/parallel/test-http-response-multiheaders.js index 6f477d663810..4705548d3a38 100644 --- a/test/parallel/test-http-response-multiheaders.js +++ b/test/parallel/test-http-response-multiheaders.js @@ -48,6 +48,7 @@ const server = http.createServer(function(req, res) { }); server.listen(common.PORT, common.mustCall(function() { + var count = 0; for (let n = 1; n <= 2 ; n++) { // this runs twice, the first time, the server will use // setHeader, the second time it uses writeHead. The @@ -58,7 +59,7 @@ server.listen(common.PORT, common.mustCall(function() { http.get( {port:common.PORT, headers:{'x-num': n}}, common.mustCall(function(res) { - if (n == 2) server.close(); + if (++ count === 2) server.close(); assert.equal(res.headers['content-length'], 1); for (const name of norepeat) { assert.equal(res.headers[name], 'A'); diff --git a/test/parallel/test-http-server-multiheaders.js b/test/parallel/test-http-server-multiheaders.js index 7033ef8e7079..99d729884799 100644 --- a/test/parallel/test-http-server-multiheaders.js +++ b/test/parallel/test-http-server-multiheaders.js @@ -16,6 +16,7 @@ var srv = http.createServer(function(req, res) { assert.equal(req.headers['x-bar'], 'banjo, bango'); assert.equal(req.headers['sec-websocket-protocol'], 'chat, share'); assert.equal(req.headers['sec-websocket-extensions'], 'foo; 1, bar; 2, baz'); + assert.equal(req.headers['constructor'], 'foo, bar, baz'); res.writeHead(200, {'Content-Type' : 'text/plain'}); res.end('EOF'); @@ -48,7 +49,10 @@ srv.listen(common.PORT, function() { ['sec-websocket-protocol', 'share'], ['sec-websocket-extensions', 'foo; 1'], ['sec-websocket-extensions', 'bar; 2'], - ['sec-websocket-extensions', 'baz'] + ['sec-websocket-extensions', 'baz'], + ['constructor', 'foo'], + ['constructor', 'bar'], + ['constructor', 'baz'], ] }); }); diff --git a/test/parallel/test-http-server-stale-close.js b/test/parallel/test-http-server-stale-close.js index a866d39c2cc7..349e869c1a4f 100644 --- a/test/parallel/test-http-server-stale-close.js +++ b/test/parallel/test-http-server-stale-close.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var http = require('http'); var util = require('util'); var fork = require('child_process').fork; diff --git a/test/parallel/test-http-status-code.js b/test/parallel/test-http-status-code.js index 19c36b0b2fd2..5fedb529f82f 100644 --- a/test/parallel/test-http-status-code.js +++ b/test/parallel/test-http-status-code.js @@ -7,7 +7,7 @@ var http = require('http'); // ServerResponse.prototype.statusCode var testsComplete = 0; -var tests = [200, 202, 300, 404, 500]; +var tests = [200, 202, 300, 404, 451, 500]; var testIdx = 0; var s = http.createServer(function(req, res) { @@ -42,6 +42,6 @@ function nextTest() { process.on('exit', function() { - assert.equal(4, testsComplete); + assert.equal(5, testsComplete); }); diff --git a/test/parallel/test-http-timeout.js b/test/parallel/test-http-timeout.js index aab903420f0a..f45996151785 100644 --- a/test/parallel/test-http-timeout.js +++ b/test/parallel/test-http-timeout.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var http = require('http'); diff --git a/test/parallel/test-http-unix-socket.js b/test/parallel/test-http-unix-socket.js index 98ed839241c2..bdac0566c33a 100644 --- a/test/parallel/test-http-unix-socket.js +++ b/test/parallel/test-http-unix-socket.js @@ -1,7 +1,6 @@ 'use strict'; var common = require('../common'); var assert = require('assert'); -var fs = require('fs'); var http = require('http'); var status_ok = false; // status code == 200? diff --git a/test/parallel/test-http-url.parse-https.request.js b/test/parallel/test-http-url.parse-https.request.js index 10c40ec03107..df01ae64f81d 100644 --- a/test/parallel/test-http-url.parse-https.request.js +++ b/test/parallel/test-http-url.parse-https.request.js @@ -10,7 +10,6 @@ var https = require('https'); var url = require('url'); var fs = require('fs'); -var clientRequest; // https options var httpsOptions = { diff --git a/test/parallel/test-http-url.parse-only-support-http-https-protocol.js b/test/parallel/test-http-url.parse-only-support-http-https-protocol.js index fd52a0b62d11..0e997694aa74 100644 --- a/test/parallel/test-http-url.parse-only-support-http-https-protocol.js +++ b/test/parallel/test-http-url.parse-only-support-http-https-protocol.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var http = require('http'); var url = require('url'); diff --git a/test/parallel/test-https-agent-disable-session-reuse.js b/test/parallel/test-https-agent-disable-session-reuse.js index 551f0150bfb3..a4f9517bd52f 100644 --- a/test/parallel/test-https-agent-disable-session-reuse.js +++ b/test/parallel/test-https-agent-disable-session-reuse.js @@ -10,7 +10,6 @@ if (!common.hasCrypto) { const TOTAL_REQS = 2; const https = require('https'); -const crypto = require('crypto'); const fs = require('fs'); diff --git a/test/parallel/test-https-agent-servername.js b/test/parallel/test-https-agent-servername.js index 2be40836a04e..f7d5e5a40d86 100644 --- a/test/parallel/test-https-agent-servername.js +++ b/test/parallel/test-https-agent-servername.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); if (!common.hasCrypto) { console.log('1..0 # Skipped: missing crypto'); diff --git a/test/parallel/test-https-agent-sni.js b/test/parallel/test-https-agent-sni.js new file mode 100644 index 000000000000..117075f68264 --- /dev/null +++ b/test/parallel/test-https-agent-sni.js @@ -0,0 +1,52 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +if (!common.hasCrypto) { + console.log('1..0 # Skipped: missing crypto'); + return; +} +const https = require('https'); + +const fs = require('fs'); + +const options = { + key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'), + cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem') +}; + +const TOTAL = 4; +var waiting = TOTAL; + +const server = https.Server(options, function(req, res) { + if (--waiting === 0) server.close(); + + res.writeHead(200, { + 'x-sni': req.socket.servername + }); + res.end('hello world'); +}); + +server.listen(common.PORT, function() { + function expectResponse(id) { + return common.mustCall(function(res) { + res.resume(); + assert.equal(res.headers['x-sni'], 'sni.' + id); + }); + } + + var agent = new https.Agent({ + maxSockets: 1 + }); + for (var j = 0; j < TOTAL; j++) { + https.get({ + agent: agent, + + path: '/', + port: common.PORT, + host: '127.0.0.1', + servername: 'sni.' + j, + rejectUnauthorized: false + }, expectResponse(j)); + } +}); diff --git a/test/parallel/test-https-byteswritten.js b/test/parallel/test-https-byteswritten.js index 5163eccc262f..beef89b25ccb 100644 --- a/test/parallel/test-https-byteswritten.js +++ b/test/parallel/test-https-byteswritten.js @@ -2,7 +2,6 @@ var common = require('../common'); var assert = require('assert'); var fs = require('fs'); -var http = require('http'); if (!common.hasCrypto) { console.log('1..0 # Skipped: missing crypto'); diff --git a/test/parallel/test-https-eof-for-eom.js b/test/parallel/test-https-eof-for-eom.js index 0445625bace6..50d909373ff5 100644 --- a/test/parallel/test-https-eof-for-eom.js +++ b/test/parallel/test-https-eof-for-eom.js @@ -53,7 +53,7 @@ var bodyBuffer = ''; server.listen(common.PORT, function() { console.log('1) Making Request'); - var req = https.get({ + https.get({ port: common.PORT, rejectUnauthorized: false }, function(res) { diff --git a/test/parallel/test-https-localaddress-bind-error.js b/test/parallel/test-https-localaddress-bind-error.js index 66551a780aed..f5bb1f84c310 100644 --- a/test/parallel/test-https-localaddress-bind-error.js +++ b/test/parallel/test-https-localaddress-bind-error.js @@ -28,7 +28,7 @@ var server = https.createServer(options, function(req, res) { }); server.listen(common.PORT, '127.0.0.1', function() { - var req = https.request({ + https.request({ host: 'localhost', port: common.PORT, path: '/', diff --git a/test/parallel/test-https-socket-options.js b/test/parallel/test-https-socket-options.js index 44e179f27a80..2adf8c798dff 100644 --- a/test/parallel/test-https-socket-options.js +++ b/test/parallel/test-https-socket-options.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); if (!common.hasCrypto) { console.log('1..0 # Skipped: missing crypto'); @@ -9,7 +8,6 @@ if (!common.hasCrypto) { var https = require('https'); var fs = require('fs'); -var exec = require('child_process').exec; var http = require('http'); diff --git a/test/parallel/test-https-strict.js b/test/parallel/test-https-strict.js index 65ebfabde2bc..04561959de13 100644 --- a/test/parallel/test-https-strict.js +++ b/test/parallel/test-https-strict.js @@ -110,7 +110,7 @@ function makeReq(path, port, error, host, ca) { path: path, ca: ca }; - var whichCa = 0; + if (!ca) { options.agent = agent0; } else { diff --git a/test/parallel/test-https-timeout-server-2.js b/test/parallel/test-https-timeout-server-2.js index df605958cf42..a195ce1938b9 100644 --- a/test/parallel/test-https-timeout-server-2.js +++ b/test/parallel/test-https-timeout-server-2.js @@ -9,7 +9,6 @@ if (!common.hasCrypto) { } var https = require('https'); -var net = require('net'); var tls = require('tls'); var fs = require('fs'); diff --git a/test/parallel/test-https-timeout-server.js b/test/parallel/test-https-timeout-server.js index ba175ecf763e..f6d5d75a88ab 100644 --- a/test/parallel/test-https-timeout-server.js +++ b/test/parallel/test-https-timeout-server.js @@ -9,7 +9,6 @@ if (!common.hasCrypto) { var https = require('https'); var net = require('net'); -var tls = require('tls'); var fs = require('fs'); var clientErrors = 0; diff --git a/test/parallel/test-https-timeout.js b/test/parallel/test-https-timeout.js index 7f34c18bec08..2b41dadaec78 100644 --- a/test/parallel/test-https-timeout.js +++ b/test/parallel/test-https-timeout.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); if (!common.hasCrypto) { console.log('1..0 # Skipped: missing crypto'); @@ -9,7 +8,6 @@ if (!common.hasCrypto) { var https = require('https'); var fs = require('fs'); -var exec = require('child_process').exec; var options = { key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'), diff --git a/test/parallel/test-https-truncate.js b/test/parallel/test-https-truncate.js index e77bf29ed254..83506c65d6f3 100644 --- a/test/parallel/test-https-truncate.js +++ b/test/parallel/test-https-truncate.js @@ -9,7 +9,6 @@ if (!common.hasCrypto) { var https = require('https'); var fs = require('fs'); -var path = require('path'); var key = fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'); var cert = fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem'); diff --git a/test/parallel/test-internal-modules-expose.js b/test/parallel/test-internal-modules-expose.js index 4ece1d0c7b6f..ed3cecb6f297 100644 --- a/test/parallel/test-internal-modules-expose.js +++ b/test/parallel/test-internal-modules-expose.js @@ -1,7 +1,7 @@ 'use strict'; // Flags: --expose_internals -var common = require('../common'); +require('../common'); var assert = require('assert'); assert.equal(typeof require('internal/freelist').FreeList, 'function'); diff --git a/test/parallel/test-internal-modules.js b/test/parallel/test-internal-modules.js index 011b6f7132e9..5d93a381c7ac 100644 --- a/test/parallel/test-internal-modules.js +++ b/test/parallel/test-internal-modules.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); assert.throws(function() { diff --git a/test/parallel/test-intl.js b/test/parallel/test-intl.js index 7288febf9e6b..1219c330386c 100644 --- a/test/parallel/test-intl.js +++ b/test/parallel/test-intl.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // does node think that i18n was enabled? diff --git a/test/parallel/test-js-stream-call-properties.js b/test/parallel/test-js-stream-call-properties.js index c6b1adb3cb7a..280e5d9dabee 100644 --- a/test/parallel/test-js-stream-call-properties.js +++ b/test/parallel/test-js-stream-call-properties.js @@ -1,6 +1,6 @@ 'use strict'; -const common = require('../common'); +require('../common'); const util = require('util'); const JSStream = process.binding('js_stream').JSStream; diff --git a/test/parallel/test-listen-fd-cluster.js b/test/parallel/test-listen-fd-cluster.js index f6d00c72a0f7..c321f699d7a8 100644 --- a/test/parallel/test-listen-fd-cluster.js +++ b/test/parallel/test-listen-fd-cluster.js @@ -4,7 +4,6 @@ var assert = require('assert'); var http = require('http'); var net = require('net'); var PORT = common.PORT; -var spawn = require('child_process').spawn; var cluster = require('cluster'); console.error('Cluster listen fd test', process.argv[2] || 'runner'); diff --git a/test/parallel/test-listen-fd-server.js b/test/parallel/test-listen-fd-server.js index d51d51ee8eb4..3e0fa521f753 100644 --- a/test/parallel/test-listen-fd-server.js +++ b/test/parallel/test-listen-fd-server.js @@ -4,7 +4,6 @@ var assert = require('assert'); var http = require('http'); var net = require('net'); var PORT = common.PORT; -var spawn = require('child_process').spawn; if (common.isWindows) { console.log('1..0 # Skipped: This test is disabled on windows.'); diff --git a/test/parallel/test-memory-usage.js b/test/parallel/test-memory-usage.js index 8394fc16599e..9b39601e2e20 100644 --- a/test/parallel/test-memory-usage.js +++ b/test/parallel/test-memory-usage.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var r = process.memoryUsage(); diff --git a/test/parallel/test-microtask-queue-integration-domain.js b/test/parallel/test-microtask-queue-integration-domain.js index 7a4ad77cd321..f0d0196ac2f9 100644 --- a/test/parallel/test-microtask-queue-integration-domain.js +++ b/test/parallel/test-microtask-queue-integration-domain.js @@ -1,7 +1,13 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); -var domain = require('domain'); + +// Requiring the domain module here changes the function that is used by node to +// call process.nextTick's callbacks to a variant that specifically handles +// domains. We want to test this specific variant in this test, and so even if +// the domain module is not used, this require call is needed and must not be +// removed. +require('domain'); var implementations = [ function(fn) { diff --git a/test/parallel/test-microtask-queue-integration.js b/test/parallel/test-microtask-queue-integration.js index 37de5ee33b14..fe873d27c914 100644 --- a/test/parallel/test-microtask-queue-integration.js +++ b/test/parallel/test-microtask-queue-integration.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var implementations = [ diff --git a/test/parallel/test-microtask-queue-run-domain.js b/test/parallel/test-microtask-queue-run-domain.js index 77534920ff14..fb5139f71d65 100644 --- a/test/parallel/test-microtask-queue-run-domain.js +++ b/test/parallel/test-microtask-queue-run-domain.js @@ -1,7 +1,13 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); -var domain = require('domain'); + +// Requiring the domain module here changes the function that is used by node to +// call process.nextTick's callbacks to a variant that specifically handles +// domains. We want to test this specific variant in this test, and so even if +// the domain module is not used, this require call is needed and must not be +// removed. +require('domain'); function enqueueMicrotask(fn) { Promise.resolve().then(fn); diff --git a/test/parallel/test-microtask-queue-run-immediate-domain.js b/test/parallel/test-microtask-queue-run-immediate-domain.js index 2dea0a76cc1b..4a7729ab98a0 100644 --- a/test/parallel/test-microtask-queue-run-immediate-domain.js +++ b/test/parallel/test-microtask-queue-run-immediate-domain.js @@ -1,7 +1,13 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); -var domain = require('domain'); + +// Requiring the domain module here changes the function that is used by node to +// call process.nextTick's callbacks to a variant that specifically handles +// domains. We want to test this specific variant in this test, and so even if +// the domain module is not used, this require call is needed and must not be +// removed. +require('domain'); function enqueueMicrotask(fn) { Promise.resolve().then(fn); diff --git a/test/parallel/test-microtask-queue-run-immediate.js b/test/parallel/test-microtask-queue-run-immediate.js index cfd9cd3659ef..479062ad4710 100644 --- a/test/parallel/test-microtask-queue-run-immediate.js +++ b/test/parallel/test-microtask-queue-run-immediate.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); function enqueueMicrotask(fn) { diff --git a/test/parallel/test-microtask-queue-run.js b/test/parallel/test-microtask-queue-run.js index ca758546c2bc..ce743d930032 100644 --- a/test/parallel/test-microtask-queue-run.js +++ b/test/parallel/test-microtask-queue-run.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); function enqueueMicrotask(fn) { diff --git a/test/parallel/test-module-loading-error.js b/test/parallel/test-module-loading-error.js index e67c53fc3b07..072a6aadcb8c 100644 --- a/test/parallel/test-module-loading-error.js +++ b/test/parallel/test-module-loading-error.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); console.error('load test-module-loading-error.js'); diff --git a/test/parallel/test-net-connect-options-ipv6.js b/test/parallel/test-net-connect-options-ipv6.js index f0f7bc65b3c7..8b11612a1286 100644 --- a/test/parallel/test-net-connect-options-ipv6.js +++ b/test/parallel/test-net-connect-options-ipv6.js @@ -1,57 +1,56 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var net = require('net'); -var dns = require('dns'); +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); if (!common.hasIPv6) { console.log('1..0 # Skipped: no IPv6 support'); return; } -var serverGotEnd = false; -var clientGotEnd = false; +const hosts = common.localIPv6Hosts; +var hostIdx = 0; +var host = hosts[hostIdx]; +var localhostTries = 10; -dns.lookup('localhost', 6, function(err) { - if (err) { - console.error('Looks like IPv6 is not really supported'); - console.error(err); - return; - } +const server = net.createServer({allowHalfOpen: true}, function(socket) { + socket.resume(); + socket.on('end', common.mustCall(function() {})); + socket.end(); +}); - var server = net.createServer({allowHalfOpen: true}, function(socket) { - socket.resume(); - socket.on('end', function() { - serverGotEnd = true; - }); - socket.end(); - }); +server.listen(common.PORT, '::1', tryConnect); - server.listen(common.PORT, '::1', function() { - var client = net.connect({ - host: 'localhost', - port: common.PORT, - family: 6, - allowHalfOpen: true - }, function() { - console.error('client connect cb'); - client.resume(); - client.on('end', function() { - clientGotEnd = true; - setTimeout(function() { - assert(client.writable); - client.end(); - }, 10); - }); - client.on('close', function() { - server.close(); - }); +function tryConnect() { + const client = net.connect({ + host: host, + port: common.PORT, + family: 6, + allowHalfOpen: true + }, function() { + console.error('client connect cb'); + client.resume(); + client.on('end', common.mustCall(function() { + setTimeout(function() { + assert(client.writable); + client.end(); + }, 10); + })); + client.on('close', function() { + server.close(); }); + }).on('error', function(err) { + if (err.syscall === 'getaddrinfo' && err.code === 'ENOTFOUND') { + if (host !== 'localhost' || --localhostTries === 0) + host = hosts[++hostIdx]; + if (host) + tryConnect(); + else { + console.log('1..0 # Skipped: no IPv6 localhost support'); + server.close(); + } + return; + } + throw err; }); - - process.on('exit', function() { - console.error('exit', serverGotEnd, clientGotEnd); - assert(serverGotEnd); - assert(clientGotEnd); - }); -}); +} diff --git a/test/parallel/test-net-create-connection.js b/test/parallel/test-net-create-connection.js index c245ddc2ae78..38452be6e6a9 100644 --- a/test/parallel/test-net-create-connection.js +++ b/test/parallel/test-net-create-connection.js @@ -22,7 +22,7 @@ server.listen(tcpPort, 'localhost', function() { function fail(opts, errtype, msg) { assert.throws(function() { - var client = net.createConnection(opts, cb); + net.createConnection(opts, cb); }, function(err) { return err instanceof errtype && msg === err.message; }); diff --git a/test/parallel/test-net-dns-custom-lookup.js b/test/parallel/test-net-dns-custom-lookup.js index 008e831c61fc..a2ce3966ae12 100644 --- a/test/parallel/test-net-dns-custom-lookup.js +++ b/test/parallel/test-net-dns-custom-lookup.js @@ -2,7 +2,6 @@ var common = require('../common'); var assert = require('assert'); var net = require('net'); -var dns = require('dns'); var ok = false; function check(addressType, cb) { diff --git a/test/parallel/test-net-dns-error.js b/test/parallel/test-net-dns-error.js index 17f251cec3b6..fc27eb1b9b07 100644 --- a/test/parallel/test-net-dns-error.js +++ b/test/parallel/test-net-dns-error.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var net = require('net'); diff --git a/test/parallel/test-net-dns-lookup-skip.js b/test/parallel/test-net-dns-lookup-skip.js index b293196ad45c..9b3ae15fc393 100644 --- a/test/parallel/test-net-dns-lookup-skip.js +++ b/test/parallel/test-net-dns-lookup-skip.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var net = require('net'); function check(addressType) { diff --git a/test/parallel/test-net-end-without-connect.js b/test/parallel/test-net-end-without-connect.js index 2911591f9f48..69abf486316f 100644 --- a/test/parallel/test-net-end-without-connect.js +++ b/test/parallel/test-net-end-without-connect.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var net = require('net'); var sock = new net.Socket(); diff --git a/test/parallel/test-net-error-twice.js b/test/parallel/test-net-error-twice.js index af92ca93206f..28e90ddd611b 100644 --- a/test/parallel/test-net-error-twice.js +++ b/test/parallel/test-net-error-twice.js @@ -1,16 +1,24 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); -var net = require('net'); +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); -var buf = new Buffer(10 * 1024 * 1024); +const buf = new Buffer(10 * 1024 * 1024); buf.fill(0x62); -var errs = []; +const errs = []; +var clientSocket; +var serverSocket; + +function ready() { + if (clientSocket && serverSocket) { + clientSocket.destroy(); + serverSocket.write(buf); + } +} var srv = net.createServer(function onConnection(conn) { - conn.write(buf); conn.on('error', function(err) { errs.push(err); if (errs.length > 1 && errs[0] === errs[1]) @@ -19,11 +27,14 @@ var srv = net.createServer(function onConnection(conn) { conn.on('close', function() { srv.unref(); }); + serverSocket = conn; + ready(); }).listen(common.PORT, function() { var client = net.connect({ port: common.PORT }); client.on('connect', function() { - client.destroy(); + clientSocket = client; + ready(); }); }); diff --git a/test/parallel/test-net-isip.js b/test/parallel/test-net-isip.js index 96177122b7ba..76432ed34882 100644 --- a/test/parallel/test-net-isip.js +++ b/test/parallel/test-net-isip.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var net = require('net'); diff --git a/test/parallel/test-net-listen-close-server.js b/test/parallel/test-net-listen-close-server.js index 144ca58bbbe2..9cde6df1645d 100644 --- a/test/parallel/test-net-listen-close-server.js +++ b/test/parallel/test-net-listen-close-server.js @@ -2,7 +2,6 @@ var common = require('../common'); var assert = require('assert'); var net = require('net'); -var gotError = false; var server = net.createServer(function(socket) { }); diff --git a/test/parallel/test-net-listen-error.js b/test/parallel/test-net-listen-error.js index 79cfc7da6c92..4c4d27d703a9 100644 --- a/test/parallel/test-net-listen-error.js +++ b/test/parallel/test-net-listen-error.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var net = require('net'); var gotError = false; diff --git a/test/parallel/test-net-local-address-port.js b/test/parallel/test-net-local-address-port.js index aa28d180dae6..728993ee1bb0 100644 --- a/test/parallel/test-net-local-address-port.js +++ b/test/parallel/test-net-local-address-port.js @@ -3,7 +3,7 @@ var common = require('../common'); var assert = require('assert'); var net = require('net'); -var conns = 0, conns_closed = 0; +var conns = 0; var server = net.createServer(function(socket) { conns++; diff --git a/test/parallel/test-net-localerror.js b/test/parallel/test-net-localerror.js index 45ec1fc90999..ed7c9471e039 100644 --- a/test/parallel/test-net-localerror.js +++ b/test/parallel/test-net-localerror.js @@ -17,6 +17,6 @@ connect({ function connect(opts, msg) { assert.throws(function() { - var client = net.connect(opts); + net.connect(opts); }, msg); } diff --git a/test/parallel/test-net-pipe-connect-errors.js b/test/parallel/test-net-pipe-connect-errors.js index 81ad90ef829c..8e341015d96b 100644 --- a/test/parallel/test-net-pipe-connect-errors.js +++ b/test/parallel/test-net-pipe-connect-errors.js @@ -19,10 +19,12 @@ if (common.isWindows) { // file instead emptyTxt = path.join(common.fixturesDir, 'empty.txt'); } else { - // use common.PIPE to ensure we stay within POSIX socket path length - // restrictions, even on CI common.refreshTmpDir(); - emptyTxt = common.PIPE + '.txt'; + // Keep the file name very short so tht we don't exceed the 108 char limit + // on CI for a POSIX socket. Even though this isn't actually a socket file, + // the error will be different from the one we are expecting if we exceed the + // limit. + emptyTxt = common.tmpDir + '0.txt'; function cleanup() { try { @@ -42,7 +44,8 @@ var notSocketClient = net.createConnection(emptyTxt, function() { }); notSocketClient.on('error', function(err) { - assert(err.code === 'ENOTSOCK' || err.code === 'ECONNREFUSED'); + assert(err.code === 'ENOTSOCK' || err.code === 'ECONNREFUSED', + `received ${err.code} instead of ENOTSOCK or ECONNREFUSED`); notSocketErrorFired = true; }); diff --git a/test/parallel/test-net-reconnect.js b/test/parallel/test-net-reconnect.js index b2e8f6ea8b4e..f8cdcbdc4e76 100644 --- a/test/parallel/test-net-reconnect.js +++ b/test/parallel/test-net-reconnect.js @@ -5,7 +5,6 @@ var assert = require('assert'); var net = require('net'); var N = 50; -var c = 0; var client_recv_count = 0; var client_end_count = 0; var disconnect_count = 0; diff --git a/test/parallel/test-net-server-connections.js b/test/parallel/test-net-server-connections.js index 138a78defb26..ae89d9aac7b3 100644 --- a/test/parallel/test-net-server-connections.js +++ b/test/parallel/test-net-server-connections.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var net = require('net'); diff --git a/test/parallel/test-net-server-unref-persistent.js b/test/parallel/test-net-server-unref-persistent.js index a071b625ef26..8e8f45f5fd7d 100644 --- a/test/parallel/test-net-server-unref-persistent.js +++ b/test/parallel/test-net-server-unref-persistent.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var net = require('net'); var closed = false; diff --git a/test/parallel/test-next-tick-domain.js b/test/parallel/test-next-tick-domain.js index 4d53bba6c4f5..8f9d9bb4aa50 100644 --- a/test/parallel/test-next-tick-domain.js +++ b/test/parallel/test-next-tick-domain.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var origNextTick = process.nextTick; diff --git a/test/parallel/test-next-tick-errors.js b/test/parallel/test-next-tick-errors.js index eccd7a43a082..7c511b8d5e18 100644 --- a/test/parallel/test-next-tick-errors.js +++ b/test/parallel/test-next-tick-errors.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var order = [], diff --git a/test/parallel/test-next-tick-intentional-starvation.js b/test/parallel/test-next-tick-intentional-starvation.js index d4a8a1b74813..414524e5405e 100644 --- a/test/parallel/test-next-tick-intentional-starvation.js +++ b/test/parallel/test-next-tick-intentional-starvation.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // this is the inverse of test-next-tick-starvation. diff --git a/test/parallel/test-next-tick-ordering.js b/test/parallel/test-next-tick-ordering.js index c2b936a1061d..63f8d37828e5 100644 --- a/test/parallel/test-next-tick-ordering.js +++ b/test/parallel/test-next-tick-ordering.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var i; diff --git a/test/parallel/test-next-tick-ordering2.js b/test/parallel/test-next-tick-ordering2.js index 4252d623679f..70f7611dbadd 100644 --- a/test/parallel/test-next-tick-ordering2.js +++ b/test/parallel/test-next-tick-ordering2.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var order = []; diff --git a/test/parallel/test-next-tick.js b/test/parallel/test-next-tick.js index 54e7b88cf022..8b45e8c705fc 100644 --- a/test/parallel/test-next-tick.js +++ b/test/parallel/test-next-tick.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var complete = 0; diff --git a/test/parallel/test-path-zero-length-strings.js b/test/parallel/test-path-zero-length-strings.js index 083eb3e7ac03..07de030aa0b3 100644 --- a/test/parallel/test-path-zero-length-strings.js +++ b/test/parallel/test-path-zero-length-strings.js @@ -5,7 +5,7 @@ // directory. This test makes sure that the behaviour is intact between commits. // See: https://github.com/nodejs/node/pull/2106 -const common = require('../common'); +require('../common'); const assert = require('assert'); const path = require('path'); const pwd = process.cwd(); diff --git a/test/parallel/test-pipe-return-val.js b/test/parallel/test-pipe-return-val.js index 718d052cd24c..eab5db8f70cf 100644 --- a/test/parallel/test-pipe-return-val.js +++ b/test/parallel/test-pipe-return-val.js @@ -1,10 +1,9 @@ 'use strict'; // This test ensures SourceStream.pipe(DestStream) returns DestStream -var common = require('../common'); +require('../common'); var Stream = require('stream').Stream; var assert = require('assert'); -var util = require('util'); var sourceStream = new Stream(); var destStream = new Stream(); diff --git a/test/parallel/test-preload.js b/test/parallel/test-preload.js index b4a3af78d8df..f30ad1d218e6 100644 --- a/test/parallel/test-preload.js +++ b/test/parallel/test-preload.js @@ -1,6 +1,6 @@ 'use strict'; -var common = require('../common'), - assert = require('assert'), +require('../common'); +var assert = require('assert'), path = require('path'), child_process = require('child_process'); @@ -82,7 +82,6 @@ child_process.exec(nodeBinary + ' ' }); // https://github.com/nodejs/node/issues/1691 -var originalCwd = process.cwd(); process.chdir(path.join(__dirname, '../fixtures/')); child_process.exec(nodeBinary + ' ' + '--expose_debug_as=v8debug ' diff --git a/test/parallel/test-process-before-exit.js b/test/parallel/test-process-before-exit.js index eff96da98e47..5d8855869a8e 100644 --- a/test/parallel/test-process-before-exit.js +++ b/test/parallel/test-process-before-exit.js @@ -1,6 +1,6 @@ 'use strict'; +require('../common'); var assert = require('assert'); -var common = require('../common'); var N = 5; var n = 0; diff --git a/test/parallel/test-process-config.js b/test/parallel/test-process-config.js index 4fc3bcaa98af..cedd773dfbea 100644 --- a/test/parallel/test-process-config.js +++ b/test/parallel/test-process-config.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var fs = require('fs'); var path = require('path'); diff --git a/test/parallel/test-process-env.js b/test/parallel/test-process-env.js index 7e927d09bae6..932bae3f8ff0 100644 --- a/test/parallel/test-process-env.js +++ b/test/parallel/test-process-env.js @@ -4,7 +4,7 @@ // first things first, set the timezone; see tzset(3) process.env.TZ = 'Europe/Amsterdam'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; diff --git a/test/parallel/test-process-exit-code.js b/test/parallel/test-process-exit-code.js index fea8c2d4fcdc..8d657528d055 100644 --- a/test/parallel/test-process-exit-code.js +++ b/test/parallel/test-process-exit-code.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); switch (process.argv[2]) { diff --git a/test/parallel/test-process-exit.js b/test/parallel/test-process-exit.js index 999eefc1eff5..0ea36f158eaf 100644 --- a/test/parallel/test-process-exit.js +++ b/test/parallel/test-process-exit.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // calling .exit() from within "exit" should not overflow the call stack diff --git a/test/parallel/test-process-getactivehandles.js b/test/parallel/test-process-getactivehandles.js new file mode 100644 index 000000000000..96464cf3b22f --- /dev/null +++ b/test/parallel/test-process-getactivehandles.js @@ -0,0 +1,44 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); +const NUM = 8; +const connections = []; +const clients = []; +var clients_counter = 0; + +const server = net.createServer(function listener(c) { + connections.push(c); +}).listen(common.PORT, function makeConnections() { + for (var i = 0; i < NUM; i++) { + net.connect(common.PORT, function connected() { + clientConnected(this); + }); + } +}); + + +function clientConnected(client) { + clients.push(client); + if (++clients_counter >= NUM) + checkAll(); +} + + +function checkAll() { + const handles = process._getActiveHandles(); + + clients.forEach(function(item) { + assert.ok(handles.indexOf(item) > -1); + item.destroy(); + }); + + connections.forEach(function(item) { + assert.ok(handles.indexOf(item) > -1); + item.end(); + }); + + assert.ok(handles.indexOf(server) > -1); + server.close(); +} diff --git a/test/parallel/test-process-getactiverequests.js b/test/parallel/test-process-getactiverequests.js index 4b7e0df1a502..30773f8f1138 100644 --- a/test/parallel/test-process-getactiverequests.js +++ b/test/parallel/test-process-getactiverequests.js @@ -1,6 +1,6 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const fs = require('fs'); diff --git a/test/parallel/test-process-getgroups.js b/test/parallel/test-process-getgroups.js index b18b5a0f2f90..08eab8d5a8af 100644 --- a/test/parallel/test-process-getgroups.js +++ b/test/parallel/test-process-getgroups.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var exec = require('child_process').exec; diff --git a/test/parallel/test-process-hrtime.js b/test/parallel/test-process-hrtime.js index 0e2c5b110e92..ad186a3507d1 100644 --- a/test/parallel/test-process-hrtime.js +++ b/test/parallel/test-process-hrtime.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // the default behavior, return an Array "tuple" of numbers diff --git a/test/parallel/test-process-kill-null.js b/test/parallel/test-process-kill-null.js index 65dab752f12e..2516773f0878 100644 --- a/test/parallel/test-process-kill-null.js +++ b/test/parallel/test-process-kill-null.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; diff --git a/test/parallel/test-process-kill-pid.js b/test/parallel/test-process-kill-pid.js index f193e979166d..5c11be2903c4 100644 --- a/test/parallel/test-process-kill-pid.js +++ b/test/parallel/test-process-kill-pid.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // test variants of pid diff --git a/test/parallel/test-process-next-tick.js b/test/parallel/test-process-next-tick.js index e7b5f8f3fe88..6b20cfbe9337 100644 --- a/test/parallel/test-process-next-tick.js +++ b/test/parallel/test-process-next-tick.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var N = 2; var tickCount = 0; diff --git a/test/parallel/test-process-raw-debug.js b/test/parallel/test-process-raw-debug.js index f849457d6438..ab461902911a 100644 --- a/test/parallel/test-process-raw-debug.js +++ b/test/parallel/test-process-raw-debug.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var os = require('os'); diff --git a/test/parallel/test-process-wrap.js b/test/parallel/test-process-wrap.js index bf3dfe4e8b16..b5d4dc35e4fe 100644 --- a/test/parallel/test-process-wrap.js +++ b/test/parallel/test-process-wrap.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Process = process.binding('process_wrap').Process; var Pipe = process.binding('pipe_wrap').Pipe; diff --git a/test/parallel/test-promises-unhandled-rejections.js b/test/parallel/test-promises-unhandled-rejections.js index e229bada3a10..5e7739daa5b4 100644 --- a/test/parallel/test-promises-unhandled-rejections.js +++ b/test/parallel/test-promises-unhandled-rejections.js @@ -185,12 +185,11 @@ asyncTest('When re-throwing new errors in a promise catch, only the' + asyncTest('Test params of unhandledRejection for a synchronously-rejected' + 'promise', function(done) { var e = new Error(); - var e2 = new Error(); onUnhandledSucceed(done, function(reason, promise) { assert.strictEqual(e, reason); assert.strictEqual(promise, promise); }); - var promise = Promise.reject(e); + Promise.reject(e); }); asyncTest('When re-throwing new errors in a promise catch, only the ' + @@ -629,7 +628,7 @@ asyncTest('Promise unhandledRejection handler does not interfere with domain' + assert.strictEqual(domainReceivedError, domainError); d.dispose(); }); - var a = Promise.reject(e); + Promise.reject(e); process.nextTick(function() { throw domainError; }); diff --git a/test/parallel/test-punycode.js b/test/parallel/test-punycode.js index 179bca51ec2f..42927549eae3 100644 --- a/test/parallel/test-punycode.js +++ b/test/parallel/test-punycode.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var punycode = require('punycode'); var assert = require('assert'); diff --git a/test/parallel/test-querystring-multichar-separator.js b/test/parallel/test-querystring-multichar-separator.js index 257492659bdf..488b5ac56aef 100644 --- a/test/parallel/test-querystring-multichar-separator.js +++ b/test/parallel/test-querystring-multichar-separator.js @@ -1,5 +1,5 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const qs = require('querystring'); diff --git a/test/parallel/test-querystring.js b/test/parallel/test-querystring.js index 66497ac2d3b6..bb3c361f882a 100644 --- a/test/parallel/test-querystring.js +++ b/test/parallel/test-querystring.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // test using assert diff --git a/test/parallel/test-readdouble.js b/test/parallel/test-readdouble.js index c0dab8956593..6c55a65007aa 100644 --- a/test/parallel/test-readdouble.js +++ b/test/parallel/test-readdouble.js @@ -2,7 +2,7 @@ /* * Tests to verify we're reading in doubles correctly */ -var common = require('../common'); +require('../common'); var ASSERT = require('assert'); /* diff --git a/test/parallel/test-readfloat.js b/test/parallel/test-readfloat.js index 5572bbf18e29..468faf760296 100644 --- a/test/parallel/test-readfloat.js +++ b/test/parallel/test-readfloat.js @@ -2,7 +2,7 @@ /* * Tests to verify we're reading in floats correctly */ -var common = require('../common'); +require('../common'); var ASSERT = require('assert'); /* diff --git a/test/parallel/test-readint.js b/test/parallel/test-readint.js index 233128d792d0..b3997f74f177 100644 --- a/test/parallel/test-readint.js +++ b/test/parallel/test-readint.js @@ -2,7 +2,7 @@ /* * Tests to verify we're reading in signed integers correctly */ -var common = require('../common'); +require('../common'); var ASSERT = require('assert'); /* diff --git a/test/parallel/test-readline-keys.js b/test/parallel/test-readline-keys.js index 5cac38a1d7db..e026c0b583cd 100644 --- a/test/parallel/test-readline-keys.js +++ b/test/parallel/test-readline-keys.js @@ -1,6 +1,5 @@ 'use strict'; require('../common'); -var EventEmitter = require('events').EventEmitter; var PassThrough = require('stream').PassThrough; var assert = require('assert'); var inherits = require('util').inherits; @@ -16,7 +15,7 @@ inherits(FakeInput, PassThrough); var fi = new FakeInput(); var fo = new FakeInput(); -var rli = new Interface({ input: fi, output: fo, terminal: true }); +new Interface({ input: fi, output: fo, terminal: true }); var keys = []; fi.on('keypress', function(s, k) { diff --git a/test/parallel/test-readline-undefined-columns.js b/test/parallel/test-readline-undefined-columns.js index 73945af8bc52..24f138f46bce 100644 --- a/test/parallel/test-readline-undefined-columns.js +++ b/test/parallel/test-readline-undefined-columns.js @@ -11,7 +11,7 @@ const readline = require('readline'); const iStream = new PassThrough(); const oStream = new PassThrough(); -const rli = readline.createInterface({ +readline.createInterface({ terminal: true, input: iStream, output: oStream, diff --git a/test/parallel/test-readuint.js b/test/parallel/test-readuint.js index b984541bfe9e..154af1841a98 100644 --- a/test/parallel/test-readuint.js +++ b/test/parallel/test-readuint.js @@ -3,7 +3,7 @@ * A battery of tests to help us read a series of uints */ -var common = require('../common'); +require('../common'); var ASSERT = require('assert'); /* diff --git a/test/parallel/test-ref-unref-return.js b/test/parallel/test-ref-unref-return.js index a82a433ab1af..89ac52d2bcaa 100644 --- a/test/parallel/test-ref-unref-return.js +++ b/test/parallel/test-ref-unref-return.js @@ -1,8 +1,8 @@ 'use strict'; +require('../common'); var assert = require('assert'); var net = require('net'); var dgram = require('dgram'); -var common = require('../common'); assert.ok((new net.Server()).ref() instanceof net.Server); assert.ok((new net.Server()).unref() instanceof net.Server); diff --git a/test/parallel/test-regress-GH-4256.js b/test/parallel/test-regress-GH-4256.js index 1a4a78b3c078..a312fb277fda 100644 --- a/test/parallel/test-regress-GH-4256.js +++ b/test/parallel/test-regress-GH-4256.js @@ -1,6 +1,6 @@ 'use strict'; require('../common'); process.domain = null; -var timer = setTimeout(function() { +setTimeout(function() { console.log('this console.log statement should not make node crash'); }, 1); diff --git a/test/parallel/test-regress-GH-6235.js b/test/parallel/test-regress-GH-6235.js index 2f2f17d9698f..0bf9b8965d11 100644 --- a/test/parallel/test-regress-GH-6235.js +++ b/test/parallel/test-regress-GH-6235.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); assert.doesNotThrow(function() { diff --git a/test/parallel/test-regress-GH-7511.js b/test/parallel/test-regress-GH-7511.js index 0e5c4ded011a..03813dea003e 100644 --- a/test/parallel/test-regress-GH-7511.js +++ b/test/parallel/test-regress-GH-7511.js @@ -1,6 +1,6 @@ 'use strict'; -var common = require('../common'), - assert = require('assert'), +require('../common'); +var assert = require('assert'), vm = require('vm'); assert.doesNotThrow(function() { diff --git a/test/parallel/test-regress-GH-897.js b/test/parallel/test-regress-GH-897.js index 4b7ba61f9cec..1b46994dc37d 100644 --- a/test/parallel/test-regress-GH-897.js +++ b/test/parallel/test-regress-GH-897.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var t = Date.now(); diff --git a/test/parallel/test-repl-.save.load.js b/test/parallel/test-repl-.save.load.js index c71b383bcd74..6d28015b385e 100644 --- a/test/parallel/test-repl-.save.load.js +++ b/test/parallel/test-repl-.save.load.js @@ -1,6 +1,5 @@ 'use strict'; var assert = require('assert'); -var util = require('util'); var join = require('path').join; var fs = require('fs'); var common = require('../common'); diff --git a/test/parallel/test-repl-autolibs.js b/test/parallel/test-repl-autolibs.js index 05cc299f5688..15f779d3b122 100644 --- a/test/parallel/test-repl-autolibs.js +++ b/test/parallel/test-repl-autolibs.js @@ -8,7 +8,7 @@ var repl = require('repl'); common.globalCheck = false; const putIn = new common.ArrayStream(); -var testMe = repl.start('', putIn, null, true); +repl.start('', putIn, null, true); test1(); diff --git a/test/parallel/test-repl-domain.js b/test/parallel/test-repl-domain.js index baf0485b3b80..adc8478beef4 100644 --- a/test/parallel/test-repl-domain.js +++ b/test/parallel/test-repl-domain.js @@ -1,12 +1,10 @@ 'use strict'; -var assert = require('assert'); var common = require('../common'); -var util = require('util'); var repl = require('repl'); const putIn = new common.ArrayStream(); -var testMe = repl.start('', putIn); +repl.start('', putIn); putIn.write = function(data) { // Don't use assert for this because the domain might catch it, and diff --git a/test/parallel/test-repl-envvars.js b/test/parallel/test-repl-envvars.js index 607314408584..2c34bbf2da86 100644 --- a/test/parallel/test-repl-envvars.js +++ b/test/parallel/test-repl-envvars.js @@ -2,7 +2,7 @@ // Flags: --expose-internals -const common = require('../common'); +require('../common'); const stream = require('stream'); const REPL = require('internal/repl'); const assert = require('assert'); diff --git a/test/parallel/test-repl-harmony.js b/test/parallel/test-repl-harmony.js index 6bc5cb57aa11..a5928800381c 100644 --- a/test/parallel/test-repl-harmony.js +++ b/test/parallel/test-repl-harmony.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; diff --git a/test/parallel/test-repl-persistent-history.js b/test/parallel/test-repl-persistent-history.js index 10e0dedf53ec..7571527b7380 100644 --- a/test/parallel/test-repl-persistent-history.js +++ b/test/parallel/test-repl-persistent-history.js @@ -7,7 +7,6 @@ const stream = require('stream'); const REPL = require('internal/repl'); const assert = require('assert'); const fs = require('fs'); -const util = require('util'); const path = require('path'); const os = require('os'); @@ -66,6 +65,10 @@ const homedirErr = '\nError: Could not get the home directory.\n' + 'REPL session history will not be persisted.\n'; const replFailedRead = '\nError: Could not open history file.\n' + 'REPL session history will not be persisted.\n'; +const sameHistoryFilePaths = '\nThe old repl history file has the same name ' + + 'and location as the new one i.e., ' + + path.join(common.tmpDir, '.node_repl_history') + + ' and is empty.\nUsing it as is.\n'; // File paths const fixtures = path.join(common.testDir, 'fixtures'); const historyFixturePath = path.join(fixtures, '.node_repl_history'); @@ -73,9 +76,9 @@ const historyPath = path.join(common.tmpDir, '.fixture_copy_repl_history'); const historyPathFail = path.join(common.tmpDir, '.node_repl\u0000_history'); const oldHistoryPath = path.join(fixtures, 'old-repl-history-file.json'); const enoentHistoryPath = path.join(fixtures, 'enoent-repl-history-file.json'); +const emptyHistoryPath = path.join(fixtures, '.empty-repl-history-file'); const defaultHistoryPath = path.join(common.tmpDir, '.node_repl_history'); - const tests = [{ env: { NODE_REPL_HISTORY: '' }, test: [UP], @@ -93,6 +96,16 @@ const tests = [{ test: [UP], expected: [prompt, replDisabled, prompt] }, +{ + env: { NODE_REPL_HISTORY_FILE: emptyHistoryPath }, + test: [UP], + expected: [prompt, convertMsg, prompt] +}, +{ + env: { NODE_REPL_HISTORY_FILE: defaultHistoryPath }, + test: [UP], + expected: [prompt, sameHistoryFilePaths, prompt] +}, { env: { NODE_REPL_HISTORY: historyPath }, test: [UP, CLEAR], diff --git a/test/parallel/test-repl-require-cache.js b/test/parallel/test-repl-require-cache.js index d9b4d71d4846..c5f317ac268e 100644 --- a/test/parallel/test-repl-require-cache.js +++ b/test/parallel/test-repl-require-cache.js @@ -1,6 +1,6 @@ 'use strict'; -var common = require('../common'), - assert = require('assert'), +require('../common'); +var assert = require('assert'), repl = require('repl'); // https://github.com/joyent/node/issues/3226 diff --git a/test/parallel/test-repl-setprompt.js b/test/parallel/test-repl-setprompt.js index f2c65583b365..2708a3e6af54 100644 --- a/test/parallel/test-repl-setprompt.js +++ b/test/parallel/test-repl-setprompt.js @@ -1,5 +1,5 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const spawn = require('child_process').spawn; const os = require('os'); diff --git a/test/parallel/test-repl-syntax-error-handling.js b/test/parallel/test-repl-syntax-error-handling.js index 66e8fb6b352c..10166b4f06a6 100644 --- a/test/parallel/test-repl-syntax-error-handling.js +++ b/test/parallel/test-repl-syntax-error-handling.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); switch (process.argv[2]) { diff --git a/test/parallel/test-repl-syntax-error-stack.js b/test/parallel/test-repl-syntax-error-stack.js index 647d3e3569ce..ebf0b2e4d8ae 100644 --- a/test/parallel/test-repl-syntax-error-stack.js +++ b/test/parallel/test-repl-syntax-error-stack.js @@ -4,7 +4,6 @@ const common = require('../common'); const assert = require('assert'); const path = require('path'); const repl = require('repl'); -const util = require('util'); let found = false; process.on('exit', () => { @@ -17,7 +16,7 @@ common.ArrayStream.prototype.write = function(output) { }; const putIn = new common.ArrayStream(); -const testMe = repl.start('', putIn); +repl.start('', putIn); let file = path.resolve(__dirname, '../fixtures/syntax/bad_syntax'); if (common.isWindows) diff --git a/test/parallel/test-repl-tab-complete-crash.js b/test/parallel/test-repl-tab-complete-crash.js index 484580f1e72f..ce2837574381 100644 --- a/test/parallel/test-repl-tab-complete-crash.js +++ b/test/parallel/test-repl-tab-complete-crash.js @@ -2,7 +2,6 @@ const common = require('../common'); const assert = require('assert'); -const util = require('util'); const repl = require('repl'); var referenceErrorCount = 0; diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index 6bf7d5059d01..86a0444c953d 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -4,7 +4,6 @@ var common = require('../common'); var assert = require('assert'); -var util = require('util'); var repl = require('repl'); var referenceErrors = 0; var expectedReferenceErrors = 0; diff --git a/test/parallel/test-repl-tab.js b/test/parallel/test-repl-tab.js index 1ab3b4743913..6474d8e40881 100644 --- a/test/parallel/test-repl-tab.js +++ b/test/parallel/test-repl-tab.js @@ -1,7 +1,6 @@ 'use strict'; require('../common'); var assert = require('assert'); -var util = require('util'); var repl = require('repl'); var zlib = require('zlib'); diff --git a/test/parallel/test-repl-unexpected-token-recoverable.js b/test/parallel/test-repl-unexpected-token-recoverable.js index 4cfaa5136b6a..84668c8657c4 100644 --- a/test/parallel/test-repl-unexpected-token-recoverable.js +++ b/test/parallel/test-repl-unexpected-token-recoverable.js @@ -2,7 +2,7 @@ /* * This is a regression test for https://github.com/joyent/node/issues/8874. */ -var common = require('../common'); +require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; diff --git a/test/parallel/test-require-cache.js b/test/parallel/test-require-cache.js index f2245345e3e4..7ea68dd05157 100644 --- a/test/parallel/test-require-cache.js +++ b/test/parallel/test-require-cache.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); (function testInjectFakeModule() { diff --git a/test/parallel/test-require-extensions-main.js b/test/parallel/test-require-extensions-main.js index 198fa6a8c52d..0376082262dd 100644 --- a/test/parallel/test-require-extensions-main.js +++ b/test/parallel/test-require-extensions-main.js @@ -1,5 +1,4 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); require(common.fixturesDir + '/require-bin/bin/req.js'); diff --git a/test/parallel/test-signal-safety.js b/test/parallel/test-signal-safety.js index 549c26662f71..7938ae04d659 100644 --- a/test/parallel/test-signal-safety.js +++ b/test/parallel/test-signal-safety.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Signal = process.binding('signal_wrap').Signal; diff --git a/test/parallel/test-stdin-hang.js b/test/parallel/test-stdin-hang.js index 4818a9ee9520..bb43d52506e5 100644 --- a/test/parallel/test-stdin-hang.js +++ b/test/parallel/test-stdin-hang.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); // This test *only* verifies that invoking the stdin getter does not // cause node to hang indefinitely. diff --git a/test/parallel/test-stdio-readable-writable.js b/test/parallel/test-stdio-readable-writable.js index f8a8923498cb..7b9b69d309ae 100644 --- a/test/parallel/test-stdio-readable-writable.js +++ b/test/parallel/test-stdio-readable-writable.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); assert(process.stdout.writable); diff --git a/test/parallel/test-stdout-close-unref.js b/test/parallel/test-stdout-close-unref.js index 12a031562bf6..37ab4987eebc 100644 --- a/test/parallel/test-stdout-close-unref.js +++ b/test/parallel/test-stdout-close-unref.js @@ -1,6 +1,6 @@ 'use strict'; +require('../common'); var assert = require('assert'); -var common = require('../common'); var errs = 0; diff --git a/test/parallel/test-stream-big-packet.js b/test/parallel/test-stream-big-packet.js index a9f6064c7e72..67bb32847bd7 100644 --- a/test/parallel/test-stream-big-packet.js +++ b/test/parallel/test-stream-big-packet.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var util = require('util'); var stream = require('stream'); diff --git a/test/parallel/test-stream-big-push.js b/test/parallel/test-stream-big-push.js index e02ff98d3c74..b46665efc94f 100644 --- a/test/parallel/test-stream-big-push.js +++ b/test/parallel/test-stream-big-push.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var stream = require('stream'); var str = 'asdfasdfasdfasdfasdf'; diff --git a/test/parallel/test-stream-duplex.js b/test/parallel/test-stream-duplex.js index 0e8789d6bf55..200de24877bf 100644 --- a/test/parallel/test-stream-duplex.js +++ b/test/parallel/test-stream-duplex.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Duplex = require('stream').Transform; diff --git a/test/parallel/test-stream-end-paused.js b/test/parallel/test-stream-end-paused.js index 585d6c327fd5..9cc32db880ea 100644 --- a/test/parallel/test-stream-end-paused.js +++ b/test/parallel/test-stream-end-paused.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var gotEnd = false; diff --git a/test/parallel/test-stream-ispaused.js b/test/parallel/test-stream-ispaused.js index 8112dc733a72..38f8da3fd512 100644 --- a/test/parallel/test-stream-ispaused.js +++ b/test/parallel/test-stream-ispaused.js @@ -1,6 +1,6 @@ 'use strict'; +require('../common'); var assert = require('assert'); -var common = require('../common'); var stream = require('stream'); diff --git a/test/parallel/test-stream-pipe-after-end.js b/test/parallel/test-stream-pipe-after-end.js index 4bead73f68ce..258c9330a960 100644 --- a/test/parallel/test-stream-pipe-after-end.js +++ b/test/parallel/test-stream-pipe-after-end.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Readable = require('_stream_readable'); diff --git a/test/parallel/test-stream-pipe-cleanup-pause.js b/test/parallel/test-stream-pipe-cleanup-pause.js index b38f57a4ff0b..332930c813a3 100644 --- a/test/parallel/test-stream-pipe-cleanup-pause.js +++ b/test/parallel/test-stream-pipe-cleanup-pause.js @@ -1,6 +1,5 @@ 'use strict'; const common = require('../common'); -const assert = require('assert'); const stream = require('stream'); const reader = new stream.Readable(); diff --git a/test/parallel/test-stream-pipe-cleanup.js b/test/parallel/test-stream-pipe-cleanup.js index 08da96f92c3a..251695c9f723 100644 --- a/test/parallel/test-stream-pipe-cleanup.js +++ b/test/parallel/test-stream-pipe-cleanup.js @@ -2,7 +2,7 @@ // This test asserts that Stream.prototype.pipe does not leave listeners // hanging on the source or dest. -var common = require('../common'); +require('../common'); var stream = require('stream'); var assert = require('assert'); var util = require('util'); diff --git a/test/parallel/test-stream-pipe-error-handling.js b/test/parallel/test-stream-pipe-error-handling.js index 031a0da7e395..88a70fb58e2c 100644 --- a/test/parallel/test-stream-pipe-error-handling.js +++ b/test/parallel/test-stream-pipe-error-handling.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Stream = require('stream').Stream; @@ -38,7 +38,6 @@ var Stream = require('stream').Stream; })(); (function testErrorWithRemovedListenerThrows() { - var EE = require('events').EventEmitter; var R = Stream.Readable; var W = Stream.Writable; @@ -73,7 +72,6 @@ var Stream = require('stream').Stream; })(); (function testErrorWithRemovedListenerThrows() { - var EE = require('events').EventEmitter; var R = Stream.Readable; var W = Stream.Writable; diff --git a/test/parallel/test-stream-pipe-event.js b/test/parallel/test-stream-pipe-event.js index 0d10533b0c49..d8601dd04a4d 100644 --- a/test/parallel/test-stream-pipe-event.js +++ b/test/parallel/test-stream-pipe-event.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var stream = require('stream'); var assert = require('assert'); var util = require('util'); diff --git a/test/parallel/test-stream-push-order.js b/test/parallel/test-stream-push-order.js index d67233aff7a4..f09cf95f370b 100644 --- a/test/parallel/test-stream-push-order.js +++ b/test/parallel/test-stream-push-order.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var Readable = require('stream').Readable; var assert = require('assert'); @@ -21,7 +21,7 @@ s._read = function(n) { } }; -var v = s.read(0); +s.read(0); // ACTUALLY [1, 3, 5, 6, 4, 2] diff --git a/test/parallel/test-stream-push-strings.js b/test/parallel/test-stream-push-strings.js index 0d9c0653c0dc..21621ff3fd11 100644 --- a/test/parallel/test-stream-push-strings.js +++ b/test/parallel/test-stream-push-strings.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Readable = require('stream').Readable; diff --git a/test/parallel/test-stream-readable-constructor-set-methods.js b/test/parallel/test-stream-readable-constructor-set-methods.js index 928ce31a8ebe..fb2114f44dad 100644 --- a/test/parallel/test-stream-readable-constructor-set-methods.js +++ b/test/parallel/test-stream-readable-constructor-set-methods.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Readable = require('stream').Readable; diff --git a/test/parallel/test-stream-readable-event.js b/test/parallel/test-stream-readable-event.js index 965fc82c05a1..10d314f4eec2 100644 --- a/test/parallel/test-stream-readable-event.js +++ b/test/parallel/test-stream-readable-event.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Readable = require('stream').Readable; diff --git a/test/parallel/test-stream-readable-flow-recursion.js b/test/parallel/test-stream-readable-flow-recursion.js index 07edd579f1de..57e295e53835 100644 --- a/test/parallel/test-stream-readable-flow-recursion.js +++ b/test/parallel/test-stream-readable-flow-recursion.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // this test verifies that passing a huge number to read(size) diff --git a/test/parallel/test-stream-transform-constructor-set-methods.js b/test/parallel/test-stream-transform-constructor-set-methods.js index c24c273b6f20..bf76b93690c8 100644 --- a/test/parallel/test-stream-transform-constructor-set-methods.js +++ b/test/parallel/test-stream-transform-constructor-set-methods.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Transform = require('stream').Transform; diff --git a/test/parallel/test-stream-transform-objectmode-falsey-value.js b/test/parallel/test-stream-transform-objectmode-falsey-value.js index 762f0500ad3e..eeb3d3f4ccc6 100644 --- a/test/parallel/test-stream-transform-objectmode-falsey-value.js +++ b/test/parallel/test-stream-transform-objectmode-falsey-value.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var stream = require('stream'); diff --git a/test/parallel/test-stream-transform-split-objectmode.js b/test/parallel/test-stream-transform-split-objectmode.js index 24833ece051e..4e33028da2f7 100644 --- a/test/parallel/test-stream-transform-split-objectmode.js +++ b/test/parallel/test-stream-transform-split-objectmode.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Transform = require('stream').Transform; diff --git a/test/parallel/test-stream-unshift-empty-chunk.js b/test/parallel/test-stream-unshift-empty-chunk.js index a7dcad425310..0da979e33748 100644 --- a/test/parallel/test-stream-unshift-empty-chunk.js +++ b/test/parallel/test-stream-unshift-empty-chunk.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // This test verifies that stream.unshift(Buffer(0)) or diff --git a/test/parallel/test-stream-unshift-read-race.js b/test/parallel/test-stream-unshift-read-race.js index 90f519b5b5d7..8239a380def6 100644 --- a/test/parallel/test-stream-unshift-read-race.js +++ b/test/parallel/test-stream-unshift-read-race.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // This test verifies that: @@ -13,7 +13,6 @@ var stream = require('stream'); var hwm = 10; var r = stream.Readable({ highWaterMark: hwm }); var chunks = 10; -var t = (chunks * 5); var data = new Buffer(chunks * hwm + Math.ceil(hwm / 2)); for (var i = 0; i < data.length; i++) { diff --git a/test/parallel/test-stream-wrap.js b/test/parallel/test-stream-wrap.js index e7a7ecddd238..5a8b75d4dc1f 100644 --- a/test/parallel/test-stream-wrap.js +++ b/test/parallel/test-stream-wrap.js @@ -1,5 +1,5 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const StreamWrap = require('_stream_wrap'); diff --git a/test/parallel/test-stream-writable-change-default-encoding.js b/test/parallel/test-stream-writable-change-default-encoding.js index a6fcda3e62a5..d8193123d6f3 100644 --- a/test/parallel/test-stream-writable-change-default-encoding.js +++ b/test/parallel/test-stream-writable-change-default-encoding.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var stream = require('stream'); diff --git a/test/parallel/test-stream-writable-constructor-set-methods.js b/test/parallel/test-stream-writable-constructor-set-methods.js index 47fc458ce971..4a5f90216070 100644 --- a/test/parallel/test-stream-writable-constructor-set-methods.js +++ b/test/parallel/test-stream-writable-constructor-set-methods.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Writable = require('stream').Writable; diff --git a/test/parallel/test-stream-writable-decoded-encoding.js b/test/parallel/test-stream-writable-decoded-encoding.js index b637838c0c65..b5f1b4f6b73f 100644 --- a/test/parallel/test-stream-writable-decoded-encoding.js +++ b/test/parallel/test-stream-writable-decoded-encoding.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var stream = require('stream'); diff --git a/test/parallel/test-stream-writev.js b/test/parallel/test-stream-writev.js index f73270f2ff53..5b07dd11198e 100644 --- a/test/parallel/test-stream-writev.js +++ b/test/parallel/test-stream-writev.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var stream = require('stream'); @@ -30,11 +30,9 @@ function test(decode, uncork, multi, next) { function cnt(msg) { expectCount++; var expect = expectCount; - var called = false; return function(er) { if (er) throw er; - called = true; counter++; assert.equal(counter, expect); }; diff --git a/test/parallel/test-stream2-base64-single-char-read-end.js b/test/parallel/test-stream2-base64-single-char-read-end.js index 2d60877de836..900e090921b7 100644 --- a/test/parallel/test-stream2-base64-single-char-read-end.js +++ b/test/parallel/test-stream2-base64-single-char-read-end.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var R = require('_stream_readable'); var W = require('_stream_writable'); var assert = require('assert'); diff --git a/test/parallel/test-stream2-compatibility.js b/test/parallel/test-stream2-compatibility.js index cbb65facfa70..2d62d6390776 100644 --- a/test/parallel/test-stream2-compatibility.js +++ b/test/parallel/test-stream2-compatibility.js @@ -1,11 +1,10 @@ 'use strict'; -var common = require('../common'); +require('../common'); var R = require('_stream_readable'); var W = require('_stream_writable'); var assert = require('assert'); var util = require('util'); -var EE = require('events').EventEmitter; var ondataCalled = 0; diff --git a/test/parallel/test-stream2-finish-pipe.js b/test/parallel/test-stream2-finish-pipe.js index 913bb7b0b4db..63c78759cab6 100644 --- a/test/parallel/test-stream2-finish-pipe.js +++ b/test/parallel/test-stream2-finish-pipe.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var stream = require('stream'); var Buffer = require('buffer').Buffer; diff --git a/test/parallel/test-stream2-large-read-stall.js b/test/parallel/test-stream2-large-read-stall.js index 4cd89599fee7..6a38baac5dac 100644 --- a/test/parallel/test-stream2-large-read-stall.js +++ b/test/parallel/test-stream2-large-read-stall.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // If everything aligns so that you do a read(n) of exactly the @@ -53,9 +53,6 @@ function push() { setTimeout(push); } -// start the flow -var ret = r.read(0); - process.on('exit', function() { assert.equal(pushes, PUSHCOUNT + 1); assert(endEmitted); diff --git a/test/parallel/test-stream2-objects.js b/test/parallel/test-stream2-objects.js index a2f554a0b8a0..e67359eff2b2 100644 --- a/test/parallel/test-stream2-objects.js +++ b/test/parallel/test-stream2-objects.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var Readable = require('_stream_readable'); var Writable = require('_stream_writable'); var assert = require('assert'); @@ -167,8 +167,6 @@ test('read(0) for object streams', function(t) { r.push('foobar'); r.push(null); - var v = r.read(0); - r.pipe(toArray(function(array) { assert.deepEqual(array, ['foobar']); diff --git a/test/parallel/test-stream2-pipe-error-handling.js b/test/parallel/test-stream2-pipe-error-handling.js index 9eddbdd90d00..7d7cfb6b2b33 100644 --- a/test/parallel/test-stream2-pipe-error-handling.js +++ b/test/parallel/test-stream2-pipe-error-handling.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var stream = require('stream'); diff --git a/test/parallel/test-stream2-pipe-error-once-listener.js b/test/parallel/test-stream2-pipe-error-once-listener.js index f2ecb87ce97a..d046c5ea55e4 100644 --- a/test/parallel/test-stream2-pipe-error-once-listener.js +++ b/test/parallel/test-stream2-pipe-error-once-listener.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); var util = require('util'); var stream = require('stream'); diff --git a/test/parallel/test-stream2-push.js b/test/parallel/test-stream2-push.js index b58bce143585..99b73d7277aa 100644 --- a/test/parallel/test-stream2-push.js +++ b/test/parallel/test-stream2-push.js @@ -1,11 +1,10 @@ 'use strict'; -var common = require('../common'); +require('../common'); var stream = require('stream'); var Readable = stream.Readable; var Writable = stream.Writable; var assert = require('assert'); -var util = require('util'); var EE = require('events').EventEmitter; diff --git a/test/parallel/test-stream2-read-sync-stack.js b/test/parallel/test-stream2-read-sync-stack.js index e912e1039ff5..4bce87ffb9df 100644 --- a/test/parallel/test-stream2-read-sync-stack.js +++ b/test/parallel/test-stream2-read-sync-stack.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Readable = require('stream').Readable; var r = new Readable(); diff --git a/test/parallel/test-stream2-readable-empty-buffer-no-eof.js b/test/parallel/test-stream2-readable-empty-buffer-no-eof.js index 8e4001f8022f..18012df3a41d 100644 --- a/test/parallel/test-stream2-readable-empty-buffer-no-eof.js +++ b/test/parallel/test-stream2-readable-empty-buffer-no-eof.js @@ -1,14 +1,14 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +const common = require('../common'); +const assert = require('assert'); -var Readable = require('stream').Readable; +const Readable = require('stream').Readable; test1(); test2(); function test1() { - var r = new Readable(); + const r = new Readable(); // should not end when we get a Buffer(0) or '' as the _read result // that just means that there is *temporarily* no data, but to go @@ -20,9 +20,9 @@ function test1() { // r.read(0) again later, otherwise there is no more work being done // and the process just exits. - var buf = new Buffer(5); - buf.fill('x'); - var reads = 5; + const buf = Buffer(5).fill('x'); + let reads = 5; + const timeout = common.platformTimeout(50); r._read = function(n) { switch (reads--) { case 0: @@ -30,15 +30,15 @@ function test1() { case 1: return r.push(buf); case 2: - setTimeout(r.read.bind(r, 0), 50); + setTimeout(r.read.bind(r, 0), timeout); return r.push(new Buffer(0)); // Not-EOF! case 3: - setTimeout(r.read.bind(r, 0), 50); + setTimeout(r.read.bind(r, 0), timeout); return process.nextTick(function() { return r.push(new Buffer(0)); }); case 4: - setTimeout(r.read.bind(r, 0), 50); + setTimeout(r.read.bind(r, 0), timeout); return setTimeout(function() { return r.push(new Buffer(0)); }); @@ -51,9 +51,9 @@ function test1() { } }; - var results = []; + const results = []; function flow() { - var chunk; + let chunk; while (null !== (chunk = r.read())) results.push(chunk + ''); } diff --git a/test/parallel/test-stream2-readable-from-list.js b/test/parallel/test-stream2-readable-from-list.js index a8d9fb38f250..ab9d9c5d72ca 100644 --- a/test/parallel/test-stream2-readable-from-list.js +++ b/test/parallel/test-stream2-readable-from-list.js @@ -1,6 +1,6 @@ 'use strict'; +require('../common'); var assert = require('assert'); -var common = require('../common'); var fromList = require('_stream_readable')._fromList; // tiny node-tap lookalike. @@ -39,8 +39,6 @@ process.nextTick(run); test('buffers', function(t) { - // have a length - var len = 16; var list = [ new Buffer('foog'), new Buffer('bark'), new Buffer('bazy'), @@ -69,8 +67,6 @@ test('buffers', function(t) { }); test('strings', function(t) { - // have a length - var len = 16; var list = [ 'foog', 'bark', 'bazy', diff --git a/test/parallel/test-stream2-readable-legacy-drain.js b/test/parallel/test-stream2-readable-legacy-drain.js index 4218bace2b87..399771e46a11 100644 --- a/test/parallel/test-stream2-readable-legacy-drain.js +++ b/test/parallel/test-stream2-readable-legacy-drain.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Stream = require('stream'); diff --git a/test/parallel/test-stream2-readable-non-empty-end.js b/test/parallel/test-stream2-readable-non-empty-end.js index 46d6f92f2b9d..1953503ef9be 100644 --- a/test/parallel/test-stream2-readable-non-empty-end.js +++ b/test/parallel/test-stream2-readable-non-empty-end.js @@ -1,6 +1,6 @@ 'use strict'; +require('../common'); var assert = require('assert'); -var common = require('../common'); var Readable = require('_stream_readable'); var len = 0; diff --git a/test/parallel/test-stream2-readable-wrap-empty.js b/test/parallel/test-stream2-readable-wrap-empty.js index 60417ca89330..d2bf8f3f306f 100644 --- a/test/parallel/test-stream2-readable-wrap-empty.js +++ b/test/parallel/test-stream2-readable-wrap-empty.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Readable = require('_stream_readable'); diff --git a/test/parallel/test-stream2-readable-wrap.js b/test/parallel/test-stream2-readable-wrap.js index 8e3e04b96601..acf1cfdb0304 100644 --- a/test/parallel/test-stream2-readable-wrap.js +++ b/test/parallel/test-stream2-readable-wrap.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Readable = require('_stream_readable'); diff --git a/test/parallel/test-stream2-set-encoding.js b/test/parallel/test-stream2-set-encoding.js index ea9a315cb1a6..40e09035a98e 100644 --- a/test/parallel/test-stream2-set-encoding.js +++ b/test/parallel/test-stream2-set-encoding.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var R = require('_stream_readable'); var util = require('util'); diff --git a/test/parallel/test-stream2-transform.js b/test/parallel/test-stream2-transform.js index e45c913c94f5..11ee45915c83 100644 --- a/test/parallel/test-stream2-transform.js +++ b/test/parallel/test-stream2-transform.js @@ -1,6 +1,6 @@ 'use strict'; +require('../common'); var assert = require('assert'); -var common = require('../common'); var PassThrough = require('_stream_passthrough'); var Transform = require('_stream_transform'); @@ -303,13 +303,10 @@ test('passthrough event emission', function(t) { var pt = new PassThrough(); var emits = 0; pt.on('readable', function() { - var state = pt._readableState; console.error('>>> emit readable %d', emits); emits++; }); - var i = 0; - pt.write(new Buffer('foog')); console.error('need emit 0'); diff --git a/test/parallel/test-stream2-unpipe-leak.js b/test/parallel/test-stream2-unpipe-leak.js index 15b510e7f643..3b529bac1f2e 100644 --- a/test/parallel/test-stream2-unpipe-leak.js +++ b/test/parallel/test-stream2-unpipe-leak.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var stream = require('stream'); diff --git a/test/parallel/test-stream2-writable.js b/test/parallel/test-stream2-writable.js index 1d87d7f920c0..81e57d06eb3b 100644 --- a/test/parallel/test-stream2-writable.js +++ b/test/parallel/test-stream2-writable.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var W = require('_stream_writable'); var D = require('_stream_duplex'); var assert = require('assert'); diff --git a/test/parallel/test-stream3-pause-then-read.js b/test/parallel/test-stream3-pause-then-read.js index 135629a243d6..e4e33738b332 100644 --- a/test/parallel/test-stream3-pause-then-read.js +++ b/test/parallel/test-stream3-pause-then-read.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var stream = require('stream'); diff --git a/test/parallel/test-string-decoder.js b/test/parallel/test-string-decoder.js index 0b22d3dd04ef..9d0034e2fc9c 100644 --- a/test/parallel/test-string-decoder.js +++ b/test/parallel/test-string-decoder.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var StringDecoder = require('string_decoder').StringDecoder; diff --git a/test/parallel/test-stringbytes-external.js b/test/parallel/test-stringbytes-external.js index ba3f0c5d1d9a..1f03e2be42f5 100644 --- a/test/parallel/test-stringbytes-external.js +++ b/test/parallel/test-stringbytes-external.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // minimum string size to overflow into external string space var EXTERN_APEX = 0xFBEE9; diff --git a/test/parallel/test-tick-processor.js b/test/parallel/test-tick-processor.js index 796f6ee0aa59..84146ed48177 100644 --- a/test/parallel/test-tick-processor.js +++ b/test/parallel/test-tick-processor.js @@ -1,7 +1,6 @@ 'use strict'; var fs = require('fs'); var assert = require('assert'); -var path = require('path'); var cp = require('child_process'); var common = require('../common'); diff --git a/test/parallel/test-timers-active.js b/test/parallel/test-timers-active.js index acddc2f41a45..d8faa1f5a334 100644 --- a/test/parallel/test-timers-active.js +++ b/test/parallel/test-timers-active.js @@ -1,5 +1,5 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const active = require('timers').active; diff --git a/test/parallel/test-timers-args.js b/test/parallel/test-timers-args.js index abb785ea0fc7..ae11e35ba278 100644 --- a/test/parallel/test-timers-args.js +++ b/test/parallel/test-timers-args.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); function range(n) { diff --git a/test/parallel/test-timers-immediate-queue.js b/test/parallel/test-timers-immediate-queue.js index a71472d46442..62482d510a66 100644 --- a/test/parallel/test-timers-immediate-queue.js +++ b/test/parallel/test-timers-immediate-queue.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // setImmediate should run clear its queued cbs once per event loop turn diff --git a/test/parallel/test-timers-immediate.js b/test/parallel/test-timers-immediate.js index bcfc4616ac62..9486465602ce 100644 --- a/test/parallel/test-timers-immediate.js +++ b/test/parallel/test-timers-immediate.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var immediateA = false, diff --git a/test/parallel/test-timers-linked-list.js b/test/parallel/test-timers-linked-list.js index 0c76af970a1f..c046a3024af3 100644 --- a/test/parallel/test-timers-linked-list.js +++ b/test/parallel/test-timers-linked-list.js @@ -2,7 +2,7 @@ // Flags: --expose-internals -const common = require('../common'); +require('../common'); const assert = require('assert'); const L = require('_linklist'); const internalL = require('internal/linkedlist'); diff --git a/test/parallel/test-timers-non-integer-delay.js b/test/parallel/test-timers-non-integer-delay.js index 97b2c0734f60..b42053db3b18 100644 --- a/test/parallel/test-timers-non-integer-delay.js +++ b/test/parallel/test-timers-non-integer-delay.js @@ -16,7 +16,6 @@ */ require('../common'); -var assert = require('assert'); var TIMEOUT_DELAY = 1.1; var NB_TIMEOUTS_FIRED = 50; diff --git a/test/parallel/test-timers-now.js b/test/parallel/test-timers-now.js index 466bd064b8de..8a47e397ce97 100644 --- a/test/parallel/test-timers-now.js +++ b/test/parallel/test-timers-now.js @@ -1,6 +1,6 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); // Return value of Timer.now() should easily fit in a SMI right after start-up. diff --git a/test/parallel/test-timers-ordering.js b/test/parallel/test-timers-ordering.js index 730a78a072c6..cef91e58e78c 100644 --- a/test/parallel/test-timers-ordering.js +++ b/test/parallel/test-timers-ordering.js @@ -1,15 +1,12 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var Timer = process.binding('timer_wrap').Timer; -var i; - var N = 30; var last_i = 0; var last_ts = 0; -var start = Timer.now(); var f = function(i) { if (i <= N) { diff --git a/test/parallel/test-timers-reset-process-domain-on-throw.js b/test/parallel/test-timers-reset-process-domain-on-throw.js new file mode 100644 index 000000000000..f72530b54238 --- /dev/null +++ b/test/parallel/test-timers-reset-process-domain-on-throw.js @@ -0,0 +1,45 @@ +'use strict'; + +// This test makes sure that when throwing from within a timer's callback, +// its active domain at the time of the throw is not the process' active domain +// for the next timers that need to be processed on the same turn of the event +// loop. + +const common = require('../common'); +const assert = require('assert'); +const domain = require('domain'); + +// Use the same timeout value so that both timers' callbacks are called during +// the same invocation of the underlying native timer's callback (listOnTimeout +// in lib/timers.js). +setTimeout(err, 50); +setTimeout(common.mustCall(secondTimer), 50); + +function err() { + const d = domain.create(); + d.on('error', handleDomainError); + d.run(err2); + + function err2() { + // this function doesn't exist, and throws an error as a result. + err3(); + } + + function handleDomainError(e) { + // In the domain's error handler, the current active domain should be the + // domain within which the error was thrown. + assert.equal(process.domain, d); + } +} + +function secondTimer() { + // secondTimer was scheduled before any domain had been created, so its + // callback should not have any active domain set when it runs. + if (process.domain !== null) { + console.log('process.domain should be null in this timer callback, but ' + + 'instead is:', process.domain); + // Do not use assert here, as it throws errors and if a domain with an error + // handler is active, then asserting wouldn't make the test fail. + process.exit(1); + } +} diff --git a/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js b/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js index 081688cfa5e8..c9ca3eafd64e 100644 --- a/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js +++ b/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js @@ -5,7 +5,6 @@ */ const common = require('../common'); -const assert = require('assert'); const net = require('net'); const clients = []; diff --git a/test/parallel/test-timers-uncaught-exception.js b/test/parallel/test-timers-uncaught-exception.js index 794b3b923be1..6b6dc5837158 100644 --- a/test/parallel/test-timers-uncaught-exception.js +++ b/test/parallel/test-timers-uncaught-exception.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var exceptions = 0; diff --git a/test/parallel/test-timers-unref-active.js b/test/parallel/test-timers-unref-active.js index 08f28b0153fe..ad72ac404774 100644 --- a/test/parallel/test-timers-unref-active.js +++ b/test/parallel/test-timers-unref-active.js @@ -15,7 +15,7 @@ * all 10 timeouts had the time to expire. */ -const common = require('../common'); +require('../common'); const timers = require('timers'); const assert = require('assert'); diff --git a/test/parallel/test-timers-unref-call.js b/test/parallel/test-timers-unref-call.js index b348330d200d..edd5865e8f61 100644 --- a/test/parallel/test-timers-unref-call.js +++ b/test/parallel/test-timers-unref-call.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var Timer = process.binding('timer_wrap').Timer; Timer.now = function() { return ++Timer.now.ticks; }; diff --git a/test/parallel/test-timers-unref-remove-other-unref-timers-only-one-fires.js b/test/parallel/test-timers-unref-remove-other-unref-timers-only-one-fires.js index aead4a4e7def..971c485a4cf9 100644 --- a/test/parallel/test-timers-unref-remove-other-unref-timers-only-one-fires.js +++ b/test/parallel/test-timers-unref-remove-other-unref-timers-only-one-fires.js @@ -10,7 +10,7 @@ * This behavior is a private implementation detail and should not be * considered public interface. */ -const common = require('../common'); +require('../common'); const timers = require('timers'); const assert = require('assert'); diff --git a/test/parallel/test-timers-unref-remove-other-unref-timers.js b/test/parallel/test-timers-unref-remove-other-unref-timers.js index 8c1864f1a7da..dcc50a5171ad 100644 --- a/test/parallel/test-timers-unref-remove-other-unref-timers.js +++ b/test/parallel/test-timers-unref-remove-other-unref-timers.js @@ -7,7 +7,6 @@ * considered public interface. */ const common = require('../common'); -const assert = require('assert'); const timers = require('timers'); const foo = { diff --git a/test/parallel/test-timers-unref.js b/test/parallel/test-timers-unref.js index c0b24a4275be..671c676e350e 100644 --- a/test/parallel/test-timers-unref.js +++ b/test/parallel/test-timers-unref.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var interval_fired = false, diff --git a/test/parallel/test-timers-unrefd-interval-still-fires.js b/test/parallel/test-timers-unrefd-interval-still-fires.js index a716c6ed645c..8f26d28816b6 100644 --- a/test/parallel/test-timers-unrefd-interval-still-fires.js +++ b/test/parallel/test-timers-unrefd-interval-still-fires.js @@ -3,7 +3,6 @@ * This test is a regression test for joyent/node#8900. */ const common = require('../common'); -const assert = require('assert'); const TEST_DURATION = common.platformTimeout(100); const N = 5; diff --git a/test/parallel/test-timers-zero-timeout.js b/test/parallel/test-timers-zero-timeout.js index 1c84814363a6..ab0c38f60842 100644 --- a/test/parallel/test-timers-zero-timeout.js +++ b/test/parallel/test-timers-zero-timeout.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // https://github.com/joyent/node/issues/2079 - zero timeout drops extra args @@ -7,7 +7,7 @@ var assert = require('assert'); var ncalled = 0; setTimeout(f, 0, 'foo', 'bar', 'baz'); - var timer = setTimeout(function() {}, 0); + setTimeout(function() {}, 0); function f(a, b, c) { assert.equal(a, 'foo'); diff --git a/test/parallel/test-timers.js b/test/parallel/test-timers.js index e784e262959d..0b379e0eb45a 100644 --- a/test/parallel/test-timers.js +++ b/test/parallel/test-timers.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var inputs = [ diff --git a/test/parallel/test-tls-0-dns-altname.js b/test/parallel/test-tls-0-dns-altname.js index 61458142bc01..95ceb1aa59aa 100644 --- a/test/parallel/test-tls-0-dns-altname.js +++ b/test/parallel/test-tls-0-dns-altname.js @@ -9,7 +9,6 @@ if (!common.hasCrypto) { var tls = require('tls'); var fs = require('fs'); -var net = require('net'); var common = require('../common'); diff --git a/test/parallel/test-tls-async-cb-after-socket-end.js b/test/parallel/test-tls-async-cb-after-socket-end.js index ea40205bfff0..d89a4e9930ca 100644 --- a/test/parallel/test-tls-async-cb-after-socket-end.js +++ b/test/parallel/test-tls-async-cb-after-socket-end.js @@ -2,7 +2,6 @@ var common = require('../common'); -var assert = require('assert'); var path = require('path'); var fs = require('fs'); var constants = require('constants'); diff --git a/test/parallel/test-tls-client-default-ciphers.js b/test/parallel/test-tls-client-default-ciphers.js index e38671fd6f9d..9905fc45bdcd 100644 --- a/test/parallel/test-tls-client-default-ciphers.js +++ b/test/parallel/test-tls-client-default-ciphers.js @@ -19,7 +19,7 @@ function test1() { }; try { - var s = tls.connect(common.PORT); + tls.connect(common.PORT); } catch (e) { assert(e instanceof Done); } diff --git a/test/parallel/test-tls-close-error.js b/test/parallel/test-tls-close-error.js index 5c5a797c280a..bd38cb55f7a1 100644 --- a/test/parallel/test-tls-close-error.js +++ b/test/parallel/test-tls-close-error.js @@ -10,7 +10,6 @@ if (!common.hasCrypto) { var tls = require('tls'); var fs = require('fs'); -var net = require('net'); var errorCount = 0; var closeCount = 0; diff --git a/test/parallel/test-tls-close-notify.js b/test/parallel/test-tls-close-notify.js index 5cc3021ab8dd..5545f4512d5f 100644 --- a/test/parallel/test-tls-close-notify.js +++ b/test/parallel/test-tls-close-notify.js @@ -9,7 +9,6 @@ if (!common.hasCrypto) { var tls = require('tls'); var fs = require('fs'); -var net = require('net'); var ended = 0; diff --git a/test/parallel/test-tls-connect-secure-context.js b/test/parallel/test-tls-connect-secure-context.js index 3b080432e49d..c7519ed770fd 100644 --- a/test/parallel/test-tls-connect-secure-context.js +++ b/test/parallel/test-tls-connect-secure-context.js @@ -1,6 +1,5 @@ 'use strict'; const common = require('../common'); -const assert = require('assert'); if (!common.hasCrypto) { console.log('1..0 # Skipped: missing crypto'); diff --git a/test/parallel/test-tls-destroy-whilst-write.js b/test/parallel/test-tls-destroy-whilst-write.js index f42ed1d4ea77..26c202647359 100644 --- a/test/parallel/test-tls-destroy-whilst-write.js +++ b/test/parallel/test-tls-destroy-whilst-write.js @@ -1,5 +1,4 @@ 'use strict'; -var assert = require('assert'); var common = require('../common'); if (!common.hasCrypto) { diff --git a/test/parallel/test-tls-fast-writing.js b/test/parallel/test-tls-fast-writing.js index 009fa40b631e..1f65391480d5 100644 --- a/test/parallel/test-tls-fast-writing.js +++ b/test/parallel/test-tls-fast-writing.js @@ -20,7 +20,7 @@ var server = tls.createServer(options, onconnection); var gotChunk = false; var gotDrain = false; -var timer = setTimeout(function() { +setTimeout(function() { console.log('not ok - timed out'); process.exit(1); }, common.platformTimeout(500)); diff --git a/test/parallel/test-tls-handshake-error.js b/test/parallel/test-tls-handshake-error.js index f33177455f89..f65440ed93b1 100644 --- a/test/parallel/test-tls-handshake-error.js +++ b/test/parallel/test-tls-handshake-error.js @@ -10,7 +10,6 @@ if (!common.hasCrypto) { var tls = require('tls'); var fs = require('fs'); -var net = require('net'); var errorCount = 0; var closeCount = 0; diff --git a/test/parallel/test-tls-handshake-nohang.js b/test/parallel/test-tls-handshake-nohang.js index ae07551ef980..374ac02a2f45 100644 --- a/test/parallel/test-tls-handshake-nohang.js +++ b/test/parallel/test-tls-handshake-nohang.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); if (!common.hasCrypto) { console.log('1..0 # Skipped: missing crypto'); diff --git a/test/parallel/test-tls-invoke-queued.js b/test/parallel/test-tls-invoke-queued.js index f833108ea3f9..efa5c0aa9aa3 100644 --- a/test/parallel/test-tls-invoke-queued.js +++ b/test/parallel/test-tls-invoke-queued.js @@ -9,7 +9,6 @@ if (!common.hasCrypto) { var tls = require('tls'); var fs = require('fs'); -var net = require('net'); var received = ''; diff --git a/test/parallel/test-tls-key-mismatch.js b/test/parallel/test-tls-key-mismatch.js index f7919c545aef..2e17a4931078 100644 --- a/test/parallel/test-tls-key-mismatch.js +++ b/test/parallel/test-tls-key-mismatch.js @@ -14,8 +14,6 @@ var options = { cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem') }; -var cert = null; - assert.throws(function() { tls.createSecureContext(options); }); diff --git a/test/parallel/test-tls-legacy-onselect.js b/test/parallel/test-tls-legacy-onselect.js index 6f1e9a91a834..d3b20d5d8a4c 100644 --- a/test/parallel/test-tls-legacy-onselect.js +++ b/test/parallel/test-tls-legacy-onselect.js @@ -9,18 +9,8 @@ if (!common.hasCrypto) { var tls = require('tls'); var net = require('net'); -var fs = require('fs'); - var success = false; -function filenamePEM(n) { - return require('path').join(common.fixturesDir, 'keys', n + '.pem'); -} - -function loadPEM(n) { - return fs.readFileSync(filenamePEM(n)); -} - var server = net.Server(function(raw) { var pair = tls.createSecurePair(null, true, false, false); pair.on('error', function() {}); diff --git a/test/parallel/test-tls-max-send-fragment.js b/test/parallel/test-tls-max-send-fragment.js index cc9413b81e78..8b1bf0998aad 100644 --- a/test/parallel/test-tls-max-send-fragment.js +++ b/test/parallel/test-tls-max-send-fragment.js @@ -9,7 +9,6 @@ if (!common.hasCrypto) { var tls = require('tls'); var fs = require('fs'); -var net = require('net'); var common = require('../common'); diff --git a/test/parallel/test-tls-ocsp-callback.js b/test/parallel/test-tls-ocsp-callback.js index d970b2ab0134..e9443f453579 100644 --- a/test/parallel/test-tls-ocsp-callback.js +++ b/test/parallel/test-tls-ocsp-callback.js @@ -22,11 +22,7 @@ var constants = require('constants'); var fs = require('fs'); var join = require('path').join; -test({ response: false }, function() { - test({ response: 'hello world' }, function() { - test({ ocsp: false }); - }); -}); +var pfx = fs.readFileSync(join(common.fixturesDir, 'keys', 'agent1-pfx.pem')); function test(testOptions, cb) { @@ -45,7 +41,13 @@ function test(testOptions, cb) { var clientSecure = 0; var ocspCount = 0; var ocspResponse; - var session; + + if (testOptions.pfx) { + delete options.key; + delete options.cert; + options.pfx = testOptions.pfx; + options.passphrase = testOptions.passphrase; + } var server = tls.createServer(options, function(cleartext) { cleartext.on('error', function(er) { @@ -106,3 +108,23 @@ function test(testOptions, cb) { assert.equal(ocspCount, 1); }); } + +var tests = [ + { response: false }, + { response: 'hello world' }, + { ocsp: false } +]; + +if (!common.hasFipsCrypto) { + tests.push({ pfx: pfx, passphrase: 'sample', response: 'hello pfx' }); +} + +function runTests(i) { + if (i === tests.length) return; + + test(tests[i], common.mustCall(function() { + runTests(i + 1); + })); +} + +runTests(0); diff --git a/test/parallel/test-tls-parse-cert-string.js b/test/parallel/test-tls-parse-cert-string.js index 57180c9ce9df..11128783871f 100644 --- a/test/parallel/test-tls-parse-cert-string.js +++ b/test/parallel/test-tls-parse-cert-string.js @@ -1,6 +1,6 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const tls = require('tls'); diff --git a/test/parallel/test-tls-peer-certificate-encoding.js b/test/parallel/test-tls-peer-certificate-encoding.js index 96cb6944ef6a..32b1583a0c48 100644 --- a/test/parallel/test-tls-peer-certificate-encoding.js +++ b/test/parallel/test-tls-peer-certificate-encoding.js @@ -11,7 +11,6 @@ var tls = require('tls'); var fs = require('fs'); var util = require('util'); var join = require('path').join; -var spawn = require('child_process').spawn; var options = { key: fs.readFileSync(join(common.fixturesDir, 'keys', 'agent5-key.pem')), diff --git a/test/parallel/test-tls-peer-certificate-multi-keys.js b/test/parallel/test-tls-peer-certificate-multi-keys.js index fca7a1a77dda..50ce9037f8d7 100644 --- a/test/parallel/test-tls-peer-certificate-multi-keys.js +++ b/test/parallel/test-tls-peer-certificate-multi-keys.js @@ -11,7 +11,6 @@ var tls = require('tls'); var fs = require('fs'); var util = require('util'); var join = require('path').join; -var spawn = require('child_process').spawn; var options = { key: fs.readFileSync(join(common.fixturesDir, 'agent.key')), diff --git a/test/parallel/test-tls-peer-certificate.js b/test/parallel/test-tls-peer-certificate.js index 3cb0eef2d562..cdf8bf5644f6 100644 --- a/test/parallel/test-tls-peer-certificate.js +++ b/test/parallel/test-tls-peer-certificate.js @@ -11,7 +11,6 @@ var tls = require('tls'); var fs = require('fs'); var util = require('util'); var join = require('path').join; -var spawn = require('child_process').spawn; var options = { key: fs.readFileSync(join(common.fixturesDir, 'keys', 'agent1-key.pem')), diff --git a/test/parallel/test-tls-request-timeout.js b/test/parallel/test-tls-request-timeout.js index a9b1c78c91a0..0db2a613afc9 100644 --- a/test/parallel/test-tls-request-timeout.js +++ b/test/parallel/test-tls-request-timeout.js @@ -29,7 +29,7 @@ var server = tls.Server(options, function(socket) { }); server.listen(common.PORT, function() { - var socket = tls.connect({ + tls.connect({ port: common.PORT, rejectUnauthorized: false }); diff --git a/test/parallel/test-tls-socket-default-options.js b/test/parallel/test-tls-socket-default-options.js index 7b41d0f5a9ec..c2c6e518bbc4 100644 --- a/test/parallel/test-tls-socket-default-options.js +++ b/test/parallel/test-tls-socket-default-options.js @@ -9,7 +9,6 @@ if (!common.hasCrypto) { const tls = require('tls'); const fs = require('fs'); -const net = require('net'); const sent = 'hello world'; diff --git a/test/parallel/test-tls-ticket-cluster.js b/test/parallel/test-tls-ticket-cluster.js index fc0f1d5e858d..1fd1776ca819 100644 --- a/test/parallel/test-tls-ticket-cluster.js +++ b/test/parallel/test-tls-ticket-cluster.js @@ -42,7 +42,6 @@ if (cluster.isMaster) { function fork() { var worker = cluster.fork(); - var workerReqCount = 0; worker.on('message', function(msg) { console.error('[master] got %j', msg); if (msg === 'reused') { diff --git a/test/parallel/test-tty-stdout-end.js b/test/parallel/test-tty-stdout-end.js index 57f9c03ec449..a33a2e5ed272 100644 --- a/test/parallel/test-tty-stdout-end.js +++ b/test/parallel/test-tty-stdout-end.js @@ -1,6 +1,6 @@ 'use strict'; // Can't test this when 'make test' doesn't assign a tty to the stdout. -const common = require('../common'); +require('../common'); const assert = require('assert'); const shouldThrow = function() { diff --git a/test/parallel/test-tty-wrap.js b/test/parallel/test-tty-wrap.js index dbe7b6890fd2..5e124dc89f7b 100644 --- a/test/parallel/test-tty-wrap.js +++ b/test/parallel/test-tty-wrap.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var TTY = process.binding('tty_wrap').TTY; diff --git a/test/parallel/test-url.js b/test/parallel/test-url.js index 5098c7e46ab6..cd097be24384 100644 --- a/test/parallel/test-url.js +++ b/test/parallel/test-url.js @@ -1,10 +1,9 @@ /* eslint-disable max-len */ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); -var url = require('url'), - util = require('util'); +var url = require('url'); // URLs to parse, and expected data // { url : parsed } @@ -1515,9 +1514,6 @@ relativeTests2.forEach(function(relativeTest) { //if format and parse are inverse operations then //resolveObject(parse(x), y) == parse(resolve(x, y)) -//host and hostname are special, in this case a '' value is important -var emptyIsImportant = {'host': true, 'hostname': ''}; - //format: [from, path, expected] relativeTests.forEach(function(relativeTest) { var actual = url.resolveObject(url.parse(relativeTest[0]), relativeTest[1]), diff --git a/test/parallel/test-utf8-scripts.js b/test/parallel/test-utf8-scripts.js index 3a891283509b..a9db5d10e4fd 100644 --- a/test/parallel/test-utf8-scripts.js +++ b/test/parallel/test-utf8-scripts.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // üäö diff --git a/test/parallel/test-util-decorate-error-stack.js b/test/parallel/test-util-decorate-error-stack.js index 24fee56df7b6..017a5ab6afe8 100644 --- a/test/parallel/test-util-decorate-error-stack.js +++ b/test/parallel/test-util-decorate-error-stack.js @@ -1,6 +1,6 @@ // Flags: --expose_internals 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const internalUtil = require('internal/util'); diff --git a/test/parallel/test-util-format.js b/test/parallel/test-util-format.js index 6761671e1997..00028ddbb747 100644 --- a/test/parallel/test-util-format.js +++ b/test/parallel/test-util-format.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var util = require('util'); var symbol = Symbol('foo'); diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 5831c40e77e9..d88096765694 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var util = require('util'); diff --git a/test/parallel/test-util-internal.js b/test/parallel/test-util-internal.js index 9ab883ec8b6d..b557356716a0 100644 --- a/test/parallel/test-util-internal.js +++ b/test/parallel/test-util-internal.js @@ -1,7 +1,7 @@ 'use strict'; // Flags: --expose_internals -const common = require('../common'); +require('../common'); const assert = require('assert'); const internalUtil = require('internal/util'); diff --git a/test/parallel/test-util.js b/test/parallel/test-util.js index 700532bd5a39..864361d80a6d 100644 --- a/test/parallel/test-util.js +++ b/test/parallel/test-util.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var util = require('util'); var context = require('vm').runInNewContext; diff --git a/test/parallel/test-v8-flag-type-check.js b/test/parallel/test-v8-flag-type-check.js index 68bf30dba3cd..372494482134 100644 --- a/test/parallel/test-v8-flag-type-check.js +++ b/test/parallel/test-v8-flag-type-check.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var v8 = require('v8'); diff --git a/test/parallel/test-v8-flags.js b/test/parallel/test-v8-flags.js index d21cbc6c2635..cee924d5b130 100644 --- a/test/parallel/test-v8-flags.js +++ b/test/parallel/test-v8-flags.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var v8 = require('v8'); var vm = require('vm'); diff --git a/test/parallel/test-v8-stats.js b/test/parallel/test-v8-stats.js index fc4a6df30f8e..eb5566fe2bc2 100644 --- a/test/parallel/test-v8-stats.js +++ b/test/parallel/test-v8-stats.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var v8 = require('v8'); diff --git a/test/parallel/test-vm-basic.js b/test/parallel/test-vm-basic.js index 96c615c44af1..8f9cab90eb5a 100644 --- a/test/parallel/test-vm-basic.js +++ b/test/parallel/test-vm-basic.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-context-async-script.js b/test/parallel/test-vm-context-async-script.js index e146d48343aa..b09eda852098 100644 --- a/test/parallel/test-vm-context-async-script.js +++ b/test/parallel/test-vm-context-async-script.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-context-property-forwarding.js b/test/parallel/test-vm-context-property-forwarding.js index 5fcd64b8ba90..4034441615ca 100644 --- a/test/parallel/test-vm-context-property-forwarding.js +++ b/test/parallel/test-vm-context-property-forwarding.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-context.js b/test/parallel/test-vm-context.js index e1cd2ef01e51..3fe3cf1b66a8 100644 --- a/test/parallel/test-vm-context.js +++ b/test/parallel/test-vm-context.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-create-and-run-in-context.js b/test/parallel/test-vm-create-and-run-in-context.js index 01df6ad4531e..94527598ca27 100644 --- a/test/parallel/test-vm-create-and-run-in-context.js +++ b/test/parallel/test-vm-create-and-run-in-context.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-create-context-accessors.js b/test/parallel/test-vm-create-context-accessors.js index 678cf3fbd212..d2e7d7bd8eac 100644 --- a/test/parallel/test-vm-create-context-accessors.js +++ b/test/parallel/test-vm-create-context-accessors.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-create-context-arg.js b/test/parallel/test-vm-create-context-arg.js index d44eeec18dec..a0c297623301 100644 --- a/test/parallel/test-vm-create-context-arg.js +++ b/test/parallel/test-vm-create-context-arg.js @@ -1,15 +1,15 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); assert.throws(function() { - var ctx = vm.createContext('string is not supported'); + vm.createContext('string is not supported'); }, TypeError); assert.doesNotThrow(function() { - var ctx = vm.createContext({ a: 1 }); - ctx = vm.createContext([0, 1, 2, 3]); + vm.createContext({ a: 1 }); + vm.createContext([0, 1, 2, 3]); }); assert.doesNotThrow(function() { diff --git a/test/parallel/test-vm-create-context-circular-reference.js b/test/parallel/test-vm-create-context-circular-reference.js index cb6a90dcaef3..851bebdb088a 100644 --- a/test/parallel/test-vm-create-context-circular-reference.js +++ b/test/parallel/test-vm-create-context-circular-reference.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-cross-context.js b/test/parallel/test-vm-cross-context.js index 20a3792b2857..5674f582426f 100644 --- a/test/parallel/test-vm-cross-context.js +++ b/test/parallel/test-vm-cross-context.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-function-declaration.js b/test/parallel/test-vm-function-declaration.js index 5ff194e12dd8..fd41be7564aa 100644 --- a/test/parallel/test-vm-function-declaration.js +++ b/test/parallel/test-vm-function-declaration.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-global-define-property.js b/test/parallel/test-vm-global-define-property.js index f7f3e4f3df7d..71e6ae9eaa0b 100644 --- a/test/parallel/test-vm-global-define-property.js +++ b/test/parallel/test-vm-global-define-property.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-global-identity.js b/test/parallel/test-vm-global-identity.js index 647edb22b44d..7d90408b64c2 100644 --- a/test/parallel/test-vm-global-identity.js +++ b/test/parallel/test-vm-global-identity.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-harmony-proxies.js b/test/parallel/test-vm-harmony-proxies.js index 2f008615ebaf..78ee14458274 100644 --- a/test/parallel/test-vm-harmony-proxies.js +++ b/test/parallel/test-vm-harmony-proxies.js @@ -1,19 +1,19 @@ 'use strict'; // Flags: --harmony_proxies -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); // src/node_contextify.cc filters out the Proxy object from the parent // context. Make sure that the new context has a Proxy object of its own. var sandbox = {}; -var result = vm.runInNewContext('this.Proxy = Proxy', sandbox); +vm.runInNewContext('this.Proxy = Proxy', sandbox); assert(typeof sandbox.Proxy === 'object'); assert(sandbox.Proxy !== Proxy); // Unless we copy the Proxy object explicitly, of course. var sandbox = { Proxy: Proxy }; -var result = vm.runInNewContext('this.Proxy = Proxy', sandbox); +vm.runInNewContext('this.Proxy = Proxy', sandbox); assert(typeof sandbox.Proxy === 'object'); assert(sandbox.Proxy === Proxy); diff --git a/test/parallel/test-vm-harmony-symbols.js b/test/parallel/test-vm-harmony-symbols.js index 86fde1b978ff..e4b27c9ebb85 100644 --- a/test/parallel/test-vm-harmony-symbols.js +++ b/test/parallel/test-vm-harmony-symbols.js @@ -1,16 +1,16 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); // The sandbox should have its own Symbol constructor. var sandbox = {}; -var result = vm.runInNewContext('this.Symbol = Symbol', sandbox); +vm.runInNewContext('this.Symbol = Symbol', sandbox); assert(typeof sandbox.Symbol === 'function'); assert(sandbox.Symbol !== Symbol); // Unless we copy the Symbol constructor explicitly, of course. var sandbox = { Symbol: Symbol }; -var result = vm.runInNewContext('this.Symbol = Symbol', sandbox); +vm.runInNewContext('this.Symbol = Symbol', sandbox); assert(typeof sandbox.Symbol === 'function'); assert(sandbox.Symbol === Symbol); diff --git a/test/parallel/test-vm-is-context.js b/test/parallel/test-vm-is-context.js index 5a46a452b916..cc106a15fbfc 100644 --- a/test/parallel/test-vm-is-context.js +++ b/test/parallel/test-vm-is-context.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-new-script-new-context.js b/test/parallel/test-vm-new-script-new-context.js index e3cc6e91cb43..81f9b57593ea 100644 --- a/test/parallel/test-vm-new-script-new-context.js +++ b/test/parallel/test-vm-new-script-new-context.js @@ -21,7 +21,6 @@ assert.throws(function() { console.error('undefined reference'); -var error; script = new Script('foo.bar = 5;'); assert.throws(function() { script.runInNewContext(); @@ -41,7 +40,9 @@ code = 'foo = 1;' + foo = 2; obj = { foo: 0, baz: 3 }; script = new Script(code); +/* eslint-disable no-unused-vars */ var baz = script.runInNewContext(obj); +/* eslint-enable no-unused-vars */ assert.equal(1, obj.foo); assert.equal(2, obj.bar); assert.equal(2, foo); diff --git a/test/parallel/test-vm-preserves-property.js b/test/parallel/test-vm-preserves-property.js index 85ce2d6e8165..9786ee54a7cf 100644 --- a/test/parallel/test-vm-preserves-property.js +++ b/test/parallel/test-vm-preserves-property.js @@ -1,6 +1,6 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-run-in-new-context.js b/test/parallel/test-vm-run-in-new-context.js index da14a041face..2b32eccf408f 100644 --- a/test/parallel/test-vm-run-in-new-context.js +++ b/test/parallel/test-vm-run-in-new-context.js @@ -29,7 +29,9 @@ code = 'foo = 1;' + 'if (baz !== 3) throw new Error(\'test fail\');'; foo = 2; obj = { foo: 0, baz: 3 }; +/* eslint-disable no-unused-vars */ var baz = vm.runInNewContext(code, obj); +/* eslint-enable no-unused-vars */ assert.equal(1, obj.foo); assert.equal(2, obj.bar); assert.equal(2, foo); diff --git a/test/parallel/test-vm-static-this.js b/test/parallel/test-vm-static-this.js index fb9cb764f842..a5f5ad9415a8 100644 --- a/test/parallel/test-vm-static-this.js +++ b/test/parallel/test-vm-static-this.js @@ -25,7 +25,9 @@ code = 'foo = 1;' + 'if (typeof baz !== \'undefined\') throw new Error(\'test fail\');'; foo = 2; obj = { foo: 0, baz: 3 }; +/* eslint-disable no-unused-vars */ var baz = vm.runInThisContext(code); +/* eslint-enable no-unused-vars */ assert.equal(0, obj.foo); assert.equal(2, bar); assert.equal(1, foo); diff --git a/test/parallel/test-vm-symbols.js b/test/parallel/test-vm-symbols.js index d7d0ffe3af61..d3419af559a2 100644 --- a/test/parallel/test-vm-symbols.js +++ b/test/parallel/test-vm-symbols.js @@ -1,6 +1,6 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-vm-syntax-error-message.js b/test/parallel/test-vm-syntax-error-message.js index 4b48b0d474a8..75748b24e193 100644 --- a/test/parallel/test-vm-syntax-error-message.js +++ b/test/parallel/test-vm-syntax-error-message.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var child_process = require('child_process'); diff --git a/test/parallel/test-vm-timeout.js b/test/parallel/test-vm-timeout.js index e9511e59230a..b4dd57bb54d2 100644 --- a/test/parallel/test-vm-timeout.js +++ b/test/parallel/test-vm-timeout.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var vm = require('vm'); diff --git a/test/parallel/test-writedouble.js b/test/parallel/test-writedouble.js index 2a9ab11107f1..4e86182137de 100644 --- a/test/parallel/test-writedouble.js +++ b/test/parallel/test-writedouble.js @@ -2,7 +2,7 @@ /* * Tests to verify we're writing doubles correctly */ -var common = require('../common'); +require('../common'); var ASSERT = require('assert'); function test(clazz) { diff --git a/test/parallel/test-writefloat.js b/test/parallel/test-writefloat.js index 948bf4910208..0cb748d603d0 100644 --- a/test/parallel/test-writefloat.js +++ b/test/parallel/test-writefloat.js @@ -2,7 +2,7 @@ /* * Tests to verify we're writing floats correctly */ -var common = require('../common'); +require('../common'); var ASSERT = require('assert'); function test(clazz) { diff --git a/test/parallel/test-writeint.js b/test/parallel/test-writeint.js index ee981a157ad7..d05a90d48b5a 100644 --- a/test/parallel/test-writeint.js +++ b/test/parallel/test-writeint.js @@ -2,7 +2,7 @@ /* * Tests to verify we're writing signed integers correctly */ -var common = require('../common'); +require('../common'); var ASSERT = require('assert'); function test8(clazz) { diff --git a/test/parallel/test-writeuint.js b/test/parallel/test-writeuint.js index baa12aa57666..843cc4230722 100644 --- a/test/parallel/test-writeuint.js +++ b/test/parallel/test-writeuint.js @@ -2,7 +2,7 @@ /* * A battery of tests to help us read a series of uints */ -var common = require('../common'); +require('../common'); var ASSERT = require('assert'); /* diff --git a/test/parallel/test-zlib-close-after-write.js b/test/parallel/test-zlib-close-after-write.js index c02ff33fb5eb..b47deddd8889 100644 --- a/test/parallel/test-zlib-close-after-write.js +++ b/test/parallel/test-zlib-close-after-write.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var zlib = require('zlib'); diff --git a/test/parallel/test-zlib-const.js b/test/parallel/test-zlib-const.js index 511eca613a52..b7eb31d2c5f4 100644 --- a/test/parallel/test-zlib-const.js +++ b/test/parallel/test-zlib-const.js @@ -1,5 +1,5 @@ /* eslint-disable strict */ -var common = require('../common'); +require('../common'); var assert = require('assert'); var zlib = require('zlib'); diff --git a/test/parallel/test-zlib-convenience-methods.js b/test/parallel/test-zlib-convenience-methods.js index 5808bdf04a8f..70c102efd286 100644 --- a/test/parallel/test-zlib-convenience-methods.js +++ b/test/parallel/test-zlib-convenience-methods.js @@ -1,7 +1,7 @@ 'use strict'; // test convenience methods with and without options supplied -var common = require('../common'); +require('../common'); var assert = require('assert'); var zlib = require('zlib'); diff --git a/test/parallel/test-zlib-dictionary.js b/test/parallel/test-zlib-dictionary.js index 7e11b1966c69..1a491c2ca1f2 100644 --- a/test/parallel/test-zlib-dictionary.js +++ b/test/parallel/test-zlib-dictionary.js @@ -1,10 +1,9 @@ 'use strict'; // test compression/decompression with dictionary -const common = require('../common'); +require('../common'); const assert = require('assert'); const zlib = require('zlib'); -const path = require('path'); const spdyDict = new Buffer([ 'optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-', diff --git a/test/parallel/test-zlib-flush-drain.js b/test/parallel/test-zlib-flush-drain.js index 93966cd85d26..f04dac9f0699 100644 --- a/test/parallel/test-zlib-flush-drain.js +++ b/test/parallel/test-zlib-flush-drain.js @@ -1,8 +1,7 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const zlib = require('zlib'); -const path = require('path'); const bigData = new Buffer(10240).fill('x'); diff --git a/test/parallel/test-zlib-from-string.js b/test/parallel/test-zlib-from-string.js index 49f4d139c148..14c747fc4336 100644 --- a/test/parallel/test-zlib-from-string.js +++ b/test/parallel/test-zlib-from-string.js @@ -1,7 +1,7 @@ 'use strict'; // test compressing and uncompressing a string with zlib -var common = require('../common'); +require('../common'); var assert = require('assert'); var zlib = require('zlib'); diff --git a/test/parallel/test-zlib-invalid-input.js b/test/parallel/test-zlib-invalid-input.js index e1e81bacc1a4..9850c6078c53 100644 --- a/test/parallel/test-zlib-invalid-input.js +++ b/test/parallel/test-zlib-invalid-input.js @@ -1,8 +1,8 @@ 'use strict'; // test uncompressing invalid input -var common = require('../common'), - assert = require('assert'), +require('../common'); +var assert = require('assert'), zlib = require('zlib'); var nonStringInputs = [1, true, {a: 1}, ['a']]; diff --git a/test/parallel/test-zlib-truncated.js b/test/parallel/test-zlib-truncated.js index 46bd83960bba..38888b68be70 100644 --- a/test/parallel/test-zlib-truncated.js +++ b/test/parallel/test-zlib-truncated.js @@ -1,7 +1,7 @@ 'use strict'; // tests zlib streams with truncated compressed input -const common = require('../common'); +require('../common'); const assert = require('assert'); const zlib = require ('zlib'); diff --git a/test/parallel/test-zlib-write-after-close.js b/test/parallel/test-zlib-write-after-close.js index a1d9adb6d9b9..b1d35935e8ab 100644 --- a/test/parallel/test-zlib-write-after-close.js +++ b/test/parallel/test-zlib-write-after-close.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var zlib = require('zlib'); diff --git a/test/parallel/test-zlib-write-after-flush.js b/test/parallel/test-zlib-write-after-flush.js index 4c53ca49ebf7..fa70c5f14dee 100644 --- a/test/parallel/test-zlib-write-after-flush.js +++ b/test/parallel/test-zlib-write-after-flush.js @@ -1,8 +1,7 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var zlib = require('zlib'); -var fs = require('fs'); var gzip = zlib.createGzip(); var gunz = zlib.createUnzip(); diff --git a/test/parallel/test-zlib-zero-byte.js b/test/parallel/test-zlib-zero-byte.js index 9aa260a7f314..826a9c7c7979 100644 --- a/test/parallel/test-zlib-zero-byte.js +++ b/test/parallel/test-zlib-zero-byte.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var zlib = require('zlib'); diff --git a/test/pummel/test-dtrace-jsstack.js b/test/pummel/test-dtrace-jsstack.js index 67194a3dd77f..2e5c86705531 100644 --- a/test/pummel/test-dtrace-jsstack.js +++ b/test/pummel/test-dtrace-jsstack.js @@ -1,8 +1,7 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var os = require('os'); -var util = require('util'); if (os.type() != 'SunOS') { console.log('1..0 # Skipped: no DTRACE support'); @@ -13,7 +12,6 @@ if (os.type() != 'SunOS') { * Some functions to create a recognizable stack. */ var frames = [ 'stalloogle', 'bagnoogle', 'doogle' ]; -var expected; var stalloogle = function(str) { expected = str; @@ -34,8 +32,6 @@ var doogle = function() { }; var spawn = require('child_process').spawn; -var prefix = '/var/tmp/node'; -var corefile = prefix + '.' + process.pid; /* * We're going to use DTrace to stop us, gcore us, and set us running again diff --git a/test/pummel/test-fs-watch-file.js b/test/pummel/test-fs-watch-file.js index 7b57803dd4ec..4e08e9e9d1cc 100644 --- a/test/pummel/test-fs-watch-file.js +++ b/test/pummel/test-fs-watch-file.js @@ -9,7 +9,6 @@ var watchSeenTwo = 0; var watchSeenThree = 0; var watchSeenFour = 0; -var startDir = process.cwd(); var testDir = common.tmpDir; var filenameOne = 'watch.txt'; diff --git a/test/pummel/test-fs-watch-non-recursive.js b/test/pummel/test-fs-watch-non-recursive.js index 2586aec59b2d..ead7de9e28dc 100644 --- a/test/pummel/test-fs-watch-non-recursive.js +++ b/test/pummel/test-fs-watch-non-recursive.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); var path = require('path'); var fs = require('fs'); diff --git a/test/pummel/test-http-client-reconnect-bug.js b/test/pummel/test-http-client-reconnect-bug.js index bd852e45f194..12a6fecc7050 100644 --- a/test/pummel/test-http-client-reconnect-bug.js +++ b/test/pummel/test-http-client-reconnect-bug.js @@ -3,7 +3,6 @@ var common = require('../common'); var assert = require('assert'); var net = require('net'), - util = require('util'), http = require('http'); var errorCount = 0; diff --git a/test/pummel/test-http-upload-timeout.js b/test/pummel/test-http-upload-timeout.js index 08132e3c7594..d1be5311db0c 100644 --- a/test/pummel/test-http-upload-timeout.js +++ b/test/pummel/test-http-upload-timeout.js @@ -3,7 +3,6 @@ // data in random intervals. Clients are also randomly disconnecting until there // are no more clients left. If no false timeout occurs, this test has passed. var common = require('../common'), - assert = require('assert'), http = require('http'), server = http.createServer(), connections = 0; diff --git a/test/pummel/test-https-no-reader.js b/test/pummel/test-https-no-reader.js index 753687e67a55..d9d2b64cc73d 100644 --- a/test/pummel/test-https-no-reader.js +++ b/test/pummel/test-https-no-reader.js @@ -18,8 +18,6 @@ var options = { }; var buf = new Buffer(1024 * 1024); -var sent = 0; -var received = 0; var server = https.createServer(options, function(req, res) { res.writeHead(200); @@ -30,7 +28,6 @@ var server = https.createServer(options, function(req, res) { }); server.listen(common.PORT, function() { - var resumed = false; var req = https.request({ method: 'POST', port: common.PORT, diff --git a/test/pummel/test-keep-alive.js b/test/pummel/test-keep-alive.js index c2ec7fd81f16..46190555b272 100644 --- a/test/pummel/test-keep-alive.js +++ b/test/pummel/test-keep-alive.js @@ -5,7 +5,6 @@ var common = require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; var http = require('http'); -var path = require('path'); var url = require('url'); if (common.isWindows) { diff --git a/test/pummel/test-next-tick-infinite-calls.js b/test/pummel/test-next-tick-infinite-calls.js index d4fdb3496423..18223885d6cc 100644 --- a/test/pummel/test-next-tick-infinite-calls.js +++ b/test/pummel/test-next-tick-infinite-calls.js @@ -1,6 +1,5 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); var complete = 0; diff --git a/test/pummel/test-process-hrtime.js b/test/pummel/test-process-hrtime.js index 4fd66c03907a..04225bae421b 100644 --- a/test/pummel/test-process-hrtime.js +++ b/test/pummel/test-process-hrtime.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var start = process.hrtime(); diff --git a/test/pummel/test-process-uptime.js b/test/pummel/test-process-uptime.js index a80806c2099c..8d2d88b74f73 100644 --- a/test/pummel/test-process-uptime.js +++ b/test/pummel/test-process-uptime.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); console.error(process.uptime()); diff --git a/test/pummel/test-regress-GH-892.js b/test/pummel/test-regress-GH-892.js index 67f9dd95aebe..11cab1b8b623 100644 --- a/test/pummel/test-regress-GH-892.js +++ b/test/pummel/test-regress-GH-892.js @@ -17,11 +17,7 @@ var https = require('https'); var fs = require('fs'); -var PORT = 8000; - - var bytesExpected = 1024 * 1024 * 32; -var gotResponse = false; var started = false; diff --git a/test/pummel/test-stream-pipe-multi.js b/test/pummel/test-stream-pipe-multi.js index 807e3c141515..44d6973938de 100644 --- a/test/pummel/test-stream-pipe-multi.js +++ b/test/pummel/test-stream-pipe-multi.js @@ -2,7 +2,7 @@ // Test that having a bunch of streams piping in parallel // doesn't break anything. -var common = require('../common'); +require('../common'); var assert = require('assert'); var Stream = require('stream').Stream; var rr = []; diff --git a/test/pummel/test-stream2-basic.js b/test/pummel/test-stream2-basic.js index fe921dc00583..564a3f7f42d5 100644 --- a/test/pummel/test-stream2-basic.js +++ b/test/pummel/test-stream2-basic.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var R = require('_stream_readable'); var assert = require('assert'); @@ -157,7 +157,6 @@ test('pipe', function(t) { 'xxxxx' ]; var w = new TestWriter(); - var flush = true; w.on('end', function(received) { t.same(received, expect); @@ -439,7 +438,6 @@ test('adding readable triggers data flow', function(t) { r.push(new Buffer('asdf')); }; - var called = false; r.on('readable', function() { onReadable = true; r.read(); diff --git a/test/pummel/test-timer-wrap.js b/test/pummel/test-timer-wrap.js index 62ba69d3fde0..d2e96e066d2f 100644 --- a/test/pummel/test-timer-wrap.js +++ b/test/pummel/test-timer-wrap.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var timeouts = 0; diff --git a/test/pummel/test-timer-wrap2.js b/test/pummel/test-timer-wrap2.js index b289a85644a0..87497b2685f5 100644 --- a/test/pummel/test-timer-wrap2.js +++ b/test/pummel/test-timer-wrap2.js @@ -1,9 +1,8 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +require('../common'); // Test that allocating a timer does not increase the loop's reference // count. var Timer = process.binding('timer_wrap').Timer; -var t = new Timer(); +new Timer(); diff --git a/test/pummel/test-timers.js b/test/pummel/test-timers.js index 2225da91edcf..d911beb6b092 100644 --- a/test/pummel/test-timers.js +++ b/test/pummel/test-timers.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var WINDOW = 200; // why is does this need to be so big? @@ -91,12 +91,12 @@ function t() { expectedTimeouts--; } -var w = setTimeout(t, 200); -var x = setTimeout(t, 200); +setTimeout(t, 200); +setTimeout(t, 200); var y = setTimeout(t, 200); clearTimeout(y); -var z = setTimeout(t, 200); +setTimeout(t, 200); clearTimeout(y); diff --git a/test/pummel/test-tls-securepair-client.js b/test/pummel/test-tls-securepair-client.js index aaf8e628d6a2..3d33ef8f2162 100644 --- a/test/pummel/test-tls-securepair-client.js +++ b/test/pummel/test-tls-securepair-client.js @@ -17,9 +17,7 @@ var join = require('path').join; var net = require('net'); var assert = require('assert'); var fs = require('fs'); -var crypto = require('crypto'); var tls = require('tls'); -var exec = require('child_process').exec; var spawn = require('child_process').spawn; test1(); @@ -47,8 +45,6 @@ function test(keyfn, certfn, check, next) { // EADDRINUSE. var PORT = common.PORT + 5; - var connections = 0; - keyfn = join(common.fixturesDir, keyfn); var key = fs.readFileSync(keyfn).toString(); diff --git a/test/pummel/test-vm-memleak.js b/test/pummel/test-vm-memleak.js index f93f34127f92..c6623991922d 100644 --- a/test/pummel/test-vm-memleak.js +++ b/test/pummel/test-vm-memleak.js @@ -1,8 +1,8 @@ 'use strict'; // Flags: --max_old_space_size=32 +require('../common'); var assert = require('assert'); -var common = require('../common'); var start = Date.now(); var maxMem = 0; diff --git a/test/pummel/test-watch-file.js b/test/pummel/test-watch-file.js index 1d0ef77d543e..b87711c7a17c 100644 --- a/test/pummel/test-watch-file.js +++ b/test/pummel/test-watch-file.js @@ -6,7 +6,6 @@ var fs = require('fs'); var path = require('path'); var f = path.join(common.fixturesDir, 'x.txt'); -var f2 = path.join(common.fixturesDir, 'x2.txt'); console.log('watching for changes of ' + f); diff --git a/test/sequential/test-child-process-execsync.js b/test/sequential/test-child-process-execsync.js index 0bc4e02c65ed..205485c9ebbc 100644 --- a/test/sequential/test-child-process-execsync.js +++ b/test/sequential/test-child-process-execsync.js @@ -1,7 +1,6 @@ 'use strict'; var common = require('../common'); var assert = require('assert'); -var os = require('os'); var execSync = require('child_process').execSync; var execFileSync = require('child_process').execFileSync; diff --git a/test/sequential/test-debug-args.js b/test/sequential/test-debug-args.js index 43853b3af342..e5f9f3716119 100644 --- a/test/sequential/test-debug-args.js +++ b/test/sequential/test-debug-args.js @@ -1,7 +1,7 @@ 'use strict'; // Flags: --debug-code -var common = require('../common'); +require('../common'); var assert = require('assert'); assert.notEqual(process.execArgv.indexOf('--debug-code'), -1); diff --git a/test/sequential/test-deprecation-flags.js b/test/sequential/test-deprecation-flags.js index a243cc44f29d..77c2af569bc9 100644 --- a/test/sequential/test-deprecation-flags.js +++ b/test/sequential/test-deprecation-flags.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var execFile = require('child_process').execFile; var depmod = require.resolve('../fixtures/deprecated.js'); diff --git a/test/sequential/test-memory-usage-emfile.js b/test/sequential/test-memory-usage-emfile.js index 6b4390498057..92c103669a9a 100644 --- a/test/sequential/test-memory-usage-emfile.js +++ b/test/sequential/test-memory-usage-emfile.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var fs = require('fs'); diff --git a/test/sequential/test-net-GH-5504.js b/test/sequential/test-net-GH-5504.js index 9526993dfd12..179b3ae3c2e2 100644 --- a/test/sequential/test-net-GH-5504.js +++ b/test/sequential/test-net-GH-5504.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var assert = require('assert'); // this test only fails with CentOS 6.3 using kernel version 2.6.32 // On other linuxes and darwin, the `read` call gets an ECONNRESET in diff --git a/test/sequential/test-net-listen-exclusive-random-ports.js b/test/sequential/test-net-listen-exclusive-random-ports.js index c32273a59b2a..f46f9a01d773 100644 --- a/test/sequential/test-net-listen-exclusive-random-ports.js +++ b/test/sequential/test-net-listen-exclusive-random-ports.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var cluster = require('cluster'); var net = require('net'); diff --git a/test/sequential/test-pump-file2tcp.js b/test/sequential/test-pump-file2tcp.js index f5949085e0ae..f99ae1c5d79e 100644 --- a/test/sequential/test-pump-file2tcp.js +++ b/test/sequential/test-pump-file2tcp.js @@ -28,7 +28,6 @@ server.listen(common.PORT, function() { }); var buffer = ''; -var count = 0; server.on('listening', function() { }); diff --git a/test/sequential/test-regress-GH-1697.js b/test/sequential/test-regress-GH-1697.js index ff5754f357df..ba7f90ecf009 100644 --- a/test/sequential/test-regress-GH-1697.js +++ b/test/sequential/test-regress-GH-1697.js @@ -1,8 +1,7 @@ 'use strict'; var common = require('../common'); var net = require('net'), - cp = require('child_process'), - util = require('util'); + cp = require('child_process'); if (process.argv[2] === 'server') { // Server diff --git a/test/sequential/test-regress-GH-1726.js b/test/sequential/test-regress-GH-1726.js index 859ab6cc5e42..c5f0bba13352 100644 --- a/test/sequential/test-regress-GH-1726.js +++ b/test/sequential/test-regress-GH-1726.js @@ -4,7 +4,7 @@ // exit when its child exits. // https://github.com/joyent/node/issues/1726 -var common = require('../common'); +require('../common'); var assert = require('assert'); var ch = require('child_process'); diff --git a/test/sequential/test-regress-GH-819.js b/test/sequential/test-regress-GH-819.js index e459587d97cb..20ca75c793ce 100644 --- a/test/sequential/test-regress-GH-819.js +++ b/test/sequential/test-regress-GH-819.js @@ -1,7 +1,6 @@ 'use strict'; -var common = require('../common'); +require('../common'); var net = require('net'); -var assert = require('assert'); // Connect to something that we need to DNS resolve var c = net.createConnection(80, 'google.com'); diff --git a/test/sequential/test-setproctitle.js b/test/sequential/test-setproctitle.js index 11395f4fdbc5..40107f577496 100644 --- a/test/sequential/test-setproctitle.js +++ b/test/sequential/test-setproctitle.js @@ -7,7 +7,7 @@ if ('linux freebsd darwin'.indexOf(process.platform) === -1) { return; } -var common = require('../common'); +require('../common'); var assert = require('assert'); var exec = require('child_process').exec; var path = require('path'); diff --git a/test/sequential/test-sigint-infinite-loop.js b/test/sequential/test-sigint-infinite-loop.js index 8211aeb69ec5..1570f9c59dd5 100644 --- a/test/sequential/test-sigint-infinite-loop.js +++ b/test/sequential/test-sigint-infinite-loop.js @@ -2,7 +2,7 @@ // This test is to assert that we can SIGINT a script which loops forever. // Ref(http): // groups.google.com/group/nodejs-dev/browse_thread/thread/e20f2f8df0296d3f -var common = require('../common'); +require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; diff --git a/test/sequential/test-stdin-child-proc.js b/test/sequential/test-stdin-child-proc.js index 93bf265b8b00..0189e94d5d4c 100644 --- a/test/sequential/test-stdin-child-proc.js +++ b/test/sequential/test-stdin-child-proc.js @@ -1,7 +1,7 @@ 'use strict'; // This tests that pausing and resuming stdin does not hang and timeout // when done in a child process. See test/simple/test-stdin-pause-resume.js -var common = require('../common'); +require('../common'); var child_process = require('child_process'); var path = require('path'); child_process.spawn(process.execPath, diff --git a/test/sequential/test-stdin-pipe-resume.js b/test/sequential/test-stdin-pipe-resume.js index dbac78d78c5e..cd409a1d236f 100644 --- a/test/sequential/test-stdin-pipe-resume.js +++ b/test/sequential/test-stdin-pipe-resume.js @@ -1,6 +1,6 @@ 'use strict'; // This tests that piping stdin will cause it to resume() as well. -var common = require('../common'); +require('../common'); var assert = require('assert'); if (process.argv[2] === 'child') { diff --git a/test/sequential/test-stdin-script-child.js b/test/sequential/test-stdin-script-child.js index c5d5d6d44281..ad65734364e7 100644 --- a/test/sequential/test-stdin-script-child.js +++ b/test/sequential/test-stdin-script-child.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var spawn = require('child_process').spawn; diff --git a/test/sequential/test-stdout-cannot-be-closed-child-process-pipe.js b/test/sequential/test-stdout-cannot-be-closed-child-process-pipe.js index c6f5aecd40e2..a138108fae7e 100644 --- a/test/sequential/test-stdout-cannot-be-closed-child-process-pipe.js +++ b/test/sequential/test-stdout-cannot-be-closed-child-process-pipe.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); if (process.argv[2] === 'child') diff --git a/test/sequential/test-stdout-close-catch.js b/test/sequential/test-stdout-close-catch.js index f0ecf9a7c4b7..470fa9843cb9 100644 --- a/test/sequential/test-stdout-close-catch.js +++ b/test/sequential/test-stdout-close-catch.js @@ -3,7 +3,6 @@ var common = require('../common'); var assert = require('assert'); var path = require('path'); var child_process = require('child_process'); -var fs = require('fs'); var testScript = path.join(common.fixturesDir, 'catch-stdout-error.js'); diff --git a/test/sequential/test-stdout-stderr-reading.js b/test/sequential/test-stdout-stderr-reading.js index 82fd51cedda1..2cc029c501c1 100644 --- a/test/sequential/test-stdout-stderr-reading.js +++ b/test/sequential/test-stdout-stderr-reading.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); // verify that stdout is never read from. diff --git a/test/sequential/test-stream2-fs.js b/test/sequential/test-stream2-fs.js index 96ab97174b24..e775dd7c0ab6 100644 --- a/test/sequential/test-stream2-fs.js +++ b/test/sequential/test-stream2-fs.js @@ -1,6 +1,5 @@ 'use strict'; var common = require('../common'); -var R = require('_stream_readable'); var assert = require('assert'); var fs = require('fs'); @@ -41,7 +40,6 @@ var w = new TestWriter(); w.on('results', function(res) { console.error(res, w.length); assert.equal(w.length, size); - var l = 0; assert.deepEqual(res.map(function(c) { return c.length; }), expectLengths); diff --git a/test/sequential/test-stream2-stderr-sync.js b/test/sequential/test-stream2-stderr-sync.js index ccbdc55e4fea..c7daaa6b0832 100644 --- a/test/sequential/test-stream2-stderr-sync.js +++ b/test/sequential/test-stream2-stderr-sync.js @@ -1,11 +1,7 @@ 'use strict'; // Make sure that sync writes to stderr get processed before exiting. -var common = require('../common'); -var assert = require('assert'); -var util = require('util'); - -var errnoException = util._errnoException; +require('../common'); function parent() { var spawn = require('child_process').spawn; diff --git a/test/sequential/test-sync-fileread.js b/test/sequential/test-sync-fileread.js index 24a80d96c260..6208e4c619ef 100644 --- a/test/sequential/test-sync-fileread.js +++ b/test/sequential/test-sync-fileread.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); var path = require('path'); var fs = require('fs'); diff --git a/test/sequential/test-tcp-wrap-listen.js b/test/sequential/test-tcp-wrap-listen.js index a2c07a7a9ce2..44254c3d3f39 100644 --- a/test/sequential/test-tcp-wrap-listen.js +++ b/test/sequential/test-tcp-wrap-listen.js @@ -12,7 +12,7 @@ assert.equal(0, r); server.listen(128); -var slice, sliceCount = 0, eofCount = 0; +var sliceCount = 0, eofCount = 0; var writeCount = 0; var recvCount = 0; diff --git a/test/sequential/test-util-debug.js b/test/sequential/test-util-debug.js index 02d30449a994..5f0306e5e016 100644 --- a/test/sequential/test-util-debug.js +++ b/test/sequential/test-util-debug.js @@ -1,5 +1,5 @@ 'use strict'; -var common = require('../common'); +require('../common'); var assert = require('assert'); if (process.argv[2] === 'child') diff --git a/test/timers/test-timers-reliability.js b/test/timers/test-timers-reliability.js index b4332468bc2e..76aa6ea31afe 100644 --- a/test/timers/test-timers-reliability.js +++ b/test/timers/test-timers-reliability.js @@ -1,7 +1,7 @@ 'use strict'; // FaketimeFlags: --exclude-monotonic -f '2014-07-21 09:00:00' -var common = require('../common'); +require('../common'); var Timer = process.binding('timer_wrap').Timer; var assert = require('assert'); @@ -44,7 +44,7 @@ monoTimer.ontimeout = function() { monoTimer.start(300, 0); -var timer = setTimeout(function() { +setTimeout(function() { timerFired = true; }, 200); diff --git a/tools/doc/addon-verify.js b/tools/doc/addon-verify.js index 4d1aaab3cc75..cc80a7bd3290 100644 --- a/tools/doc/addon-verify.js +++ b/tools/doc/addon-verify.js @@ -51,6 +51,12 @@ function once(fn) { function verifyFiles(files, onprogress, ondone) { var dir = path.resolve(verifyDir, 'doc-' + id++); + // must have a .cc and a .js to be a valid test + if (!Object.keys(files).some((name) => /\.cc$/.test(name)) || + !Object.keys(files).some((name) => /\.js$/.test(name))) { + return; + } + files = Object.keys(files).map(function(name) { return { path: path.resolve(dir, name), @@ -58,6 +64,7 @@ function verifyFiles(files, onprogress, ondone) { content: files[name] }; }); + files.push({ path: path.resolve(dir, 'binding.gyp'), content: JSON.stringify({ diff --git a/tools/doc/json.js b/tools/doc/json.js index 4c57aefd797e..07aef469f3e3 100644 --- a/tools/doc/json.js +++ b/tools/doc/json.js @@ -283,7 +283,7 @@ function parseSignature(text, sig) { // [foo] -> optional if (p.charAt(p.length - 1) === ']') { optional = true; - p = p.substr(0, p.length - 1); + p = p.replace(/\]/g, ''); p = p.trim(); } var eq = p.indexOf('='); diff --git a/tools/test.py b/tools/test.py index 4baca769c25e..217e72b870a6 100755 --- a/tools/test.py +++ b/tools/test.py @@ -1310,6 +1310,8 @@ def BuildOptions(): result.add_option("-r", "--run", help="Divide the tests in m groups (interleaved) and run tests from group n (--run=n,m with n < m)", default="") + result.add_option('--temp-dir', + help='Optional path to change directory used for tests', default=False) return result @@ -1337,7 +1339,10 @@ def ProcessOptions(options): print "The test group to run (n) must be smaller than number of groups (m)." return False if options.J: - options.j = multiprocessing.cpu_count() + # inherit JOBS from environment if provided. some virtualised systems + # tends to exaggerate the number of available cpus/cores. + cores = os.environ.get('JOBS') + options.j = int(cores) if cores is not None else multiprocessing.cpu_count() if options.flaky_tests not in ["run", "skip", "dontcare"]: print "Unknown flaky-tests mode %s" % options.flaky_tests return False @@ -1538,6 +1543,16 @@ def Main(): for rule in globally_unused_rules: print "Rule for '%s' was not used." % '/'.join([str(s) for s in rule.path]) + tempdir = os.environ.get('NODE_TEST_DIR') or options.temp_dir + if tempdir: + try: + os.makedirs(tempdir) + os.environ['NODE_TEST_DIR'] = tempdir + except OSError as exception: + if exception.errno != errno.EEXIST: + print "Could not create the temporary directory", options.temp_dir + sys.exit(1) + if options.report: PrintReport(all_cases)