Skip to content

Commit

Permalink
Merge branch 'test/binary-canaries' of https://github.com/aws/aws-sam…
Browse files Browse the repository at this point in the history
…-cli into test/binary-canaries
  • Loading branch information
mildaniel committed Aug 3, 2023
2 parents 0637cd8 + 10ba052 commit 1af97d2
Show file tree
Hide file tree
Showing 23 changed files with 291 additions and 129 deletions.
132 changes: 132 additions & 0 deletions tests/iac_integration/cdk/test_sam_cdk_integration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
from unittest import TestCase
from subprocess import Popen, PIPE
import os
import random
from pathlib import Path
import threading

import pytest
import requests
from parameterized import parameterized_class, parameterized

from tests.testing_utils import run_command, start_persistent_process, read_until_string, kill_process


@parameterized_class(
("cdk_project_path", "cdk_version", "cdk_stack_template"),
[
("/testdata/cdk_v1/typescript", "1.x", "TestStack.template.json"),
("/testdata/cdk_v2/typescript", "2.x", "TestStack.template.json"),
("/testdata/cdk_v1/python", "1.x", "TestStack.template.json"),
("/testdata/cdk_v2/python", "2.x", "TestStack.template.json"),
("/testdata/cdk_v1/java", "1.x", "TestStack.template.json"),
("/testdata/cdk_v2/java", "2.x", "TestStack.template.json"),
],
)
class TestSamCdkIntegration(TestCase):
integration_dir = str(Path(__file__).resolve().parents[0])
cdk_project_path = ""
cdk_version = ""
cdk_stack_template = ""

@classmethod
def setUpClass(cls):
cls.cdk_project = cls.integration_dir + cls.cdk_project_path
cls.api_port = str(TestSamCdkIntegration.random_port())
cls.build_cdk_project()
cls.build()

cls.start_api()
cls.url = "http://127.0.0.1:{}".format(cls.api_port)

@classmethod
def build_cdk_project(cls):
command_list = ["npx", f"aws-cdk@{cls.cdk_version}", "synth", "--no-staging"]
working_dir = cls.cdk_project
result = run_command(command_list, cwd=working_dir)
if result.process.returncode != 0:
raise Exception("cdk synth command failed")

@classmethod
def build(cls):
command = "sam"
if os.getenv("SAM_CLI_DEV"):
command = "samdev"
command_list = [command, "build", "-t", cls.cdk_stack_template]
working_dir = cls.cdk_project + "/cdk.out"
result = run_command(command_list, cwd=working_dir)
if result.process.returncode != 0:
raise Exception("sam build command failed")

@classmethod
def start_api(cls):
command = "sam"
if os.getenv("SAM_CLI_DEV"):
command = "samdev"

command_list = [command, "local", "start-api", "-p", cls.api_port]

working_dir = cls.cdk_project + "/cdk.out"
cls.start_api_process = Popen(command_list, cwd=working_dir, stderr=PIPE, shell=True,)

while True:
line = cls.start_api_process.stderr.readline()
if "Press CTRL+C to quit" in str(line):
break

cls.stop_api_reading_thread = False

def read_sub_process_stderr():
while not cls.stop_api_reading_thread:
cls.start_api_process.stderr.readline()

cls.api_read_threading = threading.Thread(target=read_sub_process_stderr, daemon=True)
cls.api_read_threading.start()

@classmethod
def tearDownClass(cls):
# After all the tests run, we need to kill the start_lambda process.
cls.stop_api_reading_thread = True
kill_process(cls.start_api_process)

@staticmethod
def random_port():
return random.randint(30000, 40000)

@parameterized.expand(
[
("/httpapis/nestedPythonFunction", "Hello World from Nested Python Function Construct 7"),
("/restapis/spec/pythonFunction", "Hello World from python function construct 7"),
("/restapis/normal/pythonFunction", "Hello World from python function construct 7"),
("/restapis/normal/functionPythonRuntime", "Hello World from function construct with python runtime 7"),
("/restapis/normal/preBuiltFunctionPythonRuntime", "Hello World from python pre built function 7"),
(
"/restapis/normal/bundledFunctionPythonRuntime",
"Hello World from bundled function construct with python runtime 7",
),
("/restapis/normal/nodejsFunction", "Hello World from nodejs function construct 7"),
("/restapis/normal/functionNodeJsRuntime", "Hello World from function construct with nodejs runtime 7"),
("/restapis/normal/preBuiltFunctionNodeJsRuntime", "Hello World from nodejs pre built function 7"),
("/restapis/normal/goFunction", "Hello World from go function construct"),
("/restapis/normal/functionGoRuntime", "Hello World from function construct with go runtime"),
("/restapis/normal/dockerImageFunction", "Hello World from docker image function construct"),
("/restapis/normal/functionImageAsset", "Hello World from function construct with image asset"),
(
"/restapis/normal/dockerImageFunctionWithSharedCode",
"Hello World from docker image function construct "
"with a Dockerfile that shares code with another Dockerfile",
),
(
"/restapis/normal/functionImageAssetWithSharedCode",
"Hello World from function construct with image asset "
"with a Dockerfile that shares code with another Dockerfile",
),
]
)
@pytest.mark.flaky(reruns=3)
@pytest.mark.timeout(timeout=1000, method="thread")
def test_invoke_api(self, url_suffix, expected_message):
response = requests.get(self.url + url_suffix, timeout=800)

self.assertEqual(response.status_code, 200)
self.assertEqual(response.json().get("message"), expected_message)
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def setUp(self):
shutil.copytree(Path(self.terraform_application_path), Path(self.working_dir))

def run_command(self, command_list, env=None, input=None):
process = Popen(command_list, stdout=PIPE, stderr=PIPE, stdin=PIPE, env=env, cwd=self.working_dir)
process = Popen(command_list, stdout=PIPE, stderr=PIPE, stdin=PIPE, env=env, cwd=self.working_dir, shell=True)
try:
(stdout, stderr) = process.communicate(input=input)
return stdout, stderr, process.returncode
Expand Down
45 changes: 35 additions & 10 deletions tests/integration/init/test_init_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def test_init_command_passes_and_dir_created(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -82,7 +83,8 @@ def test_init_command_passes_and_dir_created_image(self):
"--no-interactive",
"-o",
temp,
]
],
shell = True,
)
try:
process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -113,6 +115,7 @@ def test_init_new_app_template(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -145,6 +148,7 @@ def test_init_command_java_maven(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -177,6 +181,7 @@ def test_init_command_java_gradle(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -209,6 +214,7 @@ def test_init_command_go_provided_image(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -243,6 +249,7 @@ def test_init_command_with_extra_context_parameter(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -277,6 +284,7 @@ def test_init_command_passes_with_arm_architecture(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -311,6 +319,7 @@ def test_init_command_passes_with_x86_64_architecture(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -342,7 +351,8 @@ def test_init_command_passes_with_unknown_architecture(self):
temp,
"--architecture",
"unknown_arch",
]
],
shell=True,
)
capture_output = ""
try:
Expand Down Expand Up @@ -374,7 +384,8 @@ def test_init_command_passes_with_enabled_tracing(self):
"-o",
temp,
"--tracing",
]
],
shell=True,
)
try:
process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -404,7 +415,8 @@ def test_init_command_passes_with_disabled_tracing(self):
"-o",
temp,
"--no-tracing",
]
],
shell=True,
)
try:
process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -434,7 +446,8 @@ def test_init_command_passes_with_enabled_application_insights(self):
"-o",
temp,
"--application-insights",
]
],
shell=True,
)
try:
process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -464,7 +477,8 @@ def test_init_command_passes_with_disabled_application_insights(self):
"-o",
temp,
"--no-application-insights",
]
],
shell=True,
)
try:
process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -524,6 +538,7 @@ def test_init_command_no_interactive_missing_name(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -553,6 +568,7 @@ def test_init_command_no_interactive_apptemplate_location(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -585,6 +601,7 @@ def test_init_command_no_interactive_runtime_location(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -616,6 +633,7 @@ def test_init_command_no_interactive_base_image_location(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -648,6 +666,7 @@ def test_init_command_no_interactive_base_image_no_dependency(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -677,6 +696,7 @@ def test_init_command_no_interactive_packagetype_location(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -707,6 +727,7 @@ def test_init_command_no_interactive_base_image_no_packagetype(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand All @@ -733,6 +754,7 @@ def test_init_command_wrong_packagetype(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -785,7 +807,7 @@ def test_arbitrary_project(self, project_name):
if project_name:
args.extend(["--name", project_name])

process = Popen(args)
process = Popen(args, shell=True,)
try:
process.communicate(timeout=TIMEOUT)
except TimeoutExpired:
Expand All @@ -801,7 +823,7 @@ def test_zip_not_exists(self):
with tempfile.TemporaryDirectory() as temp:
args = [get_sam_command(), "init", "--location", str(Path("invalid", "zip", "path")), "-o", temp]

process = Popen(args)
process = Popen(args, shell=True,)
try:
process.communicate(timeout=TIMEOUT)
except TimeoutExpired:
Expand All @@ -825,7 +847,7 @@ def test_location_with_no_interactive_and_name(self):
"-o",
tmp,
]
process = Popen(args)
process = Popen(args, shell=True,)

try:
process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -937,6 +959,7 @@ def _run_init(self, cwd):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -977,6 +1000,7 @@ def test_zip_template_config(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -1012,6 +1036,7 @@ def test_image_template_config(self):
],
stdout=PIPE,
stderr=PIPE,
shell=True,
)
try:
stdout_data, stderr_data = process.communicate(timeout=TIMEOUT)
Expand Down Expand Up @@ -1072,7 +1097,7 @@ class TestInitCommand(InitIntegBase):
def test_graceful_exit(self):
# Run the Base Command
command_list = self.get_command()
process_execute = Popen(command_list, stdout=PIPE, stderr=PIPE)
process_execute = Popen(command_list, stdout=PIPE, stderr=PIPE, shell=True,)

# Wait for binary to be ready before sending interrupts.
time.sleep(self.BINARY_READY_WAIT_TIME)
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/local/generate_event/test_cli_integ.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@

class Test_EventGeneration_Integ(TestCase):
def test_generate_event_substitution(self):
process = Popen([get_sam_command(), "local", "generate-event", "s3", "put"])
process = Popen([get_sam_command(), "local", "generate-event", "s3", "put"], shell=True,)
process.communicate()
self.assertEqual(process.returncode, 0)
Loading

0 comments on commit 1af97d2

Please sign in to comment.