Skip to content

Commit

Permalink
test: Remote invoke integration tests for response stream configured …
Browse files Browse the repository at this point in the history
…lambda functions (aws#5383)

* Created base integ glass for remote invoke tests

* Add integration tests for invoking response streaming lambda fns

* make black

* Moved tearDownClass to base class

* Moved tearDownClass method to base class and removed architectures from template file

* Remove the check to skip appveyor tests on master branch
  • Loading branch information
hnnasit authored and lucashuy committed Jun 22, 2023
1 parent 4d8c272 commit 876f7e1
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 0 deletions.
103 changes: 103 additions & 0 deletions tests/integration/remote/invoke/test_lambda_invoke_response_stream.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import json
import uuid

from tests.integration.remote.invoke.remote_invoke_integ_base import RemoteInvokeIntegBase
from tests.testing_utils import run_command

from pathlib import Path
import pytest


@pytest.mark.xdist_group(name="sam_remote_invoke_lambda_response_streaming")
class TestInvokeResponseStreamingLambdas(RemoteInvokeIntegBase):
template = Path("template-lambda-response-streaming-fns.yaml")

@classmethod
def setUpClass(cls):
super().setUpClass()
cls.stack_name = f"{TestInvokeResponseStreamingLambdas.__name__}-{uuid.uuid4().hex}"
cls.create_resources_and_boto_clients()

def test_invoke_empty_event_provided(self):
command_list = self.get_command_list(stack_name=self.stack_name, resource_id="NodeStreamingFunction")

expected_streamed_responses = "LambdaFunctionStreamingResponsesTestDone!"
remote_invoke_result = run_command(command_list)

self.assertEqual(0, remote_invoke_result.process.returncode)
remote_invoke_result_stdout = remote_invoke_result.stdout.strip().decode()
self.assertIn(expected_streamed_responses, remote_invoke_result_stdout)

def test_invoke_with_only_event_provided(self):
command_list = self.get_command_list(
stack_name=self.stack_name,
resource_id="NodeStreamingFunction",
event='{"key1": "Hello", "key2": "serverless", "key3": "world"}',
)

expected_streamed_responses = "LambdaFunctionStreamingResponsesTestDone!"
remote_invoke_result = run_command(command_list)

self.assertEqual(0, remote_invoke_result.process.returncode)
remote_invoke_result_stdout = remote_invoke_result.stdout.strip().decode()
self.assertIn(expected_streamed_responses, remote_invoke_result_stdout)

def test_invoke_with_only_event_file_provided(self):
event_file_path = str(self.events_folder_path.joinpath("default_event.json"))
command_list = self.get_command_list(
stack_name=self.stack_name, resource_id="NodeStreamingEventValuesFunction", event_file=event_file_path
)

expected_streamed_responses = "Helloserverlessworld"
remote_invoke_result = run_command(command_list)

self.assertEqual(0, remote_invoke_result.process.returncode)
remote_invoke_result_stdout = remote_invoke_result.stdout.strip().decode()

self.assertEqual(expected_streamed_responses, remote_invoke_result_stdout)

def test_invoke_json_output_option(self):
command_list = self.get_command_list(
stack_name=self.stack_name,
event='{"key1": "Hello", "key2": "serverless", "key3": "world"}',
resource_id="NodeStreamingEventValuesFunction",
output="json",
parameter_list=[("LogType", "None")],
)

remote_invoke_result = run_command(command_list)
expected_output_result = [
{"PayloadChunk": {"Payload": "Hello"}},
{"PayloadChunk": {"Payload": "serverless"}},
{"PayloadChunk": {"Payload": "world"}},
{"InvokeComplete": {}},
]

self.assertEqual(0, remote_invoke_result.process.returncode)
remote_invoke_result_stdout = json.loads(remote_invoke_result.stdout.strip().decode())

response_event_stream = remote_invoke_result_stdout["EventStream"]
self.assertEqual(response_event_stream, expected_output_result)

def test_invoke_different_boto_options(self):
command_list = self.get_command_list(
stack_name=self.stack_name,
event='{"key1": "Hello", "key2": "serverless", "key3": "world"}',
resource_id="NodeStreamingEventValuesFunction",
output="json",
parameter_list=[("LogType", "None"), ("InvocationType", "DryRun"), ("Qualifier", "$LATEST")],
)

remote_invoke_result = run_command(command_list)
expected_output_result = [
{"PayloadChunk": {"Payload": "Hello"}},
{"PayloadChunk": {"Payload": "serverless"}},
{"PayloadChunk": {"Payload": "world"}},
{"InvokeComplete": {}},
]

self.assertEqual(0, remote_invoke_result.process.returncode)
remote_invoke_result_stdout = json.loads(remote_invoke_result.stdout.strip().decode())

response_event_stream = remote_invoke_result_stdout["EventStream"]
self.assertEqual(response_event_stream, expected_output_result)
26 changes: 26 additions & 0 deletions tests/integration/testdata/remote_invoke/lambda-fns/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
exports.handler = awslambda.streamifyResponse(
async (event, responseStream, context) => {
responseStream.write("Lambda");
responseStream.write("Function");

responseStream.write("Streaming");
await new Promise(r => setTimeout(r, 1000));
responseStream.write("Responses");
await new Promise(r => setTimeout(r, 1000));
responseStream.write("Test");
await new Promise(r => setTimeout(r, 1000));

responseStream.write("Done!");
responseStream.end();
}
);

exports.stream_event_values = awslambda.streamifyResponse(
async (event, responseStream, context) => {
for (let k in event) {
responseStream.write(event[k]);
await new Promise(r => setTimeout(r, 1000));
}
responseStream.end();
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Description: >
Testing application for lambda functions with response streaming
Resources:
NodeStreamingFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./lambda-fns/src/
Handler: index.handler
Runtime: nodejs18.x
Timeout: 10
FunctionUrlConfig:
AuthType: AWS_IAM
InvokeMode: RESPONSE_STREAM

NodeStreamingEventValuesFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./lambda-fns/src/
Handler: index.stream_event_values
Runtime: nodejs18.x
Timeout: 10
FunctionUrlConfig:
AuthType: AWS_IAM
InvokeMode: RESPONSE_STREAM

0 comments on commit 876f7e1

Please sign in to comment.