diff --git a/src/coffee/storage.coffee b/src/coffee/storage.coffee index 46d5ca2..17b08b3 100644 --- a/src/coffee/storage.coffee +++ b/src/coffee/storage.coffee @@ -3,6 +3,8 @@ fs = require 'fs-extra' path = require 'path' request = require 'request' +lib = require './storage/lib.coffee' + module.exports = (agent, mqtt, config) -> remoteFs = (cmd, payload, cb) -> request @@ -32,35 +34,15 @@ module.exports = (agent, mqtt, config) -> publishStorageBuckets = (err, buckets) -> mqtt.publish '/agent/storage/buckets', buckets unless err - listStorageBuckets = (dir, cb) -> - fs.readdir dir, (err, dirList) -> - if err - console.error err - cb? err, null - else - try - files = dirList?.map (file) -> - copyLock = ".#{file}.copy.lock" - deleteLock = ".#{file}.delete.lock" - stat = fs.statSync path.join(basePath, file) - if stat.isDirectory() - name: file - created: stat.birthtime - isLocked: copyLock in dirList or deleteLock in dirList - .filter (file) -> file? - cb? null, files - catch ex - cb? ex, null - basePath = path.join config.dataDir, config.domain - listStorageBuckets basePath, publishStorageBuckets + lib.listStorageBuckets fs, basePath, publishStorageBuckets fs.watch basePath, (eventType, filename) -> - listStorageBuckets basePath, publishStorageBuckets + lib.listStorageBuckets fs, basePath, publishStorageBuckets agent.on '/storage/list', (params, data, callback) -> - listStorageBuckets basePath, (err, buckets) -> + lib.listStorageBuckets fs, basePath, (err, buckets) -> publishStorageBuckets err, buckets callback() diff --git a/src/coffee/storage/lib.coffee b/src/coffee/storage/lib.coffee new file mode 100644 index 0000000..34ca1b2 --- /dev/null +++ b/src/coffee/storage/lib.coffee @@ -0,0 +1,22 @@ +path = require 'path' + +module.exports = + listStorageBuckets: (fs, dir, cb) -> + fs.readdir dir, (err, dirList) -> + if err + console.error err + cb? err, null + else + try + files = dirList?.map (file) -> + copyLock = ".#{file}.copy.lock" + deleteLock = ".#{file}.delete.lock" + stat = fs.statSync path.join(dir, file) + if stat?.isDirectory() + name: file + created: stat.birthtime + isLocked: copyLock in dirList or deleteLock in dirList + .filter (file) -> file? + cb? null, files + catch ex + cb? ex, null diff --git a/tests/coffee/storage.test.coffee b/tests/coffee/storage.test.coffee new file mode 100644 index 0000000..57959a6 --- /dev/null +++ b/tests/coffee/storage.test.coffee @@ -0,0 +1,5 @@ +assert = require 'assert' +td = require 'testdouble' +storage = require '../../src/coffee/storage.coffee' + +describe 'Storage', -> diff --git a/tests/coffee/storage/lib.test.coffee b/tests/coffee/storage/lib.test.coffee new file mode 100644 index 0000000..dae0cca --- /dev/null +++ b/tests/coffee/storage/lib.test.coffee @@ -0,0 +1,60 @@ +assert = require 'assert' +td = require 'testdouble' +lib = require '../../../src/coffee/storage/lib.coffee' + +describe 'Storage/Lib', -> + describe 'listStorageBuckets', -> + it 'should callback with an error when there was a problem listing files in the dir', -> + fs = td.object ['readdir'] + cb = td.function() + td.when(fs.readdir 'mydir').thenCallback('err', null) + lib.listStorageBuckets fs, 'mydir', cb + td.verify cb 'err', null + it 'should callback with an error when there was a problem retrieving file stats', -> + fs = td.object ['readdir', 'statSync'] + cb = td.function() + td.when(fs.readdir 'mydir').thenCallback( null, ['dir1', '.dir1.delete.lock']) + td.when(fs.statSync 'mydir/dir1').thenThrow 'An Error' + lib.listStorageBuckets fs, 'mydir', cb + td.verify cb 'An Error', null + it 'should retrieve stats for each file', -> + fs = td.object ['readdir', 'statSync'] + cb = td.function() + td.when(fs.readdir 'mydir').thenCallback( null, ['file1', 'file2']) + lib.listStorageBuckets fs, 'mydir', cb + td.verify fs.statSync('mydir/file1'), times:1 + td.verify fs.statSync('mydir/file2'), times:1 + it 'should return stats for directories only', -> + fs = td.object ['readdir', 'statSync'] + cb = td.function() + td.when(fs.readdir 'mydir').thenCallback( null, ['dir1', 'file2']) + td.when(fs.statSync 'mydir/dir1').thenReturn isDirectory:(-> true), birthtime: 'sometime' + td.when(fs.statSync 'mydir/file2').thenReturn isDirectory: -> false + lib.listStorageBuckets fs, 'mydir', cb + td.verify cb null, [ + name: 'dir1' + created: 'sometime' + isLocked: false + ] + it 'should set the isLocked property to true for directories which are locked by a copy lock', -> + fs = td.object ['readdir', 'statSync'] + cb = td.function() + td.when(fs.readdir 'mydir').thenCallback( null, ['dir1', '.dir1.copy.lock']) + td.when(fs.statSync 'mydir/dir1').thenReturn isDirectory:(-> true), birthtime: 'sometime' + lib.listStorageBuckets fs, 'mydir', cb + td.verify cb null, [ + name: 'dir1' + created: 'sometime' + isLocked: true + ] + it 'should set the isLocked property to true for directories which are locked by a delete lock', -> + fs = td.object ['readdir', 'statSync'] + cb = td.function() + td.when(fs.readdir 'mydir').thenCallback( null, ['dir1', '.dir1.delete.lock']) + td.when(fs.statSync 'mydir/dir1').thenReturn isDirectory:(-> true), birthtime: 'sometime' + lib.listStorageBuckets fs, 'mydir', cb + td.verify cb null, [ + name: 'dir1' + created: 'sometime' + isLocked: true + ]