Skip to content

Commit 45e0613

Browse files
committed
test(integration): cover dist/handler.handler under AWS-stock RIC
Add container-image integration tests that exercise the npm-redirect path through the AWS-published `public.ecr.aws/lambda/nodejs:N` base image, with both CJS and ESM user handlers. Closes the gap from the existing `esm_node*` tests, which only cover the layer path (`/opt/nodejs/node_modules/datadog-lambda-js/handler.handler`) where only `handler.mjs` has ever been shipped. These tests would fail under any future regression that re-introduces a CJS-shadowing artifact at `dist/handler.js`, including the original #305 scenario for stock AWS RIC. - integration_tests/container/{cjs,esm}/ — Dockerfiles + handlers - serverless.yml — provider.ecr.images + container-{cjs,esm}_node funcs - run_integration_tests.sh — pack local datadog-lambda-js before deploy, thread NODE_MAJOR for ECR build args, add handlers to snapshot loop
1 parent 1d86f65 commit 45e0613

9 files changed

Lines changed: 94 additions & 5 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ package-lock.json
1414
/.idea/
1515

1616
.gitlab/build-*.yaml
17+
18+
# Local datadog-lambda-js tarballs produced for container integration tests
19+
integration_tests/container/*/datadog-lambda-js-local.tgz
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
ARG NODE_VERSION=22
2+
FROM public.ecr.aws/lambda/nodejs:${NODE_VERSION}
3+
4+
COPY package.json handler.js ${LAMBDA_TASK_ROOT}/
5+
COPY datadog-lambda-js-local.tgz /tmp/datadog-lambda-js-local.tgz
6+
RUN cd ${LAMBDA_TASK_ROOT} && npm install /tmp/datadog-lambda-js-local.tgz \
7+
&& rm /tmp/datadog-lambda-js-local.tgz
8+
9+
CMD ["node_modules/datadog-lambda-js/dist/handler.handler"]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
exports.handle = (event) => {
2+
return { message: "hello, dog!" };
3+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "container-cjs-test",
3+
"version": "1.0.0",
4+
"private": true
5+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
ARG NODE_VERSION=22
2+
FROM public.ecr.aws/lambda/nodejs:${NODE_VERSION}
3+
4+
COPY package.json handler.mjs ${LAMBDA_TASK_ROOT}/
5+
COPY datadog-lambda-js-local.tgz /tmp/datadog-lambda-js-local.tgz
6+
RUN cd ${LAMBDA_TASK_ROOT} && npm install /tmp/datadog-lambda-js-local.tgz \
7+
&& rm /tmp/datadog-lambda-js-local.tgz
8+
9+
CMD ["node_modules/datadog-lambda-js/dist/handler.handler"]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { promisify } from "util";
2+
3+
// Verify top-level await works in the container-image ESM path
4+
await promisify(setTimeout)(50);
5+
6+
export function handle(event) {
7+
return { message: "hello, dog!" };
8+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "container-esm-test",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module"
6+
}

integration_tests/serverless.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@ provider:
1515
iam:
1616
# IAM permissions require that all functions are deployed with this role
1717
role: "arn:aws:iam::425362996713:role/serverless-integration-test-lambda-role"
18+
# Container image builds for the npm-redirect tests. Each Node major is built
19+
# from public.ecr.aws/lambda/nodejs:${NODE_MAJOR} so the AWS-stock RIC for
20+
# that runtime is exercised against `dist/handler.handler`.
21+
ecr:
22+
images:
23+
datadog-lambda-js-cjs:
24+
path: ./container/cjs
25+
platform: linux/amd64
26+
buildArgs:
27+
NODE_VERSION: ${env:NODE_MAJOR}
28+
datadog-lambda-js-esm:
29+
path: ./container/esm
30+
platform: linux/amd64
31+
buildArgs:
32+
NODE_VERSION: ${env:NODE_MAJOR}
1833

1934
layers:
2035
node:
@@ -81,6 +96,27 @@ functions:
8196
environment:
8297
DD_FLUSH_TO_LOG: true
8398

99+
# container-cjs — npm-installed datadog-lambda-js, CJS user handler,
100+
# invoked through AWS-stock RIC via `dist/handler.handler`.
101+
container-cjs_node:
102+
name: integration-tests-js-${sls:stage}-container-cjs_${env:RUNTIME}
103+
image:
104+
name: datadog-lambda-js-cjs
105+
environment:
106+
DD_FLUSH_TO_LOG: true
107+
DD_LAMBDA_HANDLER: handler.handle
108+
109+
# container-esm — npm-installed datadog-lambda-js, ESM user handler,
110+
# invoked through AWS-stock RIC via `dist/handler.handler`. Guards against
111+
# ERR_REQUIRE_ESM if `dist/handler.js` ever returns to the published tarball.
112+
container-esm_node:
113+
name: integration-tests-js-${sls:stage}-container-esm_${env:RUNTIME}
114+
image:
115+
name: datadog-lambda-js-esm
116+
environment:
117+
DD_FLUSH_TO_LOG: true
118+
DD_LAMBDA_HANDLER: handler.handle
119+
84120
# status-code-500s
85121
status-code-500s_node:
86122
name: integration-tests-js-${sls:stage}-status-code-500s_${env:RUNTIME}

scripts/run_integration_tests.sh

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ set -e
1010

1111
# These values need to be in sync with serverless.yml, where there needs to be a function
1212
# defined for every handler_runtime combination
13-
LAMBDA_HANDLERS=("async-metrics" "esm" "sync-metrics" "http-requests" "process-input-traced" "throw-error-traced" "status-code-500s")
13+
LAMBDA_HANDLERS=("async-metrics" "esm" "sync-metrics" "http-requests" "process-input-traced" "throw-error-traced" "status-code-500s" "container-cjs" "container-esm")
1414

1515
LOGS_WAIT_SECONDS=20
1616

@@ -70,6 +70,16 @@ else
7070
echo "Not building layers, ensure they've already been built or re-run with 'BUILD_LAYERS=true DD_API_KEY=XXXX ./scripts/run_integration_tests.sh'"
7171
fi
7272

73+
# Build and pack the locally-modified datadog-lambda-js so the container-image
74+
# tests install the version under test (not the published one) via npm.
75+
echo "Packing local datadog-lambda-js for container tests"
76+
cd $repo_dir
77+
yarn build
78+
npm pack
79+
mv datadog-lambda-js-*.tgz $integration_tests_dir/container/cjs/datadog-lambda-js-local.tgz
80+
cp $integration_tests_dir/container/cjs/datadog-lambda-js-local.tgz \
81+
$integration_tests_dir/container/esm/datadog-lambda-js-local.tgz
82+
7383
cd $integration_tests_dir
7484
yarn
7585

@@ -86,7 +96,7 @@ function remove_stack() {
8696
nodejs_version=$parameters_set[1]
8797
run_id=$parameters_set[2]
8898
echo "Removing stack for stage : ${!run_id}"
89-
NODE_VERSION=${!nodejs_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \
99+
NODE_VERSION=${!nodejs_version} NODE_MAJOR=${parameters_set#node} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \
90100
serverless remove --stage ${!run_id}
91101
done
92102
}
@@ -102,7 +112,7 @@ for parameters_set in "${PARAMETERS_SETS[@]}"; do
102112
echo "Deploying functions for runtime : $parameters_set, serverless runtime : ${!serverless_runtime}, \
103113
nodejs version : ${!nodejs_version} and run id : ${!run_id}"
104114

105-
NODE_VERSION=${!nodejs_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \
115+
NODE_VERSION=${!nodejs_version} NODE_MAJOR=${parameters_set#node} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \
106116
serverless deploy --stage ${!run_id}
107117

108118
echo "Invoking functions for runtime $parameters_set"
@@ -119,7 +129,7 @@ nodejs version : ${!nodejs_version} and run id : ${!run_id}"
119129
snapshot_path="./snapshots/return_values/${handler_name}_${parameters_set}_${input_event_name}.json"
120130
function_failed=FALSE
121131

122-
return_value=$(NODE_VERSION=${!nodejs_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \
132+
return_value=$(NODE_VERSION=${!nodejs_version} NODE_MAJOR=${parameters_set#node} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \
123133
serverless invoke --stage ${!run_id} -f "$function_name" --path "./input_events/$input_event_file")
124134
invoke_success=$?
125135
if [ $invoke_success -ne 0 ]; then
@@ -166,7 +176,7 @@ for handler_name in "${LAMBDA_HANDLERS[@]}"; do
166176
# Fetch logs with serverless cli, retrying to avoid AWS account-wide rate limit error
167177
retry_counter=0
168178
while [ $retry_counter -lt 10 ]; do
169-
raw_logs=$(NODE_VERSION=${!nodejs_version} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \
179+
raw_logs=$(NODE_VERSION=${!nodejs_version} NODE_MAJOR=${parameters_set#node} RUNTIME=$parameters_set SERVERLESS_RUNTIME=${!serverless_runtime} \
170180
serverless logs --stage ${!run_id} -f $function_name --startTime $script_utc_start_time)
171181
fetch_logs_exit_code=$?
172182
if [ $fetch_logs_exit_code -eq 1 ]; then

0 commit comments

Comments
 (0)