From b940e0fd86f29694c571e4fef5b49434eb1cbb8d Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 20 Feb 2014 20:52:26 +0400 Subject: [PATCH 1/9] gyp: specialize node.d for freebsd `node.d` should use `psinfo.d` instead of `procfs.d` and have statically defined architecture on FreeBSD. --- node.gyp | 34 ++++++++++++++++++++++++++++++++-- tools/install.py | 2 +- tools/specialize_node_d.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100755 tools/specialize_node_d.py diff --git a/node.gyp b/node.gyp index 28714b3f7bd..c24c230b650 100644 --- a/node.gyp +++ b/node.gyp @@ -159,8 +159,12 @@ }], [ 'node_use_dtrace=="true"', { 'defines': [ 'HAVE_DTRACE=1' ], - 'dependencies': [ 'node_dtrace_header' ], + 'dependencies': [ + 'node_dtrace_header', + 'specialize_node_d', + ], 'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)' ], + # # DTrace is supported on solaris, mac, and bsd. There are three # object files associated with DTrace support, but they're not all @@ -482,10 +486,36 @@ ] } ], ] - } + }, ] } ], ] + }, + { + 'target_name': 'specialize_node_d', + 'type': 'none', + 'conditions': [ + [ 'node_use_dtrace=="true"', { + 'actions': [ + { + 'action_name': 'specialize_node_d', + 'inputs': [ + 'src/node.d' + ], + 'outputs': [ + '<(PRODUCT_DIR)/node.d', + ], + 'action': [ + 'tools/specialize_node_d.py', + '<@(_outputs)', + '<@(_inputs)', + '<@(OS)', + '<@(target_arch)', + ], + }, + ], + } ], + ] } ] # end targets } diff --git a/tools/install.py b/tools/install.py index 7249de36e98..f51d95a1294 100755 --- a/tools/install.py +++ b/tools/install.py @@ -132,7 +132,7 @@ def files(action): # install unconditionally, checking if the platform supports dtrace doesn't # work when cross-compiling and besides, there's at least one linux flavor # with dtrace support now (oracle's "unbreakable" linux) - action(['src/node.d'], 'lib/dtrace/') + action(['out/Release/node.d'], 'lib/dtrace/node.d') if 'freebsd' in sys.platform or 'openbsd' in sys.platform: action(['doc/node.1'], 'man/man1/') diff --git a/tools/specialize_node_d.py b/tools/specialize_node_d.py new file mode 100755 index 00000000000..0ee505ae911 --- /dev/null +++ b/tools/specialize_node_d.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +# +# specialize_node_d.py output_file src/node.d flavor arch +# +# Specialize node.d for given flavor (`freebsd`) and arch (`x64` or `ia32`) +# + +import re +import subprocess +import sys +import errno + +if len(sys.argv) != 5: + print "usage: specialize_node_d.py outfile src/node.d flavor arch" + sys.exit(2); + +outfile = file(sys.argv[1], 'w'); +infile = file(sys.argv[2], 'r'); +flavor = sys.argv[3]; +arch = sys.argv[4]; + +model = r'curpsinfo->pr_dmodel == PR_MODEL_ILP32' + +for line in infile: + if flavor == 'freebsd': + line = re.sub('procfs.d', 'psinfo.d', line); + if arch == 'x64': + line = re.sub(model, '0', line); + else: + line = re.sub(model, '1', line); + outfile.write(line); From b7776fb192b803847d07a582bdb62851e93cd98e Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 20 Feb 2014 21:00:29 +0400 Subject: [PATCH 2/9] configure: allow --with-dtrace on freebsd --- configure | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure b/configure index 72c3c5f30a6..a55d8c966e1 100755 --- a/configure +++ b/configure @@ -491,6 +491,8 @@ def configure_node(o): # SunOS, and we haven't implemented it.) if flavor in ('solaris', 'mac'): o['variables']['node_use_dtrace'] = b(not options.without_dtrace) + elif flavor == 'freebsd': + o['variables']['node_use_dtrace'] = b(options.with_dtrace) elif flavor == 'linux': o['variables']['node_use_dtrace'] = 'false' o['variables']['node_use_systemtap'] = b(options.with_dtrace) From a6f89ccd76a7b5daea774b84552385597c4a2579 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 21 Feb 2014 00:56:17 +0400 Subject: [PATCH 3/9] dtrace: workaround linker bug on FreeBSD --- src/node_dtrace.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node_dtrace.cc b/src/node_dtrace.cc index d5ac60c3fc2..4b851e38fed 100644 --- a/src/node_dtrace.cc +++ b/src/node_dtrace.cc @@ -341,7 +341,7 @@ Handle DTRACE_HTTP_CLIENT_RESPONSE(const Arguments& args) { #define NODE_PROBE(name) #name, name, Persistent() -static int dtrace_gc_start(GCType type, GCCallbackFlags flags) { +int dtrace_gc_start(GCType type, GCCallbackFlags flags) { #ifdef HAVE_SYSTEMTAP NODE_GC_START(); #else @@ -354,7 +354,7 @@ static int dtrace_gc_start(GCType type, GCCallbackFlags flags) { return 0; } -static int dtrace_gc_done(GCType type, GCCallbackFlags flags) { +int dtrace_gc_done(GCType type, GCCallbackFlags flags) { #ifdef HAVE_SYSTEMTAP NODE_GC_DONE(); #else From e0c530259050c4ecc6fe9cf8963992575e43f376 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 21 Feb 2014 01:03:03 +0400 Subject: [PATCH 4/9] installer: copy `node.d` only with node_use_dtrace --- tools/install.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/install.py b/tools/install.py index f51d95a1294..25bd3493d4f 100755 --- a/tools/install.py +++ b/tools/install.py @@ -129,10 +129,8 @@ def subdir_files(path, dest, action): def files(action): action(['out/Release/node'], 'bin/node') - # install unconditionally, checking if the platform supports dtrace doesn't - # work when cross-compiling and besides, there's at least one linux flavor - # with dtrace support now (oracle's "unbreakable" linux) - action(['out/Release/node.d'], 'lib/dtrace/node.d') + if 'true' == variables.get('node_use_dtrace'): + action(['out/Release/node.d'], 'lib/dtrace/node.d') if 'freebsd' in sys.platform or 'openbsd' in sys.platform: action(['doc/node.1'], 'man/man1/') From 1efe6837b23a2a70a226b4fcab8dc5ea1c7bf2c8 Mon Sep 17 00:00:00 2001 From: Nicolas Talle Date: Sat, 22 Feb 2014 16:02:10 +0100 Subject: [PATCH 5/9] doc: update assert.markdown Update assert.throws() and assert.doesNotThrow() docs --- doc/api/assert.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/assert.markdown b/doc/api/assert.markdown index 5849f6d938b..1a66022219d 100644 --- a/doc/api/assert.markdown +++ b/doc/api/assert.markdown @@ -39,7 +39,7 @@ Tests strict non-equality, as determined by the strict not equal operator ( `!== ## assert.throws(block, [error], [message]) -Expects `block` to throw an error. `error` can be constructor, regexp or +Expects `block` to throw an error. `error` can be constructor, `RegExp` or validation function. Validate instanceof using constructor: @@ -76,7 +76,7 @@ Custom error validation: ## assert.doesNotThrow(block, [message]) -Expects `block` not to throw an error, see assert.throws for details. +Expects `block` not to throw an error, see `assert.throws` for details. ## assert.ifError(value) From 70ea5bac431ae136368fc2c88e4bbe9e4b93a9aa Mon Sep 17 00:00:00 2001 From: Brian White Date: Sun, 23 Feb 2014 14:00:28 -0500 Subject: [PATCH 6/9] stream: remove useless check --- lib/_stream_readable.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index fd639694818..1d486cf7b76 100755 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -360,8 +360,7 @@ function chunkInvalid(state, chunk) { 'string' !== typeof chunk && chunk !== null && chunk !== undefined && - !state.objectMode && - !er) { + !state.objectMode) { er = new TypeError('Invalid non-string/buffer chunk'); } return er; From aae51ecf7d407b2fb56c1f3e1edf91a16940c973 Mon Sep 17 00:00:00 2001 From: Mike Pennisi Date: Mon, 24 Feb 2014 14:16:40 -0500 Subject: [PATCH 7/9] assert: Ensure reflexivity of deepEqual Ensure that the behavior of `assert.deepEqual` does not depend on argument ordering when comparing an `arguments` object with a non-`arguments` object. --- lib/assert.js | 9 +++++---- test/simple/test-assert.js | 5 +++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index 11fef455ab7..52b89baef6a 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -199,10 +199,11 @@ function objEquiv(a, b) { if (a.prototype !== b.prototype) return false; //~~~I've managed to break Object.keys through screwy arguments passing. // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } + var aIsArgs = isArguments(a), + bIsArgs = isArguments(b); + if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) + return false; + if (aIsArgs) { a = pSlice.call(a); b = pSlice.call(b); return _deepEqual(a, b); diff --git a/test/simple/test-assert.js b/test/simple/test-assert.js index 2885858cf44..6b8350095db 100644 --- a/test/simple/test-assert.js +++ b/test/simple/test-assert.js @@ -249,6 +249,11 @@ try { gotError = true; } +// GH-7178. Ensure reflexivity of deepEqual with `arguments` objects. +var args = (function() { return arguments; })(); +a.throws(makeBlock(a.deepEqual, [], args)); +a.throws(makeBlock(a.deepEqual, args, [])); + console.log('All OK'); assert.ok(gotError); From 0a01a42e8729cfb1c2bbf59e98daac9d13b06c80 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Tue, 25 Feb 2014 18:17:35 -0800 Subject: [PATCH 8/9] http: invoke createConnection when no agent This makes it so that the user may pass in a `createConnection()` option, and they don't have to pass `agent: false` at the same time. Also adding a test for the `createConnection` option, since none was in place before. See #7014. --- lib/http.js | 4 +- test/simple/test-http-createConnection.js | 47 +++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/simple/test-http-createConnection.js diff --git a/lib/http.js b/lib/http.js index 32e2ef30725..3b1484b8f9a 100644 --- a/lib/http.js +++ b/lib/http.js @@ -1346,7 +1346,9 @@ function ClientRequest(options, cb) { var self = this; OutgoingMessage.call(self); - self.agent = options.agent === undefined ? globalAgent : options.agent; + self.agent = options.agent; + if (!options.agent && options.agent !== false && !options.createConnection) + self.agent = globalAgent; var defaultPort = options.defaultPort || 80; diff --git a/test/simple/test-http-createConnection.js b/test/simple/test-http-createConnection.js new file mode 100644 index 00000000000..bc29d9aee48 --- /dev/null +++ b/test/simple/test-http-createConnection.js @@ -0,0 +1,47 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); +var http = require('http'); +var net = require('net'); + +var create = 0; +var response = 0; +process.on('exit', function() { + assert.equal(1, create, 'createConnection() http option was not called'); + assert.equal(1, response, 'http server "request" callback was not called'); +}); + +var server = http.createServer(function(req, res) { + res.end(); + response++; +}).listen(common.PORT, '127.0.0.1', function() { + http.get({ createConnection: createConnection }, function (res) { + res.resume(); + server.close(); + }); +}); + +function createConnection() { + create++; + return net.createConnection(common.PORT, '127.0.0.1'); +} From 47abdd9c43ae97ed11cb8cc4c770b43043718308 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 26 Feb 2014 11:39:53 -0800 Subject: [PATCH 9/9] test: add `agent: null` http client request test This is just the test portion from #7012 / #7189, but targetted for the v0.10 branch. --- test/simple/test-http-agent-null.js | 47 +++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 test/simple/test-http-agent-null.js diff --git a/test/simple/test-http-agent-null.js b/test/simple/test-http-agent-null.js new file mode 100644 index 00000000000..8ae71d50887 --- /dev/null +++ b/test/simple/test-http-agent-null.js @@ -0,0 +1,47 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); +var http = require('http'); +var net = require('net'); + +var request = 0; +var response = 0; +process.on('exit', function() { + assert.equal(request, 1, 'http server "request" callback was not called'); + assert.equal(response, 1, 'http request "response" callback was not called'); +}); + +var server = http.createServer(function(req, res) { + request++; + res.end(); +}).listen(function() { + var options = { + agent: null, + port: this.address().port + }; + http.get(options, function(res) { + response++; + res.resume(); + server.close(); + }); +});