API/api.medcify.app/node_modules/continuation-local-storage/test/fs.tap.js
2022-09-26 11:41:44 +05:30

893 lines
27 KiB
JavaScript

'use strict';
var createNamespace = require('../context.js').createNamespace
, fs = require('fs')
, path = require('path')
, exec = require('child_process').exec
, tap = require('tap')
, test = tap.test
;
// CONSTANTS
var FILENAME = '__testfile'
, DIRNAME = '__TESTDIR'
, LINKNAME = '__testlink'
, HARDLINKNAME = '__testhardlink'
;
function createFile(assert) {
var contents = new Buffer("UHOH")
, file = fs.openSync(FILENAME, 'w')
, written = fs.writeSync(file, contents, 0, contents.length, 0)
;
assert.equals(written, contents.length, "whole buffer was written");
var rc = fs.closeSync(file);
// need this here to avoid dealing with umask complications
fs.chmodSync(FILENAME, '0666');
return rc;
}
function deleteFile() { return fs.unlinkSync(FILENAME); }
function createLink(assert) {
createFile(assert);
fs.symlinkSync(FILENAME, LINKNAME);
if (fs.lchmodSync) {
// This function only exists on BSD systems (like OSX)
fs.lchmodSync(LINKNAME, '0777');
}
}
function deleteLink() {
fs.unlinkSync(LINKNAME);
return deleteFile();
}
function createDirectory(assert) {
fs.mkdirSync(DIRNAME);
assert.ok(fs.existsSync(DIRNAME), "directory was created");
}
function deleteDirectory() { return fs.rmdirSync(DIRNAME); }
function mapIds(username, groupname, callback) {
if (!callback) throw new Error("mapIds requires callback");
if (!username) return callback(new Error("mapIds requires username"));
if (!groupname) return callback(new Error("mapIds requires groupname"));
exec('id -u ' + username, function (error, stdout, stderr) {
if (error) return callback(error);
if (stderr) return callback(new Error(stderr));
var uid = +stdout;
exec('id -g ' + groupname, function (error, stdout, stderr) {
if (error) return callback(error);
if (stderr) return callback(new Error(stderr));
var gid = +stdout;
callback(null, uid, gid);
});
});
}
test("continuation-local state with MakeCallback and fs module", function (t) {
t.plan(33);
var namespace = createNamespace('fs');
namespace.run(function () {
namespace.set('test', 0xabad1dea);
t.test("fs.rename", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'rename');
t.equal(namespace.get('test'), 'rename', "state has been mutated");
fs.rename(FILENAME, '__renamed', function (error) {
t.notOk(error, "renaming shouldn't error");
t.equal(namespace.get('test'), 'rename',
"mutated state has persisted to fs.rename's callback");
fs.unlinkSync('__renamed');
t.end();
});
});
});
t.test("fs.truncate", function (t) {
// truncate -> ftruncate in Node > 0.8.x
if (!fs.ftruncate) return t.end();
createFile(t);
namespace.run(function () {
namespace.set('test', 'truncate');
t.equal(namespace.get('test'), 'truncate', "state has been mutated");
fs.truncate(FILENAME, 0, function (error) {
t.notOk(error, "truncation shouldn't error");
var stats = fs.statSync(FILENAME);
t.equal(stats.size, 0, "file has been truncated");
t.equal(namespace.get('test'), 'truncate',
"mutated state has persisted to fs.truncate's callback");
deleteFile();
t.end();
});
});
});
t.test("fs.ftruncate", function (t) {
createFile(t);
// truncate -> ftruncate in Node > 0.8.x
var truncate = fs.ftruncate ? fs.ftruncate : fs.truncate;
namespace.run(function () {
namespace.set('test', 'ftruncate');
t.equal(namespace.get('test'), 'ftruncate', "state has been mutated");
var file = fs.openSync(FILENAME, 'w');
truncate(file, 0, function (error) {
t.notOk(error, "truncation shouldn't error");
fs.closeSync(file);
var stats = fs.statSync(FILENAME);
t.equal(stats.size, 0, "file has been truncated");
t.equal(namespace.get('test'), 'ftruncate',
"mutated state has persisted to fs.ftruncate's callback");
deleteFile();
t.end();
});
});
});
t.test("fs.chown", function (t) {
createFile(t);
mapIds('daemon', 'daemon', function (error, uid, gid) {
t.notOk(error, "looking up uid & gid shouldn't error");
t.ok(uid, "uid for daemon was found");
t.ok(gid, "gid for daemon was found");
namespace.run(function () {
namespace.set('test', 'chown');
t.equal(namespace.get('test'), 'chown', "state has been mutated");
fs.chown(FILENAME, uid, gid, function (error) {
t.ok(error, "changing ownership will error for non-root users");
t.equal(namespace.get('test'), 'chown',
"mutated state has persisted to fs.chown's callback");
deleteFile();
t.end();
});
});
});
});
t.test("fs.fchown", function (t) {
createFile(t);
mapIds('daemon', 'daemon', function (error, uid, gid) {
t.notOk(error, "looking up uid & gid shouldn't error");
t.ok(uid, "uid for daemon was found");
t.ok(gid, "gid for daemon was found");
namespace.run(function () {
namespace.set('test', 'fchown');
t.equal(namespace.get('test'), 'fchown', "state has been mutated");
var file = fs.openSync(FILENAME, 'w');
fs.fchown(file, uid, gid, function (error) {
t.ok(error, "changing ownership will error for non-root users");
t.equal(namespace.get('test'), 'fchown',
"mutated state has persisted to fs.fchown's callback");
fs.closeSync(file);
deleteFile();
t.end();
});
});
});
});
t.test("fs.lchown", function (t) {
if (!fs.lchown) return t.end();
createLink(t);
mapIds('daemon', 'daemon', function (error, uid, gid) {
t.notOk(error, "looking up uid & gid shouldn't error");
t.ok(uid, "uid for daemon was found");
t.ok(gid, "gid for daemon was found");
namespace.run(function () {
namespace.set('test', 'lchown');
t.equal(namespace.get('test'), 'lchown', "state has been mutated");
fs.lchown(LINKNAME, uid, gid, function (error) {
t.ok(error, "changing ownership will error for non-root users");
t.equal(namespace.get('test'), 'lchown',
"mutated state has persisted to fs.lchown's callback");
deleteLink();
t.end();
});
});
});
});
t.test("fs.chmod", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'chmod');
t.equal(namespace.get('test'), 'chmod', "state has been mutated");
fs.chmod(FILENAME, '0700', function (error) {
t.notOk(error, "changing mode shouldn't error");
t.equal(namespace.get('test'), 'chmod',
"mutated state has persisted to fs.chmod's callback");
var stats = fs.statSync(FILENAME);
t.equal(stats.mode.toString(8), '100700', "extra access bits are stripped");
deleteFile();
t.end();
});
});
});
t.test("fs.fchmod", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'fchmod');
t.equal(namespace.get('test'), 'fchmod', "state has been mutated");
var file = fs.openSync(FILENAME, 'w+');
fs.fchmod(file, '0700', function (error) {
t.notOk(error, "changing mode shouldn't error");
t.equal(namespace.get('test'), 'fchmod',
"mutated state has persisted to fs.fchmod's callback");
fs.closeSync(file);
var stats = fs.statSync(FILENAME);
t.equal(stats.mode.toString(8), '100700', "extra access bits are stripped");
deleteFile();
t.end();
});
});
});
t.test("fs.lchmod", function (t) {
if (!fs.lchmod) return t.end();
createLink(t);
namespace.run(function () {
namespace.set('test', 'lchmod');
t.equal(namespace.get('test'), 'lchmod', "state has been mutated");
fs.lchmod(LINKNAME, '0700', function (error) {
t.notOk(error, "changing mode shouldn't error");
t.equal(namespace.get('test'), 'lchmod',
"mutated state has persisted to fs.lchmod's callback");
var stats = fs.lstatSync(LINKNAME);
t.equal(stats.mode.toString(8), '120700', "extra access bits are stripped");
deleteLink();
t.end();
});
});
});
t.test("fs.stat", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'stat');
t.equal(namespace.get('test'), 'stat', "state has been mutated");
fs.stat(FILENAME, function (error, stats) {
t.notOk(error, "reading stats shouldn't error");
t.equal(namespace.get('test'), 'stat',
"mutated state has persisted to fs.stat's callback");
t.equal(stats.mode.toString(8), '100666', "permissions should be as created");
deleteFile();
t.end();
});
});
});
t.test("fs.fstat", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'fstat');
t.equal(namespace.get('test'), 'fstat', "state has been mutated");
var file = fs.openSync(FILENAME, 'r');
fs.fstat(file, function (error, stats) {
t.notOk(error, "reading stats shouldn't error");
t.equal(namespace.get('test'), 'fstat',
"mutated state has persisted to fs.fstat's callback");
t.equal(stats.mode.toString(8), '100666', "permissions should be as created");
fs.closeSync(file);
deleteFile();
t.end();
});
});
});
t.test("fs.lstat", function (t) {
createLink(t);
namespace.run(function () {
namespace.set('test', 'lstat');
t.equal(namespace.get('test'), 'lstat', "state has been mutated");
fs.lstat(LINKNAME, function (error, stats) {
t.notOk(error, "reading stats shouldn't error");
t.equal(namespace.get('test'), 'lstat',
"mutated state has persisted to fs.lstat's callback");
t.equal(
stats.mode.toString(8),
'120777',
"permissions should be as created"
);
deleteLink();
t.end();
});
});
});
t.test("fs.link", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'link');
t.equal(namespace.get('test'), 'link', "state has been mutated");
fs.link(FILENAME, HARDLINKNAME, function (error) {
t.notOk(error, "creating a link shouldn't error");
t.equal(namespace.get('test'), 'link',
"mutated state has persisted to fs.link's callback");
var orig = fs.statSync(FILENAME)
, linked = fs.statSync(HARDLINKNAME)
;
t.equal(orig.ino, linked.ino, "entries should point to same file");
t.notOk(fs.unlinkSync(HARDLINKNAME), "link has been removed");
deleteFile();
t.end();
});
});
});
t.test("fs.symlink", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'symlink');
t.equal(namespace.get('test'), 'symlink', "state has been mutated");
fs.symlink(FILENAME, LINKNAME, function (error) {
t.notOk(error, "creating a symlink shouldn't error");
t.equal(namespace.get('test'), 'symlink',
"mutated state has persisted to fs.symlink's callback");
var pointed = fs.readlinkSync(LINKNAME);
t.equal(pointed, FILENAME, "symlink points back to original file");
t.notOk(fs.unlinkSync(LINKNAME), "symlink has been removed");
deleteFile();
t.end();
});
});
});
t.test("fs.readlink", function (t) {
createLink(t);
namespace.run(function () {
namespace.set('test', 'readlink');
t.equal(namespace.get('test'), 'readlink', "state has been mutated");
fs.readlink(LINKNAME, function (error, pointed) {
t.notOk(error, "reading symlink shouldn't error");
t.equal(namespace.get('test'), 'readlink',
"mutated state has persisted to fs.readlink's callback");
t.equal(pointed, FILENAME, "symlink points back to original file");
deleteLink();
t.end();
});
});
});
t.test("fs.unlink", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'unlink');
t.equal(namespace.get('test'), 'unlink', "state has been mutated");
fs.unlink(FILENAME, function (error) {
t.notOk(error, "deleting file shouldn't error");
t.equal(namespace.get('test'), 'unlink',
"mutated state has persisted to fs.unlink's callback");
t.notOk(fs.exists(FILENAME), "file should be gone");
t.end();
});
});
});
t.test("fs.realpath", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'realpath');
t.equal(namespace.get('test'), 'realpath', "state has been mutated");
fs.realpath(FILENAME, function (error, real) {
t.notOk(error, "deleting file shouldn't error");
t.equal(namespace.get('test'), 'realpath',
"mutated state has persisted to fs.realpath's callback");
t.equal(real, path.resolve(FILENAME), "no funny business with the real path");
deleteFile();
t.end();
});
});
});
t.test("fs.mkdir", function (t) {
namespace.run(function () {
namespace.set('test', 'mkdir');
t.equal(namespace.get('test'), 'mkdir', "state has been mutated");
fs.mkdir(DIRNAME, function (error) {
t.notOk(error, "creating directory shouldn't error");
t.equal(namespace.get('test'), 'mkdir',
"mutated state has persisted to fs.mkdir's callback");
t.ok(fs.existsSync(DIRNAME), "directory was created");
fs.rmdirSync(DIRNAME);
t.end();
});
});
});
t.test("fs.rmdir", function (t) {
createDirectory(t);
namespace.run(function () {
namespace.set('test', 'rmdir');
t.equal(namespace.get('test'), 'rmdir', "state has been mutated");
fs.rmdir(DIRNAME, function (error) {
t.notOk(error, "deleting directory shouldn't error");
t.equal(namespace.get('test'), 'rmdir',
"mutated state has persisted to fs.rmdir's callback");
t.notOk(fs.existsSync(DIRNAME), "directory was removed");
t.end();
});
});
});
t.test("fs.readdir", function (t) {
createDirectory(t);
var file1 = fs.openSync(path.join(DIRNAME, 'file1'), 'w');
fs.writeSync(file1, 'one');
fs.closeSync(file1);
var file2 = fs.openSync(path.join(DIRNAME, 'file2'), 'w');
fs.writeSync(file2, 'two');
fs.closeSync(file2);
var file3 = fs.openSync(path.join(DIRNAME, 'file3'), 'w');
fs.writeSync(file3, 'three');
fs.closeSync(file3);
namespace.run(function () {
namespace.set('test', 'readdir');
t.equal(namespace.get('test'), 'readdir', "state has been mutated");
fs.readdir(DIRNAME, function (error, contents) {
t.notOk(error, "reading directory shouldn't error");
t.equal(namespace.get('test'), 'readdir',
"mutated state has persisted to fs.readdir's callback");
t.equal(contents.length, 3, "3 files were found");
fs.unlinkSync(path.join(DIRNAME, 'file1'));
fs.unlinkSync(path.join(DIRNAME, 'file2'));
fs.unlinkSync(path.join(DIRNAME, 'file3'));
deleteDirectory();
t.end();
});
});
});
t.test("fs.watch", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'watch');
t.equal(namespace.get('test'), 'watch', "state has been mutated");
var watcher = fs.watch(FILENAME,
{persistent : false, interval : 200},
function (event) {
t.equal(namespace.get('test'), 'watch',
"mutated state has persisted to fs.watch's callback");
t.equal(event, 'change', "file was changed");
watcher.close();
process.nextTick(function cleanup() {
deleteFile();
t.end();
});
});
setTimeout(function poke() {
fs.writeFileSync(FILENAME, 'still a test');
}, 20);
});
});
t.test("fs.utimes", function (t) {
createFile(t);
/* utimes(2) takes seconds since the epoch, and Date() deals with
* milliseconds. I just want a date some time in the past.
*/
var PASTIME = new Date(Math.floor((Date.now() - 31337) / 1000) * 1000);
namespace.run(function () {
namespace.set('test', 'utimes');
t.equal(namespace.get('test'), 'utimes', "state has been mutated");
var before = fs.statSync(FILENAME);
t.ok(before.atime, "access time of newly-created file set");
t.ok(before.mtime, "modification time of newly-created file set");
fs.utimes(FILENAME, PASTIME, PASTIME, function (error) {
t.notOk(error, "setting utimes shouldn't error");
t.equal(namespace.get('test'), 'utimes',
"mutated state has persisted to fs.utimes's callback");
var after = fs.statSync(FILENAME);
t.deepEqual(after.atime, PASTIME, "access time of newly-created file is reset");
t.deepEqual(after.mtime, PASTIME, "mod time of newly-created file is reset");
t.notDeepEqual(before.atime, after.atime, "access time changed");
t.notDeepEqual(before.mtime, after.mtime, "mod time changed");
deleteFile();
t.end();
});
});
});
t.test("fs.futimes", function (t) {
createFile(t);
/* futimes(2) takes seconds since the epoch, and Date() deals with
* milliseconds. I just want a date some time in the past.
*/
var PASTIME = new Date(Math.floor((Date.now() - 0xb33fd) / 1000) * 1000);
namespace.run(function () {
namespace.set('test', 'futimes');
t.equal(namespace.get('test'), 'futimes', "state has been mutated");
var before = fs.statSync(FILENAME);
t.ok(before.atime, "access time of newly-created file set");
t.ok(before.mtime, "modification time of newly-created file set");
var file = fs.openSync(FILENAME, "w+");
fs.futimes(file, PASTIME, PASTIME, function (error) {
t.notOk(error, "setting futimes shouldn't error");
fs.closeSync(file);
t.equal(namespace.get('test'), 'futimes',
"mutated state has persisted to fs.futimes's callback");
var after = fs.statSync(FILENAME);
t.deepEqual(after.atime, PASTIME, "access time of newly-created file is reset");
t.deepEqual(after.mtime, PASTIME, "mod time of newly-created file is reset");
t.notDeepEqual(before.atime, after.atime, "access time changed");
t.notDeepEqual(before.mtime, after.mtime, "mod time changed");
deleteFile();
t.end();
});
});
});
t.test("fs.fsync", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'fsync');
t.equal(namespace.get('test'), 'fsync', "state has been mutated");
var file = fs.openSync(FILENAME, 'w+');
fs.fsync(file, function (error) {
t.notOk(error, "syncing the file shouldn't error");
t.equal(namespace.get('test'), 'fsync',
"mutated state has persisted to fs.fsync's callback");
fs.closeSync(file);
deleteFile();
t.end();
});
});
});
t.test("fs.open", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'open');
t.equal(namespace.get('test'), 'open', "state has been mutated");
fs.open(FILENAME, 'r', function (error, file) {
t.notOk(error, "opening the file shouldn't error");
t.equal(namespace.get('test'), 'open',
"mutated state has persisted to fs.open's callback");
var contents = new Buffer(4);
fs.readSync(file, contents, 0, 4, 0);
t.equal(contents.toString(), 'UHOH', "contents are still available");
fs.closeSync(file);
deleteFile();
t.end();
});
});
});
t.test("fs.close", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'close');
t.equal(namespace.get('test'), 'close', "state has been mutated");
var file = fs.openSync(FILENAME, 'r');
fs.close(file, function (error) {
t.notOk(error, "closing the file shouldn't error");
t.equal(namespace.get('test'), 'close',
"mutated state has persisted to fs.close's callback");
deleteFile();
t.end();
});
});
});
t.test("fs.read", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'read');
t.equal(namespace.get('test'), 'read', "state has been mutated");
var file = fs.openSync(FILENAME, 'r')
, contents = new Buffer(4)
;
fs.read(file, contents, 0, 4, 0, function (error) {
t.notOk(error, "reading from the file shouldn't error");
t.equal(namespace.get('test'), 'read',
"mutated state has persisted to fs.read's callback");
t.equal(contents.toString(), 'UHOH', "contents are still available");
fs.closeSync(file);
deleteFile();
t.end();
});
});
});
t.test("fs.write", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'write');
t.equal(namespace.get('test'), 'write', "state has been mutated");
var file = fs.openSync(FILENAME, 'w')
, contents = new Buffer('yeap')
;
fs.write(file, contents, 0, 4, 0, function (error) {
t.notOk(error, "writing to the file shouldn't error");
t.equal(namespace.get('test'), 'write',
"mutated state has persisted to fs.write's callback");
fs.closeSync(file);
var readback = fs.readFileSync(FILENAME);
t.equal(readback.toString(), 'yeap', "contents are still available");
deleteFile();
t.end();
});
});
});
t.test("fs.readFile", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'readFile');
t.equal(namespace.get('test'), 'readFile', "state has been mutated");
fs.readFile(FILENAME, function (error, contents) {
t.notOk(error, "reading from the file shouldn't error");
t.equal(namespace.get('test'), 'readFile',
"mutated state has persisted to fs.readFile's callback");
t.equal(contents.toString(), 'UHOH', "contents are still available");
deleteFile();
t.end();
});
});
});
t.test("fs.writeFile", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'writeFile');
t.equal(namespace.get('test'), 'writeFile', "state has been mutated");
fs.writeFile(FILENAME, 'woopwoop', function (error) {
t.notOk(error, "rewriting the file shouldn't error");
t.equal(namespace.get('test'), 'writeFile',
"mutated state has persisted to fs.writeFile's callback");
var readback = fs.readFileSync(FILENAME);
t.equal(readback.toString(), 'woopwoop', "rewritten contents are available");
deleteFile();
t.end();
});
});
});
t.test("fs.appendFile", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'appendFile');
t.equal(namespace.get('test'), 'appendFile', "state has been mutated");
fs.appendFile(FILENAME, '/jk', function (error) {
t.notOk(error, "appending to the file shouldn't error");
t.equal(namespace.get('test'), 'appendFile',
"mutated state has persisted to fs.appendFile's callback");
var readback = fs.readFileSync(FILENAME);
t.equal(readback.toString(), 'UHOH/jk',
"appended contents are still available");
deleteFile();
t.end();
});
});
});
t.test("fs.exists", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'exists');
t.equal(namespace.get('test'), 'exists', "state has been mutated");
fs.exists(FILENAME, function (yep) {
t.equal(namespace.get('test'), 'exists',
"mutated state has persisted to fs.exists's callback");
t.ok(yep, "precreated file does indeed exist.");
fs.exists('NOPENOWAY', function (nope) {
t.equal(namespace.get('test'), 'exists',
"mutated state continues to persist to fs.exists's second callback");
t.notOk(nope, "nonexistent file doesn't exist.");
deleteFile();
t.end();
});
});
});
});
t.test("fs.watchFile", function (t) {
createFile(t);
namespace.run(function () {
namespace.set('test', 'watchFile');
t.equal(namespace.get('test'), 'watchFile', "state has been mutated");
var options = {
persistent: true,
interval: 20
};
fs.watchFile(FILENAME, options, function (before, after) {
t.equal(namespace.get('test'), 'watchFile',
"mutated state has persisted to fs.watchFile's callback");
t.ok(before.ino, "file has an entry");
t.equal(before.ino, after.ino, "file is at the same location");
fs.unwatchFile(FILENAME);
process.nextTick(function () {
deleteFile();
t.end();
});
});
setTimeout(function poke() {
fs.appendFileSync(FILENAME, 'still a test');
}, 20);
});
});
});
});