0
0
mirror of https://github.com/nodejs/node.git synced 2024-12-01 16:10:02 +01:00
nodejs/test/common.js
Roman Reiss 7049d7b474 test: increase timeouts on ARM
This commit introduces platform-specific test timeouts for the ARM
architectures. ARMv6 is notoriously slow so gets very large timeouts on
both the timeout value for each test, as well as certain problematic
individual tests. ARMv7 and ARMv8 also get slightly increased headroom.

PR-URL: https://github.com/iojs/io.js/pull/1366
Fixes: https://github.com/iojs/io.js/issues/1343
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-04-09 15:10:34 +02:00

410 lines
11 KiB
JavaScript

var path = require('path');
var fs = require('fs');
var assert = require('assert');
var os = require('os');
var child_process = require('child_process');
exports.testDir = path.dirname(__filename);
exports.fixturesDir = path.join(exports.testDir, 'fixtures');
exports.libDir = path.join(exports.testDir, '../lib');
exports.tmpDirName = 'tmp';
exports.PORT = +process.env.NODE_COMMON_PORT || 12346;
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.tmpDirName += '.' + process.env.TEST_THREAD_ID;
}
exports.tmpDir = path.join(exports.testDir, exports.tmpDirName);
var opensslCli = null;
var inFreeBSDJail = null;
var localhostIPv4 = null;
Object.defineProperty(exports, 'inFreeBSDJail', {
get: function() {
if (inFreeBSDJail !== null) return inFreeBSDJail;
if (process.platform === 'freebsd' &&
child_process.execSync('sysctl -n security.jail.jailed').toString() ===
'1\n') {
inFreeBSDJail = true;
} else {
inFreeBSDJail = false;
}
return inFreeBSDJail;
}
});
Object.defineProperty(exports, 'localhostIPv4', {
get: function() {
if (localhostIPv4 !== null) return localhostIPv4;
if (exports.inFreeBSDJail) {
// Jailed network interfaces are a bit special - since we need to jump
// through loops, as well as this being an exception case, assume the
// user will provide this instead.
if (process.env.LOCALHOST) {
localhostIPv4 = process.env.LOCALHOST;
} else {
console.error('Looks like we\'re in a FreeBSD Jail. ' +
'Please provide your default interface address ' +
'as LOCALHOST or expect some tests to fail.');
}
}
if (localhostIPv4 === null) localhostIPv4 = '127.0.0.1';
return localhostIPv4;
}
});
// opensslCli defined lazily to reduce overhead of spawnSync
Object.defineProperty(exports, 'opensslCli', {get: function() {
if (opensslCli !== null) return opensslCli;
if (process.config.variables.node_shared_openssl) {
// use external command
opensslCli = 'openssl';
} else {
// use command built from sources included in io.js repository
opensslCli = path.join(path.dirname(process.execPath), 'openssl-cli');
}
if (process.platform === 'win32') opensslCli += '.exe';
var openssl_cmd = child_process.spawnSync(opensslCli, ['version']);
if (openssl_cmd.status !== 0 || openssl_cmd.error !== undefined) {
// openssl command cannot be executed
opensslCli = false;
}
return opensslCli;
}, enumerable: true });
Object.defineProperty(exports, 'hasCrypto', {get: function() {
return process.versions.openssl ? true : false;
}});
if (process.platform === 'win32') {
exports.PIPE = '\\\\.\\pipe\\libuv-test';
} 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 (process.platform === 'win32') {
exports.faketimeCli = false;
} else {
exports.faketimeCli = path.join(__dirname, "..", "tools", "faketime", "src",
"faketime");
}
var ifaces = os.networkInterfaces();
exports.hasIPv6 = Object.keys(ifaces).some(function(name) {
return /lo/.test(name) && ifaces[name].some(function(info) {
return info.family === 'IPv6';
});
});
var util = require('util');
for (var i in util) exports[i] = util[i];
//for (var i in exports) global[i] = exports[i];
function protoCtrChain(o) {
var result = [];
for (; o; o = o.__proto__) { result.push(o.constructor); }
return result.join();
}
exports.indirectInstanceOf = function(obj, cls) {
if (obj instanceof cls) { return true; }
var clsChain = protoCtrChain(cls.prototype);
var objChain = protoCtrChain(obj);
return objChain.slice(-clsChain.length) === clsChain;
};
exports.ddCommand = function(filename, kilobytes) {
if (process.platform === 'win32') {
var p = path.resolve(exports.fixturesDir, 'create-file.js');
return '"' + process.argv[0] + '" "' + p + '" "' +
filename + '" ' + (kilobytes * 1024);
} else {
return 'dd if=/dev/zero of="' + filename + '" bs=1024 count=' + kilobytes;
}
};
exports.spawnCat = function(options) {
var spawn = require('child_process').spawn;
if (process.platform === 'win32') {
return spawn('more', [], options);
} else {
return spawn('cat', [], options);
}
};
exports.spawnSyncCat = function(options) {
var spawnSync = require('child_process').spawnSync;
if (process.platform === 'win32') {
return spawnSync('more', [], options);
} else {
return spawnSync('cat', [], options);
}
};
exports.spawnPwd = function(options) {
var spawn = require('child_process').spawn;
if (process.platform === 'win32') {
return spawn('cmd.exe', ['/c', 'cd'], options);
} else {
return spawn('pwd', [], options);
}
};
exports.platformTimeout = function(ms) {
if (process.arch !== 'arm')
return ms;
if (process.config.variables.arm_version === '6')
return 6 * ms; // ARMv6
return 2 * ms; // ARMv7 and up.
};
var knownGlobals = [setTimeout,
setInterval,
setImmediate,
clearTimeout,
clearInterval,
clearImmediate,
console,
constructor, // Enumerable in V8 3.21.
Buffer,
process,
global];
if (global.gc) {
knownGlobals.push(gc);
}
if (global.DTRACE_HTTP_SERVER_RESPONSE) {
knownGlobals.push(DTRACE_HTTP_SERVER_RESPONSE);
knownGlobals.push(DTRACE_HTTP_SERVER_REQUEST);
knownGlobals.push(DTRACE_HTTP_CLIENT_RESPONSE);
knownGlobals.push(DTRACE_HTTP_CLIENT_REQUEST);
knownGlobals.push(DTRACE_NET_STREAM_END);
knownGlobals.push(DTRACE_NET_SERVER_CONNECTION);
}
if (global.COUNTER_NET_SERVER_CONNECTION) {
knownGlobals.push(COUNTER_NET_SERVER_CONNECTION);
knownGlobals.push(COUNTER_NET_SERVER_CONNECTION_CLOSE);
knownGlobals.push(COUNTER_HTTP_SERVER_REQUEST);
knownGlobals.push(COUNTER_HTTP_SERVER_RESPONSE);
knownGlobals.push(COUNTER_HTTP_CLIENT_REQUEST);
knownGlobals.push(COUNTER_HTTP_CLIENT_RESPONSE);
}
if (global.LTTNG_HTTP_SERVER_RESPONSE) {
knownGlobals.push(LTTNG_HTTP_SERVER_RESPONSE);
knownGlobals.push(LTTNG_HTTP_SERVER_REQUEST);
knownGlobals.push(LTTNG_HTTP_CLIENT_RESPONSE);
knownGlobals.push(LTTNG_HTTP_CLIENT_REQUEST);
knownGlobals.push(LTTNG_NET_STREAM_END);
knownGlobals.push(LTTNG_NET_SERVER_CONNECTION);
}
if (global.ArrayBuffer) {
knownGlobals.push(ArrayBuffer);
knownGlobals.push(Int8Array);
knownGlobals.push(Uint8Array);
knownGlobals.push(Uint8ClampedArray);
knownGlobals.push(Int16Array);
knownGlobals.push(Uint16Array);
knownGlobals.push(Int32Array);
knownGlobals.push(Uint32Array);
knownGlobals.push(Float32Array);
knownGlobals.push(Float64Array);
knownGlobals.push(DataView);
}
// Harmony features.
if (global.Proxy) {
knownGlobals.push(Proxy);
}
if (global.Symbol) {
knownGlobals.push(Symbol);
}
function leakedGlobals() {
var leaked = [];
for (var val in global)
if (-1 === knownGlobals.indexOf(global[val]))
leaked.push(val);
return leaked;
};
exports.leakedGlobals = leakedGlobals;
// Turn this off if the test should not check for global leaks.
exports.globalCheck = true;
process.on('exit', function() {
if (!exports.globalCheck) return;
var leaked = leakedGlobals();
if (leaked.length > 0) {
console.error('Unknown globals: %s', leaked);
assert.ok(false, 'Unknown global found');
}
});
var mustCallChecks = [];
function runCallChecks(exitCode) {
if (exitCode !== 0) return;
var failed = mustCallChecks.filter(function(context) {
return context.actual !== context.expected;
});
failed.forEach(function(context) {
console.log('Mismatched %s function calls. Expected %d, actual %d.',
context.name,
context.expected,
context.actual);
console.log(context.stack.split('\n').slice(2).join('\n'));
});
if (failed.length) process.exit(1);
}
exports.mustCall = function(fn, expected) {
if (typeof expected !== 'number') expected = 1;
var context = {
expected: expected,
actual: 0,
stack: (new Error).stack,
name: fn.name || '<anonymous>'
};
// add the exit listener only once to avoid listener leak warnings
if (mustCallChecks.length === 0) process.on('exit', runCallChecks);
mustCallChecks.push(context);
return function() {
context.actual++;
return fn.apply(this, arguments);
};
};
exports.checkSpawnSyncRet = function(ret) {
assert.strictEqual(ret.status, 0);
assert.strictEqual(ret.error, undefined);
};
var etcServicesFileName = path.join('/etc', 'services');
if (process.platform === 'win32') {
etcServicesFileName = path.join(process.env.SystemRoot, 'System32', 'drivers',
'etc', 'services');
}
/*
* Returns a string that represents the service name associated
* to the service bound to port "port" and using protocol "protocol".
*
* If the service is not defined in the services file, it returns
* the port number as a string.
*
* Returns undefined if /etc/services (or its equivalent on non-UNIX
* platforms) can't be read.
*/
exports.getServiceName = function getServiceName(port, protocol) {
if (port == null) {
throw new Error("Missing port number");
}
if (typeof protocol !== 'string') {
throw new Error("Protocol must be a string");
}
/*
* By default, if a service can't be found in /etc/services,
* its name is considered to be its port number.
*/
var serviceName = port.toString();
try {
/*
* I'm not a big fan of readFileSync, but reading /etc/services asynchronously
* here would require implementing a simple line parser, which seems overkill
* for a simple utility function that is not running concurrently with any
* other one.
*/
var servicesContent = fs.readFileSync(etcServicesFileName,
{ encoding: 'utf8'});
var regexp = util.format('^(\\w+)\\s+\\s%d/%s\\s', port, protocol);
var re = new RegExp(regexp, 'm');
var matches = re.exec(servicesContent);
if (matches && matches.length > 1) {
serviceName = matches[1];
}
} catch(e) {
console.error('Cannot read file: ', etcServicesFileName);
return undefined;
}
return serviceName;
}
exports.hasMultiLocalhost = function hasMultiLocalhost() {
var TCP = process.binding('tcp_wrap').TCP;
var t = new TCP();
var ret = t.bind('127.0.0.2', exports.PORT);
t.close();
return ret === 0;
};
exports.isValidHostname = function(str) {
// See http://stackoverflow.com/a/3824105
var re = new RegExp(
'^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])' +
'(\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]))*$');
return !!str.match(re) && str.length <= 255;
}
exports.fileExists = function(pathname) {
try {
fs.accessSync(pathname);
return true;
} catch (err) {
return false;
}
};