Skip to content

Commit 0dab9b3

Browse files
committed
test both lambda layer and npm package in ESM and CJS
1 parent ec8c39e commit 0dab9b3

File tree

7 files changed

+139
-47
lines changed

7 files changed

+139
-47
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports.handler = async (event, context) => {
2+
return {
3+
statusCode: 200,
4+
body: JSON.stringify({
5+
event,
6+
context,
7+
}),
8+
};
9+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import * as Sentry from '@sentry/aws-serverless';
2+
3+
export const handler = Sentry.wrapHandler(async (event, context) => {
4+
return {
5+
statusCode: 200,
6+
body: JSON.stringify({
7+
event,
8+
}),
9+
};
10+
});

dev-packages/e2e-tests/test-applications/aws-lambda-sam/package.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,15 @@
66
"scripts": {
77
"test": "playwright test",
88
"clean": "npx rimraf node_modules pnpm-lock.yaml",
9-
"test:build": "pnpm install && npx rimraf node_modules/@sentry/aws-serverless-layer/nodejs",
9+
"test:build": "pnpm install && npx rimraf node_modules/@sentry/aws-serverless/nodejs",
1010
"test:assert": "pnpm test"
1111
},
12-
"dependencies": {
13-
"@sentry/aws-serverless": "* || latest"
14-
},
15-
"//": "@sentry/aws-serverless-layer is not a package, but we use it to copy the layer zip file to the test app",
12+
"//": "We just need the AWS layer zip file, not the NPM package",
1613
"devDependencies": {
14+
"@sentry/aws-serverless": "link:../../../../packages/aws-serverless/build/aws/dist-serverless/",
1715
"@aws-sdk/client-lambda": "^3.863.0",
1816
"@playwright/test": "~1.53.2",
1917
"@sentry-internal/test-utils": "link:../../../test-utils",
20-
"@sentry/aws-serverless-layer": "link:../../../../packages/aws-serverless/build/aws/dist-serverless/",
2118
"aws-cdk-lib": "^2.210.0",
2219
"constructs": "^10.4.2",
2320
"glob": "^11.0.3"

dev-packages/e2e-tests/test-applications/aws-lambda-sam/stack.ts

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import * as os from 'node:os';
66
import * as dns from 'node:dns/promises';
77
import { platform } from 'node:process';
88
import { globSync } from 'glob';
9+
import { execSync } from 'node:child_process';
910

10-
const LAMBDA_FUNCTION_DIR = './lambda-functions';
11+
const LAMBDA_FUNCTIONS_WITH_LAYER_DIR = './lambda-functions-layer';
12+
const LAMBDA_FUNCTIONS_WITH_NPM_DIR = './lambda-functions-npm';
1113
const LAMBDA_FUNCTION_TIMEOUT = 10;
12-
const LAYER_DIR = './node_modules/@sentry/aws-serverless-layer/';
14+
const LAYER_DIR = './node_modules/@sentry/aws-serverless/';
1315
export const SAM_PORT = 3001;
1416
const NODE_RUNTIME = `nodejs${process.version.split('.').at(0)?.replace('v', '')}.x`;
1517

@@ -42,27 +44,45 @@ export class LocalLambdaStack extends Stack {
4244
const dsn = `http://public@${hostIp}:3031/1337`;
4345
console.log(`[LocalLambdaStack] Using Sentry DSN: ${dsn}`);
4446

45-
console.log('[LocalLambdaStack] Add all Lambda function defined in ./lambda-functions/ to the SAM stack');
47+
this.addLambdaFunctions({ functionsDir: LAMBDA_FUNCTIONS_WITH_LAYER_DIR, dsn, addLayer: true });
48+
this.addLambdaFunctions({ functionsDir: LAMBDA_FUNCTIONS_WITH_NPM_DIR, dsn, addLayer: false });
49+
}
50+
51+
private addLambdaFunctions({
52+
functionsDir,
53+
dsn,
54+
addLayer,
55+
}: {
56+
functionsDir: string;
57+
dsn: string;
58+
addLayer: boolean;
59+
}) {
60+
console.log(`[LocalLambdaStack] Add all Lambda functions defined in ${functionsDir} to the SAM stack`);
4661

4762
const lambdaDirs = fs
48-
.readdirSync(LAMBDA_FUNCTION_DIR)
49-
.filter(dir => fs.statSync(path.join(LAMBDA_FUNCTION_DIR, dir)).isDirectory());
63+
.readdirSync(functionsDir)
64+
.filter(dir => fs.statSync(path.join(functionsDir, dir)).isDirectory());
5065

5166
for (const lambdaDir of lambdaDirs) {
52-
const isEsm = fs.existsSync(path.join(LAMBDA_FUNCTION_DIR, lambdaDir, 'index.mjs'));
67+
const functionName = `${lambdaDir}${addLayer ? 'Layer' : 'Npm'}`;
68+
69+
if (!addLayer) {
70+
console.log(`[LocalLambdaStack] Install dependencies for ${functionName}`);
71+
const packageJson = { dependencies: { '@sentry/aws-serverless': '* || latest' } };
72+
fs.writeFileSync(path.join(functionsDir, lambdaDir, 'package.json'), JSON.stringify(packageJson, null, 2));
73+
execSync(`npm install --prefix ${path.join(functionsDir, lambdaDir)}`);
74+
}
75+
76+
const isEsm = fs.existsSync(path.join(functionsDir, lambdaDir, 'index.mjs'));
5377

54-
new CfnResource(this, lambdaDir, {
78+
new CfnResource(this, functionName, {
5579
type: 'AWS::Serverless::Function',
5680
properties: {
57-
CodeUri: path.join(LAMBDA_FUNCTION_DIR, lambdaDir),
81+
CodeUri: path.join(functionsDir, lambdaDir),
5882
Handler: 'index.handler',
5983
Runtime: NODE_RUNTIME,
6084
Timeout: LAMBDA_FUNCTION_TIMEOUT,
61-
Layers: [
62-
{
63-
Ref: this.sentryLayer.logicalId,
64-
},
65-
],
85+
Layers: addLayer ? [{ Ref: this.sentryLayer.logicalId }] : undefined,
6686
Environment: {
6787
Variables: {
6888
SENTRY_DSN: dsn,
@@ -74,7 +94,7 @@ export class LocalLambdaStack extends Stack {
7494
},
7595
});
7696

77-
console.log(`[LocalLambdaStack] Added Lambda function: ${lambdaDir}`);
97+
console.log(`[LocalLambdaStack] Added Lambda function: ${functionName}`);
7898
}
7999
}
80100

dev-packages/e2e-tests/test-applications/aws-lambda-sam/tests/lambda.test.ts

Lines changed: 83 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { test as base } from '@playwright/test';
1+
import { test as base, expect } from '@playwright/test';
22
import { waitForTransaction } from '@sentry-internal/test-utils';
33
import { App } from 'aws-cdk-lib';
44
import { LocalLambdaStack, SAM_PORT, getHostIp } from '../stack.js';
@@ -83,38 +83,94 @@ const test = base.extend<{ testEnvironment: LocalLambdaStack; lambdaClient: Lamb
8383
},
8484
});
8585

86-
test('basic no exception', async ({ lambdaClient }) => {
87-
const transactionEventPromise = waitForTransaction('aws-serverless-lambda-sam', transactionEvent => {
88-
return transactionEvent?.transaction === 'basic';
89-
});
90-
91-
await lambdaClient.send(
92-
new InvokeCommand({
93-
FunctionName: 'basic',
94-
Payload: JSON.stringify({}),
95-
}),
96-
);
86+
test.describe('Lambda layer', () => {
87+
test('CJS', async ({ lambdaClient }) => {
88+
const transactionEventPromise = waitForTransaction('aws-serverless-lambda-sam', transactionEvent => {
89+
return transactionEvent?.transaction === 'CjsLayer';
90+
});
9791

98-
const transactionEvent = await transactionEventPromise;
92+
await lambdaClient.send(
93+
new InvokeCommand({
94+
FunctionName: 'CjsLayer',
95+
Payload: JSON.stringify({}),
96+
}),
97+
);
98+
99+
const transactionEvent = await transactionEventPromise;
100+
101+
expect(transactionEvent.type).toEqual('transaction');
102+
expect(transactionEvent.transaction).toEqual('CjsLayer');
103+
expect(transactionEvent.sdk?.name).toEqual('sentry.javascript.aws-serverless');
104+
expect(transactionEvent.contexts?.trace?.origin).toEqual('auto.otel.aws-lambda');
105+
expect(transactionEvent.contexts?.trace?.op).toEqual('function.aws.lambda');
106+
expect(transactionEvent.spans).toHaveLength(0);
107+
});
99108

100-
console.log('Transaction event received');
109+
test('ESM', async ({ lambdaClient }) => {
110+
const transactionEventPromise = waitForTransaction('aws-serverless-lambda-sam', transactionEvent => {
111+
return transactionEvent?.transaction === 'EsmLayer';
112+
});
101113

102-
console.log(transactionEvent);
114+
await lambdaClient.send(
115+
new InvokeCommand({
116+
FunctionName: 'EsmLayer',
117+
Payload: JSON.stringify({}),
118+
}),
119+
);
120+
121+
const transactionEvent = await transactionEventPromise;
122+
123+
expect(transactionEvent.type).toEqual('transaction');
124+
expect(transactionEvent.transaction).toEqual('EsmLayer');
125+
expect(transactionEvent.sdk?.name).toEqual('sentry.javascript.aws-serverless');
126+
expect(transactionEvent.contexts?.trace?.origin).toEqual('auto.otel.aws-lambda');
127+
expect(transactionEvent.contexts?.trace?.op).toEqual('function.aws.lambda');
128+
expect(transactionEvent.spans).toHaveLength(0);
129+
});
103130
});
104131

105-
test('esm', async ({ lambdaClient }) => {
106-
const transactionEventPromise = waitForTransaction('aws-serverless-lambda-sam', transactionEvent => {
107-
return transactionEvent?.transaction === 'esm';
108-
});
132+
test.describe('NPM package', () => {
133+
test('CJS', async ({ lambdaClient }) => {
134+
const transactionEventPromise = waitForTransaction('aws-serverless-lambda-sam', transactionEvent => {
135+
return transactionEvent?.transaction === 'CjsNpm';
136+
});
109137

110-
await lambdaClient.send(
111-
new InvokeCommand({
112-
FunctionName: 'esm',
113-
Payload: JSON.stringify({}),
114-
}),
115-
);
138+
await lambdaClient.send(
139+
new InvokeCommand({
140+
FunctionName: 'CjsNpm',
141+
Payload: JSON.stringify({}),
142+
}),
143+
);
144+
145+
const transactionEvent = await transactionEventPromise;
146+
147+
expect(transactionEvent.type).toEqual('transaction');
148+
expect(transactionEvent.transaction).toEqual('CjsNpm');
149+
expect(transactionEvent.sdk?.name).toEqual('sentry.javascript.aws-serverless');
150+
expect(transactionEvent.contexts?.trace?.origin).toEqual('auto.otel.aws-lambda');
151+
expect(transactionEvent.contexts?.trace?.op).toEqual('function.aws.lambda');
152+
expect(transactionEvent.spans).toHaveLength(0);
153+
});
116154

117-
const transactionEvent = await transactionEventPromise;
155+
test('ESM', async ({ lambdaClient }) => {
156+
const transactionEventPromise = waitForTransaction('aws-serverless-lambda-sam', transactionEvent => {
157+
return transactionEvent?.transaction === 'EsmNpm';
158+
});
118159

119-
console.log(transactionEvent);
160+
await lambdaClient.send(
161+
new InvokeCommand({
162+
FunctionName: 'EsmNpm',
163+
Payload: JSON.stringify({}),
164+
}),
165+
);
166+
167+
const transactionEvent = await transactionEventPromise;
168+
169+
expect(transactionEvent.type).toEqual('transaction');
170+
expect(transactionEvent.transaction).toEqual('EsmNpm');
171+
expect(transactionEvent.sdk?.name).toEqual('sentry.javascript.aws-serverless');
172+
expect(transactionEvent.contexts?.trace?.origin).toEqual('auto.otel.aws-lambda');
173+
expect(transactionEvent.contexts?.trace?.op).toEqual('function.aws.lambda');
174+
expect(transactionEvent.spans).toHaveLength(0);
175+
});
120176
});

0 commit comments

Comments
 (0)