node-smb-server
Version:
A Pure JavaScript SMB Server Implementation
377 lines (347 loc) • 14.9 kB
JavaScript
/*
* Copyright 2016 Adobe Systems Incorporated. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
var RQCommon = require('./rq-common');
var RQProcessor = RQCommon.require(__dirname, '../../../../lib/backends/rq/rqprocessor');
var RequestQueue = RQCommon.require(__dirname, '../../../../lib/backends/rq/requestqueue');
var Path = require('path');
var URL = require('url');
describe('RQProcessor', function () {
var processor, c, rq, config;
beforeEach(function () {
c = new RQCommon();
processor = new RQProcessor(c.testTree);
config = {
expiration: 0,
maxRetries: 3,
retryDelay: 200,
frequency: 500
};
spyOn(processor, 'emit').andCallThrough();
});
describe('RQUpdated', function () {
it('testItemUpdatedUploading', function (done) {
var delayed = false;
c.addQueuedFile('/testfile', function () {
c.setPipeDelay(function (delayCb) {
if (!delayed) {
delayed = true;
c.testTree.rq.queueRequest({
method: 'POST',
path: '/testfile',
localPrefix: c.localPrefix,
remotePrefix: c.hostPrefix
}, function (err) {
delayCb();
});
} else {
delayCb();
}
});
processor.sync(config, function (err) {
expect(err).toBeFalsy();
expect(processor.emit).toHaveBeenCalledWith('syncabort', {path: '/testfile', file: '/local/path/testfile'});
expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testfile', file: '/local/path/testfile', method: 'POST'});
done();
});
});
});
it('testItemUpdatedNotUploading', function (done) {
c.addQueuedFile('/testfile', function () {
c.testTree.rq.queueRequest({
method: 'POST',
path: '/testfile',
localPrefix: c.localPrefix,
remotePrefix: c.hostPrefix
}, function (err) {
expect(err).toBeFalsy();
c.expectQueuedMethod('/', 'testfile', 'PUT', function () {
expect(processor.emit).not.toHaveBeenCalledWith('syncabort', {path: '/testfile', file: '/local/path/testfile'});
done();
});
});
});
});
var testPathUpdated = function (path, removePath, done) {
c.addQueuedFile(path, function () {
c.setPipeDelay(function (pipeCb) {
c.testTree.rq.removePath(removePath, function (err) {
pipeCb();
});
});
processor.sync(config, function (err) {
expect(err).toBeFalsy();
expect(processor.emit).toHaveBeenCalledWith('syncabort', {path: path, file: '/local/path' + path});
expect(processor.emit).not.toHaveBeenCalledWith('syncend', {path: path, file: '/local/path' + path, method:'POST'});
done();
});
});
};
it('testPathUpdatedUploading', function (done) {
testPathUpdated('/testfile', '/', done);
});
it('testPathUpdatedUploadingSubPath', function (done) {
testPathUpdated('/dir/testfile', '/', done);
});
it('testPathUpdatedUploadingSubPathNotRoot', function (done) {
testPathUpdated('/dir/testfile', '/dir', done);
});
});
describe('Sync', function () {
var testDotFile = function (path, name, done) {
c.testTree.rq.getProcessRequest = function (expiration, maxRetries, cb) {
cb(null, {
path: path,
name: name,
method: 'DELETE',
remotePrefix: c.hostPrefix,
localPrefix: c.localPrefix
});
};
c.testTree.rq.completeRequest = function (path, name, cb) {
c.testTree.rq.getProcessRequest = function (expiration, maxRetries, getCb) {
getCb();
};
cb();
};
processor.sync(config, function (err) {
expect(err).toBeFalsy();
expect(processor.emit).toHaveBeenCalledWith('syncerr', {path: Path.join(path, name), file: Path.join(c.localPrefix, path, name), method: 'DELETE', err: jasmine.any(String)});
done();
});
};
var addLocalCachedFile = function (path, cb) {
c.addFile(c.remoteTree, path, function () {
c.testTree.open(path, function (err, file) {
expect(err).toBeFalsy();
file.cacheFile(function (err) {
expect(err).toBeFalsy();
cb(file);
});
});
});
};
it('testSyncCreate', function (done) {
c.addQueuedFile('/testfile', function () {
processor.sync(config, function (err) {
expect(err).toBeFalsy();
c.expectLocalFileExist('/testfile', true, false, function () {
c.expectQueuedMethod('/', 'testfile', false, function () {
expect(processor.emit).toHaveBeenCalledWith('syncstart', {path: '/testfile', file: '/local/path/testfile', method: 'POST'});
expect(processor.emit).toHaveBeenCalledWith('syncprogress', {path: '/testfile', file: '/local/path/testfile', read: jasmine.any(Number), total: jasmine.any(Number), rate: jasmine.any(Number)});
expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testfile', file: '/local/path/testfile', method: 'POST'});
done();
});
});
});
});
});
it('testSyncUpdate', function (done) {
addLocalCachedFile('/testfile', function (file) {
file.setLength(100, function (err) {
expect(err).toBeFalsy();
file.close(function (err) {
expect(err).toBeFalsy();
processor.sync(config, function (err) {
expect(err).toBeFalsy();
c.expectQueuedMethod('/', 'testfile', false, function () {
expect(processor.emit).toHaveBeenCalledWith('syncstart', {path: '/testfile', file: '/local/path/testfile', method: 'PUT'});
expect(processor.emit).toHaveBeenCalledWith('syncprogress', {path: '/testfile', file: '/local/path/testfile', read: jasmine.any(Number), total: jasmine.any(Number), rate: jasmine.any(Number)});
expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testfile', file: '/local/path/testfile', method: 'PUT'});
done();
});
});
});
});
});
});
it('testSyncDelete', function (done) {
addLocalCachedFile('/testfile', function (file) {
c.testTree.delete('/testfile', function (err) {
expect(err).toBeFalsy();
processor.sync(config, function (err) {
expect(err).toBeFalsy();
c.expectQueuedMethod('/', 'testfile', false, function () {
expect(processor.emit).toHaveBeenCalledWith('syncstart', {path: '/testfile', file: '/local/path/testfile', method: 'DELETE'});
expect(processor.emit).not.toHaveBeenCalledWith('syncprogress', {path: '/testfile', file: '/local/path/testfile', read: jasmine.any(Number), total: jasmine.any(Number), rate: jasmine.any(Number)});
expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testfile', file: '/local/path/testfile', method: 'DELETE'});
done();
});
});
});
});
});
it('testSyncDotFile', function (done) {
testDotFile('/', '.badfile', done);
});
it('testSyncDotFolder', function (done) {
testDotFile('/.badfolder', 'testfile', done);
});
it('testSyncErrorStatusCode', function (done) {
c.registerPathStatusCode('/testfile', 500);
c.addQueuedFile('/testfile', function (file) {
processor.sync(config, function (err) {
expect(err).toBeFalsy();
c.expectQueuedMethod('/', 'testfile', 'PUT', function () {
expect(processor.emit).toHaveBeenCalledWith('syncerr', {path: '/testfile', file: Path.join(c.localPrefix, '/testfile'), method: 'POST', err: jasmine.any(String)});
c.testTree.rq.queueRequest({
method: 'DELETE',
path: '/testfile',
localPrefix: c.localPrefix,
remotePrefix: c.hostPrefix
}, function (err) {
expect(err).toBeFalsy();
expect(processor.emit).not.toHaveBeenCalledWith('syncabort', {path:any(String), file:any(String)});
done();
});
});
});
});
});
it('testSyncCheckedOut', function (done) {
c.registerPathStatusCode('/testfile', 423);
c.addQueuedFile('/testfile', function (file) {
processor.sync(config, function (err) {
expect(err).toBeFalsy();
c.expectQueuedMethod('/', 'testfile', false, function () {
expect(processor.emit).toHaveBeenCalledWith('syncerr', {path: '/testfile', file: '/local/path/testfile', method: 'POST', err: jasmine.any(String)});
done();
});
});
});
});
it('testSyncEncoded', function (done) {
var remoteEncodedName = '/%EC%9D%B4%EB%91%90%E5%90%8F%E8%AE%80.jpg';
var remoteFileName = decodeURI(remoteEncodedName);
var localFileNameOnly = decodeURI('%E1%84%8B%E1%85%B5%E1%84%83%E1%85%AE%E5%90%8F%E8%AE%80.jpg');
var localFileName = '/' + localFileNameOnly;
c.addFile(c.remoteTree, remoteFileName, function () {
c.addFile(c.localTree, localFileName, function () {
c.testTree.open(localFileName, function (err, rqFile) {
expect(err).toBeFalsy();
rqFile.setLength(10, function (err) {
expect(err).toBeFalsy();
rqFile.close(function (err) {
expect(err).toBeFalsy();
processor.sync(config, function (err) {
expect(err).toBeFalsy();
expect(c.wasPathRequested(remoteEncodedName)).toBeTruthy();
c.expectQueuedMethod('/', localFileNameOnly, false, done);
});
});
});
});
});
});
});
it('testSyncNoExist', function (done) {
c.registerPathStatusCode('/testfile', 404);
c.addQueuedFile('/testfile', function () {
processor.sync(config, function (err) {
expect(err).toBeFalsy();
c.expectQueuedMethod('/', 'testfile', 'PUT', function () {
expect(processor.emit).toHaveBeenCalledWith('syncerr', { path: '/testfile', file: Path.join(c.localPrefix, '/testfile'), method: 'POST', err: jasmine.any(String) });
done();
});
});
});
});
it('testSyncDates', function (done) {
c.addFile(c.remoteTree, '/test', function () {
c.testTree.open('/test', function (err, file) {
expect(err).toBeFalsy();
var lastModified = file.lastModified();
file.write('hello', 0, function (err) {
expect(err).toBeFalsy();
setTimeout(function () {
file.setLastModified(new Date().getTime());
file.close(function (err) {
expect(err).toBeFalsy();
processor.sync(config, function (err) {
expect(err).toBeFalsy();
c.testTree.open('/test', function (err, newFile) {
expect(err).toBeFalsy();
expect(file.created()).toEqual(newFile.created());
expect(file.lastModified()).toEqual(newFile.lastModified());
expect(file.lastChanged()).toEqual(newFile.lastChanged());
done();
});
});
});
}, 10);
});
});
});
});
it('testCacheFileAfterSync', function (done) {
c.addQueuedFile('/testfile', function () {
processor.sync(config, function (err) {
expect(err).toBeFalsy();
expect(c.getPathMethodRequestCount('/testfile', 'POST')).toEqual(1);
c.testTree.open('/testfile', function (err, file) {
expect(err).toBeFalsy();
file.cacheFile(function (err) {
expect(err).toBeFalsy();
expect(c.getPathMethodRequestCount('/testfile', 'GET')).toEqual(0);
done();
});
});
});
});
});
});
describe('StartStop', function () {
it('testStartStop', function (done) {
c.addQueuedFile('/testfile', function (file) {
c.addCachedFile('/testdelete', function () {
c.testTree.delete('/testdelete', function (err) {
expect(err).toBeFalsy();
c.testTree.rq.incrementRetryCount('/', 'testdelete', 400, function (err) {
expect(err).toBeFalsy();
processor.start(config);
setTimeout(function () {
processor.stop();
expect(processor.emit).toHaveBeenCalledWith('syncstart', {path: '/testfile', file: '/local/path/testfile', method: 'POST'});
expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testfile', file: '/local/path/testfile', method: 'POST'});
expect(processor.emit).toHaveBeenCalledWith('syncstart', {path: '/testdelete', file: '/local/path/testdelete', method: 'DELETE'});
expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testdelete', file: '/local/path/testdelete', method: 'DELETE'});
done();
}, 1000);
});
});
});
});
});
it('testStartStopPurgeRequests', function (done) {
c.addQueuedFile('/testfile', function (file) {
config.maxRetries = 0;
processor.start(config);
setTimeout(function () {
processor.stop();
expect(processor.emit).toHaveBeenCalledWith('purged', any(Object));
expect(processor.emit).not.toHaveBeenCalledWith('syncstart', any(Object));
done();
}, 200);
});
});
it('testStartStopCancelRequest', function (done) {
c.addQueuedFile('/testfile', function (file) {
c.setPipeDelay(function (delayCb) {
processor.stop();
delayCb();
expect(processor.emit).toHaveBeenCalledWith('syncabort', {path: '/testfile', file: '/local/path/testfile'});
done();
});
processor.start(config);
});
});
});
});