Expand description
§Lambda Runtime Simulator
A high-fidelity AWS Lambda Runtime API simulator for testing Lambda runtimes and extensions in a local development environment.
§Overview
This crate provides a simulator that implements the AWS Lambda Runtime API, allowing you to test Lambda runtimes and extensions without deploying to AWS. It’s particularly useful for testing Lambda extensions like OpenTelemetry collectors, custom extensions, and runtime implementations.
§Features
- Runtime API: Full implementation of the Lambda Runtime Interface
- High Fidelity: Accurately simulates Lambda behavior including timeouts
- Test-Friendly: Easy to use in test harnesses with state inspection
- Async: Built on tokio for efficient async execution
§Quick Start
use lambda_simulator::{Simulator, InvocationBuilder};
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a simulator
let simulator = Simulator::builder()
.function_name("my-test-function")
.build()
.await?;
// Get the Runtime API URL
let runtime_api = simulator.runtime_api_url();
println!("Runtime API available at: {}", runtime_api);
// Enqueue an invocation
simulator.enqueue_payload(json!({
"message": "Hello, Lambda!"
})).await;
// Your runtime would connect to runtime_api and process the invocation
// ...
Ok(())
}§Testing Lambda Runtimes
The simulator provides efficient, event-driven wait helpers that eliminate flaky sleep-based synchronisation:
use lambda_simulator::{Simulator, InvocationStatus};
use serde_json::json;
use std::time::Duration;
#[tokio::test]
async fn test_my_runtime() {
let simulator = Simulator::builder()
.function_name("test-function")
.build()
.await
.unwrap();
// Set the runtime API URL for your runtime
std::env::set_var("AWS_LAMBDA_RUNTIME_API", simulator.runtime_api_url());
// Enqueue returns the request ID for tracking
let request_id = simulator.enqueue_payload(json!({"key": "value"})).await;
// Start your runtime in a background task
// tokio::spawn(async { my_runtime::run().await });
// Wait for completion with timeout - no polling loops needed!
let state = simulator
.wait_for_invocation_complete(&request_id, Duration::from_secs(5))
.await
.expect("Invocation should complete");
assert_eq!(state.status, InvocationStatus::Success);
}§Testing with Telemetry Capture
Capture telemetry events in memory without setting up HTTP servers:
use lambda_simulator::Simulator;
use serde_json::json;
#[tokio::test]
async fn test_telemetry_events() {
let simulator = Simulator::builder().build().await.unwrap();
// Enable in-memory capture
simulator.enable_telemetry_capture().await;
// Enqueue and process invocations...
simulator.enqueue_payload(json!({"test": "data"})).await;
// Assert on captured events
let start_events = simulator.get_telemetry_events_by_type("platform.start").await;
assert_eq!(start_events.len(), 1);
}§Predicate-Based Waiting
Wait for arbitrary conditions with wait_for:
use lambda_simulator::Simulator;
use std::time::Duration;
let simulator = Simulator::builder().build().await?;
// Wait for extensions to register
simulator.wait_for(
|| async { simulator.extension_count().await >= 2 },
Duration::from_secs(5)
).await?;§Architecture
The simulator uses an HTTP server built with axum and tokio to implement
the Lambda Runtime API endpoints. Invocations are queued and delivered to
runtimes via long-polling on the /runtime/invocation/next endpoint.
§AWS Lambda Runtime API
The simulator implements these endpoints:
GET /2018-06-01/runtime/invocation/next- Get next invocation (long-poll)POST /2018-06-01/runtime/invocation/{requestId}/response- Submit responsePOST /2018-06-01/runtime/invocation/{requestId}/error- Report errorPOST /2018-06-01/runtime/init/error- Report initialization error
For more details on the Lambda Runtime API, see: https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html
Re-exports§
pub use error::BuilderError;pub use error::RuntimeError;pub use error::SimulatorError;pub use error::SimulatorResult;pub use extension::EventType;pub use extension::ExtensionId;pub use extension::LifecycleEvent;pub use extension::RegisteredExtension;pub use extension::ShutdownReason;pub use freeze::FreezeError;pub use freeze::FreezeMode;pub use freeze::FreezeState;pub use invocation::Invocation;pub use invocation::InvocationBuilder;pub use invocation::InvocationError;pub use invocation::InvocationResponse;pub use invocation::InvocationStatus;pub use simulator::Simulator;pub use simulator::SimulatorBuilder;pub use simulator::SimulatorConfig;pub use simulator::SimulatorPhase;pub use state::InvocationState;pub use telemetry::TelemetryEvent;pub use telemetry::TelemetryEventType;pub use telemetry::TelemetrySubscription;
Modules§
- error
- Error types for the Lambda runtime simulator.
- extension
- Lambda Extensions API types and state management.
- extensions_
api - Lambda Extensions API HTTP endpoints implementation.
- freeze
- Process freezing simulation for Lambda’s freeze/thaw behaviour.
- invocation
- Invocation lifecycle management and data structures.
- process
- Process spawning and lifecycle management for Lambda simulation.
- runtime_
api - Lambda Runtime API HTTP endpoints implementation.
- simulator
- Main simulator orchestration and builder.
- state
- Shared state management for the Lambda runtime simulator.
- telemetry
- Telemetry API types and event schemas.