summaryrefslogtreecommitdiff
path: root/test/parallel/test-module-circular-symlinks.js
diff options
context:
space:
mode:
authorJames M Snell <jasnell@gmail.com>2016-05-02 16:31:20 -0700
committerJames M Snell <jasnell@gmail.com>2016-05-13 11:43:47 -0700
commit5d38d543cdd25962fadc49a997798d156a41e4c7 (patch)
tree04b538b19025ddaf9017cbce4aa35fb004e6a145 /test/parallel/test-module-circular-symlinks.js
parentf52b2f116bf510e2af8750061ac6f8a0c9caa653 (diff)
downloadandroid-node-v8-5d38d543cdd25962fadc49a997798d156a41e4c7.tar.gz
android-node-v8-5d38d543cdd25962fadc49a997798d156a41e4c7.tar.bz2
android-node-v8-5d38d543cdd25962fadc49a997798d156a41e4c7.zip
src,module: add --preserve-symlinks command line flag
Add the `--preserve-symlinks` flag. This makes the changes added in #5950 conditional. By default the old behavior is used. With the flag set, symlinks are preserved, switching to the new behavior. This should be considered to be a temporary solution until we figure out how to solve the symlinked peer dependency problem in a more general way that does not break everything else. Additional test cases are included. PR-URL: https://github.com/nodejs/node/pull/6537 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'test/parallel/test-module-circular-symlinks.js')
-rw-r--r--test/parallel/test-module-circular-symlinks.js68
1 files changed, 68 insertions, 0 deletions
diff --git a/test/parallel/test-module-circular-symlinks.js b/test/parallel/test-module-circular-symlinks.js
new file mode 100644
index 0000000000..a04022c656
--- /dev/null
+++ b/test/parallel/test-module-circular-symlinks.js
@@ -0,0 +1,68 @@
+'use strict';
+
+// This tests to make sure that modules with symlinked circular dependencies
+// do not blow out the module cache and recurse forever. See issue
+// https://github.com/nodejs/node/pull/5950 for context. PR #5950 attempted
+// to solve a problem with symlinked peer dependencies by caching using the
+// symlink path. Unfortunately, that breaks the case tested in this module
+// because each symlinked module, despite pointing to the same code on disk,
+// is loaded and cached as a separate module instance, which blows up the
+// cache and leads to a recursion bug.
+
+// This test should pass in Node.js v4 and v5. It should pass in Node.js v6
+// after https://github.com/nodejs/node/pull/5950 has been reverted.
+
+const common = require('../common');
+const assert = require('assert');
+const path = require('path');
+const fs = require('fs');
+
+// {tmpDir}
+// ├── index.js
+// └── node_modules
+// ├── moduleA
+// │ ├── index.js
+// │ └── node_modules
+// │ └── moduleB -> {tmpDir}/node_modules/moduleB
+// └── moduleB
+// ├── index.js
+// └── node_modules
+// └── moduleA -> {tmpDir}/node_modules/moduleA
+
+common.refreshTmpDir();
+const tmpDir = common.tmpDir;
+
+const node_modules = path.join(tmpDir, 'node_modules');
+const moduleA = path.join(node_modules, 'moduleA');
+const moduleB = path.join(node_modules, 'moduleB');
+const moduleA_link = path.join(moduleB, 'node_modules', 'moduleA');
+const moduleB_link = path.join(moduleA, 'node_modules', 'moduleB');
+
+fs.mkdirSync(node_modules);
+fs.mkdirSync(moduleA);
+fs.mkdirSync(moduleB);
+fs.mkdirSync(path.join(moduleA, 'node_modules'));
+fs.mkdirSync(path.join(moduleB, 'node_modules'));
+
+try {
+ fs.symlinkSync(moduleA, moduleA_link);
+ fs.symlinkSync(moduleB, moduleB_link);
+} catch (err) {
+ if (err.code !== 'EPERM') throw err;
+ common.skip('insufficient privileges for symlinks');
+ return;
+}
+
+fs.writeFileSync(path.join(tmpDir, 'index.js'),
+ 'module.exports = require(\'moduleA\');', 'utf8');
+fs.writeFileSync(path.join(moduleA, 'index.js'),
+ 'module.exports = {b: require(\'moduleB\')};', 'utf8');
+fs.writeFileSync(path.join(moduleB, 'index.js'),
+ 'module.exports = {a: require(\'moduleA\')};', 'utf8');
+
+// Ensure that the symlinks are not followed forever...
+const obj = require(path.join(tmpDir, 'index'));
+assert.ok(obj);
+assert.ok(obj.b);
+assert.ok(obj.b.a);
+assert.ok(!obj.b.a.b);