mirror of
https://github.com/serverless/serverless.git
synced 2025-12-08 19:46:03 +00:00
427 lines
13 KiB
JavaScript
427 lines
13 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({ commands: [], options: {} })
|
|
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)
|
|
})
|
|
})
|
|
})
|