ITADN

Feature: In-process Lambda execution mode for use_docker: False

#9916OpenHen00af 创建于 2026-03-27
H
Hen00afcommented
## Problem Currently, moto offers two Lambda execution modes: 1. **Docker mode** (`use_docker: True`, default): Runs Lambda code inside a Docker container. Full fidelity, but requires Docker runtime. 2. **Simple mode** (`use_docker: False`): No Docker needed, but doesn't execute handler code at all — returns a canned response (`"Simple Lambda happy path OK"` or a queued result). There is no middle ground. This creates a gap for a common use case: **Testing event source mapping chains (e.g., S3 → SQS → Lambda) in CI environments without Docker.** With the current simple mode, the Event Source Mapping trigger fires correctly (`_send_sqs_message` calls `invoke`), but the Lambda handler never actually runs. This means you can't verify that your handler processes the SQS event correctly without Docker. ## Use case ```python @mock_aws(config={"lambda": {"use_docker": False}}) def test_s3_triggers_lambda_via_sqs(): # Setup S3 bucket with event notification → SQS # Setup SQS queue with event source mapping → Lambda # Lambda handler posts to an external webhook s3.put_object(Bucket="my-bucket", Key="test.txt", Body=b"data") # With current simple mode: Lambda "runs" but handler code never executes # With in-process mode: handler code runs in the same process, # so unittest.mock.patch works for external HTTP calls ``` The key advantage of in-process execution is that `unittest.mock.patch` works because everything runs in the same Python process. This makes it straightforward to mock external dependencies (HTTP calls, etc.) that the Lambda handler uses. ## Proposal Add an in-process execution option when `use_docker: False`. When a Lambda function is created with a Python runtime and a ZipFile deployment, moto could: 1. Extract the zip to a temp directory 2. Import the handler module 3. Call the handler function directly with the event and a mock context A rough sketch: ```python # In LambdaSimpleBackend or a new LambdaInlineBackend def invoke(self, function_name, qualifier, body, headers, response_headers): func = self._lambdas.get_function_by_name_or_arn_with_qualifier(function_name, qualifier) if func.code and func.run_time.startswith("python"): module_name, handler_name = func.handler.rsplit(".", 1) # Extract zip, importlib the module, call handler_name(event, context) ... else: # Fall back to current simple behavior for non-Python / non-zip return super().invoke(...) ``` This would be opt-in (e.g., `{"lambda": {"use_docker": False, "execute_inline": True}}`) so it doesn't change existing behavior. ## Scope / Limitations - Python runtimes only (at least initially) - ZipFile deployments only (not S3 or ECR image) - No sandboxing — the handler runs in the test process with full access - No Lambda runtime API emulation — just direct function call ## Related - #9852 — `use_docker: False` not working in server mode (different issue, same pain point)
0 条评论