Skip to content

Commit 25a2eac

Browse files
authored
Merge changes for v1.17 release
Merge changes for v1.17 release
2 parents c6779f7 + 42aee21 commit 25a2eac

File tree

5 files changed

+87
-128
lines changed

5 files changed

+87
-128
lines changed

.github/workflows/integ-tests.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Run Integration Tests
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- develop
7+
8+
jobs:
9+
integ-tests:
10+
runs-on: ubuntu-latest
11+
environment:
12+
name: prod
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: actions/setup-python@v5
16+
with:
17+
python-version: '3.11'
18+
- name: allows us to build arm64 images
19+
run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
20+
- name: run integration tests
21+
run: make integ-tests-with-docker

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ compile-lambda-linux-all:
2121
make ARCH=old compile-lambda-linux
2222

2323
compile-with-docker:
24-
docker run --env GOPROXY=direct -v $(shell pwd):/LambdaRuntimeLocal -w /LambdaRuntimeLocal golang:1.20 make ARCH=${ARCH} compile-lambda-linux
24+
docker run --env GOPROXY=direct -v $(shell pwd):/LambdaRuntimeLocal -w /LambdaRuntimeLocal golang:1.21 make ARCH=${ARCH} compile-lambda-linux
2525

2626
compile-lambda-linux:
2727
CGO_ENABLED=0 GOOS=linux GOARCH=${GO_ARCH_${ARCH}} go build -buildvcs=false -ldflags "${RELEASE_BUILD_LINKER_FLAGS}" -o ${DESTINATION_${ARCH}} ./cmd/aws-lambda-rie

go.mod

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
module go.amzn.com
22

3-
go 1.20
3+
go 1.21
44

55
require (
6-
github.com/aws/aws-lambda-go v1.41.0
7-
github.com/go-chi/chi v4.1.2+incompatible
8-
github.com/google/uuid v1.3.0
6+
github.com/aws/aws-lambda-go v1.46.0
7+
github.com/go-chi/chi v1.5.5
8+
github.com/google/uuid v1.6.0
99
github.com/jessevdk/go-flags v1.5.0
1010
github.com/sirupsen/logrus v1.9.3
11-
github.com/stretchr/testify v1.8.4
12-
golang.org/x/sync v0.2.0
11+
github.com/stretchr/testify v1.9.0
12+
golang.org/x/sync v0.6.0
1313
)
1414

1515
require (
1616
github.com/davecgh/go-spew v1.1.1 // indirect
1717
github.com/pmezard/go-difflib v1.0.0 // indirect
18-
github.com/stretchr/objx v0.5.0 // indirect
19-
golang.org/x/net v0.18.0 // indirect
18+
github.com/stretchr/objx v0.5.2 // indirect
2019
golang.org/x/sys v0.14.0 // indirect
2120
gopkg.in/yaml.v3 v3.0.1 // indirect
2221
)

go.sum

+12-18
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,30 @@
1-
github.com/aws/aws-lambda-go v1.41.0 h1:l/5fyVb6Ud9uYd411xdHZzSf2n86TakxzpvIoz7l+3Y=
2-
github.com/aws/aws-lambda-go v1.41.0/go.mod h1:jwFe2KmMsHmffA1X2R09hH6lFzJQxzI8qK17ewzbQMM=
1+
github.com/aws/aws-lambda-go v1.46.0 h1:UWVnvh2h2gecOlFhHQfIPQcD8pL/f7pVCutmFl+oXU8=
2+
github.com/aws/aws-lambda-go v1.46.0/go.mod h1:dpMpZgvWx5vuQJfBt0zqBha60q7Dd7RfgJv23DymV8A=
33
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
44
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
55
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6-
github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec=
7-
github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
8-
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
9-
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
6+
github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE=
7+
github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
8+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
9+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
1010
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
1111
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
1212
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1313
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1414
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
1515
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
1616
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
17-
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
18-
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
19-
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
17+
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
18+
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
2019
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
21-
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
22-
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
23-
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
24-
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
25-
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
26-
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
27-
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
28-
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
20+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
21+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
22+
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
23+
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
2924
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3025
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
3126
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
3227
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
33-
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
3428
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
3529
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
3630
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

test/integration/local_lambda/test_end_to_end.py

+46-101
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,34 @@ def tagged_name(self, name, architecture):
7272

7373
def get_tag(self, architecture):
7474
return "" if architecture == "" else str(f"-{architecture}")
75+
76+
def run_command(self, cmd):
77+
Popen(cmd.split(" ")).communicate()
78+
79+
def sleep_1s(self):
80+
time.sleep(SLEEP_TIME)
81+
82+
def invoke_function(self, port):
83+
return requests.post(
84+
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
85+
)
86+
87+
def create_container_and_invoke_function(self, cmd, port):
88+
self.run_command(cmd)
89+
90+
# sleep 1s to give enough time for the endpoint to be up to curl
91+
self.sleep_1s()
92+
93+
return self.invoke_function(port)
7594

7695
@parameterized.expand([("x86_64", "8000"), ("arm64", "9000"), ("", "9050")])
7796
def test_env_var_with_equal_sign(self, arch, port):
7897
image, rie, image_name = self.tagged_name("envvarcheck", arch)
7998

8099
cmd = f"docker run --name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.check_env_var_handler"
81-
Popen(cmd.split(" ")).communicate()
82-
83-
# sleep 1s to give enough time for the endpoint to be up to curl
84-
time.sleep(SLEEP_TIME)
85-
86-
r = requests.post(
87-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
88-
)
100+
101+
r = self.create_container_and_invoke_function(cmd, port)
102+
89103
self.assertEqual(b'"4=4"', r.content)
90104

91105
@parameterized.expand([("x86_64", "8001"), ("arm64", "9001"), ("", "9051")])
@@ -94,20 +108,13 @@ def test_two_invokes(self, arch, port):
94108

95109
cmd = f"docker run --name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.success_handler"
96110

97-
Popen(cmd.split(" ")).communicate()
98-
99-
# sleep 1s to give enough time for the endpoint to be up to curl
100-
time.sleep(SLEEP_TIME)
101-
102-
r = requests.post(
103-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
104-
)
111+
r = self.create_container_and_invoke_function(cmd, port)
112+
105113
self.assertEqual(b'"My lambda ran succesfully"', r.content)
106114

107115
# Make sure we can invoke the function twice
108-
r = requests.post(
109-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
110-
)
116+
r = self.invoke_function(port)
117+
111118
self.assertEqual(b'"My lambda ran succesfully"', r.content)
112119

113120
@parameterized.expand([("x86_64", "8002"), ("arm64", "9002"), ("", "9052")])
@@ -116,29 +123,18 @@ def test_lambda_function_arn_exists(self, arch, port):
116123

117124
cmd = f"docker run --name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.assert_lambda_arn_in_context"
118125

119-
Popen(cmd.split(" ")).communicate()
120-
121-
# sleep 1s to give enough time for the endpoint to be up to curl
122-
time.sleep(SLEEP_TIME)
123-
124-
r = requests.post(
125-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
126-
)
126+
r = self.create_container_and_invoke_function(cmd, port)
127+
127128
self.assertEqual(b'"My lambda ran succesfully"', r.content)
128129

129130
@parameterized.expand([("x86_64", "8003"), ("arm64", "9003"), ("", "9053")])
130131
def test_lambda_function_arn_exists_with_defining_custom_name(self, arch, port):
131132
image, rie, image_name = self.tagged_name("customname", arch)
132133

133134
cmd = f"docker run --name {image} --env AWS_LAMBDA_FUNCTION_NAME=MyCoolName -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.assert_lambda_arn_in_context"
134-
Popen(cmd.split(" ")).communicate()
135-
136-
# sleep 1s to give enough time for the endpoint to be up to curl
137-
time.sleep(SLEEP_TIME)
138-
139-
r = requests.post(
140-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
141-
)
135+
136+
r = self.create_container_and_invoke_function(cmd, port)
137+
142138
self.assertEqual(b'"My lambda ran succesfully"', r.content)
143139

144140
@parameterized.expand([("x86_64", "8004"), ("arm64", "9004"), ("", "9054")])
@@ -147,14 +143,8 @@ def test_timeout_invoke(self, arch, port):
147143

148144
cmd = f"docker run --name {image} -d --env AWS_LAMBDA_FUNCTION_TIMEOUT=1 -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.sleep_handler"
149145

150-
Popen(cmd.split(" ")).communicate()
151-
152-
# sleep 1s to give enough time for the endpoint to be up to curl
153-
time.sleep(SLEEP_TIME)
154-
155-
r = requests.post(
156-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
157-
)
146+
r = self.create_container_and_invoke_function(cmd, port)
147+
158148
self.assertEqual(b"Task timed out after 1.00 seconds", r.content)
159149

160150
@parameterized.expand([("x86_64", "8005"), ("arm64", "9005"), ("", "9055")])
@@ -163,14 +153,8 @@ def test_exception_returned(self, arch, port):
163153

164154
cmd = f"docker run --name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.exception_handler"
165155

166-
Popen(cmd.split(" ")).communicate()
167-
168-
# sleep 1s to give enough time for the endpoint to be up to curl
169-
time.sleep(SLEEP_TIME)
170-
171-
r = requests.post(
172-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
173-
)
156+
r = self.create_container_and_invoke_function(cmd, port)
157+
174158
self.assertEqual(
175159
b'{"errorMessage": "Raising an exception", "errorType": "Exception", "stackTrace": [" File \\"/var/task/main.py\\", line 13, in exception_handler\\n raise Exception(\\"Raising an exception\\")\\n"]}',
176160
r.content,
@@ -182,15 +166,8 @@ def test_context_get_remaining_time_in_three_seconds(self, arch, port):
182166

183167
cmd = f"docker run --name {image} -d --env AWS_LAMBDA_FUNCTION_TIMEOUT=3 -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.check_remaining_time_handler"
184168

185-
Popen(cmd.split(' ')).communicate()
186-
187-
# sleep 1s to give enough time for the endpoint to be up to curl
188-
time.sleep(SLEEP_TIME)
189-
190-
r = requests.post(
191-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
192-
)
193-
169+
r = self.create_container_and_invoke_function(cmd, port)
170+
194171
# Execution time is not decided, 1.0s ~ 3.0s is a good estimation
195172
self.assertLess(int(r.content), 3000)
196173
self.assertGreater(int(r.content), 1000)
@@ -201,15 +178,8 @@ def test_context_get_remaining_time_in_ten_seconds(self, arch, port):
201178

202179
cmd = f"docker run --name {image} -d --env AWS_LAMBDA_FUNCTION_TIMEOUT=10 -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.check_remaining_time_handler"
203180

204-
Popen(cmd.split(' ')).communicate()
205-
206-
# sleep 1s to give enough time for the endpoint to be up to curl
207-
time.sleep(SLEEP_TIME)
208-
209-
r = requests.post(
210-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
211-
)
212-
181+
r = self.create_container_and_invoke_function(cmd, port)
182+
213183
# Execution time is not decided, 8.0s ~ 10.0s is a good estimation
214184
self.assertLess(int(r.content), 10000)
215185
self.assertGreater(int(r.content), 8000)
@@ -220,14 +190,7 @@ def test_context_get_remaining_time_in_default_deadline(self, arch, port):
220190

221191
cmd = f"docker run --name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.check_remaining_time_handler"
222192

223-
Popen(cmd.split(' ')).communicate()
224-
225-
# sleep 1s to give enough time for the endpoint to be up to curl
226-
time.sleep(SLEEP_TIME)
227-
228-
r = requests.post(
229-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
230-
)
193+
r = self.create_container_and_invoke_function(cmd, port)
231194

232195
# Executation time is not decided, 298.0s ~ 300.0s is a good estimation
233196
self.assertLess(int(r.content), 300000)
@@ -239,14 +202,8 @@ def test_invoke_with_pre_runtime_api_runtime(self, arch, port):
239202

240203
cmd = f"docker run --name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.success_handler"
241204

242-
Popen(cmd.split(" ")).communicate()
243-
244-
# sleep 1s to give enough time for the endpoint to be up to curl
245-
time.sleep(SLEEP_TIME)
246-
247-
r = requests.post(
248-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
249-
)
205+
r = self.create_container_and_invoke_function(cmd, port)
206+
250207
self.assertEqual(b'"My lambda ran succesfully"', r.content)
251208

252209
@parameterized.expand([("x86_64", "8010"), ("arm64", "9010"), ("", "9060")])
@@ -255,14 +212,8 @@ def test_function_name_is_overriden(self, arch, port):
255212

256213
cmd = f"docker run --name {image} -d --env AWS_LAMBDA_FUNCTION_NAME=MyCoolName -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.assert_env_var_is_overwritten"
257214

258-
Popen(cmd.split(" ")).communicate()
259-
260-
# sleep 1s to give enough time for the endpoint to be up to curl
261-
time.sleep(SLEEP_TIME)
262-
263-
r = requests.post(
264-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
265-
)
215+
r = self.create_container_and_invoke_function(cmd, port)
216+
266217
self.assertEqual(b'"My lambda ran succesfully"', r.content)
267218

268219
@parameterized.expand([("x86_64", "8011"), ("arm64", "9011"), ("", "9061")])
@@ -272,14 +223,8 @@ def test_port_override(self, arch, port):
272223
# Use port 8081 inside the container instead of 8080
273224
cmd = f"docker run --name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {port}:8081 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.success_handler --runtime-interface-emulator-address 0.0.0.0:8081"
274225

275-
Popen(cmd.split(" ")).communicate()
276-
277-
# sleep 1s to give enough time for the endpoint to be up to curl
278-
time.sleep(SLEEP_TIME)
279-
280-
r = requests.post(
281-
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
282-
)
226+
r = self.create_container_and_invoke_function(cmd, port)
227+
283228
self.assertEqual(b'"My lambda ran succesfully"', r.content)
284229

285230

0 commit comments

Comments
 (0)