Skip to content

Commit

Permalink
Support setting setuid/setgid/sticky in updateMetadata (#162)
Browse files Browse the repository at this point in the history
Adapt tests to support for setuid/setgid/sticky bits
Relates to #156
  • Loading branch information
tmcgee123 authored and phated committed Nov 28, 2017
1 parent ef7aab3 commit 3920fd9
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 9 deletions.
3 changes: 1 addition & 2 deletions lib/fileOperations.js
Expand Up @@ -6,8 +6,7 @@ var isEqual = require('lodash.isequal');
var isValidDate = require('vali-date');

// TODO shared module
// TODO include sticky/setuid/setgid, i.e. 7777?
var MASK_MODE = parseInt('0777', 8);
var MASK_MODE = parseInt('7777', 8);
var DEFAULT_FILE_MODE = parseInt('0666', 8);
var APPEND_MODE_REGEXP = /a/;

Expand Down
86 changes: 82 additions & 4 deletions test/destModes.js
Expand Up @@ -23,13 +23,14 @@ function wipeOut() {
});
}

var MASK_MODE = parseInt('777', 8);
var MASK_MODE = parseInt('7777', 8);

function masked(mode) {
return mode & MASK_MODE;
}

var isWindows = (os.platform() === 'win32');
var isDarwin = (os.platform() === 'darwin');

describe('.dest() with custom modes', function() {
beforeEach(wipeOut);
Expand Down Expand Up @@ -70,6 +71,46 @@ describe('.dest() with custom modes', function() {
stream.end();
});



it('should set the sticky bit on the mode of a written stream file if set on the vinyl object', function(done) {
if (isWindows) {
this.skip();
return;
}

var inputPath = path.join(__dirname, './fixtures/test.coffee');
var inputBase = path.join(__dirname, './fixtures/');
var expectedPath = path.join(__dirname, './out-fixtures/test.coffee');
var expectedContents = fs.readFileSync(inputPath);
var expectedMode = parseInt('1655', 8);

var contentStream = through.obj();
var expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: contentStream,
stat: {
mode: expectedMode,
},
});

var onEnd = function() {
expect(masked(fs.lstatSync(expectedPath).mode)).toEqual(expectedMode);
done();
};

var stream = vfs.dest('./out-fixtures/', { cwd: __dirname });
stream.on('end', onEnd);
stream.write(expectedFile);
setTimeout(function() {
contentStream.write(expectedContents);
contentStream.end();
}, 100);
stream.end();
});

it('should set the mode of a written stream file if set on the vinyl object', function(done) {
if (isWindows) {
this.skip();
Expand Down Expand Up @@ -143,6 +184,41 @@ describe('.dest() with custom modes', function() {
stream.end();
});

it('should set sticky bit on the mode of a written directory if set on the vinyl object', function(done) {
if (isWindows) {
this.skip();
return;
}

var inputPath = path.join(__dirname, './fixtures/test');
var inputBase = path.join(__dirname, './fixtures/');
var expectedPath = path.join(__dirname, './out-fixtures/test');
var expectedMode = parseInt('1655', 8);

var expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: null,
stat: {
isDirectory: function() {
return true;
},
mode: expectedMode,
},
});

var onEnd = function() {
expect(masked(fs.lstatSync(expectedPath).mode)).toEqual(expectedMode);
done();
};

var stream = vfs.dest('./out-fixtures/', { cwd: __dirname });
stream.on('end', onEnd);
stream.write(expectedFile);
stream.end();
});

it('should write new files with the mode specified in options', function(done) {
if (isWindows) {
this.skip();
Expand Down Expand Up @@ -255,11 +331,13 @@ describe('.dest() with custom modes', function() {
return;
}


var inputBase = path.join(__dirname, './fixtures');
var inputPath = path.join(__dirname, './fixtures/wow/suchempty');
var expectedBase = path.join(__dirname, './out-fixtures/wow');
var expectedPath = path.join(__dirname, './out-fixtures/wow/suchempty');
var expectedDirMode = parseInt('755', 8);
// NOTE: Darwin does not set setgid
var expectedDirMode = isDarwin ? parseInt('755', 8) : parseInt('2755', 8);
var expectedFileMode = parseInt('655', 8);

var firstFile = new File({
Expand Down Expand Up @@ -322,7 +400,7 @@ describe('.dest() with custom modes', function() {
stream.end();
});

it('should see a file with special chmod (setuid/setgid/sticky) as matching', function(done) {
it('should see a file with special chmod (setuid/setgid/sticky) as distinct', function(done) {
if (isWindows) {
this.skip();
return;
Expand All @@ -349,7 +427,7 @@ describe('.dest() with custom modes', function() {
});

var onEnd = function() {
expect(fchmodSpy.calls.length).toEqual(0);
expect(fchmodSpy.calls.length).toEqual(1);
done();
};

Expand Down
29 changes: 26 additions & 3 deletions test/fileOperations.js
Expand Up @@ -21,7 +21,7 @@ var updateMetadata = fo.updateMetadata;

var resolution = defaultResolution();

var MASK_MODE = parseInt('777', 8);
var MASK_MODE = parseInt('7777', 8);

function masked(mode) {
return mode & MASK_MODE;
Expand Down Expand Up @@ -170,13 +170,13 @@ describe('getModeDiff', function() {
done();
});

it('ignores the sticky/setuid/setgid bits', function(done) {
it('includes the sticky/setuid/setgid bits', function(done) {
var fsMode = parseInt('1777', 8);
var vfsMode = parseInt('4777', 8);

var result = getModeDiff(fsMode, vfsMode);

expect(result).toEqual(0);
expect(result).toEqual(fsMode ^ vfsMode);

done();
});
Expand Down Expand Up @@ -795,6 +795,29 @@ describe('updateMetadata', function() {
});
});


it('updates the sticky bit on mode on fs and vinyl object if there is a diff', function(done) {
if (isWindows) {
this.skip();
return;
}

var fchmodSpy = expect.spyOn(fs, 'fchmod').andCallThrough();

var mode = parseInt('1777', 8);
file.stat.mode = mode;

var fd = fs.openSync(inputPath, 'w+');

updateMetadata(fd, file, function(err, fd2) {
expect(fchmodSpy.calls.length).toEqual(1);
var stats = fs.fstatSync(fd);
expect(file.stat.mode).toEqual(stats.mode);

fs.close(fd2, done);
});
});

it('forwards fchmod error and descriptor upon error', function(done) {
if (isWindows) {
this.skip();
Expand Down

0 comments on commit 3920fd9

Please sign in to comment.