mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
325 lines
10 KiB
JavaScript
325 lines
10 KiB
JavaScript
'use strict';
|
|
|
|
const expect = require('chai').expect;
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
const JsZip = require('jszip');
|
|
const _ = require('lodash');
|
|
const Package = require('../index');
|
|
const Serverless = require('../../../../lib/Serverless');
|
|
const testUtils = require('../../../../tests/utils');
|
|
|
|
describe('#zipService()', () => {
|
|
let serverless;
|
|
let packageService;
|
|
let zip;
|
|
let servicePath;
|
|
|
|
const testDirectory = {
|
|
// root
|
|
'.': {
|
|
'event.json': 'some content',
|
|
'handler.js': 'some content',
|
|
'file-1': 'some content',
|
|
'file-2': 'some content',
|
|
},
|
|
// bin
|
|
bin: {
|
|
'binary-777': {
|
|
content: 'some content',
|
|
permissions: 777,
|
|
},
|
|
'binary-444': {
|
|
content: 'some content',
|
|
permissions: 444,
|
|
},
|
|
},
|
|
// lib
|
|
lib: {
|
|
'file-1.js': 'some content',
|
|
},
|
|
'lib/directory-1': {
|
|
'file-1.js': 'some content',
|
|
},
|
|
// node_modules
|
|
'node_modules/directory-1': {
|
|
'file-1': 'some content',
|
|
'file-2': 'some content',
|
|
},
|
|
'node_modules/directory-2': {
|
|
'file-1': 'some content',
|
|
'file-2': 'some content',
|
|
},
|
|
};
|
|
|
|
function getTestArtifactFileName(testName) {
|
|
return `test-${testName}-${(new Date()).getTime().toString()}.zip`;
|
|
}
|
|
|
|
beforeEach(() => {
|
|
serverless = new Serverless();
|
|
zip = new JsZip();
|
|
packageService = new Package(serverless);
|
|
packageService.serverless.cli = new serverless.classes.CLI();
|
|
|
|
// create a mock service in a temporary directory
|
|
const tmpDirPath = testUtils.getTmpDirPath();
|
|
|
|
Object.keys(testDirectory).forEach(dirName => {
|
|
const dirPath = path.join(tmpDirPath, dirName);
|
|
const files = testDirectory[dirName];
|
|
|
|
Object.keys(files).forEach(fileName => {
|
|
const filePath = path.join(dirPath, fileName);
|
|
const fileValue = files[fileName];
|
|
const file = _.isObject(fileValue) ? fileValue : { content: fileValue };
|
|
|
|
if (!file.content) {
|
|
throw new Error('File content is required');
|
|
}
|
|
|
|
serverless.utils.writeFileSync(filePath, file.content);
|
|
|
|
if (file.permissions) {
|
|
fs.chmodSync(filePath, file.permissions);
|
|
}
|
|
});
|
|
});
|
|
// set the service name
|
|
serverless.service.service = 'first-service';
|
|
|
|
// set the servicePath
|
|
servicePath = tmpDirPath;
|
|
});
|
|
|
|
it('should zip a whole service (without include / exclude usage)', () => {
|
|
const exclude = [];
|
|
const include = [];
|
|
const zipFileName = getTestArtifactFileName('whole-service');
|
|
|
|
return packageService
|
|
.zipDirectory(servicePath, exclude, include, zipFileName).then((artifact) => {
|
|
const data = fs.readFileSync(artifact);
|
|
|
|
return zip.loadAsync(data);
|
|
}).then(unzippedData => {
|
|
const unzippedFileData = unzippedData.files;
|
|
|
|
expect(Object.keys(unzippedFileData)
|
|
.filter(file => !unzippedFileData[file].dir).length).to.equal(13);
|
|
|
|
// root directory
|
|
expect(unzippedFileData['event.json'].name)
|
|
.to.equal('event.json');
|
|
expect(unzippedFileData['handler.js'].name)
|
|
.to.equal('handler.js');
|
|
expect(unzippedFileData['file-1'].name)
|
|
.to.equal('file-1');
|
|
expect(unzippedFileData['file-2'].name)
|
|
.to.equal('file-2');
|
|
|
|
// bin directory
|
|
expect(unzippedFileData['bin/binary-777'].name)
|
|
.to.equal('bin/binary-777');
|
|
expect(unzippedFileData['bin/binary-444'].name)
|
|
.to.equal('bin/binary-444');
|
|
|
|
// lib directory
|
|
expect(unzippedFileData['lib/file-1.js'].name)
|
|
.to.equal('lib/file-1.js');
|
|
expect(unzippedFileData['lib/directory-1/file-1.js'].name)
|
|
.to.equal('lib/directory-1/file-1.js');
|
|
|
|
// node_modules directory
|
|
expect(unzippedFileData['node_modules/directory-1/file-1'].name)
|
|
.to.equal('node_modules/directory-1/file-1');
|
|
expect(unzippedFileData['node_modules/directory-1/file-2'].name)
|
|
.to.equal('node_modules/directory-1/file-2');
|
|
expect(unzippedFileData['node_modules/directory-2/file-1'].name)
|
|
.to.equal('node_modules/directory-2/file-1');
|
|
expect(unzippedFileData['node_modules/directory-2/file-2'].name)
|
|
.to.equal('node_modules/directory-2/file-2');
|
|
});
|
|
});
|
|
|
|
it('should keep file permissions', () => {
|
|
const exclude = [];
|
|
const include = [];
|
|
const zipFileName = getTestArtifactFileName('file-permissions');
|
|
|
|
return packageService.zipDirectory(servicePath, exclude, include, zipFileName)
|
|
.then((artifact) => {
|
|
const data = fs.readFileSync(artifact);
|
|
return zip.loadAsync(data);
|
|
}).then(unzippedData => {
|
|
const unzippedFileData = unzippedData.files;
|
|
|
|
if (os.platform() === 'win32') {
|
|
// chmod does not work right on windows. this is better than nothing?
|
|
expect(unzippedFileData['bin/binary-777'].unixPermissions)
|
|
.to.not.equal(unzippedFileData['bin/binary-444'].unixPermissions);
|
|
} else {
|
|
// binary file is set with chmod of 777
|
|
expect(unzippedFileData['bin/binary-777'].unixPermissions)
|
|
.to.equal(Math.pow(2, 15) + 777);
|
|
|
|
// read only file is set with chmod of 444
|
|
expect(unzippedFileData['bin/binary-444'].unixPermissions)
|
|
.to.equal(Math.pow(2, 15) + 444);
|
|
}
|
|
});
|
|
});
|
|
|
|
it('should exclude with globs', () => {
|
|
const exclude = [
|
|
'event.json',
|
|
'lib/**',
|
|
'node_modules/directory-1/**',
|
|
];
|
|
const include = [];
|
|
|
|
const zipFileName = getTestArtifactFileName('exclude-with-globs');
|
|
|
|
return packageService.zipDirectory(servicePath, exclude, include, zipFileName)
|
|
.then((artifact) => {
|
|
const data = fs.readFileSync(artifact);
|
|
|
|
return zip.loadAsync(data);
|
|
}).then(unzippedData => {
|
|
const unzippedFileData = unzippedData.files;
|
|
|
|
expect(Object.keys(unzippedFileData)
|
|
.filter(file => !unzippedFileData[file].dir).length).to.equal(8);
|
|
|
|
// root directory
|
|
expect(unzippedFileData['handler.js'].name)
|
|
.to.equal('handler.js');
|
|
expect(unzippedFileData['file-1'].name)
|
|
.to.equal('file-1');
|
|
expect(unzippedFileData['file-2'].name)
|
|
.to.equal('file-2');
|
|
|
|
// bin directory
|
|
expect(unzippedFileData['bin/binary-777'].name)
|
|
.to.equal('bin/binary-777');
|
|
expect(unzippedFileData['bin/binary-444'].name)
|
|
.to.equal('bin/binary-444');
|
|
|
|
// node_modules directory
|
|
expect(unzippedFileData['node_modules/directory-2/file-1'].name)
|
|
.to.equal('node_modules/directory-2/file-1');
|
|
expect(unzippedFileData['node_modules/directory-2/file-2'].name)
|
|
.to.equal('node_modules/directory-2/file-2');
|
|
});
|
|
});
|
|
|
|
it('should re-include files using ! glob pattern', () => {
|
|
const exclude = [
|
|
'event.json',
|
|
'lib/**',
|
|
'node_modules/directory-1/**',
|
|
|
|
'!event.json', // re-include
|
|
'!lib/**', // re-include
|
|
];
|
|
const include = [];
|
|
|
|
const zipFileName = getTestArtifactFileName('re-include-with-globs');
|
|
|
|
return packageService.zipDirectory(servicePath, exclude, include, zipFileName)
|
|
.then((artifact) => {
|
|
const data = fs.readFileSync(artifact);
|
|
|
|
return zip.loadAsync(data);
|
|
}).then(unzippedData => {
|
|
const unzippedFileData = unzippedData.files;
|
|
|
|
expect(Object.keys(unzippedFileData)
|
|
.filter(file => !unzippedFileData[file].dir).length).to.equal(11);
|
|
|
|
// root directory
|
|
expect(unzippedFileData['event.json'].name)
|
|
.to.equal('event.json');
|
|
expect(unzippedFileData['handler.js'].name)
|
|
.to.equal('handler.js');
|
|
expect(unzippedFileData['file-1'].name)
|
|
.to.equal('file-1');
|
|
expect(unzippedFileData['file-2'].name)
|
|
.to.equal('file-2');
|
|
|
|
// bin directory
|
|
expect(unzippedFileData['bin/binary-777'].name)
|
|
.to.equal('bin/binary-777');
|
|
expect(unzippedFileData['bin/binary-444'].name)
|
|
.to.equal('bin/binary-444');
|
|
|
|
// lib directory
|
|
expect(unzippedFileData['lib/file-1.js'].name)
|
|
.to.equal('lib/file-1.js');
|
|
expect(unzippedFileData['lib/directory-1/file-1.js'].name)
|
|
.to.equal('lib/directory-1/file-1.js');
|
|
|
|
// node_modules directory
|
|
expect(unzippedFileData['node_modules/directory-2/file-1'].name)
|
|
.to.equal('node_modules/directory-2/file-1');
|
|
expect(unzippedFileData['node_modules/directory-2/file-2'].name)
|
|
.to.equal('node_modules/directory-2/file-2');
|
|
});
|
|
});
|
|
|
|
it('should re-include files using include config', () => {
|
|
const exclude = [
|
|
'event.json',
|
|
'lib/**',
|
|
'node_modules/directory-1/**',
|
|
];
|
|
const include = [
|
|
'event.json',
|
|
'lib/**',
|
|
];
|
|
|
|
const zipFileName = getTestArtifactFileName('re-include-with-include');
|
|
|
|
return packageService.zipDirectory(servicePath, exclude, include, zipFileName)
|
|
.then((artifact) => {
|
|
const data = fs.readFileSync(artifact);
|
|
|
|
return zip.loadAsync(data);
|
|
}).then(unzippedData => {
|
|
const unzippedFileData = unzippedData.files;
|
|
|
|
expect(Object.keys(unzippedFileData)
|
|
.filter(file => !unzippedFileData[file].dir).length).to.equal(11);
|
|
|
|
// root directory
|
|
expect(unzippedFileData['event.json'].name)
|
|
.to.equal('event.json');
|
|
expect(unzippedFileData['handler.js'].name)
|
|
.to.equal('handler.js');
|
|
expect(unzippedFileData['file-1'].name)
|
|
.to.equal('file-1');
|
|
expect(unzippedFileData['file-2'].name)
|
|
.to.equal('file-2');
|
|
|
|
// bin directory
|
|
expect(unzippedFileData['bin/binary-777'].name)
|
|
.to.equal('bin/binary-777');
|
|
expect(unzippedFileData['bin/binary-444'].name)
|
|
.to.equal('bin/binary-444');
|
|
|
|
// lib directory
|
|
expect(unzippedFileData['lib/file-1.js'].name)
|
|
.to.equal('lib/file-1.js');
|
|
expect(unzippedFileData['lib/directory-1/file-1.js'].name)
|
|
.to.equal('lib/directory-1/file-1.js');
|
|
|
|
// node_modules directory
|
|
expect(unzippedFileData['node_modules/directory-2/file-1'].name)
|
|
.to.equal('node_modules/directory-2/file-1');
|
|
expect(unzippedFileData['node_modules/directory-2/file-2'].name)
|
|
.to.equal('node_modules/directory-2/file-2');
|
|
});
|
|
});
|
|
});
|