2024-05-29 11:51:04 -04:00

241 lines
7.9 KiB
JavaScript

'use strict'
const path = require('path')
const chai = require('chai')
const runServerless = require('../../../../../../utils/run-serverless')
chai.use(require('chai-as-promised'))
const expect = chai.expect
const awsRequestStubMap = {
CloudFormation: {
describeStacks: {
Stacks: [
{
Outputs: [
{ OutputKey: 'LayerLambdaLayerHash', OutputValue: '1qaz' },
{
OutputKey: 'LayerLambdaLayerS3Key',
OutputValue: 'a/b/c/foo.zip',
},
],
},
],
},
},
}
describe('lib/plugins/aws/package/compile/layers/index.test.js', () => {
const allowedAccount = 'arn:aws:iam::123456789012:root'
let cfResources
let naming
let updateConfig
let serviceDir
let service
let cfOutputs
before(async () => {
const { awsNaming, cfTemplate, fixtureData, serverless } =
await runServerless({
fixture: 'layer',
command: 'package',
configExt: {
package: {
individually: true,
},
layers: {
layerOne: {
path: 'layer',
allowedAccounts: ['*'],
},
layerTwo: {
description: 'Layer two example',
path: 'layer',
compatibleRuntimes: ['nodejs16.x'],
compatibleArchitectures: ['arm64'],
licenseInfo: 'GPL',
allowedAccounts: ['123456789012', '123456789013'],
},
layerRetain: {
path: 'layer',
retain: true,
allowedAccounts: [allowedAccount],
},
},
},
awsRequestStubMap,
})
cfResources = cfTemplate.Resources
cfOutputs = cfTemplate.Outputs
naming = awsNaming
service = serverless.service
;({ updateConfig, servicePath: serviceDir } = fixtureData)
})
it('should support `layers[].package.artifact` with `package.individually`', () => {
const resourceName = 'layer'
const layerResource =
cfResources[naming.getLambdaLayerLogicalId(resourceName)]
const s3Folder = service.package.artifactDirectoryName
const s3FileName = service.layers[resourceName].package.artifact
.split(path.sep)
.pop()
expect(layerResource.Properties.Content.S3Key).to.equal(
`${s3Folder}/${s3FileName}`,
)
})
it('should generate expected layer version resource', () => {
const resourceName = 'layer'
const layerResource =
cfResources[naming.getLambdaLayerLogicalId(resourceName)]
const s3Folder = service.package.artifactDirectoryName
const s3FileName = service.layers[resourceName].package.artifact
.split(path.sep)
.pop()
expect(layerResource.Type).to.equals('AWS::Lambda::LayerVersion')
expect(layerResource.Properties.Content.S3Key).to.equal(
`${s3Folder}/${s3FileName}`,
)
expect(layerResource.Properties.LayerName).to.equal('layer')
expect(layerResource.Properties.Content.S3Bucket.Ref).to.equal(
'ServerlessDeploymentBucket',
)
expect(cfOutputs.LayerLambdaLayerQualifiedArn.Description).to.equals(
'Current Lambda layer version',
)
expect(cfOutputs.LayerLambdaLayerQualifiedArn.Value.Ref).to.equals(
'LayerLambdaLayer',
)
})
describe('`layers[].retain` property', () => {
it('should ensure expected deletion policy for layer resource', () => {
const layerResourceNamePrefix =
naming.getLambdaLayerLogicalId('layerRetain')
const layerResourceName = Object.keys(cfResources).find((resourceName) =>
resourceName.startsWith(layerResourceNamePrefix),
)
expect(layerResourceName).to.not.equal(layerResourceNamePrefix)
const layerResource = cfResources[layerResourceName]
expect(layerResource.DeletionPolicy).to.equal('Retain')
})
it('should ensure expected deletion policy for layer permission resource', () => {
const layerPermissionResourceNamePrefix =
naming.getLambdaLayerPermissionLogicalId('layerRetain', allowedAccount)
const layerPermissionResourceName = Object.keys(cfResources).find(
(resourceName) =>
resourceName.startsWith(layerPermissionResourceNamePrefix),
)
expect(layerPermissionResourceName).to.not.equal(
layerPermissionResourceNamePrefix,
)
const layerPermissionResource = cfResources[layerPermissionResourceName]
expect(layerPermissionResource.DeletionPolicy).to.equal('Retain')
})
it('should ensure unique resource id per layer version', async () => {
const layerResourceNamePrefix =
naming.getLambdaLayerLogicalId('layerRetain')
const firstLayerResourceName = Object.keys(cfResources).find(
(resourceName) => resourceName.startsWith(layerResourceNamePrefix),
)
await updateConfig({ layers: { layerRetain: { description: 'foo' } } })
const {
cfTemplate: { Resources: secondCfResources },
} = await runServerless({
cwd: serviceDir,
command: 'package',
awsRequestStubMap,
})
expect(secondCfResources).to.not.have.property(firstLayerResourceName)
await updateConfig({ layers: { layerRetain: { description: null } } })
const {
cfTemplate: { Resources: firstCfResources },
} = await runServerless({
cwd: serviceDir,
command: 'package',
awsRequestStubMap,
})
expect(firstCfResources).to.have.property(firstLayerResourceName)
})
})
it('should generate expected permissions resource', () => {
const layerNamePermission = naming.getLambdaLayerPermissionLogicalId(
'LayerOne',
'Wild',
)
const layerPermission = cfResources[layerNamePermission]
expect(layerPermission.Type).to.equals(
'AWS::Lambda::LayerVersionPermission',
)
expect(layerPermission.Properties.Action).to.equals(
'lambda:GetLayerVersion',
)
expect(layerPermission.Properties.LayerVersionArn.Ref).to.equals(
'LayerOneLambdaLayer',
)
expect(layerPermission.Properties.Principal).to.equals('*')
})
it('should support `layers[].allowedAccounts`', () => {
const layerNamePermissionFirstUser =
naming.getLambdaLayerPermissionLogicalId('layerTwo', '123456789012')
const layerPermissionFirstUser = cfResources[layerNamePermissionFirstUser]
expect(layerPermissionFirstUser.Properties.Principal).to.equals(
'123456789012',
)
const layerNamePermissionUserSecond =
naming.getLambdaLayerPermissionLogicalId('layerTwo', '123456789013')
const layerPermissionSecondUser = cfResources[layerNamePermissionUserSecond]
expect(layerPermissionSecondUser.Properties.Principal).to.equals(
'123456789013',
)
})
it('should support `layers[].description`', () => {
const layerResourceName = naming.getLambdaLayerLogicalId('LayerTwo')
const layerOne = cfResources[layerResourceName]
expect(layerOne.Type).to.equals('AWS::Lambda::LayerVersion')
expect(layerOne.Properties.Description).to.equals('Layer two example')
})
it('should support `layers[].compatibleRuntimes`', () => {
const layerResourceName = naming.getLambdaLayerLogicalId('LayerTwo')
const layerOne = cfResources[layerResourceName]
expect(layerOne.Type).to.equals('AWS::Lambda::LayerVersion')
expect(layerOne.Properties.CompatibleRuntimes).to.deep.equals([
'nodejs16.x',
])
})
it('should support `layers[].compatibleArchitectures`', () => {
const layerResourceName = naming.getLambdaLayerLogicalId('LayerTwo')
const layerOne = cfResources[layerResourceName]
expect(layerOne.Properties.CompatibleArchitectures).to.deep.equals([
'arm64',
])
})
it('should support `layers[].licenseInfo`', () => {
const layerResourceName = naming.getLambdaLayerLogicalId('LayerTwo')
const layerOne = cfResources[layerResourceName]
expect(layerOne.Type).to.equals('AWS::Lambda::LayerVersion')
expect(layerOne.Properties.LicenseInfo).to.deep.equals('GPL')
})
})