Skip to content

Commit 751f1fe

Browse files
committed
First running dummy function
1 parent 48d6368 commit 751f1fe

File tree

4 files changed

+136
-0
lines changed

4 files changed

+136
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ relay
2828
pip-wheel-metadata
2929
.mypy_cache
3030
.vscode/
31+
32+
# for running AWS Lambda tests using AWS SAM
33+
sam.template.yaml

requirements-testing.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ socksio
1414
httpcore[http2]
1515
setuptools
1616
Brotli
17+
18+
aws-sam-cli
19+
aws-cdk-lib
20+
requests
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def handler(event, context):
2+
return {"message": f"Hello, {event['name']}!"}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import boto3
2+
import json
3+
import pytest
4+
import requests
5+
import subprocess
6+
import time
7+
import yaml
8+
from aws_cdk import (
9+
App,
10+
CfnResource,
11+
Stack,
12+
)
13+
from constructs import Construct
14+
15+
16+
SAM_PORT = 3001
17+
SAM_REGION = "us-east-1"
18+
SAM_TEMPLATE_FILE = "sam.template.yaml"
19+
20+
21+
class DummyLambdaStack(Stack):
22+
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
23+
super().__init__(scope, construct_id, **kwargs)
24+
25+
# Override the template synthesis
26+
self.template_options.template_format_version = "2010-09-09"
27+
self.template_options.transforms = ["AWS::Serverless-2016-10-31"]
28+
29+
# Add the function using SAM format
30+
CfnResource(
31+
self,
32+
"BasicTestFunction",
33+
type="AWS::Serverless::Function",
34+
properties={
35+
"CodeUri": "./tests/integrations/aws_lambda/lambda_functions/hello_world",
36+
"Handler": "index.handler",
37+
"Runtime": "python3.12",
38+
},
39+
)
40+
41+
42+
def wait_for_sam(timeout=30, port=SAM_PORT):
43+
"""
44+
Wait for SAM to be ready, with timeout.
45+
"""
46+
start_time = time.time()
47+
while True:
48+
if time.time() - start_time > timeout:
49+
raise TimeoutError("SAM failed to start within {} seconds".format(timeout))
50+
51+
try:
52+
# Try to connect to SAM
53+
response = requests.get(f"http://127.0.0.1:{port}/")
54+
if response.status_code == 200 or response.status_code == 404:
55+
return
56+
57+
except requests.exceptions.ConnectionError:
58+
time.sleep(1)
59+
continue
60+
61+
62+
@pytest.fixture(scope="session")
63+
def sam_stack():
64+
"""
65+
Create and deploy the SAM stack once for all tests
66+
"""
67+
app = App()
68+
stack = DummyLambdaStack(app, "DummyLambdaStack", env={"region": SAM_REGION})
69+
70+
# Write template to file
71+
template = app.synth().get_stack_by_name("DummyLambdaStack").template
72+
with open(SAM_TEMPLATE_FILE, "w") as f:
73+
yaml.dump(template, f)
74+
75+
# Start SAM local
76+
process = subprocess.Popen(
77+
[
78+
"sam",
79+
"local",
80+
"start-lambda",
81+
"--region",
82+
SAM_REGION,
83+
"--template",
84+
SAM_TEMPLATE_FILE,
85+
],
86+
stdout=subprocess.PIPE,
87+
stderr=subprocess.PIPE,
88+
text=True, # This makes stdout/stderr return strings instead of bytes
89+
)
90+
91+
try:
92+
# Wait for SAM to be ready
93+
wait_for_sam()
94+
yield stack
95+
finally:
96+
process.terminate()
97+
process.wait(timeout=5) # Give it time to shut down gracefully
98+
99+
# Force kill if still running
100+
if process.poll() is None:
101+
process.kill()
102+
103+
104+
@pytest.fixture
105+
def lambda_client():
106+
"""
107+
Create a boto3 client configured to use SAM local
108+
"""
109+
return boto3.client(
110+
"lambda",
111+
endpoint_url=f"http://127.0.0.1:{SAM_PORT}",
112+
region_name=SAM_REGION,
113+
aws_access_key_id="dummy",
114+
aws_secret_access_key="dummy",
115+
)
116+
117+
118+
def test_basic(lambda_client, sam_stack):
119+
region = boto3.Session().region_name
120+
print("Region: ", region)
121+
122+
response = lambda_client.invoke(
123+
FunctionName="BasicTestFunction", Payload=json.dumps({"name": "Anton"})
124+
)
125+
result = json.loads(response["Payload"].read().decode())
126+
127+
assert result == {"message": "Hello, Anton!"}

0 commit comments

Comments
 (0)