Skip to content

Commit

Permalink
add a new test for loopback filesystem
Browse files Browse the repository at this point in the history
  • Loading branch information
EricTheMagician committed Nov 14, 2015
1 parent 8c74920 commit 3afe3f2
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 32 deletions.
90 changes: 63 additions & 27 deletions examples/loopback.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const fs = require('fs');
const pathToInode = new Map();
const inodeToPath = new Map();
inodeToPath.set(1, '/');
var next_largest_inode = 2;
pathToInode.set('/', 1);

// variable to store the loopback folder
// this will be set later
Expand All @@ -26,6 +26,7 @@ class LoopbackFS extends FileSystem {

// make sure it exists
if (!parent) {
console.log("ENOENT LOOKUP", parentInode, name)
reply.err(PosixError.ENOENT);
return;
}
Expand All @@ -39,25 +40,38 @@ class LoopbackFS extends FileSystem {
// use sync such that tests can pass. otherwise, use async
var stat = fs.statSync(path);
} catch (err) {
reply.err(-err.errno);
return;
// console.log(err);
// console.log(path);
if(!err.errno){
var path2 = path;
var idx =path2.indexOf('\u0000');
while(idx >= 0){
path2 = path2.slice(idx,1);
idx = path2.indexOf('\u0000');
console.log(idx, path2);
}
stat = fs.statSync(path);
return;
}else{
reply.err(-err.errno);
return;
}
}
// if(stat.size == 5678){
// console.log("name",name,"lookup size was 5678",stat);
// }

// check to see if the path has been visited before.
// if not, add it to the map
var inode = 0;
if (!pathToInode.has(localPath)) {
inode = next_largest_inode;
pathToInode.set(localPath, inode);
inodeToPath.set(inode, localPath);
next_largest_inode++;
} else {
inode = pathToInode.get(localPath);
}

// inode = next_largest_inode;
pathToInode.set(localPath, stat.ino);
inodeToPath.set(stat.ino, localPath);
}

stat.inode = stat.ino;
const entry = {
inode,
let entry = {
inode: stat.ino,
attr: stat,
generation: 1 //some filesystems rely on this generation number, such as the Network Filesystem
};
Expand All @@ -68,15 +82,29 @@ class LoopbackFS extends FileSystem {
}

getattr(context, inode, reply) {
const localPath = inodeToPath.get(inode);
const localPath = inodeToPath.get(inode);
if (localPath) {
try {
// use sync such that tests can pass. otherwise, use async
var stat = fs.statSync(pth.join(loopbackFolder, localPath));

if(inode != stat.ino){
if(inode == 1){
stat.ino = 1;
}else{
console.log("inode",inode,"path", localPath, "lookup size was 5678",stat);
}
}
stat.atime = Math.floor(stat.atime.getTime() / 1000);
stat.mtime = Math.floor(stat.mtime.getTime() / 1000);
stat.ctime = Math.floor(stat.ctime.getTime() / 1000);

stat.inode = stat.ino;
reply.attr(stat, 5); //5, timeout value, in seconds, for the validity of this inode. so 5 seconds
} catch (err) {
reply.err(-err.errno);
console.log("ENOENT GETATTR", inode, name);
console.log(err);
reply.err(err.errno);
return;
}

Expand All @@ -93,6 +121,7 @@ class LoopbackFS extends FileSystem {
}

opendir(context, inode, fileInfo, reply) {
// console.log(fileInfo);
reply.open(fileInfo);
}

Expand Down Expand Up @@ -130,18 +159,25 @@ class LoopbackFS extends FileSystem {
for (let file of files) {

// use sync such that tests can pass. otherwise, use async
let attr = fs.statSync(pth.join(path, file));
attr.atime = Math.floor(attr.atime.getTime() / 1000);
attr.mtime = Math.floor(attr.mtime.getTime() / 1000);
attr.ctime = Math.floor(attr.ctime.getTime() / 1000);
attr.birthtime = Math.floor(attr.birthtime.getTime() / 1000);
attr.inode = attr.ino;

// keep track of new inodes
if (!inodeToPath.has(attr.ino)) {
inodeToPath.set(attr.ino, pth.join(folder, file));
try{
let attr = fs.statSync(pth.join(path, file));
// console.log(attr.atime,attr.atime.getTime());

attr.atime = Math.floor(attr.atime.getTime() / 1000);
attr.mtime = Math.floor(attr.mtime.getTime() / 1000);
attr.ctime = Math.floor(attr.ctime.getTime() / 1000);
attr.birthtime = Math.floor(attr.birthtime.getTime() / 1000);
attr.inode = attr.ino;

// keep track of new inodes
if (!inodeToPath.has(attr.ino)) {
inodeToPath.set(attr.ino, pth.join(folder, file));
}
reply.addDirEntry(file, size, attr, offset);
}catch(err){
console.log("gettattr err", err);
continue;
}
reply.addDirEntry(file, size, attr, offset);
}
reply.buffer(new Buffer(0), requestedSize)

Expand Down
6 changes: 3 additions & 3 deletions examples/loopback_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ const fuse = require('fusejs').fuse
// setup the directories
var loopback = require('./loopback.js');
const LoopbackFS = loopback.LoopbackFS;
loopback.setLoopback( process.argv[1] );
loopback.setLoopback( process.argv[2] );

fuse.mount({
filesystem: LoopbackFS,
options: ['LoopbackFS'].concat(process.argv.slice(2,process.argv.length))
options: ['LoopbackFS'].concat(process.argv.slice(3,process.argv.length))
})

117 changes: 115 additions & 2 deletions test/test_loopback.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ describe('The Filesystem', function() {
fs.mkdir(mountpoint, function(){
fuse.mount({
filesystem: LoopbackFS,
options: ["TestLoopbackFS","-o", "allow_other", mountpoint]
// options: ["TestLoopbackFS","-o", "allow_other", '-d',mountpoint]
options: ["TestLoopbackFS","-o", "allow_other",'-s', mountpoint]
});
setTimeout(done, 150); //wait a second before actually starting the tests
});
Expand Down Expand Up @@ -47,7 +48,119 @@ describe('The Filesystem', function() {

});

it('multiple reads should not cause it to crash', function(done){
let done1 = false;
let done2 = false;
fs.readdir(homeDirectory, function(err, homeFiles){
if(err){
done(err);
return;
}
fs.readdir(mountpoint, function(err, mountedFiles){
if(err){
done(err);
return
}

expect(homeFiles).to.have.length(mountedFiles.length);
for(let file of mountedFiles){
expect(homeFiles).to.include(file);
}
done1 = true;
if( done1 && done2){
done();
}
});
});
fs.readdir(homeDirectory, function(err, homeFiles){
if(err){
done(err);
return;
}
fs.readdir(mountpoint, function(err, mountedFiles){
if(err){
done(err);
return
}

expect(homeFiles).to.have.length(mountedFiles.length);
for(let file of mountedFiles){
expect(homeFiles).to.include(file);
}
done2 = true;
if( done1 && done2){
done();
}
});
});

});

it( 'should report the same size for each file', function(done){
this.timeout(2000);
var once = false;
fs.readdir(homeDirectory, function(err, homeFiles){
if(err){
done(err);
return;
}
fs.readdir(mountpoint, function(err, mountedFiles){
if(err){
done(err);
return
}
expect(homeFiles).to.have.length(mountedFiles.length)
var count = 0;
for( const file of mountedFiles ){
expect(homeFiles).to.include(file);

fs.stat(pth.join(homeDirectory, file), (err, attr1)=>{
if(err){
once = true;
done(err);
return;
}
fs.stat(pth.join(mountpoint, file), (err, attr2)=>{
count++;
if(err){
once = true;
console.log(err);
done(err);


return;
}
// if( attr2.size == 5678 && attr2.size != attr1.size){
// // console.log(file, attr2, attr1);
// // return;
// }
// console.log(file, attr1.size, attr2.size);
expect(attr2.atime.getTime()).to.be.closeTo(attr1.atime.getTime(),1);
expect(attr2.size).to.equal(attr1.size);
expect(attr2.ino).to.equal(attr1.ino);
expect(attr2.atime).to.deep.equal(attr1.atime);
expect(attr2.ctime).to.deep.equal(attr1.ctime);
expect(attr2.mtime).to.deep.equal(attr1.mtime);
// expect(attr2).to.deep.equal(attr1);
// console.log(count, mountedFiles.length, homeFiles.length);
if(count == mountedFiles.length){
if(!once){
once = true;
done();
}
return;
}
});
});
}
// done();
});
})

})
after('should be unmounted', function(done){
const timeoutTime = 5000;
this.timeout(timeoutTime);
var command;
switch (os.type()){
case 'Linux':
Expand All @@ -57,7 +170,7 @@ describe('The Filesystem', function() {
command = `diskutil umount force /tmp/mnt2`
break;
}
exec(command, function (error, stdout, stderr) {
setTimeout(exec,0,command, function (error, stdout, stderr) {
if(error){
console.log(error);
done(error);
Expand Down

0 comments on commit 3afe3f2

Please sign in to comment.