Skip to content

Commit 584579e

Browse files
Simon-Pierre Gingrasrix0rrr
authored andcommitted
fix(lambda): compare Runtimes by value instead of identity (#2543)
Different Runtime objects that represent the same runtime now compare as equal. This is important when using Layers, which declare compatible runtimes.
1 parent 553577a commit 584579e

File tree

6 files changed

+162
-2
lines changed

6 files changed

+162
-2
lines changed

packages/@aws-cdk/aws-lambda/lib/function.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ export class Function extends FunctionBase {
479479
if (this.layers.length === 5) {
480480
throw new Error('Unable to add layer: this lambda function already uses 5 layers.');
481481
}
482-
if (layer.compatibleRuntimes && layer.compatibleRuntimes.indexOf(this.runtime) === -1) {
482+
if (layer.compatibleRuntimes && !layer.compatibleRuntimes.find(runtime => runtime.equals(this.runtime))) {
483483
const runtimes = layer.compatibleRuntimes.map(runtime => runtime.name).join(', ');
484484
throw new Error(`This lambda function uses a runtime that is incompatible with this layer (${this.runtime.name} is not in [${runtimes}])`);
485485
}

packages/@aws-cdk/aws-lambda/lib/runtime.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,10 @@ export class Runtime {
6969
public toString(): string {
7070
return this.name;
7171
}
72+
73+
public equals(other: Runtime): boolean {
74+
return other.name === this.name &&
75+
other.family === this.family &&
76+
other.supportsInlineCode === this.supportsInlineCode;
77+
}
7278
}

packages/@aws-cdk/aws-lambda/package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-lambda/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,16 @@
6666
"@types/aws-lambda": "^8.10.24",
6767
"@types/nock": "^9.3.1",
6868
"@types/sinon": "^7.0.11",
69+
"@types/lodash": "^4.14.128",
6970
"aws-sdk": "^2.438.0",
7071
"aws-sdk-mock": "^4.4.0",
7172
"cdk-build-tools": "^0.31.0",
7273
"cdk-integ-tools": "^0.31.0",
7374
"cfn2ts": "^0.31.0",
7475
"nock": "^10.0.6",
7576
"pkglint": "^0.31.0",
76-
"sinon": "^7.3.1"
77+
"sinon": "^7.3.1",
78+
"lodash": "^4.17.11"
7779
},
7880
"dependencies": {
7981
"@aws-cdk/assets": "^0.31.0",
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import s3 = require('@aws-cdk/aws-s3');
2+
import cdk = require('@aws-cdk/cdk');
3+
import _ = require('lodash');
4+
import {Test, testCase} from 'nodeunit';
5+
import lambda = require('../lib');
6+
7+
export = testCase({
8+
'add incompatible layer'(test: Test) {
9+
// GIVEN
10+
const stack = new cdk.Stack(undefined, 'TestStack');
11+
const bucket = new s3.Bucket(stack, 'Bucket');
12+
const code = new lambda.S3Code(bucket, 'ObjectKey');
13+
14+
const func = new lambda.Function(stack, 'myFunc', {
15+
runtime: lambda.Runtime.Python37,
16+
handler: 'index.handler',
17+
code,
18+
});
19+
const layer = new lambda.LayerVersion(stack, 'myLayer', {
20+
code,
21+
compatibleRuntimes: [lambda.Runtime.NodeJS]
22+
});
23+
24+
// THEN
25+
test.throws(() => func.addLayer(layer),
26+
/This lambda function uses a runtime that is incompatible with this layer/);
27+
28+
test.done();
29+
},
30+
'add compatible layer'(test: Test) {
31+
// GIVEN
32+
const stack = new cdk.Stack(undefined, 'TestStack');
33+
const bucket = new s3.Bucket(stack, 'Bucket');
34+
const code = new lambda.S3Code(bucket, 'ObjectKey');
35+
36+
const func = new lambda.Function(stack, 'myFunc', {
37+
runtime: lambda.Runtime.Python37,
38+
handler: 'index.handler',
39+
code,
40+
});
41+
const layer = new lambda.LayerVersion(stack, 'myLayer', {
42+
code,
43+
compatibleRuntimes: [lambda.Runtime.Python37]
44+
});
45+
46+
// THEN
47+
// should not throw
48+
func.addLayer(layer);
49+
50+
test.done();
51+
},
52+
'add compatible layer for deep clone'(test: Test) {
53+
// GIVEN
54+
const stack = new cdk.Stack(undefined, 'TestStack');
55+
const bucket = new s3.Bucket(stack, 'Bucket');
56+
const code = new lambda.S3Code(bucket, 'ObjectKey');
57+
58+
const runtime = lambda.Runtime.Python37;
59+
const func = new lambda.Function(stack, 'myFunc', {
60+
runtime,
61+
handler: 'index.handler',
62+
code,
63+
});
64+
const clone = _.cloneDeep(runtime);
65+
const layer = new lambda.LayerVersion(stack, 'myLayer', {
66+
code,
67+
compatibleRuntimes: [clone]
68+
});
69+
70+
// THEN
71+
// should not throw
72+
func.addLayer(layer);
73+
74+
test.done();
75+
},
76+
});
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import {Test, testCase} from 'nodeunit';
2+
import {RuntimeFamily} from "../lib";
3+
import lambda = require('../lib');
4+
5+
export = testCase({
6+
'runtimes are equal for different instances'(test: Test) {
7+
// GIVEN
8+
const runtime1 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});
9+
const runtime2 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});
10+
11+
// WHEN
12+
const result = runtime1.equals(runtime2);
13+
14+
// THEN
15+
test.strictEqual(result, true, 'Runtimes should be equal');
16+
17+
test.done();
18+
},
19+
'runtimes are equal for same instance'(test: Test) {
20+
// GIVEN
21+
const runtime = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});
22+
23+
// WHEN
24+
const result = runtime.equals(runtime);
25+
26+
// THEN
27+
test.strictEqual(result, true, 'Runtimes should be equal');
28+
29+
test.done();
30+
},
31+
'unequal when name changes'(test: Test) {
32+
// GIVEN
33+
const runtime1 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});
34+
const runtime2 = new lambda.Runtime('python3.6', RuntimeFamily.Python, {supportsInlineCode: true});
35+
36+
// WHEN
37+
const result = runtime1.equals(runtime2);
38+
39+
// THEN
40+
test.strictEqual(result, false, 'Runtimes should be unequal when name changes');
41+
42+
test.done();
43+
},
44+
'unequal when family changes'(test: Test) {
45+
// GIVEN
46+
const runtime1 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});
47+
const runtime2 = new lambda.Runtime('python3.7', RuntimeFamily.Java, {supportsInlineCode: true});
48+
49+
// WHEN
50+
const result = runtime1.equals(runtime2);
51+
52+
// THEN
53+
test.strictEqual(result, false, 'Runtimes should be unequal when family changes');
54+
55+
test.done();
56+
},
57+
'unequal when supportsInlineCode changes'(test: Test) {
58+
// GIVEN
59+
const runtime1 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: true});
60+
const runtime2 = new lambda.Runtime('python3.7', RuntimeFamily.Python, {supportsInlineCode: false});
61+
62+
// WHEN
63+
const result = runtime1.equals(runtime2);
64+
65+
// THEN
66+
test.strictEqual(result, false, 'Runtimes should be unequal when supportsInlineCode changes');
67+
68+
test.done();
69+
},
70+
});

0 commit comments

Comments
 (0)