mirror of
https://github.com/serverless/serverless.git
synced 2025-12-08 19:46:03 +00:00
149 lines
4.9 KiB
JavaScript
149 lines
4.9 KiB
JavaScript
'use strict';
|
|
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const fse = require('fs-extra');
|
|
const stripAnsi = require('strip-ansi');
|
|
const { expect } = require('chai');
|
|
const log = require('log').get('serverless:test');
|
|
const spawn = require('child-process-ext/spawn');
|
|
const resolveAwsEnv = require('@serverless/test/resolve-aws-env');
|
|
const hasFailed = require('@serverless/test/has-failed');
|
|
const awsRequest = require('@serverless/test/aws-request');
|
|
const CloudFormationService = require('aws-sdk').CloudFormation;
|
|
const { getTmpDirPath } = require('./utils/fs');
|
|
|
|
const serverlessExec = require('./serverless-binary');
|
|
|
|
describe('Service Lifecyle Integration Test', function () {
|
|
this.timeout(1000 * 60 * 10); // Involves time-taking deploys
|
|
const templateName = 'aws-nodejs';
|
|
const tmpDir = getTmpDirPath();
|
|
const env = resolveAwsEnv();
|
|
const spawnOptions = {
|
|
cwd: tmpDir,
|
|
env,
|
|
// As in invoke we optionally read stdin, we need to ensure it's closed
|
|
// See https://github.com/sindresorhus/get-stdin/issues/13#issuecomment-279234249
|
|
shouldCloseStdin: true,
|
|
};
|
|
let serviceName;
|
|
let StackName;
|
|
|
|
before(() => {
|
|
serviceName = `test-basic-${process.hrtime()[1]}`;
|
|
StackName = `${serviceName}-dev`;
|
|
log.notice(`Temporary path: ${tmpDir}`);
|
|
fse.mkdirsSync(tmpDir);
|
|
});
|
|
|
|
// Do not continue if any of the tests failed
|
|
beforeEach(function () {
|
|
if (hasFailed(this.test.parent)) this.skip();
|
|
});
|
|
|
|
after(async () => {
|
|
try {
|
|
await awsRequest(CloudFormationService, 'describeStacks', { StackName });
|
|
} catch (error) {
|
|
if (error.message.indexOf('does not exist') > -1) return;
|
|
throw error;
|
|
}
|
|
await spawn(serverlessExec, ['remove'], { cwd: tmpDir, env });
|
|
});
|
|
|
|
it('should create service in tmp directory', async () => {
|
|
await spawn(
|
|
serverlessExec,
|
|
['create', '--template', templateName, '--name', serviceName],
|
|
spawnOptions
|
|
);
|
|
expect(fs.existsSync(path.join(tmpDir, 'serverless.yml'))).to.be.equal(true);
|
|
expect(fs.existsSync(path.join(tmpDir, 'handler.js'))).to.be.equal(true);
|
|
});
|
|
|
|
it('should deploy service to aws', async () => {
|
|
await spawn(serverlessExec, ['deploy'], { cwd: tmpDir, env });
|
|
|
|
const d = await awsRequest(CloudFormationService, 'describeStacks', { StackName });
|
|
expect(d.Stacks[0].StackStatus).to.be.equal('UPDATE_COMPLETE');
|
|
});
|
|
|
|
it('should invoke function from aws', async () => {
|
|
const { stdoutBuffer: invoked } = await spawn(
|
|
serverlessExec,
|
|
['invoke', '--function', 'hello'],
|
|
spawnOptions
|
|
);
|
|
const result = JSON.parse(invoked);
|
|
// parse it once again because the body is stringified to be LAMBDA-PROXY ready
|
|
const message = JSON.parse(result.body).message;
|
|
expect(message).to.be.equal('Go Serverless v1.0! Your function executed successfully!');
|
|
});
|
|
|
|
it('should deploy updated service to aws', () => {
|
|
const newHandler = `
|
|
'use strict';
|
|
|
|
module.exports.hello = (event, context, cb) => cb(null,
|
|
{ message: 'Service Update Succeeded' }
|
|
);
|
|
`;
|
|
|
|
fs.writeFileSync(path.join(tmpDir, 'handler.js'), newHandler);
|
|
return spawn(serverlessExec, ['deploy'], spawnOptions);
|
|
});
|
|
|
|
it('should invoke updated function from aws', async () => {
|
|
const { stdoutBuffer: invoked } = await spawn(
|
|
serverlessExec,
|
|
['invoke', '--function', 'hello'],
|
|
spawnOptions
|
|
);
|
|
const result = JSON.parse(invoked);
|
|
expect(result.message).to.be.equal('Service Update Succeeded');
|
|
});
|
|
|
|
it('should list existing deployments and roll back to first deployment', async () => {
|
|
let timestamp;
|
|
const { stdoutBuffer: listDeploys } = await spawn(
|
|
serverlessExec,
|
|
['deploy', 'list'],
|
|
spawnOptions
|
|
);
|
|
const output = stripAnsi(listDeploys.toString());
|
|
const match = output.match(new RegExp('Timestamp: (.+)'));
|
|
if (match) {
|
|
timestamp = match[1];
|
|
}
|
|
expect(timestamp).to.not.undefined;
|
|
|
|
await spawn(serverlessExec, ['rollback', '-t', timestamp], { cwd: tmpDir, env });
|
|
|
|
const { stdoutBuffer: invoked } = await spawn(
|
|
serverlessExec,
|
|
['invoke', '--function', 'hello'],
|
|
spawnOptions
|
|
);
|
|
const result = JSON.parse(invoked);
|
|
// parse it once again because the body is stringified to be LAMBDA-PROXY ready
|
|
const message = JSON.parse(result.body).message;
|
|
expect(message).to.be.equal('Go Serverless v1.0! Your function executed successfully!');
|
|
});
|
|
|
|
it('should remove service from aws', async () => {
|
|
await spawn(serverlessExec, ['remove'], { cwd: tmpDir, env });
|
|
|
|
const d = await (async () => {
|
|
try {
|
|
return await awsRequest(CloudFormationService, 'describeStacks', { StackName });
|
|
} catch (error) {
|
|
if (error.message.indexOf('does not exist') > -1) return null;
|
|
throw error;
|
|
}
|
|
})();
|
|
if (!d) return;
|
|
expect(d.Stacks[0].StackStatus).to.be.equal('DELETE_COMPLETE');
|
|
});
|
|
});
|