Skip to content

Commit

Permalink
removing unecessary params, optimize make file
Browse files Browse the repository at this point in the history
  • Loading branch information
roger-zhangg committed Apr 17, 2024
1 parent 2a71f85 commit d78aea8
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 72 deletions.
15 changes: 9 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,29 @@ prep-python:
.venv/bin/pip install --upgrade pip
.venv/bin/pip install requests parameterized

exec-python-e2e-test:
TEST_ARCH=${TEST_ARCH} TEST_PORT=${TEST_PORT} .venv/bin/python3 test/integration/local_lambda/test_end_to_end.py

integ-tests:
make prep-python
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
TEST_ARCH=x86_64 TEST_PORT=8002 .venv/bin/python3 test/integration/local_lambda/test_end_to_end.py
TEST_ARCH=arm64 TEST_PORT=9002 .venv/bin/python3 test/integration/local_lambda/test_end_to_end.py
TEST_ARCH="" TEST_PORT=9052 .venv/bin/python3 test/integration/local_lambda/test_end_to_end.py
make TEST_ARCH=x86_64 TEST_PORT=8002 exec-python-e2e-test
make TEST_ARCH=arm64 TEST_PORT=9002 exec-python-e2e-test
make TEST_ARCH="" TEST_PORT=9052 exec-python-e2e-test

integ-tests-with-docker-x86-64:
make ARCH=x86_64 compile-with-docker
make prep-python
TEST_ARCH=x86_64 TEST_PORT=8002 .venv/bin/python3 test/integration/local_lambda/test_end_to_end.py
make TEST_ARCH=x86_64 TEST_PORT=8002 exec-python-e2e-test

integ-tests-with-docker-arm64:
make ARCH=arm64 compile-with-docker
make prep-python
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
TEST_ARCH="arm64" TEST_PORT=9002 .venv/bin/python3 test/integration/local_lambda/test_end_to_end.py
make TEST_ARCH=arm64 TEST_PORT=9002 exec-python-e2e-test

integ-tests-with-docker-old:
make ARCH=old compile-with-docker
make prep-python
TEST_ARCH="" TEST_PORT=9052 .venv/bin/python3 test/integration/local_lambda/test_end_to_end.py
make TEST_ARCH="" TEST_PORT=9052 exec-python-e2e-test

131 changes: 65 additions & 66 deletions test/integration/local_lambda/test_end_to_end.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from contextlib import contextmanager
from parameterized import parameterized

SLEEP_TIME = 2
SLEEP_TIME = 1.5
DEFAULT_1P_ENTRYPOINT = "/lambda-entrypoint.sh"
ARCHS = ["x86_64", "arm64", ""]

Expand All @@ -23,11 +23,11 @@ class TestEndToEnd(TestCase):
def setUpClass(cls):
testdata_path = Path(__file__).resolve().parents[1].joinpath("testdata")
dockerfile_path = testdata_path.joinpath("Dockerfile-allinone")
cls.image_name = "aws-lambda-local:testing"
cls.path_to_binary = Path().resolve().joinpath("bin")

# build image
image_name = cls.image_name if cls.ARCH == "" else f"{cls.image_name}-{cls.ARCH}"
image_name_base = "aws-lambda-local:testing"
cls.image_name = image_name_base if cls.ARCH == "" else f"{image_name_base}-{cls.ARCH}"
architecture = cls.ARCH if cls.ARCH == "arm64" else "amd64"
docker_arch = cls.ARCH if cls.ARCH == "arm64" else "x86_64"

Expand All @@ -37,44 +37,42 @@ def setUpClass(cls):
"--platform",
f"linux/{architecture}",
"-t",
image_name,
cls.image_name,
"-f",
str(dockerfile_path),
str(testdata_path),
"--build-arg",
f"IMAGE_ARCH={docker_arch}",
]
print (build_cmd)
Popen(build_cmd).communicate()

@classmethod
def tearDownClass(cls):
arch_tag = "" if cls.ARCH == "" else f"-{cls.ARCH}"
Popen(f"docker rmi {cls.image_name}{arch_tag}".split(" ")).communicate()
Popen(f"docker rmi {cls.image_name}".split(" ")).communicate()

def tagged_name(self, name, architecture):
tag = self.get_tag(architecture)
return (name + tag, "aws-lambda-rie" + tag, self.image_name + tag)
def tagged_name(self, name):
tag = self.get_tag()
return (name + tag, "aws-lambda-rie" + tag, self.image_name)

def get_tag(self, architecture):
return "" if architecture == "" else str(f"-{architecture}")
def get_tag(self):
return "" if self.ARCH == "" else str(f"-{self.ARCH}")

def run_command(self, cmd):
Popen(cmd.split(" ")).communicate()

def sleep_1s(self):
time.sleep(SLEEP_TIME)

def invoke_function(self, port):
def invoke_function(self):
return requests.post(
f"http://localhost:{port}/2015-03-31/functions/function/invocations", json={}
f"http://localhost:{self.PORT}/2015-03-31/functions/function/invocations", json={}
)

@contextmanager
def create_container(self, cmd, image):
def create_container(self, param, image):
try:
platform = "x86_64" if self.ARCH == "" else self.ARCH
cmd_full = f"docker run --platform linux/{platform} {cmd}"
cmd_full = f"docker run --platform linux/{platform} {param}"
self.run_command(cmd_full)

# sleep 1s to give enough time for the endpoint to be up to curl
Expand All @@ -88,149 +86,150 @@ def create_container(self, cmd, image):
self.run_command(f"docker rm -f {image}")


def test_env_var_with_equal_sign(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("envvarcheck", arch)
cmd = f"--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"
def test_env_var_with_equal_sign(self):
image, rie, image_name = self.tagged_name("envvarcheck")
cmd = f"--name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.PORT}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.check_env_var_handler"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

self.assertEqual(b'"4=4"', r.content)


def test_two_invokes(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("twoinvokes", arch)
def test_two_invokes(self):
image, rie, image_name = self.tagged_name("twoinvokes")

cmd = f"--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"
cmd = f"--name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.PORT}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.success_handler"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

self.assertEqual(b'"My lambda ran succesfully"', r.content)

# Make sure we can invoke the function twice
r = self.invoke_function(port)
r = self.invoke_function()

self.assertEqual(b'"My lambda ran succesfully"', r.content)


def test_lambda_function_arn_exists(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("arnexists", arch)
def test_lambda_function_arn_exists(self):
image, rie, image_name = self.tagged_name("arnexists")

cmd = f"--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"
cmd = f"--name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.PORT}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.assert_lambda_arn_in_context"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

self.assertEqual(b'"My lambda ran succesfully"', r.content)


def test_lambda_function_arn_exists_with_defining_custom_name(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("customname", arch)
def test_lambda_function_arn_exists_with_defining_custom_name(self):
image, rie, image_name = self.tagged_name("customname")

cmd = f"--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"
cmd = f"--name {image} --env AWS_LAMBDA_FUNCTION_NAME=MyCoolName -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.PORT}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.assert_lambda_arn_in_context"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

self.assertEqual(b'"My lambda ran succesfully"', r.content)


def test_timeout_invoke(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("timeout", arch)
def test_timeout_invoke(self):
image, rie, image_name = self.tagged_name("timeout")

cmd = f"--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"
cmd = f"--name {image} -d --env AWS_LAMBDA_FUNCTION_TIMEOUT=1 -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.PORT}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.sleep_handler"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

self.assertEqual(b"Task timed out after 1.00 seconds", r.content)


def test_exception_returned(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("exception", arch)
def test_exception_returned(self):
image, rie, image_name = self.tagged_name("exception")

cmd = f"--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"
cmd = f"--name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.PORT}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.exception_handler"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

# ignore request_id in python3.12 lambda
# Except the 3 fields assrted below, there's another field `request_id` included start from python3.12 runtime.
# We should ignore asserting the field `request_id` for it is in a UUID like format and chages everytime
result = r.json()
self.assertEqual(result["errorMessage"],"Raising an exception")
self.assertEqual(result["errorType"],"Exception")
self.assertEqual(result["stackTrace"],[" File \"/var/task/main.py\", line 13, in exception_handler\n raise Exception(\"Raising an exception\")\n"])


def test_context_get_remaining_time_in_three_seconds(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("remaining_time_in_three_seconds", arch)
def test_context_get_remaining_time_in_three_seconds(self):
image, rie, image_name = self.tagged_name("remaining_time_in_three_seconds")

cmd = f"--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"
cmd = f"--name {image} -d --env AWS_LAMBDA_FUNCTION_TIMEOUT=3 -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.PORT}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.check_remaining_time_handler"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

# Execution time is not decided, 1.0s ~ 3.0s is a good estimation
self.assertLess(int(r.content), 3000)
self.assertGreater(int(r.content), 1000)


def test_context_get_remaining_time_in_ten_seconds(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("remaining_time_in_ten_seconds", arch)
def test_context_get_remaining_time_in_ten_seconds(self):
image, rie, image_name = self.tagged_name("remaining_time_in_ten_seconds")

cmd = f"--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"
cmd = f"--name {image} -d --env AWS_LAMBDA_FUNCTION_TIMEOUT=10 -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.PORT}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.check_remaining_time_handler"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

# Execution time is not decided, 8.0s ~ 10.0s is a good estimation
self.assertLess(int(r.content), 10000)
self.assertGreater(int(r.content), 8000)


def test_context_get_remaining_time_in_default_deadline(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("remaining_time_in_default_deadline", arch)
def test_context_get_remaining_time_in_default_deadline(self):
image, rie, image_name = self.tagged_name("remaining_time_in_default_deadline")

cmd = f"--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"
cmd = f"--name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.PORT}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.check_remaining_time_handler"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

# Executation time is not decided, 298.0s ~ 300.0s is a good estimation
self.assertLess(int(r.content), 300000)
self.assertGreater(int(r.content), 298000)


def test_invoke_with_pre_runtime_api_runtime(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("pre-runtime-api", arch)
def test_invoke_with_pre_runtime_api_runtime(self):
image, rie, image_name = self.tagged_name("pre-runtime-api")

cmd = f"--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"
cmd = f"--name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.PORT}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.success_handler"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

self.assertEqual(b'"My lambda ran succesfully"', r.content)


def test_function_name_is_overriden(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("assert-overwritten", arch)
def test_function_name_is_overriden(self):
image, rie, image_name = self.tagged_name("assert-overwritten")

cmd = f"--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"
cmd = f"--name {image} -d --env AWS_LAMBDA_FUNCTION_NAME=MyCoolName -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.PORT}:8080 --entrypoint /local-lambda-runtime-server/{rie} {image_name} {DEFAULT_1P_ENTRYPOINT} main.assert_env_var_is_overwritten"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

self.assertEqual(b'"My lambda ran succesfully"', r.content)


def test_port_override(self, arch=ARCH, port=PORT):
image, rie, image_name = self.tagged_name("port_override", arch)
def test_port_override(self):
image, rie, image_name = self.tagged_name("port_override")

# Use port 8081 inside the container instead of 8080
cmd = f"--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"
cmd = f"--name {image} -d -v {self.path_to_binary}:/local-lambda-runtime-server -p {self.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"

with self.create_container(cmd, image):
r = self.invoke_function(port)
r = self.invoke_function()

self.assertEqual(b'"My lambda ran succesfully"', r.content)

Expand Down

0 comments on commit d78aea8

Please sign in to comment.