11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci// This tests to make sure that modules with symlinked circular dependencies 41cb0ef41Sopenharmony_ci// do not blow out the module cache and recurse forever. See issue 51cb0ef41Sopenharmony_ci// https://github.com/nodejs/node/pull/5950 for context. PR #5950 attempted 61cb0ef41Sopenharmony_ci// to solve a problem with symlinked peer dependencies by caching using the 71cb0ef41Sopenharmony_ci// symlink path. Unfortunately, that breaks the case tested in this module 81cb0ef41Sopenharmony_ci// because each symlinked module, despite pointing to the same code on disk, 91cb0ef41Sopenharmony_ci// is loaded and cached as a separate module instance, which blows up the 101cb0ef41Sopenharmony_ci// cache and leads to a recursion bug. 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci// This test should pass in Node.js v4 and v5. It should pass in Node.js v6 131cb0ef41Sopenharmony_ci// after https://github.com/nodejs/node/pull/5950 has been reverted. 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciconst common = require('../common'); 161cb0ef41Sopenharmony_ciconst assert = require('assert'); 171cb0ef41Sopenharmony_ciconst path = require('path'); 181cb0ef41Sopenharmony_ciconst fs = require('fs'); 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci// {tmpDir} 211cb0ef41Sopenharmony_ci// ├── index.js 221cb0ef41Sopenharmony_ci// └── node_modules 231cb0ef41Sopenharmony_ci// ├── moduleA 241cb0ef41Sopenharmony_ci// │ ├── index.js 251cb0ef41Sopenharmony_ci// │ └── node_modules 261cb0ef41Sopenharmony_ci// │ └── moduleB -> {tmpDir}/node_modules/moduleB 271cb0ef41Sopenharmony_ci// └── moduleB 281cb0ef41Sopenharmony_ci// ├── index.js 291cb0ef41Sopenharmony_ci// └── node_modules 301cb0ef41Sopenharmony_ci// └── moduleA -> {tmpDir}/node_modules/moduleA 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir'); 331cb0ef41Sopenharmony_citmpdir.refresh(); 341cb0ef41Sopenharmony_ciconst tmpDir = tmpdir.path; 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ciconst node_modules = path.join(tmpDir, 'node_modules'); 371cb0ef41Sopenharmony_ciconst moduleA = path.join(node_modules, 'moduleA'); 381cb0ef41Sopenharmony_ciconst moduleB = path.join(node_modules, 'moduleB'); 391cb0ef41Sopenharmony_ciconst moduleA_link = path.join(moduleB, 'node_modules', 'moduleA'); 401cb0ef41Sopenharmony_ciconst moduleB_link = path.join(moduleA, 'node_modules', 'moduleB'); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_cifs.mkdirSync(node_modules); 431cb0ef41Sopenharmony_cifs.mkdirSync(moduleA); 441cb0ef41Sopenharmony_cifs.mkdirSync(moduleB); 451cb0ef41Sopenharmony_cifs.mkdirSync(path.join(moduleA, 'node_modules')); 461cb0ef41Sopenharmony_cifs.mkdirSync(path.join(moduleB, 'node_modules')); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_citry { 491cb0ef41Sopenharmony_ci fs.symlinkSync(moduleA, moduleA_link); 501cb0ef41Sopenharmony_ci fs.symlinkSync(moduleB, moduleB_link); 511cb0ef41Sopenharmony_ci} catch (err) { 521cb0ef41Sopenharmony_ci if (err.code !== 'EPERM') throw err; 531cb0ef41Sopenharmony_ci common.skip('insufficient privileges for symlinks'); 541cb0ef41Sopenharmony_ci} 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_cifs.writeFileSync(path.join(tmpDir, 'index.js'), 571cb0ef41Sopenharmony_ci 'module.exports = require(\'moduleA\');', 'utf8'); 581cb0ef41Sopenharmony_cifs.writeFileSync(path.join(moduleA, 'index.js'), 591cb0ef41Sopenharmony_ci 'module.exports = {b: require(\'moduleB\')};', 'utf8'); 601cb0ef41Sopenharmony_cifs.writeFileSync(path.join(moduleB, 'index.js'), 611cb0ef41Sopenharmony_ci 'module.exports = {a: require(\'moduleA\')};', 'utf8'); 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci// Ensure that the symlinks are not followed forever... 641cb0ef41Sopenharmony_ciconst obj = require(path.join(tmpDir, 'index')); 651cb0ef41Sopenharmony_ciassert.ok(obj); 661cb0ef41Sopenharmony_ciassert.ok(obj.b); 671cb0ef41Sopenharmony_ciassert.ok(obj.b.a); 681cb0ef41Sopenharmony_ciassert.ok(!obj.b.a.b); 69