Skip to content

Commit 376c47a

Browse files
committed
add e2e test
1 parent c2b0d12 commit 376c47a

File tree

9 files changed

+147
-0
lines changed

9 files changed

+147
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@sentry:registry=http://127.0.0.1:4873
2+
@sentry-internal:registry=http://127.0.0.1:4873
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "aws-serverless-streaming",
3+
"version": "1.0.0",
4+
"private": true,
5+
"scripts": {
6+
"start": "node src/run.mjs",
7+
"test": "playwright test",
8+
"clean": "npx rimraf node_modules pnpm-lock.yaml",
9+
"test:build": "pnpm install",
10+
"test:assert": "pnpm test"
11+
},
12+
"dependencies": {
13+
"@sentry/aws-serverless": "* || latest"
14+
},
15+
"devDependencies": {
16+
"@sentry-internal/test-utils": "link:../../../test-utils",
17+
"@playwright/test": "~1.53.2"
18+
},
19+
"volta": {
20+
"extends": "../../package.json"
21+
},
22+
"pnpm": {
23+
"overrides": {
24+
"@opentelemetry/instrumentation-aws-lambda": "file:/Users/martin/code/opentelemetry-js-contrib/packages/instrumentation-aws-lambda"
25+
}
26+
}
27+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { getPlaywrightConfig } from '@sentry-internal/test-utils';
2+
3+
export default getPlaywrightConfig();
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as Sentry from '@sentry/aws-serverless';
2+
3+
let handler = async (event, responseStream, context) => {
4+
Sentry.startSpan({ name: 'streaming-span', op: 'stream' }, () => {
5+
responseStream.write('Starting stream\n');
6+
});
7+
8+
responseStream.write('Continuing stream\n');
9+
responseStream.write('Stream completed\n');
10+
responseStream.end();
11+
};
12+
13+
handler[Symbol.for('aws.lambda.runtime.handler.streaming')] = 'response';
14+
handler = Sentry.wrapHandler(handler);
15+
16+
export { handler };
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"//": "This is a mock package.json file which is usually created by AWS when deploying the lambda. OTEL instrumentation tries to read this file to get the lambda version",
3+
"name": "lambda",
4+
"version": "1.0.0"
5+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { handler } from './lambda-function.mjs';
2+
import { Writable } from 'node:stream';
3+
4+
const event = {};
5+
6+
const context = {
7+
invokedFunctionArn: 'arn:aws:lambda:us-east-1:123453789012:function:my-streaming-lambda',
8+
functionName: 'my-streaming-lambda',
9+
};
10+
11+
const responseStream = new Writable({
12+
write: (chunk, encoding, callback) => {
13+
console.log('Streamed chunk:', chunk.toString());
14+
callback();
15+
},
16+
});
17+
18+
await handler(event, responseStream, context);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import child_process from 'child_process';
2+
3+
child_process.execSync('node ./src/run-lambda.mjs', {
4+
stdio: 'inherit',
5+
env: {
6+
...process.env,
7+
// On AWS, LAMBDA_TASK_ROOT is usually /var/task but for testing, we set it to the CWD to correctly apply our handler
8+
LAMBDA_TASK_ROOT: process.cwd(),
9+
_HANDLER: 'src/lambda-function.handler',
10+
11+
NODE_OPTIONS: '--import @sentry/aws-serverless/awslambda-auto',
12+
SENTRY_DSN: 'http://public@localhost:3031/1337',
13+
SENTRY_TRACES_SAMPLE_RATE: '1.0',
14+
},
15+
cwd: process.cwd(),
16+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { startEventProxyServer } from '@sentry-internal/test-utils';
2+
3+
startEventProxyServer({
4+
port: 3031,
5+
proxyServerName: 'aws-serverless-streaming',
6+
});
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import * as child_process from 'child_process';
2+
import { expect, test } from '@playwright/test';
3+
import { waitForTransaction } from '@sentry-internal/test-utils';
4+
5+
test('AWS Serverless SDK sends events from streaming handler', async ({ request }) => {
6+
const transactionEventPromise = waitForTransaction('aws-serverless-streaming', transactionEvent => {
7+
return transactionEvent?.transaction === 'my-streaming-lambda';
8+
});
9+
10+
// Waiting for 1s here because attaching the listener for events in `waitForTransaction` is not synchronous
11+
// Since in this test, we don't start a browser via playwright, we don't have the usual delays (page.goto, etc)
12+
// which are usually enough for us to never have noticed this race condition before.
13+
// This is a workaround but probably sufficient as long as we only experience it in this test.
14+
await new Promise<void>(resolve =>
15+
setTimeout(() => {
16+
resolve();
17+
}, 1000),
18+
);
19+
20+
child_process.execSync('pnpm start', {
21+
stdio: 'inherit',
22+
});
23+
24+
const transactionEvent = await transactionEventPromise;
25+
26+
expect(transactionEvent.transaction).toEqual('my-streaming-lambda');
27+
expect(transactionEvent.contexts?.trace).toEqual({
28+
data: {
29+
'sentry.sample_rate': 1,
30+
'sentry.source': 'custom',
31+
'sentry.origin': 'auto.otel.aws-lambda',
32+
'sentry.op': 'function.aws.lambda',
33+
'cloud.account.id': '123453789012',
34+
'faas.id': 'arn:aws:lambda:us-east-1:123453789012:function:my-streaming-lambda',
35+
'faas.coldstart': true,
36+
'otel.kind': 'SERVER',
37+
},
38+
op: 'function.aws.lambda',
39+
origin: 'auto.otel.aws-lambda',
40+
span_id: expect.stringMatching(/[a-f0-9]{16}/),
41+
status: 'ok',
42+
trace_id: expect.stringMatching(/[a-f0-9]{32}/),
43+
});
44+
45+
expect(transactionEvent.spans).toHaveLength(1);
46+
47+
const streamingSpan = transactionEvent.spans?.[0];
48+
expect(streamingSpan).toMatchObject({
49+
description: 'streaming-span',
50+
op: 'stream',
51+
status: 'ok',
52+
origin: 'manual',
53+
});
54+
});

0 commit comments

Comments
 (0)