Skip to content

Commit

Permalink
test,bench: add tests/bench for fs.realpath() fix
Browse files Browse the repository at this point in the history
The test/benchmarks included also work for the previous JS
implementation of fs.realpath(). In case the new implementation of
realpath() needs to be reverted, we want these changes to stick around.
  • Loading branch information
trevnorris committed Jul 14, 2016
1 parent bf8827b commit e7a38ab
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 2 deletions.
46 changes: 46 additions & 0 deletions benchmark/fs/bench-realpath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use strict';

const common = require('../common');
const fs = require('fs');
const path = require('path');
const resolved_path = path.resolve(__dirname, '../../lib/');
const relative_path = path.relative(__dirname, '../../lib/');

const bench = common.createBenchmark(main, {
n: [1e4],
type: ['relative', 'resolved'],
});


function main(conf) {
const n = conf.n >>> 0;
const type = conf.type;

bench.start();
if (type === 'relative')
relativePath(n);
else if (type === 'resolved')
resolvedPath(n);
else
throw new Error('unknown "type": ' + type);
}

function relativePath(n) {
(function r(cntr) {
if (--cntr <= 0)
return bench.end(n);
fs.realpath(relative_path, function() {
r(cntr);
});
}(n));
}

function resolvedPath(n) {
(function r(cntr) {
if (--cntr <= 0)
return bench.end(n);
fs.realpath(resolved_path, function() {
r(cntr);
});
}(n));
}
39 changes: 39 additions & 0 deletions benchmark/fs/bench-realpathSync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';

const common = require('../common');
const fs = require('fs');
const path = require('path');
const resolved_path = path.resolve(__dirname, '../../lib/');
const relative_path = path.relative(__dirname, '../../lib/');

const bench = common.createBenchmark(main, {
n: [1e4],
type: ['relative', 'resolved'],
});


function main(conf) {
const n = conf.n >>> 0;
const type = conf.type;

bench.start();
if (type === 'relative')
relativePath(n);
else if (type === 'resolved')
resolvedPath(n);
else
throw new Error('unknown "type": ' + type);
bench.end(n);
}

function relativePath(n) {
for (var i = 0; i < n; i++) {
fs.realpathSync(relative_path);
}
}

function resolvedPath(n) {
for (var i = 0; i < n; i++) {
fs.realpathSync(resolved_path);
}
}
75 changes: 73 additions & 2 deletions test/parallel/test-fs-realpath.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ function test_cyclic_link_protection(callback) {
fs.symlinkSync(t[1], t[0], 'dir');
unlink.push(t[0]);
});
assert.throws(function() { fs.realpathSync(entry); });
assert.throws(function() { fs.realpathSync(entry); }, /ELOOP/);
asynctest(fs.realpath, [entry], callback, function(err, result) {
assert.ok(err && true);
return true;
Expand Down Expand Up @@ -461,6 +461,76 @@ function test_abs_with_kids(cb) {
});
}

function test_deep_symlink_eloop(callback) {
console.log('test_deep_symlink_eloop');
if (skipSymlinks) {
common.skip('symlink test (no privs)');
return runNextTest();
}

const deepsymPath = path.join(targetsAbsDir, 'deep-symlink');
const aPath = path.join(deepsymPath, 'a');
const bSympath = path.join(aPath, 'b');
const cleanupPaths = [bSympath];
const pRepeat = 33;

function cleanup() {
while (cleanupPaths.length > 0) {
try {fs.unlinkSync(cleanupPaths.pop());} catch (e) {}
}
}

fs.mkdirSync(deepsymPath);
fs.mkdirSync(aPath);
fs.mkdirSync(path.join(targetsAbsDir, 'deep-symlink', 'c'));
try {fs.unlinkSync(bSympath);} catch (e) {}
fs.symlinkSync(deepsymPath, bSympath);

// First test sync calls.

const testPath = aPath + '/b/a'.repeat(pRepeat) + '/b/c';
const resolvedPath = fs.realpathSync(testPath);
assert.equal(path.relative(deepsymPath, resolvedPath), 'c');

var reallyBigSymPath = deepsymPath;
var prev = null;

// Make massively deep set of symlinks
for (var i = 97; i < 105; i++) {
for (var j = 97; j < 101; j++) {
const link = String.fromCharCode(i) + String.fromCharCode(j);
const link_path = path.join(deepsymPath, link);
cleanupPaths.push(link_path);
try {fs.unlinkSync(link_path);} catch (e) {}
if (prev)
fs.symlinkSync(link_path, prev);
reallyBigSymPath += '/' + link;
prev = link_path;
}
}
fs.symlinkSync(deepsymPath, prev);
reallyBigSymPath += '/' + path.basename(prev);

assert.throws(() => fs.realpathSync(reallyBigSymPath), /ELOOP/);

// Now test async calls.

fs.realpath(testPath, (err, resolvedPath) => {
if (err) throw err;
assert.equal(path.relative(deepsymPath, resolvedPath), 'c');
checkAsyncReallyBigSymPath();
});

function checkAsyncReallyBigSymPath() {
fs.realpath(reallyBigSymPath, (err, path) => {
assert.ok(err);
assert.ok(/ELOOP/.test(err.message));
cleanup();
runNextTest();
});
}
}

// ----------------------------------------------------------------------------

var tests = [
Expand All @@ -476,7 +546,8 @@ var tests = [
test_non_symlinks,
test_escape_cwd,
test_abs_with_kids,
test_up_multiple
test_up_multiple,
test_deep_symlink_eloop,
];
var numtests = tests.length;
var testsRun = 0;
Expand Down

0 comments on commit e7a38ab

Please sign in to comment.