1'use strict'; 2 3// This tests to make sure that modules with symlinked circular dependencies 4// do not blow out the module cache and recurse forever. See issue 5// https://github.com/nodejs/node/pull/5950 for context. PR #5950 attempted 6// to solve a problem with symlinked peer dependencies by caching using the 7// symlink path. Unfortunately, that breaks the case tested in this module 8// because each symlinked module, despite pointing to the same code on disk, 9// is loaded and cached as a separate module instance, which blows up the 10// cache and leads to a recursion bug. 11 12// This test should pass in Node.js v4 and v5. It should pass in Node.js v6 13// after https://github.com/nodejs/node/pull/5950 has been reverted. 14 15const common = require('../common'); 16const assert = require('assert'); 17const path = require('path'); 18const fs = require('fs'); 19 20// {tmpDir} 21// ├── index.js 22// └── node_modules 23// ├── moduleA 24// │ ├── index.js 25// │ └── node_modules 26// │ └── moduleB -> {tmpDir}/node_modules/moduleB 27// └── moduleB 28// ├── index.js 29// └── node_modules 30// └── moduleA -> {tmpDir}/node_modules/moduleA 31 32const tmpdir = require('../common/tmpdir'); 33tmpdir.refresh(); 34const tmpDir = tmpdir.path; 35 36const node_modules = path.join(tmpDir, 'node_modules'); 37const moduleA = path.join(node_modules, 'moduleA'); 38const moduleB = path.join(node_modules, 'moduleB'); 39const moduleA_link = path.join(moduleB, 'node_modules', 'moduleA'); 40const moduleB_link = path.join(moduleA, 'node_modules', 'moduleB'); 41 42fs.mkdirSync(node_modules); 43fs.mkdirSync(moduleA); 44fs.mkdirSync(moduleB); 45fs.mkdirSync(path.join(moduleA, 'node_modules')); 46fs.mkdirSync(path.join(moduleB, 'node_modules')); 47 48try { 49 fs.symlinkSync(moduleA, moduleA_link); 50 fs.symlinkSync(moduleB, moduleB_link); 51} catch (err) { 52 if (err.code !== 'EPERM') throw err; 53 common.skip('insufficient privileges for symlinks'); 54} 55 56fs.writeFileSync(path.join(tmpDir, 'index.js'), 57 'module.exports = require(\'moduleA\');', 'utf8'); 58fs.writeFileSync(path.join(moduleA, 'index.js'), 59 'module.exports = {b: require(\'moduleB\')};', 'utf8'); 60fs.writeFileSync(path.join(moduleB, 'index.js'), 61 'module.exports = {a: require(\'moduleA\')};', 'utf8'); 62 63// Ensure that the symlinks are not followed forever... 64const obj = require(path.join(tmpDir, 'index')); 65assert.ok(obj); 66assert.ok(obj.b); 67assert.ok(obj.b.a); 68assert.ok(!obj.b.a.b); 69