mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
374 lines
12 KiB
JavaScript
374 lines
12 KiB
JavaScript
'use strict';
|
|
|
|
const expect = require('chai').expect;
|
|
const sinon = require('sinon');
|
|
const AwsProvider = require('../../../../../lib/plugins/aws/provider');
|
|
const AwsMetrics = require('../../../../../lib/plugins/aws/metrics');
|
|
const Serverless = require('../../../../../lib/Serverless');
|
|
const CLI = require('../../../../../lib/classes/CLI');
|
|
const dayjs = require('dayjs');
|
|
|
|
const LocalizedFormat = require('dayjs/plugin/localizedFormat');
|
|
|
|
dayjs.extend(LocalizedFormat);
|
|
|
|
describe('AwsMetrics', () => {
|
|
let awsMetrics;
|
|
let serverless;
|
|
|
|
beforeEach(() => {
|
|
serverless = new Serverless();
|
|
serverless.cli = new CLI(serverless);
|
|
const options = {
|
|
stage: 'dev',
|
|
region: 'us-east-1',
|
|
};
|
|
serverless.setProvider('aws', new AwsProvider(serverless, options));
|
|
awsMetrics = new AwsMetrics(serverless, options);
|
|
});
|
|
|
|
describe('#constructor()', () => {
|
|
it('should set the serverless instance to this.serverless', () => {
|
|
expect(awsMetrics.serverless).to.deep.equal(serverless);
|
|
});
|
|
|
|
it('should set the passed in options to this.options', () => {
|
|
expect(awsMetrics.options).to.deep.equal({ stage: 'dev', region: 'us-east-1' });
|
|
});
|
|
|
|
it('should set the provider variable to the AwsProvider instance', () =>
|
|
expect(awsMetrics.provider).to.be.instanceof(AwsProvider));
|
|
|
|
it('should have a "metrics:metrics" hook', () => {
|
|
// eslint-disable-next-line no-unused-expressions
|
|
expect(awsMetrics.hooks['metrics:metrics']).to.not.be.undefined;
|
|
});
|
|
|
|
it('should run promise chain in order for "metrics:metrics" hook', async () => {
|
|
const extendedValidateStub = sinon.stub(awsMetrics, 'extendedValidate').resolves();
|
|
const getMetricsStub = sinon.stub(awsMetrics, 'getMetrics').resolves();
|
|
const showMetricsStub = sinon.stub(awsMetrics, 'showMetrics').resolves();
|
|
|
|
await awsMetrics.hooks['metrics:metrics']();
|
|
|
|
expect(extendedValidateStub.calledOnce).to.equal(true);
|
|
expect(getMetricsStub.calledAfter(extendedValidateStub)).to.equal(true);
|
|
expect(showMetricsStub.calledAfter(getMetricsStub)).to.equal(true);
|
|
|
|
awsMetrics.extendedValidate.restore();
|
|
awsMetrics.getMetrics.restore();
|
|
awsMetrics.showMetrics.restore();
|
|
});
|
|
});
|
|
|
|
describe('#extendedValidate()', () => {
|
|
let validateStub;
|
|
|
|
beforeEach(() => {
|
|
awsMetrics.serverless.service.functions = {
|
|
function1: {},
|
|
};
|
|
awsMetrics.serverless.service.service = 'my-service';
|
|
awsMetrics.options.function = 'function1';
|
|
validateStub = sinon.stub(awsMetrics, 'validate').resolves();
|
|
});
|
|
|
|
afterEach(() => {
|
|
awsMetrics.validate.restore();
|
|
});
|
|
|
|
it('should call the shared validate() function', () => {
|
|
awsMetrics.extendedValidate();
|
|
|
|
expect(validateStub.calledOnce).to.equal(true);
|
|
});
|
|
|
|
it('should set the startTime to yesterday as the default value if not provided', () => {
|
|
awsMetrics.options.startTime = null;
|
|
|
|
let yesterday = new Date();
|
|
yesterday = yesterday.setDate(yesterday.getDate() - 1);
|
|
yesterday = new Date(yesterday);
|
|
const yesterdaysYear = yesterday.getFullYear();
|
|
const yesterdaysMonth = yesterday.getMonth() + 1;
|
|
const yesterdaysDay = yesterday.getDate();
|
|
const yesterdaysDate = `${yesterdaysYear}-${yesterdaysMonth}-${yesterdaysDay}`;
|
|
|
|
awsMetrics.extendedValidate();
|
|
|
|
const defaultsStartTime = dayjs(awsMetrics.options.startTime);
|
|
const defaultsDate = defaultsStartTime.format('YYYY-M-D');
|
|
expect(defaultsDate).to.equal(yesterdaysDate);
|
|
});
|
|
|
|
it('should set the startTime to the provided value', () => {
|
|
awsMetrics.options.startTime = '1970-01-01';
|
|
|
|
awsMetrics.extendedValidate();
|
|
|
|
const startTime = awsMetrics.options.startTime.toISOString();
|
|
const expectedStartTime = new Date('1970-01-01').toISOString();
|
|
expect(startTime).to.equal(expectedStartTime);
|
|
});
|
|
|
|
it('should translate human friendly syntax (e.g. 24h) for startTime', () => {
|
|
awsMetrics.options.startTime = '24h'; // 24 hours ago
|
|
|
|
let yesterday = new Date();
|
|
yesterday = yesterday.setDate(yesterday.getDate() - 1);
|
|
yesterday = new Date(yesterday);
|
|
const yesterdaysYear = yesterday.getFullYear();
|
|
const yesterdaysMonth = yesterday.getMonth() + 1;
|
|
const yesterdaysDay = yesterday.getDate();
|
|
const yesterdaysDate = `${yesterdaysYear}-${yesterdaysMonth}-${yesterdaysDay}`;
|
|
|
|
awsMetrics.extendedValidate();
|
|
|
|
const translatedStartTime = dayjs(awsMetrics.options.startTime);
|
|
const translatedDate = translatedStartTime.format('YYYY-M-D');
|
|
expect(translatedDate).to.equal(yesterdaysDate);
|
|
});
|
|
|
|
it('should set the endTime to today as the default value if not provided', () => {
|
|
awsMetrics.options.endTime = null;
|
|
|
|
const today = new Date();
|
|
const todaysYear = today.getFullYear();
|
|
const todaysMonth = today.getMonth() + 1;
|
|
const todaysDay = today.getDate();
|
|
const todaysDate = `${todaysYear}-${todaysMonth}-${todaysDay}`;
|
|
|
|
awsMetrics.extendedValidate();
|
|
|
|
const defaultsStartTime = dayjs(awsMetrics.options.endTime);
|
|
const defaultsDate = defaultsStartTime.format('YYYY-M-D');
|
|
|
|
expect(defaultsDate).to.equal(todaysDate);
|
|
});
|
|
|
|
it('should set the endTime to the provided value', () => {
|
|
awsMetrics.options.endTime = '1970-01-01';
|
|
|
|
awsMetrics.extendedValidate();
|
|
|
|
const endTime = awsMetrics.options.endTime.toISOString();
|
|
const expectedEndTime = new Date('1970-01-01').toISOString();
|
|
expect(endTime).to.equal(expectedEndTime);
|
|
});
|
|
});
|
|
|
|
describe('#getMetrics()', () => {
|
|
let requestStub;
|
|
|
|
beforeEach(() => {
|
|
awsMetrics.serverless.service.functions = {
|
|
function1: {
|
|
name: 'func1',
|
|
},
|
|
function2: {
|
|
name: 'func2',
|
|
},
|
|
};
|
|
awsMetrics.options.startTime = new Date('1970-01-01');
|
|
awsMetrics.options.endTime = new Date('1970-01-02');
|
|
requestStub = sinon.stub(awsMetrics.provider, 'request');
|
|
});
|
|
|
|
afterEach(() => {
|
|
awsMetrics.provider.request.restore();
|
|
});
|
|
|
|
it('should gather service wide function metrics if no function option is specified', async () => {
|
|
// stubs for function1
|
|
// invocations
|
|
requestStub.onCall(0).resolves({
|
|
ResponseMetadata: { RequestId: '1f50045b-b569-11e6-86c6-eb54d1aaa755-func1' },
|
|
Label: 'Invocations',
|
|
Datapoints: [],
|
|
});
|
|
// throttles
|
|
requestStub.onCall(1).resolves({
|
|
ResponseMetadata: { RequestId: '1f59059b-b569-11e6-aa18-c7bab68810d2-func1' },
|
|
Label: 'Throttles',
|
|
Datapoints: [],
|
|
});
|
|
// errors
|
|
requestStub.onCall(2).resolves({
|
|
ResponseMetadata: { RequestId: '1f50c7b1-b569-11e6-b1b6-ab86694b617b-func1' },
|
|
Label: 'Errors',
|
|
Datapoints: [],
|
|
});
|
|
// duration
|
|
requestStub.onCall(3).resolves({
|
|
ResponseMetadata: { RequestId: '1f63db14-b569-11e6-8501-d98a275ce164-func1' },
|
|
Label: 'Duration',
|
|
Datapoints: [],
|
|
});
|
|
// stubs for function2
|
|
// invocations
|
|
requestStub.onCall(4).resolves({
|
|
ResponseMetadata: { RequestId: '1f50045b-b569-11e6-86c6-eb54d1aaa755-func2' },
|
|
Label: 'Invocations',
|
|
Datapoints: [],
|
|
});
|
|
// throttles
|
|
requestStub.onCall(5).resolves({
|
|
ResponseMetadata: { RequestId: '1f59059b-b569-11e6-aa18-c7bab68810d2-func2' },
|
|
Label: 'Throttles',
|
|
Datapoints: [],
|
|
});
|
|
// errors
|
|
requestStub.onCall(6).resolves({
|
|
ResponseMetadata: { RequestId: '1f50c7b1-b569-11e6-b1b6-ab86694b617b-func2' },
|
|
Label: 'Errors',
|
|
Datapoints: [],
|
|
});
|
|
// duration
|
|
requestStub.onCall(7).resolves({
|
|
ResponseMetadata: { RequestId: '1f63db14-b569-11e6-8501-d98a275ce164-func2' },
|
|
Label: 'Duration',
|
|
Datapoints: [],
|
|
});
|
|
|
|
const expectedResult = [
|
|
[
|
|
{
|
|
ResponseMetadata: { RequestId: '1f50045b-b569-11e6-86c6-eb54d1aaa755-func1' },
|
|
Label: 'Invocations',
|
|
Datapoints: [],
|
|
},
|
|
{
|
|
ResponseMetadata: { RequestId: '1f59059b-b569-11e6-aa18-c7bab68810d2-func1' },
|
|
Label: 'Throttles',
|
|
Datapoints: [],
|
|
},
|
|
{
|
|
ResponseMetadata: { RequestId: '1f50c7b1-b569-11e6-b1b6-ab86694b617b-func1' },
|
|
Label: 'Errors',
|
|
Datapoints: [],
|
|
},
|
|
{
|
|
ResponseMetadata: { RequestId: '1f63db14-b569-11e6-8501-d98a275ce164-func1' },
|
|
Label: 'Duration',
|
|
Datapoints: [],
|
|
},
|
|
],
|
|
[
|
|
{
|
|
ResponseMetadata: { RequestId: '1f50045b-b569-11e6-86c6-eb54d1aaa755-func2' },
|
|
Label: 'Invocations',
|
|
Datapoints: [],
|
|
},
|
|
{
|
|
ResponseMetadata: { RequestId: '1f59059b-b569-11e6-aa18-c7bab68810d2-func2' },
|
|
Label: 'Throttles',
|
|
Datapoints: [],
|
|
},
|
|
{
|
|
ResponseMetadata: { RequestId: '1f50c7b1-b569-11e6-b1b6-ab86694b617b-func2' },
|
|
Label: 'Errors',
|
|
Datapoints: [],
|
|
},
|
|
{
|
|
ResponseMetadata: { RequestId: '1f63db14-b569-11e6-8501-d98a275ce164-func2' },
|
|
Label: 'Duration',
|
|
Datapoints: [],
|
|
},
|
|
],
|
|
];
|
|
|
|
const result = await awsMetrics.getMetrics();
|
|
expect(result).to.deep.equal(expectedResult);
|
|
});
|
|
|
|
it('should gather function metrics if function option is specified', async () => {
|
|
// only display metrics for function1
|
|
awsMetrics.options.function = 'function1';
|
|
|
|
// stubs for function1
|
|
// invocations
|
|
requestStub.onCall(0).resolves({
|
|
ResponseMetadata: { RequestId: '1f50045b-b569-11e6-86c6-eb54d1aaa755-func1' },
|
|
Label: 'Invocations',
|
|
Datapoints: [],
|
|
});
|
|
// throttles
|
|
requestStub.onCall(1).resolves({
|
|
ResponseMetadata: { RequestId: '1f59059b-b569-11e6-aa18-c7bab68810d2-func1' },
|
|
Label: 'Throttles',
|
|
Datapoints: [],
|
|
});
|
|
// errors
|
|
requestStub.onCall(2).resolves({
|
|
ResponseMetadata: { RequestId: '1f50c7b1-b569-11e6-b1b6-ab86694b617b-func1' },
|
|
Label: 'Errors',
|
|
Datapoints: [],
|
|
});
|
|
// duration
|
|
requestStub.onCall(3).resolves({
|
|
ResponseMetadata: { RequestId: '1f63db14-b569-11e6-8501-d98a275ce164-func1' },
|
|
Label: 'Duration',
|
|
Datapoints: [],
|
|
});
|
|
|
|
const expectedResult = [
|
|
[
|
|
{
|
|
ResponseMetadata: { RequestId: '1f50045b-b569-11e6-86c6-eb54d1aaa755-func1' },
|
|
Label: 'Invocations',
|
|
Datapoints: [],
|
|
},
|
|
{
|
|
ResponseMetadata: { RequestId: '1f59059b-b569-11e6-aa18-c7bab68810d2-func1' },
|
|
Label: 'Throttles',
|
|
Datapoints: [],
|
|
},
|
|
{
|
|
ResponseMetadata: { RequestId: '1f50c7b1-b569-11e6-b1b6-ab86694b617b-func1' },
|
|
Label: 'Errors',
|
|
Datapoints: [],
|
|
},
|
|
{
|
|
ResponseMetadata: { RequestId: '1f63db14-b569-11e6-8501-d98a275ce164-func1' },
|
|
Label: 'Duration',
|
|
Datapoints: [],
|
|
},
|
|
],
|
|
];
|
|
|
|
const result = await awsMetrics.getMetrics();
|
|
expect(result).to.deep.equal(expectedResult);
|
|
});
|
|
|
|
it('should gather metrics with 1 hour period for time span < 24 hours', async () => {
|
|
awsMetrics.options.startTime = new Date('1970-01-01T09:00');
|
|
awsMetrics.options.endTime = new Date('1970-01-01T16:00');
|
|
|
|
await awsMetrics.getMetrics();
|
|
|
|
expect(
|
|
requestStub.calledWith(
|
|
sinon.match.string,
|
|
sinon.match.string,
|
|
sinon.match.has('Period', 3600)
|
|
)
|
|
).to.equal(true);
|
|
});
|
|
|
|
it('should gather metrics with 1 day period for time span > 24 hours', async () => {
|
|
awsMetrics.options.startTime = new Date('1970-01-01');
|
|
awsMetrics.options.endTime = new Date('1970-01-03');
|
|
|
|
await awsMetrics.getMetrics();
|
|
|
|
expect(
|
|
requestStub.calledWith(
|
|
sinon.match.string,
|
|
sinon.match.string,
|
|
sinon.match.has('Period', 24 * 3600)
|
|
)
|
|
).to.equal(true);
|
|
});
|
|
});
|
|
});
|