Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
50 changes: 50 additions & 0 deletions .github/workflows/test-rie.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Test with RIE

on:
pull_request:
branches: [ main ]
push:
branches: [ main ]

jobs:
test-rie:
runs-on: ubuntu-latest
strategy:
matrix:
example: [basic-lambda, basic-sqs]

steps:
- uses: actions/checkout@v4

- name: Build and test ${{ matrix.example }} with RIE
run: |
docker build -f Dockerfile.rie --build-arg EXAMPLE=${{ matrix.example }} -t rust-lambda-rie-test-${{ matrix.example }} .

# Start container in background
docker run -d -p 9000:8080 --name rie-test-${{ matrix.example }} rust-lambda-rie-test-${{ matrix.example }}

# Wait for container to be ready
sleep 5

# Test the function based on example type
if [ "${{ matrix.example }}" = "basic-lambda" ]; then
PAYLOAD='{"command": "test from CI"}'
elif [ "${{ matrix.example }}" = "basic-sqs" ]; then
PAYLOAD='{"Records": [{"body": "{\"id\": \"123\", \"text\": \"hello from SQS\"}", "messageId": "test-id", "receiptHandle": "test-handle", "attributes": {}, "messageAttributes": {}, "md5OfBody": "test-md5", "eventSource": "aws:sqs", "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:test-queue", "awsRegion": "us-east-1"}]}'
fi

# Make request and verify response
RESPONSE=$(curl -s -XPOST 'http://localhost:9000/2015-03-31/functions/function/invocations' \
-d "$PAYLOAD" \
-H 'Content-Type: application/json')

echo "Response: $RESPONSE"

# Basic validation that we got a response (not empty)
if [ -z "$RESPONSE" ]; then
echo "Error: Empty response"
exit 1
fi

# Stop container
docker stop rie-test-${{ matrix.example }}
25 changes: 25 additions & 0 deletions Dockerfile.rie
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM public.ecr.aws/lambda/provided:al2023

RUN dnf install -y gcc
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"

ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/local/bin/aws-lambda-rie
RUN chmod +x /usr/local/bin/aws-lambda-rie

ARG EXAMPLE=basic-lambda
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!


COPY Cargo.toml Cargo.lock /build/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is causing CI failures since we don't currently have Cargo.lock checked in (perhaps we should start, that decision predates me maintaining):


#11 [ 6/15] COPY Cargo.toml Cargo.lock /build/
#11 ERROR: failed to calculate checksum of ref 1acf8ebc-766d-4eb7-bec2-c07f6b4097da::cdqmyuggq2sgi9amxlakl71dj: "/Cargo.lock": not found

https://github.com/awslabs/aws-lambda-rust-runtime/actions/runs/17301603573/job/49114895249?pr=1033

Maybe just do COPY Cargo.* to sidestep this issue and be agnostic about whether Cargo.lock is available?

Certainly you could update CI to use cargo-generate-lockfile but that seems kind of annoying.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! ☑️

COPY lambda-runtime /build/lambda-runtime
COPY lambda-runtime-api-client /build/lambda-runtime-api-client
COPY lambda-events /build/lambda-events
COPY lambda-http /build/lambda-http
COPY lambda-extension /build/lambda-extension
COPY examples/${EXAMPLE} /build/examples/${EXAMPLE}

WORKDIR /build/examples/${EXAMPLE}
RUN cargo build --release
RUN cp target/release/${EXAMPLE} ${LAMBDA_RUNTIME_DIR}/bootstrap

ENTRYPOINT []
CMD [ "/usr/local/bin/aws-lambda-rie", "/var/runtime/bootstrap" ]
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,7 @@ check-event-features:
cargo test --package aws_lambda_events --no-default-features --features streams

fmt:
cargo +nightly fmt --all
cargo +nightly fmt --all

test-rie:
./scripts/test-rie.sh $(EXAMPLE)
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,31 @@ curl -v -X POST \

You can read more about how [cargo lambda watch](https://www.cargo-lambda.info/commands/watch.html) and [cargo lambda invoke](https://www.cargo-lambda.info/commands/invoke.html) work on the project's [documentation page](https://www.cargo-lambda.info).

### Local testing with Runtime Interface Emulator (RIE)

For testing with the official AWS Lambda Runtime Interface Emulator, use the provided RIE testing infrastructure:

```bash
make test-rie
```

By default, this uses the `basic-lambda` example. To test a different example:

```bash
make test-rie EXAMPLE=basic-sqs
make test-rie EXAMPLE=http-basic-lambda
```

This command will:
1. Build a Docker image with Rust toolchain and RIE
2. Compile the specified example inside the Linux container
3. Start the RIE container on port 9000
4. Display the appropriate curl command for testing

Different examples expect different payload formats. Check the example's source code in `examples/EXAMPLE_NAME/src/main.rs`

This provides automated testing with Docker and RIE, ensuring your Lambda functions work in a Linux environment identical to AWS Lambda.

### Lambda Debug Proxy

Lambdas can be run and debugged locally using a special [Lambda debug proxy](https://github.com/rimutaka/lambda-debug-proxy) (a non-AWS repo maintained by @rimutaka), which is a Lambda function that forwards incoming requests to one AWS SQS queue and reads responses from another queue. A local proxy running on your development computer reads the queue, calls your Lambda locally and sends back the response. This approach allows debugging of Lambda functions locally while being part of your AWS workflow. The Lambda handler code does not need to be modified between the local and AWS versions.
Expand Down
22 changes: 22 additions & 0 deletions scripts/test-rie.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash
set -euo pipefail

EXAMPLE=${1:-basic-lambda}

echo "Building Docker image with RIE for example: $EXAMPLE..."
docker build -f Dockerfile.rie --build-arg EXAMPLE=$EXAMPLE -t rust-lambda-rie-test .

echo "Starting RIE container on port 9000..."
docker run -p 9000:8080 rust-lambda-rie-test &
CONTAINER_PID=$!

echo "Container started. Test with:"
if [ "$EXAMPLE" = "basic-lambda" ]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good middle ground for making it turnkey, thanks.

echo "curl -XPOST 'http://localhost:9000/2015-03-31/functions/function/invocations' -d '{\"command\": \"test from RIE\"}' -H 'Content-Type: application/json'"
else
echo "For example '$EXAMPLE', check examples/$EXAMPLE/src/main.rs for the expected payload format."
fi
echo ""
echo "Press Ctrl+C to stop the container."

wait $CONTAINER_PID
Loading