diff --git a/src/test/storage-provider-test.js b/src/test/storage-provider-test.js index 477f89529..fa8b14f99 100644 --- a/src/test/storage-provider-test.js +++ b/src/test/storage-provider-test.js @@ -33,7 +33,8 @@ describe('Storage', function () { const gBackupConfig = { key: 'key', backupDir: null, - prefix: 'someprefix' + prefix: 'someprefix', + _provider: 'filesystem' // need this internal variable since we call the backend logic directly for testing }; let defaultBackupSite; diff --git a/src/test/syncer-test.js b/src/test/syncer-test.js index c8db84b7a..ab1f62df3 100644 --- a/src/test/syncer-test.js +++ b/src/test/syncer-test.js @@ -25,10 +25,39 @@ describe('Syncer', function () { async function getChanges(dataLayout) { const { delQueue, addQueue, integrityMap } = await syncer.sync(dataLayout, gCacheFile); + // inject fake integrity information + for (const change of addQueue) { + integrityMap.set(change.path, { size: 42, sha256: 'fake-sha256' }); + } await syncer.finalize(integrityMap, gCacheFile); return delQueue.concat(addQueue); } + function checkCache(cacheFile, changes) { + // store cache file indexed by path + const data = fs.readFileSync(cacheFile, 'utf8'); + const pathMap = new Map(); + if (data.length !== 0) { + const lines = data.trim().split('\n'); + for (const line of lines) { + const entry = JSON.parse(line); + pathMap.set(entry.path, entry); + } + } + + // for every 'add' operation, there must be an entry in the cache file with integrity + // for every 'delete' operation, there must be no entry in the cache file + for (const change of changes) { + if (change.operation === 'add') { + expect(pathMap.get(change.path).integrity.sha256).to.be('fake-sha256'); + expect(pathMap.get(change.path).stat).to.be.an('object'); + } else if (change.operation === 'remove') { + // if a file was removed, it won't be in pathMap. but if the file became a dir, it can be in pathMap without integrity info + expect(!pathMap.has(change.path) || !pathMap.get(change.path).integrity).to.be(true); + } + } + } + it('missing cache - removes remote dir', async function () { safe.fs.unlinkSync(gCacheFile); createTree(gTmpDir, { }); @@ -36,6 +65,8 @@ describe('Syncer', function () { const dataLayout = new DataLayout(gTmpDir, []); const changes = await getChanges(dataLayout); expect(changes).to.eql([{ operation: 'removedir', path: '', reason: 'nocache' }]); + + expect(fs.readFileSync(gCacheFile, 'utf8')).to.be(''); }); it('empty cache - adds all', async function () { @@ -50,6 +81,8 @@ describe('Syncer', function () { { operation: 'add', path: 'test/test.js', reason: 'new', position: 1 }, { operation: 'add', path: 'walrus', reason: 'new', position: 2 } ]); + + checkCache(gCacheFile, changes); }); it('empty cache - deep', async function () { @@ -62,6 +95,8 @@ describe('Syncer', function () { expect(changes).to.eql([ { operation: 'add', path: 'a/b/c/d/e', reason: 'new', position: 0 } ]); + + checkCache(gCacheFile, changes); }); it('ignores special files', async function () { @@ -74,6 +109,8 @@ describe('Syncer', function () { expect(changes).to.eql([ { operation: 'add', path: 'readme', reason: 'new', position: 0 } ]); + + checkCache(gCacheFile, changes); }); it('adds changed files', async function () { @@ -93,6 +130,8 @@ describe('Syncer', function () { { operation: 'add', path: 'src/index.js', reason: 'changed', position: 0 }, { operation: 'add', path: 'test/test.js', reason: 'changed', position: 1 } ]); + + checkCache(gCacheFile, changes); }); it('removes missing files', async function () { @@ -112,6 +151,8 @@ describe('Syncer', function () { { operation: 'remove', path: 'src/index.js', reason: 'missing' }, { operation: 'remove', path: 'walrus', reason: 'missing' } ]); + + checkCache(gCacheFile, changes); }); it('removes missing dirs', async function () { @@ -131,6 +172,8 @@ describe('Syncer', function () { { operation: 'removedir', path: 'src', reason: 'missing' }, { operation: 'removedir', path: 'test', reason: 'missing' } ]); + + checkCache(gCacheFile, changes); }); it('all files disappeared', async function () { @@ -151,6 +194,8 @@ describe('Syncer', function () { { operation: 'removedir', path: 'test', reason: 'missing' }, { operation: 'remove', path: 'walrus', reason: 'missing' } ]); + + checkCache(gCacheFile, changes); }); it('no redundant deletes', async function () { @@ -170,6 +215,8 @@ describe('Syncer', function () { { operation: 'removedir', path: 'a/b', reason: 'missing' }, { operation: 'add', path: 'a/f', reason: 'new', position: 0 } ]); + + checkCache(gCacheFile, changes); }); it('file became dir', async function () { @@ -189,6 +236,8 @@ describe('Syncer', function () { { operation: 'remove', path: 'data/test/test.js', reason: 'wasfile' }, { operation: 'add', path: 'data/test/test.js/trick', reason: 'new', position: 0 } ]); + + checkCache(gCacheFile, changes); }); it('dir became file', async function () { @@ -208,6 +257,8 @@ describe('Syncer', function () { { operation: 'removedir', path: 'test', reason: 'wasdir' }, { operation: 'add', path: 'test', reason: 'wasdir', position: 0 } ]); + + checkCache(gCacheFile, changes); }); it('is complicated', async function () { @@ -260,5 +311,7 @@ describe('Syncer', function () { changes = await getChanges(dataLayout); expect(changes.length).to.be(0); + + checkCache(gCacheFile, changes); }); });