Skip to content

Commit 93094cf

Browse files
committed
Add response streaming support and standardize tests
1 parent f9d20eb commit 93094cf

File tree

13 files changed

+545
-215
lines changed

13 files changed

+545
-215
lines changed

AGENTS.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ The runtime is packaged as a Lambda Layer and is intended to be consumed directl
2929
- scripts/
3030
- build_layer.sh
3131
- package_layer.sh
32-
- smoke_test.sh
32+
- test-smoke.sh
33+
- test-unit.sh
34+
- test-int.sh
3335
- docker/Dockerfile
3436
- examples/
3537
- function.sh

DEVELOPMENT.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Template generation overrides:
4444
## Smoke test
4545

4646
```sh
47-
./scripts/smoke_test.sh
47+
./scripts/test-smoke.sh
4848
```
4949

5050
The smoke test:
@@ -56,13 +56,13 @@ The smoke test:
5656
Run ShellSpec suites via `make`:
5757

5858
```sh
59-
make test-smokespec
60-
make test-errorspec
61-
make test-integration
59+
make test-smoke
60+
make test-unit
61+
make test-int
6262
make test
6363
```
6464

65-
`make test` runs the smoke and runtime error specs together.
65+
`make test` runs the smoke, unit, and integration specs together.
6666

6767
## Shellcheck
6868

Makefile

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: build build-layer build-arm64 build-amd64 build-all package-layer package-arm64 package-amd64 package-all smoke-test test test-shellspec test-integration test-all check-release delete-release delete-sar delete-dev-arm64 delete-dev-amd64 delete-dev delete-release-arm64 delete-release-amd64 publish-sar publish-arm64 publish-amd64 publish-wrapper publish-all publish-dev-arm64 publish-dev-amd64 deploy-sar deploy-dev-arm64 deploy-dev-amd64 deploy-dev release aws-check aws-setup aws-setup-dev clean
1+
.PHONY: build build-layer build-arm64 build-amd64 build-all package-layer package-arm64 package-amd64 package-all test test-smoke test-unit test-int test-shellspec test-all check-release delete-release delete-sar delete-dev-arm64 delete-dev-amd64 delete-dev delete-release-arm64 delete-release-amd64 publish-sar publish-arm64 publish-amd64 publish-wrapper publish-all publish-dev-arm64 publish-dev-amd64 deploy-sar deploy-dev-arm64 deploy-dev-amd64 deploy-dev release aws-check aws-setup aws-setup-dev clean
22

33
ENV ?= prod
44
ARCH ?=
@@ -33,16 +33,16 @@ package-amd64: build-amd64
3333
package-all: build-all
3434
ARCH=all ./scripts/package_layer.sh
3535

36-
test: test-smokespec test-errorspec test-integration
36+
test: test-smoke test-unit test-int
3737

38-
test-smokespec:
39-
$(SHELLSPEC) $(SHELLSPEC_ARGS) spec/smoke_spec.sh
38+
test-smoke:
39+
$(SHELLSPEC) $(SHELLSPEC_ARGS) spec/test-smoke_spec.sh
4040

41-
test-errorspec:
42-
$(SHELLSPEC) $(SHELLSPEC_ARGS) spec/runtime_error_spec.sh
41+
test-unit:
42+
$(SHELLSPEC) $(SHELLSPEC_ARGS) spec/test-unit_spec.sh
4343

44-
test-integration:
45-
$(SHELLSPEC) $(SHELLSPEC_ARGS) spec/integration_spec.sh
44+
test-int:
45+
$(SHELLSPEC) $(SHELLSPEC_ARGS) spec/test-int_spec.sh
4646

4747
check-release:
4848
./scripts/check_release.sh

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ at the packaged zips.
4949
## Smoke test
5050

5151
```sh
52-
./scripts/smoke_test.sh
52+
./scripts/test-smoke.sh
5353
```
5454

5555
## Usage

runtime/bootstrap

Lines changed: 115 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,26 @@ post_runtime_response() {
123123
esac
124124
}
125125

126+
post_streaming_response() {
127+
url=$1
128+
payload=$2
129+
http_code=$(curl -sS -o /dev/null -w '%{http_code}' -X POST \
130+
-H "Lambda-Runtime-Function-Response-Mode: streaming" \
131+
-H "Trailer: Lambda-Runtime-Function-Error-Type, Lambda-Runtime-Function-Error-Body" \
132+
--data-binary @- "$url" < "$payload")
133+
curl_status=$?
134+
if [ "$curl_status" -ne 0 ]; then
135+
http_code=000
136+
fi
137+
case "$http_code" in
138+
2??) return 0 ;;
139+
*)
140+
log "Failed to post runtime streaming response to $url (HTTP $http_code)"
141+
return 1
142+
;;
143+
esac
144+
}
145+
126146
post_init_error() {
127147
message=$1
128148
error_type=$2
@@ -171,6 +191,55 @@ post_response() {
171191
"$response_file"
172192
}
173193

194+
stream_response() {
195+
request_id=$1
196+
stderr_file=$2
197+
shift 2
198+
199+
response_pipe=$(make_temp_file) || {
200+
log "Failed to create response pipe"
201+
return 1
202+
}
203+
rm -f "$response_pipe"
204+
if ! mkfifo "$response_pipe"; then
205+
log "Failed to create response pipe"
206+
return 1
207+
fi
208+
209+
post_streaming_response \
210+
"http://${runtime_api}/2018-06-01/runtime/invocation/${request_id}/response" \
211+
"$response_pipe" &
212+
post_pid=$!
213+
214+
if run_with_stderr_capture "$stderr_file" "$@" > "$response_pipe"; then
215+
handler_exit=0
216+
else
217+
handler_exit=$?
218+
fi
219+
220+
if wait "$post_pid"; then
221+
post_status=0
222+
else
223+
post_status=$?
224+
fi
225+
226+
rm -f "$response_pipe"
227+
228+
if [ "$handler_exit" -eq 0 ]; then
229+
if [ "$post_status" -eq 0 ]; then
230+
return 0
231+
fi
232+
return 1
233+
fi
234+
235+
log "Handler exited with status ${handler_exit}"
236+
set_error_from_stderr "$stderr_file" "$handler_exit"
237+
if ! post_invoke_error "$request_id" "$error_message" "$error_type" "$stack_trace"; then
238+
return 1
239+
fi
240+
return 0
241+
}
242+
174243
# Capture handler stderr while streaming it to the runtime logs.
175244
run_with_stderr_capture() {
176245
stderr_file=$1
@@ -331,6 +400,7 @@ while :; do
331400
trace_id=$(header_value "$headers" "Lambda-Runtime-Trace-Id")
332401
client_context=$(header_value "$headers" "Lambda-Runtime-Client-Context")
333402
cognito_identity=$(header_value "$headers" "Lambda-Runtime-Cognito-Identity")
403+
response_mode=$(header_value "$headers" "Lambda-Runtime-Function-Response-Mode")
334404

335405
set_invocation_env "LAMBDA_RUNTIME_AWS_REQUEST_ID" "$request_id"
336406
set_invocation_env "LAMBDA_RUNTIME_DEADLINE_MS" "$deadline_ms"
@@ -344,48 +414,69 @@ while :; do
344414
stderr_file=$(mktemp)
345415
if [ "$handler_mode" = "function" ]; then
346416
event_data=$(cat "$body")
347-
if run_with_stderr_capture "$stderr_file" "$handler_func" "$event_data" > "$response"; then
348-
if ! post_response "$request_id" "$response"; then
417+
if [ "$response_mode" = "streaming" ]; then
418+
if ! stream_response "$request_id" "$stderr_file" "$handler_func" "$event_data"; then
349419
rm -f "$headers" "$body" "$response" "$stderr_file"
350420
exit 1
351421
fi
352422
else
353-
handler_exit=$?
354-
log "Handler exited with status ${handler_exit}"
355-
set_error_from_stderr "$stderr_file" "$handler_exit"
356-
if ! post_invoke_error "$request_id" "$error_message" "$error_type" "$stack_trace"; then
357-
rm -f "$headers" "$body" "$response" "$stderr_file"
358-
exit 1
423+
if run_with_stderr_capture "$stderr_file" "$handler_func" "$event_data" > "$response"; then
424+
if ! post_response "$request_id" "$response"; then
425+
rm -f "$headers" "$body" "$response" "$stderr_file"
426+
exit 1
427+
fi
428+
else
429+
handler_exit=$?
430+
log "Handler exited with status ${handler_exit}"
431+
set_error_from_stderr "$stderr_file" "$handler_exit"
432+
if ! post_invoke_error "$request_id" "$error_message" "$error_type" "$stack_trace"; then
433+
rm -f "$headers" "$body" "$response" "$stderr_file"
434+
exit 1
435+
fi
359436
fi
360437
fi
361438
elif [ "$handler_mode" = "executable" ]; then
362-
if run_with_stderr_capture "$stderr_file" "$handler_path" < "$body" > "$response"; then
363-
if ! post_response "$request_id" "$response"; then
439+
if [ "$response_mode" = "streaming" ]; then
440+
if ! stream_response "$request_id" "$stderr_file" "$handler_path" < "$body"; then
364441
rm -f "$headers" "$body" "$response" "$stderr_file"
365442
exit 1
366443
fi
367444
else
368-
handler_exit=$?
369-
log "Handler exited with status ${handler_exit}"
370-
set_error_from_stderr "$stderr_file" "$handler_exit"
371-
if ! post_invoke_error "$request_id" "$error_message" "$error_type" "$stack_trace"; then
372-
rm -f "$headers" "$body" "$response" "$stderr_file"
373-
exit 1
445+
if run_with_stderr_capture "$stderr_file" "$handler_path" < "$body" > "$response"; then
446+
if ! post_response "$request_id" "$response"; then
447+
rm -f "$headers" "$body" "$response" "$stderr_file"
448+
exit 1
449+
fi
450+
else
451+
handler_exit=$?
452+
log "Handler exited with status ${handler_exit}"
453+
set_error_from_stderr "$stderr_file" "$handler_exit"
454+
if ! post_invoke_error "$request_id" "$error_message" "$error_type" "$stack_trace"; then
455+
rm -f "$headers" "$body" "$response" "$stderr_file"
456+
exit 1
457+
fi
374458
fi
375459
fi
376460
else
377-
if run_with_stderr_capture "$stderr_file" sh "$handler_path" < "$body" > "$response"; then
378-
if ! post_response "$request_id" "$response"; then
461+
if [ "$response_mode" = "streaming" ]; then
462+
if ! stream_response "$request_id" "$stderr_file" sh "$handler_path" < "$body"; then
379463
rm -f "$headers" "$body" "$response" "$stderr_file"
380464
exit 1
381465
fi
382466
else
383-
handler_exit=$?
384-
log "Handler exited with status ${handler_exit}"
385-
set_error_from_stderr "$stderr_file" "$handler_exit"
386-
if ! post_invoke_error "$request_id" "$error_message" "$error_type" "$stack_trace"; then
387-
rm -f "$headers" "$body" "$response" "$stderr_file"
388-
exit 1
467+
if run_with_stderr_capture "$stderr_file" sh "$handler_path" < "$body" > "$response"; then
468+
if ! post_response "$request_id" "$response"; then
469+
rm -f "$headers" "$body" "$response" "$stderr_file"
470+
exit 1
471+
fi
472+
else
473+
handler_exit=$?
474+
log "Handler exited with status ${handler_exit}"
475+
set_error_from_stderr "$stderr_file" "$handler_exit"
476+
if ! post_invoke_error "$request_id" "$error_message" "$error_type" "$stack_trace"; then
477+
rm -f "$headers" "$body" "$response" "$stderr_file"
478+
exit 1
479+
fi
389480
fi
390481
fi
391482
fi

0 commit comments

Comments
 (0)