node/test/parallel/test-module-loading-globalpaths.js
Yihong Wang ec9e7922bb
test: add lib path env when node_shared=true
When building the node with `--shared` option, the major output is the
shared library. However, we still build a node executable which links
to the shared lib. It's for testing purpose. When testing with the
executable, some test cases move/copy the executable, change the
relative path to the shared library and fail. Using lib path env would
solve the issue. However, in macOS, need to change the install name for
the shared library and use rpath in the executable. In AIX, `-brtl`
linker option rebinds the symbols in the executable and addon modules
could use them.

Signed-off-by: Yihong Wang <yh.wang@ibm.com>

PR-URL: https://github.com/nodejs/node/pull/18626
Refs: https://github.com/nodejs/node/issues/18535
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
2018-02-16 17:30:16 +01:00

106 lines
4.0 KiB
JavaScript

'use strict';
const common = require('../common');
const fixtures = require('../common/fixtures');
const assert = require('assert');
const path = require('path');
const fs = require('fs');
const child_process = require('child_process');
const pkgName = 'foo';
const { addLibraryPath } = require('../common/shared-lib-util');
addLibraryPath(process.env);
if (process.argv[2] === 'child') {
console.log(require(pkgName).string);
} else {
const tmpdir = require('../common/tmpdir');
tmpdir.refresh();
// Copy node binary into a test $PREFIX directory.
const prefixPath = path.join(tmpdir.path, 'install');
fs.mkdirSync(prefixPath);
let testExecPath;
if (common.isWindows) {
testExecPath = path.join(prefixPath, path.basename(process.execPath));
} else {
const prefixBinPath = path.join(prefixPath, 'bin');
fs.mkdirSync(prefixBinPath);
testExecPath = path.join(prefixBinPath, path.basename(process.execPath));
}
const mode = fs.statSync(process.execPath).mode;
fs.writeFileSync(testExecPath, fs.readFileSync(process.execPath));
fs.chmodSync(testExecPath, mode);
const runTest = (expectedString, env) => {
const child = child_process.execFileSync(testExecPath,
[ __filename, 'child' ],
{ encoding: 'utf8', env: env });
assert.strictEqual(child.trim(), expectedString);
};
const testFixturesDir = fixtures.path(path.basename(__filename, '.js'));
const env = Object.assign({}, process.env);
// Turn on module debug to aid diagnosing failures.
env['NODE_DEBUG'] = 'module';
// Unset NODE_PATH.
delete env['NODE_PATH'];
// Test empty global path.
const noPkgHomeDir = path.join(tmpdir.path, 'home-no-pkg');
fs.mkdirSync(noPkgHomeDir);
env['HOME'] = env['USERPROFILE'] = noPkgHomeDir;
assert.throws(
() => {
child_process.execFileSync(testExecPath, [ __filename, 'child' ],
{ encoding: 'utf8', env: env });
},
new RegExp(`Cannot find module '${pkgName}'`));
// Test module in $HOME/.node_modules.
const modHomeDir = path.join(testFixturesDir, 'home-pkg-in-node_modules');
env['HOME'] = env['USERPROFILE'] = modHomeDir;
runTest('$HOME/.node_modules', env);
// Test module in $HOME/.node_libraries.
const libHomeDir = path.join(testFixturesDir, 'home-pkg-in-node_libraries');
env['HOME'] = env['USERPROFILE'] = libHomeDir;
runTest('$HOME/.node_libraries', env);
// Test module both $HOME/.node_modules and $HOME/.node_libraries.
const bothHomeDir = path.join(testFixturesDir, 'home-pkg-in-both');
env['HOME'] = env['USERPROFILE'] = bothHomeDir;
runTest('$HOME/.node_modules', env);
// Test module in $PREFIX/lib/node.
// Write module into $PREFIX/lib/node.
const expectedString = '$PREFIX/lib/node';
const prefixLibPath = path.join(prefixPath, 'lib');
fs.mkdirSync(prefixLibPath);
const prefixLibNodePath = path.join(prefixLibPath, 'node');
fs.mkdirSync(prefixLibNodePath);
const pkgPath = path.join(prefixLibNodePath, `${pkgName}.js`);
fs.writeFileSync(pkgPath, `exports.string = '${expectedString}';`);
env['HOME'] = env['USERPROFILE'] = noPkgHomeDir;
runTest(expectedString, env);
// Test module in all global folders.
env['HOME'] = env['USERPROFILE'] = bothHomeDir;
runTest('$HOME/.node_modules', env);
// Test module in NODE_PATH is loaded ahead of global folders.
env['HOME'] = env['USERPROFILE'] = bothHomeDir;
env['NODE_PATH'] = path.join(testFixturesDir, 'node_path');
runTest('$NODE_PATH', env);
// Test module in local folder is loaded ahead of global folders.
const localDir = path.join(testFixturesDir, 'local-pkg');
env['HOME'] = env['USERPROFILE'] = bothHomeDir;
env['NODE_PATH'] = path.join(testFixturesDir, 'node_path');
const child = child_process.execFileSync(testExecPath,
[ path.join(localDir, 'test.js') ],
{ encoding: 'utf8', env: env });
assert.strictEqual(child.trim(), 'local');
}