11cb0ef41Sopenharmony_ci// Flags: --preserve-symlinks 21cb0ef41Sopenharmony_ci'use strict'; 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciif (!common.canCreateSymLink()) 61cb0ef41Sopenharmony_ci common.skip('insufficient privileges'); 71cb0ef41Sopenharmony_ciif (!common.isMainThread) 81cb0ef41Sopenharmony_ci common.skip('process.chdir is not available in Workers'); 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciconst assert = require('assert'); 111cb0ef41Sopenharmony_ciconst { spawn } = require('child_process'); 121cb0ef41Sopenharmony_ciconst fs = require('fs'); 131cb0ef41Sopenharmony_ciconst path = require('path'); 141cb0ef41Sopenharmony_ciconst process = require('process'); 151cb0ef41Sopenharmony_ciconst { Worker } = require('worker_threads'); 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci// Setup: Copy fixtures to tmp directory. 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures'); 201cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir'); 211cb0ef41Sopenharmony_ciconst dirName = 'module-require-symlink'; 221cb0ef41Sopenharmony_ciconst fixtureSource = fixtures.path(dirName); 231cb0ef41Sopenharmony_ciconst tmpDirTarget = path.join(tmpdir.path, dirName); 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci// Copy fixtureSource to linkTarget recursively. 261cb0ef41Sopenharmony_citmpdir.refresh(); 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_cifunction copyDir(source, target) { 291cb0ef41Sopenharmony_ci fs.mkdirSync(target); 301cb0ef41Sopenharmony_ci fs.readdirSync(source).forEach((entry) => { 311cb0ef41Sopenharmony_ci const fullPathSource = path.join(source, entry); 321cb0ef41Sopenharmony_ci const fullPathTarget = path.join(target, entry); 331cb0ef41Sopenharmony_ci const stats = fs.statSync(fullPathSource); 341cb0ef41Sopenharmony_ci if (stats.isDirectory()) { 351cb0ef41Sopenharmony_ci copyDir(fullPathSource, fullPathTarget); 361cb0ef41Sopenharmony_ci } else { 371cb0ef41Sopenharmony_ci fs.copyFileSync(fullPathSource, fullPathTarget); 381cb0ef41Sopenharmony_ci } 391cb0ef41Sopenharmony_ci }); 401cb0ef41Sopenharmony_ci} 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_cicopyDir(fixtureSource, tmpDirTarget); 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci// Move to tmp dir and do everything with relative paths there so that the test 451cb0ef41Sopenharmony_ci// doesn't incorrectly fail due to a symlink somewhere else in the absolute 461cb0ef41Sopenharmony_ci// path. 471cb0ef41Sopenharmony_ciprocess.chdir(tmpdir.path); 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ciconst linkDir = path.join(dirName, 501cb0ef41Sopenharmony_ci 'node_modules', 511cb0ef41Sopenharmony_ci 'dep1', 521cb0ef41Sopenharmony_ci 'node_modules', 531cb0ef41Sopenharmony_ci 'dep2'); 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ciconst linkTarget = path.join('..', '..', 'dep2'); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ciconst linkScript = './linkscript.js'; 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ciconst linkScriptTarget = path.join(dirName, 'symlinked.js'); 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_citest(); 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_cifunction test() { 641cb0ef41Sopenharmony_ci fs.symlinkSync(linkTarget, linkDir, 'dir'); 651cb0ef41Sopenharmony_ci fs.symlinkSync(linkScriptTarget, linkScript); 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci // Load symlinked-module 681cb0ef41Sopenharmony_ci const fooModule = require(path.join(tmpDirTarget, 'foo.js')); 691cb0ef41Sopenharmony_ci assert.strictEqual(fooModule.dep1.bar.version, 'CORRECT_VERSION'); 701cb0ef41Sopenharmony_ci assert.strictEqual(fooModule.dep2.bar.version, 'CORRECT_VERSION'); 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci // Load symlinked-script as main 731cb0ef41Sopenharmony_ci const node = process.execPath; 741cb0ef41Sopenharmony_ci const child = spawn(node, ['--preserve-symlinks', linkScript]); 751cb0ef41Sopenharmony_ci child.on('close', function(code, signal) { 761cb0ef41Sopenharmony_ci assert.strictEqual(code, 0); 771cb0ef41Sopenharmony_ci assert(!signal); 781cb0ef41Sopenharmony_ci }); 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci // Also verify that symlinks works for setting preserve via env variables 811cb0ef41Sopenharmony_ci const childEnv = spawn(node, [linkScript], { 821cb0ef41Sopenharmony_ci env: { ...process.env, NODE_PRESERVE_SYMLINKS: '1' } 831cb0ef41Sopenharmony_ci }); 841cb0ef41Sopenharmony_ci childEnv.on('close', function(code, signal) { 851cb0ef41Sopenharmony_ci assert.strictEqual(code, 0); 861cb0ef41Sopenharmony_ci assert(!signal); 871cb0ef41Sopenharmony_ci }); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci // Also verify that symlinks works for setting preserve via env variables in 901cb0ef41Sopenharmony_ci // Workers. 911cb0ef41Sopenharmony_ci const worker = new Worker(linkScript, { 921cb0ef41Sopenharmony_ci env: { ...process.env, NODE_PRESERVE_SYMLINKS: '1' } 931cb0ef41Sopenharmony_ci }); 941cb0ef41Sopenharmony_ci worker.on('error', (err) => { 951cb0ef41Sopenharmony_ci console.log('Worker failed'); 961cb0ef41Sopenharmony_ci throw err; 971cb0ef41Sopenharmony_ci }); 981cb0ef41Sopenharmony_ci worker.on('exit', common.mustCall((code) => { 991cb0ef41Sopenharmony_ci assert.strictEqual(code, 0); 1001cb0ef41Sopenharmony_ci })); 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci // Also verify that symlinks works for setting preserve via env variables in 1031cb0ef41Sopenharmony_ci // Workers with explicit execArgv. 1041cb0ef41Sopenharmony_ci const workerArgv = new Worker(linkScript, { 1051cb0ef41Sopenharmony_ci execArgv: [], 1061cb0ef41Sopenharmony_ci env: { ...process.env, NODE_PRESERVE_SYMLINKS: '1' } 1071cb0ef41Sopenharmony_ci }); 1081cb0ef41Sopenharmony_ci workerArgv.on('error', (err) => { 1091cb0ef41Sopenharmony_ci console.log('Worker with execArgv failed'); 1101cb0ef41Sopenharmony_ci throw err; 1111cb0ef41Sopenharmony_ci }); 1121cb0ef41Sopenharmony_ci workerArgv.on('exit', common.mustCall((code) => { 1131cb0ef41Sopenharmony_ci assert.strictEqual(code, 0); 1141cb0ef41Sopenharmony_ci })); 1151cb0ef41Sopenharmony_ci} 116