From 0d403edc0ff74df5e3f8e8f7b6b86dc3f3d5dc82 Mon Sep 17 00:00:00 2001 From: Sakthipriyan Vairamani Date: Wed, 20 Jul 2016 12:53:21 +0530 Subject: [PATCH 1/2] test: find IPv6 address from localhost names Try all the possible hostnames listed in `common.localIPv6Hosts` to get an IPv6 address. If none of them give a valid address, skip the tests. --- test/common.js | 22 +++++++++++++++++++ .../test-https-connect-address-family.js | 20 ++++++----------- .../test-tls-connect-address-family.js | 20 ++++++----------- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/test/common.js b/test/common.js index 308411a13d3427..df3adcfc0c1272 100644 --- a/test/common.js +++ b/test/common.js @@ -5,6 +5,7 @@ var fs = require('fs'); var assert = require('assert'); var os = require('os'); var child_process = require('child_process'); +const dns = require('dns'); const stream = require('stream'); const util = require('util'); const Timer = process.binding('timer_wrap').Timer; @@ -89,6 +90,7 @@ exports.tmpDir = path.join(testRoot, exports.tmpDirName); var opensslCli = null; var inFreeBSDJail = null; var localhostIPv4 = null; +var localhostIPv6 = null; exports.localIPv6Hosts = ['localhost']; if (process.platform === 'linux') { @@ -106,6 +108,26 @@ if (process.platform === 'linux') { ]; } +exports.getLocalIPv6Address = function getLocalIPv6Address(callback) { + const err = new Error('Unable to determine IPv6 address of localhost'); + + if (typeof localhostIPv6 === 'object' && localhostIPv6 !== null) + return process.nextTick(() => callback(null, localhostIPv6)); + else if (typeof localhostIPv6 === 'undefined') + return process.nextTick(() => callback(err)); + + Promise.all(exports.localIPv6Hosts.map((host) => new Promise((res, _) => { + dns.lookup(host, {family: 6}, + (_, addr) => res({hostname: host, address: addr || ''})); + }))).then((addresses) => { + localhostIPv6 = addresses.filter((d) => d.address)[0]; + if (localhostIPv6 === undefined) + callback(err); + else + callback(null, localhostIPv6); + }); +}; + Object.defineProperty(exports, 'inFreeBSDJail', { get: function() { if (inFreeBSDJail !== null) return inFreeBSDJail; diff --git a/test/parallel/test-https-connect-address-family.js b/test/parallel/test-https-connect-address-family.js index 21d0bf8dc6a1a2..11534bc8590e15 100644 --- a/test/parallel/test-https-connect-address-family.js +++ b/test/parallel/test-https-connect-address-family.js @@ -12,16 +12,15 @@ if (!common.hasIPv6) { const assert = require('assert'); const https = require('https'); -const dns = require('dns'); -function runTest() { +function runTest(hostname, ipv6) { const ciphers = 'AECDH-NULL-SHA'; https.createServer({ ciphers }, common.mustCall(function(req, res) { this.close(); res.end(); - })).listen(common.PORT, '::1', common.mustCall(function() { + })).listen(common.PORT, ipv6, common.mustCall(function() { const options = { - host: 'localhost', + host: hostname, port: common.PORT, family: 6, ciphers: ciphers, @@ -29,18 +28,13 @@ function runTest() { }; // Will fail with ECONNREFUSED if the address family is not honored. https.get(options, common.mustCall(function() { - assert.strictEqual('::1', this.socket.remoteAddress); + assert.strictEqual(ipv6, this.socket.remoteAddress); this.destroy(); })); })); } -dns.lookup('localhost', {family: 6, all: true}, (err, addresses) => { - if (err) - throw err; - - if (addresses.some((val) => val.address === '::1')) - runTest(); - else - common.skip('localhost does not resolve to ::1'); +common.getLocalIPv6Address((err, address) => { + if (err) return common.skip(err.message); + runTest(address.hostname, address.address); }); diff --git a/test/parallel/test-tls-connect-address-family.js b/test/parallel/test-tls-connect-address-family.js index 6274328956e63d..67d27acef26aa7 100644 --- a/test/parallel/test-tls-connect-address-family.js +++ b/test/parallel/test-tls-connect-address-family.js @@ -12,15 +12,14 @@ if (!common.hasIPv6) { const assert = require('assert'); const tls = require('tls'); -const dns = require('dns'); -function runTest() { +function runTest(hostname, ipv6) { const ciphers = 'AECDH-NULL-SHA'; tls.createServer({ ciphers }, common.mustCall(function() { this.close(); - })).listen(common.PORT, '::1', common.mustCall(function() { + })).listen(common.PORT, ipv6, common.mustCall(function() { const options = { - host: 'localhost', + host: hostname, port: common.PORT, family: 6, ciphers: ciphers, @@ -28,18 +27,13 @@ function runTest() { }; // Will fail with ECONNREFUSED if the address family is not honored. tls.connect(options).once('secureConnect', common.mustCall(function() { - assert.strictEqual('::1', this.remoteAddress); + assert.strictEqual(ipv6, this.remoteAddress); this.destroy(); })); })); } -dns.lookup('localhost', {family: 6, all: true}, (err, addresses) => { - if (err) - throw err; - - if (addresses.some((val) => val.address === '::1')) - runTest(); - else - common.skip('localhost does not resolve to ::1'); +common.getLocalIPv6Address((err, address) => { + if (err) return common.skip(err.message); + runTest(address.hostname, address.address); }); From 1dccdcd9e0b5bc8c9b4c440c36fc149ab6efd452 Mon Sep 17 00:00:00 2001 From: Sakthipriyan Vairamani Date: Wed, 20 Jul 2016 13:36:09 +0530 Subject: [PATCH 2/2] test: unmark address-connect tests as unflaky --- test/parallel/parallel.status | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status index fc71d4165743a6..88d0cb9465353e 100644 --- a/test/parallel/parallel.status +++ b/test/parallel/parallel.status @@ -12,13 +12,6 @@ test-tick-processor : PASS,FLAKY [$system==linux] test-tick-processor : PASS,FLAKY -# Flaky until https://github.com/nodejs/build/issues/415 is resolved. -# On some of the buildbots, AAAA queries for localhost don't resolve -# to an address and neither do any of the alternatives from the -# localIPv6Hosts list from test/common.js. -test-https-connect-address-family : PASS,FLAKY -test-tls-connect-address-family : PASS,FLAKY - [$system==macos] [$system==solaris] # Also applies to SmartOS