Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(lambda) support adding deep clones of layers to a Function #2543

Merged
merged 2 commits into from
May 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-lambda/lib/function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ export class Function extends FunctionBase {
if (this.layers.length === 5) {
throw new Error('Unable to add layer: this lambda function already uses 5 layers.');
}
if (layer.compatibleRuntimes && layer.compatibleRuntimes.indexOf(this.runtime) === -1) {
if (layer.compatibleRuntimes && !layer.compatibleRuntimes.find(runtime => runtime.equals(this.runtime))) {
const runtimes = layer.compatibleRuntimes.map(runtime => runtime.name).join(', ');
throw new Error(`This lambda function uses a runtime that is incompatible with this layer (${this.runtime.name} is not in [${runtimes}])`);
}
Expand Down
6 changes: 6 additions & 0 deletions packages/@aws-cdk/aws-lambda/lib/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,10 @@ export class Runtime {
public toString(): string {
return this.name;
}

public equals(other: Runtime): boolean {
return other.name === this.name &&
other.family === this.family &&
other.supportsInlineCode === this.supportsInlineCode;
}
}
6 changes: 6 additions & 0 deletions packages/@aws-cdk/aws-lambda/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-lambda/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,16 @@
"@types/aws-lambda": "^8.10.24",
"@types/nock": "^9.3.1",
"@types/sinon": "^7.0.11",
"@types/lodash": "^4.14.128",
"aws-sdk": "^2.438.0",
"aws-sdk-mock": "^4.4.0",
"cdk-build-tools": "^0.31.0",
"cdk-integ-tools": "^0.31.0",
"cfn2ts": "^0.31.0",
"nock": "^10.0.6",
"pkglint": "^0.31.0",
"sinon": "^7.3.1"
"sinon": "^7.3.1",
"lodash": "^4.17.11"
},
"dependencies": {
"@aws-cdk/assets": "^0.31.0",
Expand Down
76 changes: 76 additions & 0 deletions packages/@aws-cdk/aws-lambda/test/test.function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import s3 = require('@aws-cdk/aws-s3');
import cdk = require('@aws-cdk/cdk');
import _ = require('lodash');
import {Test, testCase} from 'nodeunit';
import lambda = require('../lib');

export = testCase({
'add incompatible layer'(test: Test) {
// GIVEN
const stack = new cdk.Stack(undefined, 'TestStack');
const bucket = new s3.Bucket(stack, 'Bucket');
const code = new lambda.S3Code(bucket, 'ObjectKey');

const func = new lambda.Function(stack, 'myFunc', {
runtime: lambda.Runtime.Python37,
handler: 'index.handler',
code,
});
const layer = new lambda.LayerVersion(stack, 'myLayer', {
code,
compatibleRuntimes: [lambda.Runtime.NodeJS]
});

// THEN
test.throws(() => func.addLayer(layer),
/This lambda function uses a runtime that is incompatible with this layer/);

test.done();
},
'add compatible layer'(test: Test) {
// GIVEN
const stack = new cdk.Stack(undefined, 'TestStack');
const bucket = new s3.Bucket(stack, 'Bucket');
const code = new lambda.S3Code(bucket, 'ObjectKey');

const func = new lambda.Function(stack, 'myFunc', {
runtime: lambda.Runtime.Python37,
handler: 'index.handler',
code,
});
const layer = new lambda.LayerVersion(stack, 'myLayer', {
code,
compatibleRuntimes: [lambda.Runtime.Python37]
});

// THEN
// should not throw
func.addLayer(layer);

test.done();
},
'add compatible layer for deep clone'(test: Test) {
// GIVEN
const stack = new cdk.Stack(undefined, 'TestStack');
const bucket = new s3.Bucket(stack, 'Bucket');
const code = new lambda.S3Code(bucket, 'ObjectKey');

const runtime = lambda.Runtime.Python37;
const func = new lambda.Function(stack, 'myFunc', {
runtime,
handler: 'index.handler',
code,
});
const clone = _.cloneDeep(runtime);
const layer = new lambda.LayerVersion(stack, 'myLayer', {
code,
compatibleRuntimes: [clone]
});

// THEN
// should not throw
func.addLayer(layer);

test.done();
},
});
70 changes: 70 additions & 0 deletions packages/@aws-cdk/aws-lambda/test/test.runtime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {Test, testCase} from 'nodeunit';
import {RuntimeFamily} from "../lib";
import lambda = require('../lib');

export = testCase({
'runtimes are equal for different instances'(test: Test) {
// GIVEN
const runtime1 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});
const runtime2 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});

// WHEN
const result = runtime1.equals(runtime2);

// THEN
test.strictEqual(result, true, 'Runtimes should be equal');

test.done();
},
'runtimes are equal for same instance'(test: Test) {
// GIVEN
const runtime = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});

// WHEN
const result = runtime.equals(runtime);

// THEN
test.strictEqual(result, true, 'Runtimes should be equal');

test.done();
},
'unequal when name changes'(test: Test) {
// GIVEN
const runtime1 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});
const runtime2 = new lambda.Runtime('python3.6', RuntimeFamily.Python, {supportsInlineCode: true});

// WHEN
const result = runtime1.equals(runtime2);

// THEN
test.strictEqual(result, false, 'Runtimes should be unequal when name changes');

test.done();
},
'unequal when family changes'(test: Test) {
// GIVEN
const runtime1 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});
const runtime2 = new lambda.Runtime('python3.7', RuntimeFamily.Java, {supportsInlineCode: true});

// WHEN
const result = runtime1.equals(runtime2);

// THEN
test.strictEqual(result, false, 'Runtimes should be unequal when family changes');

test.done();
},
'unequal when supportsInlineCode changes'(test: Test) {
// GIVEN
const runtime1 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});
const runtime2 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: false});

// WHEN
const result = runtime1.equals(runtime2);

// THEN
test.strictEqual(result, false, 'Runtimes should be unequal when supportsInlineCode changes');

test.done();
},
});