From d05621c10a5953067da6546ae90cc580f788d91a Mon Sep 17 00:00:00 2001 From: Clay Danford <42356991+claydanford@users.noreply.github.com> Date: Fri, 11 Mar 2022 10:11:13 -0600 Subject: [PATCH] Fix bug and change default behavior (#41) * Format according to prettier * Fix bug where zero forces defaults * Include test * Change scaleInCooldown to zero * Update version and readme. --- README.md | 6 ++++-- __tests__/aws/policy.test.ts | 2 +- __tests__/helpers/config.ts | 7 ++++++- __tests__/helpers/policy.ts | 2 +- __tests__/plugin.test.ts | 22 +++++++++++++++------- package-lock.json | 5 +++-- package.json | 2 +- src/aws/policy.ts | 6 +----- src/aws/target.ts | 15 +++++++++------ src/plugin.ts | 18 ++++++++++++------ 10 files changed, 53 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index abbb9bf..234d1a2 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ functions: maximum: 10 minimum: 1 usage: 0.75 - scaleInCooldown: 120 + scaleInCooldown: 0 scaleOutCooldown: 0 customMetric: statistic: maximum @@ -103,10 +103,12 @@ alias: provisioned maximum: 10 minimum: 1 usage: 0.75 -scaleInCooldown: 120 +scaleInCooldown: 0 scaleOutCooldown: 0 ``` +**Change in Default Behavior:** Starting in v1.7.0, the default scaleInCooldown is zero, not 120. This is backwards compatible, but different default behavior. This is in line with AWS' default scaleInCooldown. + ### Scheduled Actions For more details on Scheduled Actions formats see diff --git a/__tests__/aws/policy.test.ts b/__tests__/aws/policy.test.ts index 4e93114..1cdd594 100644 --- a/__tests__/aws/policy.test.ts +++ b/__tests__/aws/policy.test.ts @@ -13,7 +13,7 @@ describe('Policy', () => { const policy = new Policy(options, { function: 'foo', name: 'foo-svc-dev-foo', - scaleInCooldown: 120, + scaleInCooldown: 0, scaleOutCooldown: 0, usage: 0.75, }) diff --git a/__tests__/helpers/config.ts b/__tests__/helpers/config.ts index 06e267f..a4de13e 100644 --- a/__tests__/helpers/config.ts +++ b/__tests__/helpers/config.ts @@ -11,12 +11,17 @@ export const configPartial: AutoscalingConfig = { usage: 0.92, } +export const configZero: AutoscalingConfig = { + ...configMin, + scaleInCooldown: 0 +} + export const configDefault: AutoscalingConfig = { ...configMin, minimum: 1, maximum: 10, usage: 0.75, - scaleInCooldown: 120, + scaleInCooldown: 0, scaleOutCooldown: 0, alias: 'provisioned', } diff --git a/__tests__/helpers/policy.ts b/__tests__/helpers/policy.ts index e0976aa..b8109c5 100644 --- a/__tests__/helpers/policy.ts +++ b/__tests__/helpers/policy.ts @@ -12,7 +12,7 @@ export const expectedPolicy = { PredefinedMetricSpecification: { PredefinedMetricType: 'LambdaProvisionedConcurrencyUtilization', }, - ScaleInCooldown: 120, + ScaleInCooldown: 0, ScaleOutCooldown: 0, TargetValue: 0.75, }, diff --git a/__tests__/plugin.test.ts b/__tests__/plugin.test.ts index 0386628..b6069d7 100644 --- a/__tests__/plugin.test.ts +++ b/__tests__/plugin.test.ts @@ -6,14 +6,15 @@ import { configPartial, configCustomMetricDefault, configCustomMetricMin, - configScheduledActions + configScheduledActions, + configZero, } from './helpers/config' import { serverless } from './helpers/serverless' import { options } from './helpers/options' import { expectedPolicy } from './helpers/policy' import { expectedTarget, - expectedTargetWithSingleScheduledAction + expectedTargetWithSingleScheduledAction, } from './helpers/target' import { ConcurrencyFunction } from 'src/@types' @@ -37,6 +38,10 @@ describe('Defaults', () => { }) }) + it('should allow zero', () => { + expect(plugin.defaults(configZero).scaleInCooldown).toEqual(0) + }) + it('should set custom metric config defaults', () => { expect(plugin.defaults(configCustomMetricMin)).toEqual( configCustomMetricDefault, @@ -154,20 +159,22 @@ describe('Process', () => { it('Process for cloudformation object', () => { plugin.process([configDefault]) expect( - plugin.serverless.service.provider.compiledCloudFormationTemplate.Resources + plugin.serverless.service.provider.compiledCloudFormationTemplate + .Resources, ).toEqual({ ...expectedPolicy, - ...expectedTarget + ...expectedTarget, }) }) it('Process for CloudFormation with Scheduled Actions', (): void => { plugin.process([configScheduledActions]) expect( - plugin.serverless.service.provider.compiledCloudFormationTemplate.Resources + plugin.serverless.service.provider.compiledCloudFormationTemplate + .Resources, ).toEqual({ ...expectedPolicy, - ...expectedTargetWithSingleScheduledAction + ...expectedTargetWithSingleScheduledAction, }) }) }) @@ -178,7 +185,8 @@ describe('BeforeDeployResources', () => { plugin.beforeDeployResources() expect( - plugin.serverless.service.provider.compiledCloudFormationTemplate.Resources, + plugin.serverless.service.provider.compiledCloudFormationTemplate + .Resources, ).toEqual({ ...expectedPolicy, ...expectedTarget, diff --git a/package-lock.json b/package-lock.json index 4d61545..f50d656 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,12 @@ { "name": "serverless-provisioned-concurrency-autoscaling", - "version": "1.6.0", + "version": "1.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "1.6.0", + "name": "serverless-provisioned-concurrency-autoscaling", + "version": "1.7.0", "license": "Apache-2.0", "devDependencies": { "@types/jest": "^27.4.1", diff --git a/package.json b/package.json index f7ad26f..13d9430 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "serverless-provisioned-concurrency-autoscaling", - "version": "1.6.0", + "version": "1.7.0", "description": "Serverless Plugin for AWS Lambdas Provisioned Concurrency Auto Scaling Configuration.", "main": "./lib/index.js", "files": [ diff --git a/src/aws/policy.ts b/src/aws/policy.ts index 332042e..60e8627 100644 --- a/src/aws/policy.ts +++ b/src/aws/policy.ts @@ -1,9 +1,5 @@ import Name from '../name' -import { - Options, - AutoscalingConfig, - CustomMetricConfig, -} from 'src/@types' +import { Options, AutoscalingConfig, CustomMetricConfig } from 'src/@types' import { ucfirst } from '../utility' export default class Policy { diff --git a/src/aws/target.ts b/src/aws/target.ts index a87d425..46d3591 100644 --- a/src/aws/target.ts +++ b/src/aws/target.ts @@ -16,17 +16,19 @@ export default class Target { } private getSchedulesActions(): unknown[] { - return this.data.scheduledActions?.map(scheduledAction => { return { + return this.data.scheduledActions?.map((scheduledAction) => { + return { EndTime: scheduledAction.endTime, StartTime: scheduledAction.startTime, Timezone: scheduledAction.timezone, ScalableTargetAction: { MaxCapacity: scheduledAction.action.maximum, - MinCapacity: scheduledAction.action.minimum + MinCapacity: scheduledAction.action.minimum, }, ScheduledActionName: scheduledAction.name, // todo: names cannot be duplicated; add validation - Schedule: scheduledAction.schedule - }}) as unknown[] + Schedule: scheduledAction.schedule, + } + }) as unknown[] } toJSON(): Record { @@ -46,11 +48,12 @@ export default class Target { ScalableDimension: 'lambda:function:ProvisionedConcurrency', ServiceNamespace: 'lambda', RoleARN: { - 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/lambda.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_LambdaConcurrency', + 'Fn::Sub': + 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/lambda.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_LambdaConcurrency', }, ScheduledActions: this.data.scheduledActions ? this.getSchedulesActions() - : undefined + : undefined, }, Type: 'AWS::ApplicationAutoScaling::ScalableTarget', }, diff --git a/src/plugin.ts b/src/plugin.ts index e3db5a2..6bce21f 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -82,13 +82,19 @@ export default class Plugin { alias, name: config.name, function: config.function, - usage: config.usage || 0.75, - minimum: config.minimum || 1, - maximum: config.maximum || 10, - scaleInCooldown: config.scaleInCooldown || 120, - scaleOutCooldown: config.scaleOutCooldown || 0, + usage: typeof config.usage !== 'undefined' ? config.usage : 0.75, + minimum: typeof config.minimum !== 'undefined' ? config.minimum : 1, + maximum: typeof config.maximum !== 'undefined' ? config.maximum : 10, + scaleInCooldown: + typeof config.scaleInCooldown !== 'undefined' + ? config.scaleInCooldown + : 0, + scaleOutCooldown: + typeof config.scaleOutCooldown !== 'undefined' + ? config.scaleOutCooldown + : 0, customMetric: config.customMetric ? customMetricConfig : undefined, - scheduledActions: config.scheduledActions + scheduledActions: config.scheduledActions, } }