diff --git a/.eslintignore b/.eslintignore index 507305bc8f0af2..e1376c84099aa2 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 bf3fc3378f2d92..33a7919d88c9ef 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 cb3a1744cca853..f5f4bcf5dffc4f 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 a99b112508c448..94eb41995367ed 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 aa573844b790a9..7472deb5991755 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 00000000000000..d8d2b57331f7ef --- /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 00000000000000..5f0519bb3b45ad --- /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 00000000000000..99c13206d7560a --- /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 00000000000000..461378758b5951 --- /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 00000000000000..2f0eab6a821f42 --- /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 00000000000000..9f89649138cd20 --- /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 00000000000000..989d9a994fa04e --- /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 00000000000000..66f966f587bb7f --- /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 00000000000000..661dff43b0103c --- /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 00000000000000..8a59e6b48e54df --- /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 9a66c317bf337f..ed2c5058a49288 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 a3fb229161b31e..bab280f325ff27 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 9fd57040816447..090a3eef51acbd 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 e9e4b3711cbf72..029b63fd8e432c 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 d300b274a1627e..b29c13694b00fd 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 6343ca781c3dd1..5c2596fe605f5b 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 f90ec1c429a826..a731d979ac88da 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 7154b7ae50db13..1f9d6703b7e014 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 71c59db3bf747c..78bf3c2210bfca 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 ef68b93b8afabf..86bee216487683 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 16854d46acce6c..410a74498ddeaa 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 a12489fdc14123..823e9361901cb1 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 92bec13632683a..0fdfc078749046 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 82f10d9ca16e79..6b505dcadfa313 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 fb2cbae8914ee6..aedc35208f6db1 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 aab07b9ce35be3..93416633747fb4 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 00c1c77915c93f..aa1f0b074e5043 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 32d2218982db35..7e898596f5a18e 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 73724b39b96ff2..bdc71590f41c9a 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 cdf424339ed06a..5d98f501f68c65 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 d5d4ec62ec7549..99e9d0e26d8720 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 b76ef0093e1847..76d96233ac4bde 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 b58bcd2cf422c9..8bcba2cfbd51e9 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 347b22e3cad284..4a051013c4a6e1 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 4d5caf2e0ee0e5..cf2f24ae938adb 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 f7fbf1ee72a948..97d7388a291027 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 251742a0e1b89b..f01cedd702da9a 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 03386aefb5b78d..4574ae452b231b 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 1cee348ba1ca9d..70abd6c6473f24 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 fd36c6b21f7ee0..07e99ac735677c 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 5b1cf407820d53..5f238be5bff8d8 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 2adbdcbcd2d77f..57e95c266f4ff6 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 305baa2cbd2f03..ddb1c5bfff9b63 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 02d6e7ed374a98..1361e2a6e0ec0e 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 5377c84d5d3c7e..581f62f129f120 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 e3a258b1cddd12..72c5374f7b1262 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 e2221b759bd0c4..f524790fb2b13a 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 11733493450bdc..3e52ab45f66127 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 d9f0a5fad4c6fb..2daebb5e301e1c 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 6f97991f98c8e3..8e79d295bf5ea6 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 04bd270b185974..64def982c980fc 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 1a62414a49e95d..e6b41fbdd89b65 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 1beae0e4e4b536..755f8f0d65d1fb 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 543f977d4ae400..05452c18084938 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 2d537f53840a35..ddf7cee9d48791 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 76c7487b7bf3a9..de6f562238314f 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 45155fee936bbf..6489d6327d0e29 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 aa75950c217f74..5b31661507496d 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 9a4f91a95ce3b9..c59e8fec36df54 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 3409fb2603ae9b..06ede7fdef4aa9 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 0c616ddef21400..6151c57069ad7b 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 49cfc8a06053d2..3a780b5d5f294c 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 34aae9395442a0..d63ffac8b705fe 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 63d767a1f4cd7c..35a0687b9f95ec 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 d3d66e32dd1313..aaadc904dd3980 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 b6ef7d5b78f70e..5c1b39864c5508 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 ff3dfb26e529af..28322f95c40939 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 a1000907485519..92f53a9c407fae 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 763f3e3cf75e0b..cd2203b79ede45 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 94f70eba5de6cb..d7bf4ed8bee784 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 32264a6604eeb6..c94453cb3b05a4 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 6ee328d5222049..a70931d81e8977 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 bbd0c737eeba49..5591b4f2b38e90 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 3bb5d51f0127a7..32200b9e6a973c 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 14a281ab3ce4cc..6a977d7cfa72e8 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 81ed8b41ab0198..f5232dce9c8df4 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 00000000000000..e69de29bb2d1d6 diff --git a/test/fixtures/keys/Makefile b/test/fixtures/keys/Makefile index 143986274a6b93..1148e529cd9595 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 00000000000000..a36e746a72e06e 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 98d046e180f11b..7e50683c6633e5 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 04befca6370e1e..bdca60d1b4fd5d 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 27547edcd84b46..d7c50a1e86b656 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 eba5c66c464981..4c2f12f7a97c28 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 2a423f97dee7b0..6448ad7c76b07b 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 151597de14cb0e..7e2f8cd402d658 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 b92d234852967e..fd78a2936bd88b 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 a712490d31f566..ad24683b34d49e 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 b05f5e9e1d7168..0f696806be03fe 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 ab86eb1e38f7f4..221001ed8952d0 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 7805fd21935377..18d9dfb4ee998c 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 0b17bf5f97ae52..bb1569601c889f 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 1e6b030393c6cf..187bbd2cfcf7f7 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 cacd795810605a..1d2ec175c5d957 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 3c0e2d8e379fd9..22f61a36f947df 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 7d1033c3ab2b1a..cef53bfb3d35c5 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 e99c08553a916d..6e1ced4124f2a6 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 bb5dae05a9b03a..8866ca8514de7d 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 ef73c52c889dff..401581f31d5caf 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 50c69ca681019d..3bb403feb3221b 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 e83b05768433b8..d245cca4941ab5 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 a1046b725e93a4..d4dae642af882b 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 15f95fcc11699a..b98edc46ae2a6e 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 ab8fb565a61e54..9b17aa68f186e4 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 eb3eeb1294e727..5d2c677240d1a7 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 f855cdd2f7dabd..18c27dbac87799 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 c23dac051fa5f1..32a71f0486e47e 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 aaf3fbc8d2f48f..5c345ac8c0c376 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 7256c0d8e36088..73821ae53d4f5f 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 d01ab0b540b3cb..a7ca9907444181 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 179263478b84b8..23525c14d822fb 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 6b4c824cbe5eff..19d0120a90abfd 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 42b1ab14cba76f..bff0433a144b09 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 b4d449a6f57ef0..0fe1bf9027f580 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 00000000000000..68edefdc175317 --- /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 b6d695f5e81516..e9c01fda773d9e 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 b2f60f3215e850..768e38e8eff389 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 f3bd127b408b08..8e5d66f5f5d7c7 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 c25de262ea9779..522d97ece196c1 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 efc3a72c662595..94ba85a22761dd 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 b292970f94184a..32ed6dbd67615e 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 8d0c0eebbd14e6..07f763a76dc419 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 d473d16e92159f..1a1d9c0c494b84 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 be002bb7f26d1a..8eaf2d479761db 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 d358749f8efc01..aac5b18f718cb3 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 eb2f4a531d0b38..ea61e50bf5f04a 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 35da378631aee8..6d44389de735a2 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 05371d6d793fed..ad135a9113627d 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 d7b4f486e21422..cf1a3fd8eb200d 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 a37e1dbbbd7574..1efa5a65f9cea8 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 89db9cf81fddc7..6980810485c964 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 e0e83b6007a815..f13da684fbdfe4 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 25b811a8caa991..711c5d227d6b07 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 0ab05080a2cb87..a381af9631e0d8 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 e253399b96ac30..c259ffffda3dee 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 d5255bf83ca8e0..5766dc865bc975 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 f700960490cbaa..86cd6576c73b98 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 6a61bddd8a19a4..35a730b0da6c42 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 95ec26a88d0de2..dd89557b61121d 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 b4066641bae970..de34f3eb8ae9c3 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 8bc7e4c35541b2..42c43ed8882b78 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 27b4d72d2fc612..78856cb55edebc 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 c39dc93293aa8b..03ea340236ad34 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 3f09388265b89a..6cdfbbc9a24c71 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 3714d3758d0f22..c3705ab2a4d7e0 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 1398dac165319c..4eaa45ee7aefb0 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 646097f9454c5c..4455b867e30108 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 34c69a1fc597d2..122a65825949df 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 d2347849dd5b9b..79e60f333b9d6b 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 c12b24579375dc..4a371b83fb045b 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 5ae85acc54d9dd..bc414938b581e3 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 8cf08a7bd5fa71..409c0af7ca0d31 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 1ff6e4d914f7ec..d5fe6d43b64d5c 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 577a33a05082f2..b76a7cb5e5a8e2 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 289323002da4bd..0a12e4f54c5306 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 1a42850e9b2bc1..076a59108b09de 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 0253cafcf49766..6426e1c224beb7 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 00000000000000..97d55a20b1ac51 --- /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 6ff68252d9d867..3821551f00a32c 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 7749e42f608c60..fb58daee0cffdb 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 4c6dee347bb8e9..cb9b090f08e801 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 6190fb517e4d1a..fe536b5f2a43c3 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 474e4d69f225c6..95d121df875bb8 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 0376546d286b51..f0f98fbdbfb3a6 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 8b463ec97bff45..ad15c084c5924d 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 8ee6d091cd524a..5ceff2bddfaf9d 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 c32b3ea6d3b18b..561371afb027a3 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 a4de1d33a29b8d..55df57c9831ede 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 ec42773ef55856..04eac2e8ce63d4 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 e29dc01561903d..2a96d24a8a3459 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 88a0f887cc2cab..65da9865b0dd2d 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 76f5cc69a9f716..ef9f7728bad3a2 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 38886af5279a6d..41f73e1255a7c5 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 eb3c5892bb5e21..985d15ce6475e6 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 a80c6e57e4b151..1ab038df48e432 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 7846dbf2778b9c..f152e33e98f087 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 f8a927398034cb..14025694dd2656 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 806f5de18bbb1f..c4b8990beb2ec2 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 8286d58d1e44ca..9814b395552e9f 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 f315aed1a9f139..2bc4ce5433739d 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 00000000000000..a143e67ac66cd5 --- /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 6572ef50afe845..7a950458b87271 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 5fa82f236c1dd9..7376e70ba780e2 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 6d35534cb5eb56..0bca97fb294f79 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 9f8c39eb04daaf..c68b2fab70aff5 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 ba6faa62d86cec..66cdbb92ac8f1b 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 e307a23e2451db..005695654f9542 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 2aac7ae9cf7588..498a17a0e5b053 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 29ab92757bd817..883085a9cdaab2 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 d689a45e36dfa2..6505ce9b1ec886 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 fcb8d026bc547e..4bdd0d6520d7dc 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 ccd10e00555384..ddaa162c8bff10 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 a34c5e2eb6b8db..80c2d23e42ef55 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 11f3d38d2ed046..a8ab4339d8a398 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 f81dec398f72d1..58c8b69839ffe6 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 2add3d28c49760..083dab6d29589c 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 cdb1fc75f94215..7d482b78f63a7c 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 cb651c5f5afb86..a1aa18a10f88ec 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 330dfb5d57092a..4a3dd2694121f8 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 1fbd7f07a9d520..e696327d4d5f66 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 abc7edbf598097..3362e8c534eaab 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 6fe9f25fb0d887..e5b1affc0afb55 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 90e7210ce21aea..2bddb01cbd8ca5 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 93661b419b0bbf..f0115018ec1879 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 99dbf413e3a4f8..37dbc30f4234d7 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 fd21dcafe0858f..d0a468419b923e 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 e5f9f6748b178e..ac01d66deee544 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 0fba3001b543fb..69a80b7ab104d0 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 f9b5648a6619a7..e30d3b21f3af57 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 7530c9edba40b1..a97b300da02d31 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 2b9e704e43c32b..4bde30d17cb8c8 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 8792eb1ce5459f..35632dbf537202 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 1c4c7cd8085ab0..55133ba67347de 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 918e3288e8dc91..bef5e942e057a1 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 0b5773411ee592..2d30ef6891008a 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 f966b5a98c80ba..4e2ddf42b6dffa 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 d3a83fbd5a7060..59b5d1a240861a 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 cc30fd24add340..82acd65c585880 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 90f686b5422c43..3c8260e787470a 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 43a14db0cca362..34ffee3600e5e9 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 c5b75c819d17f9..ebfed8b2ee33b1 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 23076128eddfc1..5b9f2f3ddf0f41 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 48a60609e7be88..77c44907b62d8c 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 5e754698d0a018..7d80c7a32fe0c4 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 a260aa779855aa..c1e6540f0184af 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 85845cc4443b32..cd1849201dfe47 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 e85361475f894e..918ba195d4be18 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 6c403cd2f294ae..51f57e89bc6e22 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 1085e7942a59bf..d007ef663fdede 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 8993aadf51a46e..396979a923d1ac 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 f09f130ab489ed..11cfab0bb876c6 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 fe915be34efc2b..02309241514683 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 9cc8106ea6f80a..735daa51070014 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 58e84ad21ba4ee..3ed2c9520461f8 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 5cae35b69f95d5..15c6e7025978e2 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 0044548b736df0..e95760bc2d9a4e 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 1a88faa01fb8a6..a2552d95b215d4 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 0863e0cdba4ddb..c5a016f9ea2c36 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 fcbd729a5ed850..3474fc4cb9ff2b 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 a15a16404df003..4fbe64437eaff0 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 c7d53117d587fc..667abb81765f91 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 59b605841b4440..0818f2b7f63d8f 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 3ec1491d2b4768..f00df61ea7310c 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 c5c5264c0dde3b..de105737969865 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 b08f42b5c23f85..9a9b85ecaccd2c 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 2c9c6e3db9a584..a81b055494d3d2 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 12a4ce7b41b679..53312c6e8d7186 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 123d6608b4bb4f..1affdec6260c0d 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 dcc4e989cc1ef2..cb3e5a464faba9 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 5f2b63125a1d0f..f7cfd25f4b9b4c 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 2ad6cea4379b2e..5d5cb40ec1eede 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 72c0a2b19b712f..7ae9e122cae8be 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 5b38ce6ba814c4..eb0ed5caeb6612 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 8e2388fa84d809..8572668f666864 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 eac0fe51e2206a..516a02031ef247 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 9989c9b969b879..f9c865f3e630a0 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 06fd60f5572ba2..6ac1c68d0d3665 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 e24ded11d1a7ec..4d7a32c1dfb26b 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 edd03b2178b2ba..ed18def8608820 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 00000000000000..e3388ee0dcbd96 --- /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 ad8de89f2038e9..96606028bf7a45 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 d8d30a8ddbc25c..1b80b5c36e1e64 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 ef9553c8316841..6800e893e329da 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 00000000000000..1cbe37cf0cc443 --- /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 e118738f664083..29961ff3a5e84b 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 4b120311d7dac9..98ce0f75b916a8 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 974f446dd436b4..fdc407aec667ba 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 3f7ae98fa25820..477d12b25827b2 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 dd696f4dff608a..baaef855b1e6e0 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 efe241419397e4..715f8ccf79df92 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 ba9fdd658c3864..8328afb01c6478 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 457424ecfa9397..e403b401fb603f 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 5bbb3bbc946f7d..9065939ccbd798 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 e676643bab4911..fc7dd1d9fe88ce 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 dc2d5583ddbaf9..922dc2095714be 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 cac1caf752bee6..8dc7ba7418dc88 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 5a6f90507cf303..faf2168e36d0be 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 21cd3e69dfd746..1e5a910424d737 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 9ed6077b943aa8..83a0d0684cf637 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 f89f7698c46ebd..0d30bbe1da3069 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 9a4bde26cd22d6..adaeba2b9459ea 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 604dab7cc2c1d2..c415af64f9dcd6 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 348fd2e519ef64..62a4187841bdbc 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 5752e5e924cd1b..7a205dc07df3ca 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 d409dc62d008d9..545a9c1fef11c4 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 bb004f864cf468..f10f3ac26b4b10 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 05639a2a42c5a7..74fe7586726cbd 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 fc8a753f2485ce..8a579cd69aa5b4 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 7ecaaa93cfb04e..2042c0262a95ed 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 4fdef2369bb168..8725111324a869 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 c8b3bf26e0804b..206f4273ec70c7 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 6f477d6638105d..4705548d3a385f 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 7033ef8e7079f2..99d72988479928 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 a866d39c2cc735..349e869c1a4fbc 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 19c36b0b2fd27f..5fedb529f82fcc 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 aab903420f0acc..f459961517852b 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 98ed839241c2c6..bdac0566c33a42 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 10c40ec0310708..df01ae64f81dba 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 fd52a0b62d11de..0e997694aa7459 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 551f0150bfb3de..a4f9517bd52ff3 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 2be40836a04ea2..f7d5e5a40d8679 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 00000000000000..117075f68264b4 --- /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 5163eccc262ffa..beef89b25ccb98 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 0445625bace642..50d909373ff5b0 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 66551a780aed9e..f5bb1f84c310b3 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 44e179f27a800c..2adf8c798dff65 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 65ebfabde2bcdd..04561959de130f 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 df605958cf42df..a195ce1938b9cd 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 ba175ecf763ecf..f6d5d75a88abbe 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 7f34c18bec0897..2b41dadaec7857 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 e77bf29ed25454..83506c65d6f3cc 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 4ece1d0c7b6f29..ed3cecb6f29719 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 011b6f7132e9bf..5d93a381c7acdf 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 7288febf9e6bfd..1219c330386ca5 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 c6b1adb3cb7a7a..280e5d9dabee66 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 f6d00c72a0f78c..c321f699d7a89d 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 d51d51ee8eb4de..3e0fa521f75334 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 8394fc16599ef3..9b39601e2e20b3 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 7a4ad77cd321e3..f0d0196ac2f9a7 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 37de5ee33b1477..fe873d27c91447 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 77534920ff1451..fb5139f71d65aa 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 2dea0a76cc1bf4..4a7729ab98a062 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 cfd9cd3659ef00..479062ad4710f4 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 ca758546c2bcfd..ce743d93003249 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 e67c53fc3b076a..072a6aadcb8c62 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 f0f7bc65b3c7eb..8b11612a1286f2 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 c245ddc2ae7860..38452be6e6a954 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 008e831c61fc9c..a2ce3966ae1237 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 17f251cec3b6af..fc27eb1b9b0751 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 b293196ad45c7e..9b3ae15fc393ae 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 2911591f9f486d..69abf486316ff2 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 af92ca93206f18..28e90ddd611ba9 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 96177122b7ba21..76432ed3488240 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 144ca58bbbe2b9..9cde6df1645d01 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 79cfc7da6c9255..4c4d27d703a9a6 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 aa28d180dae6ff..728993ee1bb023 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 45ec1fc9099955..ed7c9471e0397f 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 81ad90ef829c07..8e341015d96b3f 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 b2e8f6ea8b4e3f..f8cdcbdc4e76dd 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 138a78defb260d..ae89d9aac7b3f7 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 a071b625ef26d7..8e8f45f5fd7d20 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 4d53bba6c4f5cc..8f9d9bb4aa50f7 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 eccd7a43a0825f..7c511b8d5e18ab 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 d4a8a1b7481329..414524e5405ecc 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 c2b936a1061d52..63f8d37828e53c 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 4252d623679f65..70f7611dbaddae 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 54e7b88cf022ca..8b45e8c705fc84 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 083eb3e7ac03c6..07de030aa0b323 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 718d052cd24c27..eab5db8f70cf92 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 b4a3af78d8df3b..f30ad1d218e645 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 eff96da98e4729..5d8855869a8e4a 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 4fc3bcaa98afc8..cedd773dfbeaeb 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 7e927d09bae668..932bae3f8ff095 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 fea8c2d4fcdc5d..8d657528d05561 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 999eefc1eff518..0ea36f158eaf9b 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 00000000000000..96464cf3b22fcd --- /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 4b7e0df1a50240..30773f8f11380a 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 b18b5a0f2f90d4..08eab8d5a8afe2 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 0e2c5b110e9292..ad186a3507d1e7 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 65dab752f12e6d..2516773f08786a 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 f193e979166da7..5c11be2903c4a7 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 e7b5f8f3fe886e..6b20cfbe93377b 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 f849457d643894..ab461902911a93 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 bf3dfe4e8b1651..b5d4dc35e4fe00 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 e229bada3a10e2..5e7739daa5b406 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 179bca51ec2fe0..42927549eae395 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 257492659bdfde..488b5ac56aefa0 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 66497ac2d3b6db..bb3c361f882a14 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 c0dab8956593fe..6c55a65007aa88 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 5572bbf18e291b..468faf76029613 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 233128d792d068..b3997f74f17721 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 5cac38a1d7db42..e026c0b583cd9e 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 73945af8bc52b9..24f138f46bce11 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 b984541bfe9eb0..154af1841a98cd 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 a82a433ab1af05..89ac52d2bcaa50 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 1a4a78b3c0781d..a312fb277fdad5 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 2f2f17d9698fc9..0bf9b8965d1184 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 0e5c4ded011a43..03813dea003eaf 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 4b7ba61f9ceca9..1b46994dc37d94 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 c71b383bcd7409..6d28015b385e15 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 05cc299f56888f..15f779d3b12269 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 baf0485b3b80b2..adc8478beef4af 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 6073144085843d..2c34bbf2da86fa 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 6bc5cb57aa1187..a5928800381cfe 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 10e0dedf53ec3e..7571527b73800d 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 d9b4d71d484640..c5f317ac268e2f 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 f2c65583b3656b..2708a3e6af5448 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 66e8fb6b352c56..10166b4f06a692 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 647d3e3569ce00..ebf0b2e4d8aed1 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 484580f1e72fe5..ce283757438192 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 6bf7d5059d0116..86a0444c953d27 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 1ab3b4743913bd..6474d8e4088167 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 4cfaa5136b6a55..84668c8657c453 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 f2245345e3e4bd..7ea68dd0515799 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 198fa6a8c52d37..0376082262dd78 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 549c26662f717a..7938ae04d6591b 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 4818a9ee952026..bb43d52506e5dc 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 f8a8923498cb03..7b9b69d309aec5 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 12a031562bf6f0..37ab4987eebcaa 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 a9f6064c7e7277..67bb32847bd7f7 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 e02ff98d3c7454..b46665efc94ff5 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 0e8789d6bf5555..200de24877bf79 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 585d6c327fd592..9cc32db880ea88 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 8112dc733a7205..38f8da3fd512e4 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 4bead73f68ce5b..258c9330a96018 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 b38f57a4ff0ba1..332930c813a3dd 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 08da96f92c3a0f..251695c9f723ab 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 031a0da7e395db..88a70fb58e2cf1 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 0d10533b0c496a..d8601dd04a4d8e 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 d67233aff7a498..f09cf95f370bce 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 0d9c0653c0dc66..21621ff3fd114f 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 928ce31a8ebe7b..fb2114f44dad19 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 965fc82c05a1d9..10d314f4eec254 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 07edd579f1deea..57e295e5383550 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 c24c273b6f20e1..bf76b93690c840 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 762f0500ad3e60..eeb3d3f4ccc692 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 24833ece051e9e..4e33028da2f7de 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 a7dcad425310b1..0da979e337486e 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 90f519b5b5d738..8239a380def66c 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 e7a7ecddd2385d..5a8b75d4dc1f19 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 a6fcda3e62a517..d8193123d6f3af 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 47fc458ce9713b..4a5f90216070c5 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 b637838c0c65be..b5f1b4f6b73f49 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 f73270f2ff53ba..5b07dd11198e1a 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 2d60877de83662..900e090921b712 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 cbb65facfa7073..2d62d639077634 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 913bb7b0b4db09..63c78759cab60d 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 4cd89599fee730..6a38baac5dacbc 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 a2f554a0b8a004..e67359eff2b29e 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 9eddbdd90d00c3..7d7cfb6b2b3307 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 f2ecb87ce97a75..d046c5ea55e498 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 b58bce143585f4..99b73d7277aa52 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 e912e1039ff558..4bce87ffb9dffd 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 8e4001f8022f1c..18012df3a41d89 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 a8d9fb38f25090..ab9d9c5d72cae1 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 4218bace2b878f..399771e46a11ed 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 46d6f92f2b9df2..1953503ef9be2e 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 60417ca893300d..d2bf8f3f306f6d 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 8e3e04b966010f..acf1cfdb030439 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 ea9a315cb1a6e1..40e09035a98e90 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 e45c913c94f559..11ee45915c8395 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 15b510e7f643cc..3b529bac1f2e9c 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 1d87d7f920c052..81e57d06eb3bec 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 135629a243d66c..e4e33738b33206 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 0b22d3dd04efc9..9d0034e2fc9c7d 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 ba3f0c5d1d9ade..1f03e2be42f577 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 796f6ee0aa598a..84146ed4817775 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 acddc2f41a45e8..d8faa1f5a33483 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 abb785ea0fc79c..ae11e35ba2784d 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 a71472d46442ab..62482d510a6608 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 bcfc4616ac6264..9486465602ce9b 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 0c76af970a1fb7..c046a3024af317 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 97b2c0734f60d5..b42053db3b1895 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 466bd064b8decf..8a47e397ce97a8 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 730a78a072c663..cef91e58e78c3d 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 00000000000000..f72530b5423886 --- /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 081688cfa5e812..c9ca3eafd64ebf 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 794b3b923be1df..6b6dc583715849 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 08f28b0153fecb..ad72ac4047747b 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 b348330d200d65..edd5865e8f610b 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 aead4a4e7def64..971c485a4cf986 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 8c1864f1a7da01..dcc50a5171ad28 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 c0b24a4275be86..671c676e350e3a 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 a716c6ed645cbd..8f26d28816b60c 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 1c84814363a641..ab0c38f6084277 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 e784e262959d97..0b379e0eb45ad0 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 61458142bc0115..95ceb1aa59aaea 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 ea40205bfff06f..d89a4e9930ca6a 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 e38671fd6f9de1..9905fc45bdcd24 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 5c5a797c280a7d..bd38cb55f7a17b 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 5cc3021ab8dd7e..5545f4512d5f39 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 3b080432e49d44..c7519ed770fd50 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 f42ed1d4ea7702..26c20264735926 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 009fa40b631ee5..1f65391480d59d 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 f33177455f8943..f65440ed93b1a3 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 ae07551ef98088..374ac02a2f45b5 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 f833108ea3f9e0..efa5c0aa9aa31d 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 f7919c545aefb1..2e17a4931078c7 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 6f1e9a91a8344c..d3b20d5d8a4cef 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 cc9413b81e78d6..8b1bf0998aad30 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 d970b2ab013446..e9443f45357995 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 57180c9ce9df56..11128783871fe4 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 96cb6944ef6a97..32b1583a0c4840 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 fca7a1a77dda67..50ce9037f8d755 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 3cb0eef2d56268..cdf8bf5644f675 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 a9b1c78c91a0bf..0db2a613afc9e4 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 7b41d0f5a9ec23..c2c6e518bbc4d8 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 fc0f1d5e858d00..1fd1776ca8199f 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 57f9c03ec449e9..a33a2e5ed27209 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 dbe7b6890fd218..5e124dc89f7b87 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 5098c7e46ab6e6..cd097be24384eb 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 3a891283509b9e..a9db5d10e4fde7 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 24fee56df7b655..017a5ab6afe807 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 6761671e1997bd..00028ddbb74728 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 5831c40e77e930..d88096765694bd 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 9ab883ec8b6dcd..b557356716a004 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 700532bd5a397b..864361d80a6dfa 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 68bf30dba3cdbc..3724944821343c 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 d21cbc6c2635a5..cee924d5b13068 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 fc4a6df30f8ed8..eb5566fe2bc28f 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 96c615c44af10c..8f9cab90eb5a1b 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 e146d48343aa60..b09eda85209807 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 5fcd64b8ba9094..4034441615ca9e 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 e1cd2ef01e5176..3fe3cf1b66a88e 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 01df6ad4531e4a..94527598ca27b1 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 678cf3fbd2128e..d2e7d7bd8eacc2 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 d44eeec18decd5..a0c29762330133 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 cb6a90dcaef321..851bebdb088adf 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 20a3792b28578e..5674f582426f1f 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 5ff194e12dd8d8..fd41be7564aab0 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 f7f3e4f3df7d76..71e6ae9eaa0b73 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 647edb22b44db0..7d90408b64c2c7 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 2f008615ebaf54..78ee144582741a 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 86fde1b978ffb2..e4b27c9ebb8579 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 5a46a452b91634..cc106a15fbfc61 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 e3cc6e91cb432a..81f9b57593ea2f 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 85ce2d6e8165c8..9786ee54a7cffd 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 da14a041face31..2b32eccf408ff0 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 fb9cb764f8422c..a5f5ad9415a828 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 d7d0ffe3af6157..d3419af559a2f2 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 4b48b0d474a88d..75748b24e193ee 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 e9511e59230a84..b4dd57bb54d234 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 2a9ab11107f147..4e86182137de29 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 948bf4910208a5..0cb748d603d0ff 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 ee981a157ad761..d05a90d48b5ac6 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 baa12aa57666f3..843cc423072225 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 c02ff33fb5eb63..b47deddd8889e9 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 511eca613a5229..b7eb31d2c5f48c 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 5808bdf04a8f14..70c102efd2862c 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 7e11b1966c69bf..1a491c2ca1f261 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 93966cd85d269a..f04dac9f0699ac 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 49f4d139c148d9..14c747fc433692 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 e1e81bacc1a499..9850c6078c5320 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 46bd83960bba36..38888b68be7084 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 a1d9adb6d9b996..b1d35935e8ab19 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 4c53ca49ebf758..fa70c5f14dee6c 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 9aa260a7f3149d..826a9c7c79793d 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 67194a3dd77f53..2e5c8670553138 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 7b57803dd4ec93..4e08e9e9d1cc9b 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 2586aec59b2d94..ead7de9e28dc47 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 bd852e45f19410..12a6fecc7050e8 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 08132e3c7594d1..d1be5311db0c00 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 753687e67a5589..d9d2b64cc73d62 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 c2ec7fd81f1691..46190555b27263 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 d4fdb3496423eb..18223885d6cc19 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 4fd66c03907aac..04225bae421b1a 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 a80806c2099cb1..8d2d88b74f736f 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 67f9dd95aebe5f..11cab1b8b6230e 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 807e3c1415154e..44d6973938debe 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 fe921dc0058374..564a3f7f42d5a0 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 62ba69d3fde033..d2e96e066d2fb1 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 b289a85644a068..87497b2685f5d3 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 2225da91edcf5f..d911beb6b09288 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 aaf8e628d6a2bc..3d33ef8f21623f 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 f93f34127f9219..c6623991922da9 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 1d0ef77d543e43..b87711c7a17c45 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 0bc4e02c65edb8..205485c9ebbc48 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 43853b3af34218..e5f9f3716119ed 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 a243cc44f29dd7..77c2af569bc92f 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 6b439049805786..92c103669a9a85 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 9526993dfd12c2..179b3ae3c2e241 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 c32273a59b2a50..f46f9a01d773ce 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 f5949085e0aec3..f99ae1c5d79ea6 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 ff5754f357dfc1..ba7f90ecf00951 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 859ab6cc5e4253..c5f0bba1335264 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 e459587d97cba9..20ca75c793ce24 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 11395f4fdbc52f..40107f5774962f 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 8211aeb69ec5db..1570f9c59dd5d3 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 93bf265b8b0020..0189e94d5d4c8c 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 dbac78d78c5e12..cd409a1d236f53 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 c5d5d6d44281e3..ad65734364e707 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 c6f5aecd40e262..a138108fae7e01 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 f0ecf9a7c4b725..470fa9843cb9de 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 82fd51cedda1de..2cc029c501c162 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 96ab97174b2478..e775dd7c0ab690 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 ccbdc55e4feaf9..c7daaa6b083205 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 24a80d96c2601b..6208e4c619efc7 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 a2c07a7a9ce2a2..44254c3d3f39aa 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 02d30449a9944b..5f0306e5e01645 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 b4332468bc2ec3..76aa6ea31afe4d 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 4d1aaab3cc75a6..cc80a7bd32906f 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 4c57aefd797eba..07aef469f3e383 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 4baca769c25ee5..217e72b870a6f8 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)