diff --git a/appveyor-windows-build-java-inprocess.yml b/appveyor-windows-build-java-ruby-inprocess.yml similarity index 79% rename from appveyor-windows-build-java-inprocess.yml rename to appveyor-windows-build-java-ruby-inprocess.yml index c15c810b90..cb975f9e4c 100644 --- a/appveyor-windows-build-java-inprocess.yml +++ b/appveyor-windows-build-java-ruby-inprocess.yml @@ -17,22 +17,6 @@ environment: install: - - "SET PATH=%PYTHON_HOME%;%PATH%" - - "echo %PYTHON_HOME%" - - "echo %PATH%" - - "python --version" - - # Upgrade setuptools, wheel and virtualenv - - "python -m pip install --upgrade setuptools wheel virtualenv" - - # Create new virtual environment with chosen python version and activate it - - "python -m virtualenv venv" - - "venv\\Scripts\\activate" - - "python --version" - - # Actually install SAM CLI's dependencies - - "pip install -e \".[dev]\"" - # setup Java, Maven and Gradle - "refreshenv" - "choco install maven -y --force" @@ -52,9 +36,22 @@ install: # Echo final Path - "echo %PATH%" + # validate ssl works with ruby + - "ruby -ropen-uri -e 'eval open(\"https://git.io/vQhWq\").read'" + + - "set PATH=%PYTHON_HOME%;%PYTHON_HOME%\\Scripts;%PYTHON_HOME%\\bin;%PATH%" + - "echo %PYTHON_HOME%" + - "echo %PATH%" + - "python --version" + + # Actually install SAM CLI's dependencies + - "pip install -e \".[dev]\"" + test_script: # Reactivate virtualenv before running tests - - "venv\\Scripts\\activate" - "pytest -vv tests/integration/buildcmd/test_build_cmd.py -k test_building_java8_in_process" - "SET JAVA_HOME=C:\\Program Files\\Java\\jdk11" - "pytest -vv tests/integration/buildcmd/test_build_cmd.py -k test_building_java11_in_process" + + # Run Ruby in-process builds + - "pytest -vv tests/integration/buildcmd/test_build_cmd.py -k test_building_ruby_in_process" diff --git a/appveyor-windows-build-python.yml b/appveyor-windows-build-python.yml index 7e83ff75ee..46f38f896a 100644 --- a/appveyor-windows-build-python.yml +++ b/appveyor-windows-build-python.yml @@ -38,6 +38,7 @@ install: # Make sure the temp directory exists for Python to use. # Install python3.8 + - "choco install chocolatey-core.extension --version 1.3.3 --force -y" - "choco install python3 --version 3.8.0" - "C:\\Python38\\python.exe -m pip freeze" - "refreshenv" diff --git a/appveyor-windows-build-ruby.yml b/appveyor-windows-build-ruby.yml index 5c60406b0b..fb91d00c63 100644 --- a/appveyor-windows-build-ruby.yml +++ b/appveyor-windows-build-ruby.yml @@ -55,6 +55,7 @@ install: - "pip install -e \".[dev]\"" # setup Ruby + - "choco install chocolatey-core.extension --version 1.3.3 --force -y" - "choco install ruby --version 2.5.3.1 --force -y" - "refreshenv" - "ruby --version" diff --git a/appveyor.yml b/appveyor.yml index 3d77f8d7ee..5651cad5ce 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ environment: matrix: - PYTHON_HOME: "C:\\Python36-x64" - PYTHON_VERSION: '3.6.8' + PYTHON_VERSION: '3.6.9' PYTHON_ARCH: '64' NOSE_PARAMETERIZED_NO_WARN: 1 INSTALL_PY_37_PIP: 1 @@ -93,7 +93,6 @@ for: - sh: "sudo apt-get -y install python3.6" - sh: "sudo apt-get -y install python2.7" - sh: "sudo apt-get -y install python3.7" - - sh: "sudo apt-get update" - sh: "sudo apt-get -y install python3.8" - sh: "which python3.8" diff --git a/samcli/__init__.py b/samcli/__init__.py index f62ab682b2..a412a93a37 100644 --- a/samcli/__init__.py +++ b/samcli/__init__.py @@ -2,4 +2,4 @@ SAM CLI version """ -__version__ = "0.37.0" +__version__ = "0.38.0" diff --git a/samcli/commands/deploy/command.py b/samcli/commands/deploy/command.py index 0c27eb6e66..bb465a64b1 100644 --- a/samcli/commands/deploy/command.py +++ b/samcli/commands/deploy/command.py @@ -231,7 +231,17 @@ def do_cli( read_config_showcase(template_file=template_file) - guided_stack_name, guided_s3_bucket, guided_s3_prefix, guided_region, guided_profile, changeset_decision, _capabilities, _parameter_overrides, save_to_config = guided_deploy( + ( + guided_stack_name, + guided_s3_bucket, + guided_s3_prefix, + guided_region, + guided_profile, + changeset_decision, + _capabilities, + _parameter_overrides, + save_to_config, + ) = guided_deploy( stack_name, s3_bucket, region, profile, confirm_changeset, _parameter_override_keys, parameter_overrides ) diff --git a/samcli/commands/local/invoke/cli.py b/samcli/commands/local/invoke/cli.py index 15705935cb..d642865b7e 100644 --- a/samcli/commands/local/invoke/cli.py +++ b/samcli/commands/local/invoke/cli.py @@ -116,7 +116,7 @@ def do_cli( # pylint: disable=R0914 from samcli.commands.validate.lib.exceptions import InvalidSamDocumentException from samcli.commands.local.lib.exceptions import OverridesNotWellDefinedError from samcli.local.docker.manager import DockerImagePullFailedException - from samcli.local.docker.lambda_debug_entrypoint import DebuggingNotSupported + from samcli.local.docker.lambda_debug_settings import DebuggingNotSupported LOG.debug("local invoke command is called") diff --git a/samcli/commands/local/lib/local_lambda.py b/samcli/commands/local/lib/local_lambda.py index c1ddbb4888..ea3a42725c 100644 --- a/samcli/commands/local/lib/local_lambda.py +++ b/samcli/commands/local/lib/local_lambda.py @@ -53,6 +53,8 @@ def __init__( self.aws_region = aws_region self.env_vars_values = env_vars_values or {} self.debug_context = debug_context + self._boto3_session_creds = None + self._boto3_region = None def invoke(self, function_name, event, stdout=None, stderr=None): """ @@ -205,6 +207,22 @@ def _make_env_vars(self, function): aws_creds=aws_creds, ) + def _get_session_creds(self): + if self._boto3_session_creds is None: + # to pass command line arguments for region & profile to setup boto3 default session + LOG.debug("Loading AWS credentials from session with profile '%s'", self.aws_profile) + session = boto3.session.Session(profile_name=self.aws_profile, region_name=self.aws_region) + + # check for region_name in session and cache + if hasattr(session, "region_name") and session.region_name: + self._boto3_region = session.region_name + + # don't set cached session creds if there is not a session + if session: + self._boto3_session_creds = session.get_credentials() + + return self._boto3_session_creds + def get_aws_creds(self): """ Returns AWS credentials obtained from the shell environment or given profile @@ -215,26 +233,17 @@ def get_aws_creds(self): """ result = {} - # to pass command line arguments for region & profile to setup boto3 default session - LOG.debug("Loading AWS credentials from session with profile '%s'", self.aws_profile) - # boto3.session.Session is not thread safe. To ensure we do not run into a race condition with start-lambda - # or start-api, we create the session object here on every invoke. - session = boto3.session.Session(profile_name=self.aws_profile, region_name=self.aws_region) - - if not session: - return result - # Load the credentials from profile/environment - creds = session.get_credentials() + creds = self._get_session_creds() + + # After loading credentials, region name might be available here. + if self._boto3_region: + result["region"] = self._boto3_region if not creds: - # If we were unable to load credentials, then just return empty. We will use the default + # If we were unable to load credentials, then just return result. We will use the default return result - # After loading credentials, region name might be available here. - if hasattr(session, "region_name") and session.region_name: - result["region"] = session.region_name - # Only add the key, if its value is present if hasattr(creds, "access_key") and creds.access_key: result["key"] = creds.access_key diff --git a/samcli/commands/local/start_api/cli.py b/samcli/commands/local/start_api/cli.py index bfb7447fbe..e06a9a7ebc 100644 --- a/samcli/commands/local/start_api/cli.py +++ b/samcli/commands/local/start_api/cli.py @@ -115,7 +115,7 @@ def do_cli( # pylint: disable=R0914 from samcli.commands.local.lib.local_api_service import LocalApiService from samcli.commands.validate.lib.exceptions import InvalidSamDocumentException from samcli.commands.local.lib.exceptions import OverridesNotWellDefinedError - from samcli.local.docker.lambda_debug_entrypoint import DebuggingNotSupported + from samcli.local.docker.lambda_debug_settings import DebuggingNotSupported LOG.debug("local start-api command is called") diff --git a/samcli/commands/local/start_lambda/cli.py b/samcli/commands/local/start_lambda/cli.py index 1e171fa5e7..6e822cd2ed 100644 --- a/samcli/commands/local/start_lambda/cli.py +++ b/samcli/commands/local/start_lambda/cli.py @@ -124,7 +124,7 @@ def do_cli( # pylint: disable=R0914 from samcli.commands.local.lib.local_lambda_service import LocalLambdaService from samcli.commands.validate.lib.exceptions import InvalidSamDocumentException from samcli.commands.local.lib.exceptions import OverridesNotWellDefinedError - from samcli.local.docker.lambda_debug_entrypoint import DebuggingNotSupported + from samcli.local.docker.lambda_debug_settings import DebuggingNotSupported LOG.debug("local start_lambda command is called") diff --git a/samcli/lib/package/artifact_exporter.py b/samcli/lib/package/artifact_exporter.py index 3fdada7ff2..334231046a 100644 --- a/samcli/lib/package/artifact_exporter.py +++ b/samcli/lib/package/artifact_exporter.py @@ -157,6 +157,13 @@ def upload_local_artifacts(resource_id, resource_dict, property_name, parent_dir raise exceptions.InvalidLocalPathError(resource_id=resource_id, property_name=property_name, local_path=local_path) +def resource_not_packageable(resource_dict): + inline_code = jmespath.search("InlineCode", resource_dict) + if inline_code is not None: + return True + return False + + def zip_and_upload(local_path, uploader): with zip_folder(local_path) as zip_file: return uploader.upload_with_dedup(zip_file) @@ -235,6 +242,9 @@ def export(self, resource_id, resource_dict, parent_dir): if resource_dict is None: return + if resource_not_packageable(resource_dict): + return + property_value = jmespath.search(self.PROPERTY_NAME, resource_dict) if not property_value and not self.PACKAGE_NULL_PROPERTY: diff --git a/samcli/local/common/runtime_template.py b/samcli/local/common/runtime_template.py index ac3ffcafde..67a03513f2 100644 --- a/samcli/local/common/runtime_template.py +++ b/samcli/local/common/runtime_template.py @@ -34,13 +34,7 @@ "dependency_manager": "npm", "init_location": os.path.join(_templates, "cookiecutter-aws-sam-hello-nodejs"), "build": True, - }, - { - "runtimes": ["nodejs6.10"], - "dependency_manager": "npm", - "init_location": os.path.join(_templates, "cookiecutter-aws-sam-hello-nodejs6"), - "build": True, - }, + } ], "dotnet": [ { @@ -83,7 +77,6 @@ "nodejs12.x": ["npm"], "nodejs10.x": ["npm"], "nodejs8.10": ["npm"], - "nodejs6.10": ["npm"], "dotnetcore2.1": ["cli-package"], "dotnetcore2.0": ["cli-package"], "dotnetcore1.0": ["cli-package"], @@ -115,7 +108,6 @@ # older nodejs runtimes "nodejs10.x", "nodejs8.10", - "nodejs6.10", # older python runtimes "python3.7", "python3.6", diff --git a/samcli/local/docker/lambda_container.py b/samcli/local/docker/lambda_container.py index 2c17a3a195..2f4e8a54a9 100644 --- a/samcli/local/docker/lambda_container.py +++ b/samcli/local/docker/lambda_container.py @@ -3,7 +3,7 @@ """ import logging -from samcli.local.docker.lambda_debug_entrypoint import LambdaDebugEntryPoint +from samcli.local.docker.lambda_debug_settings import LambdaDebugSettings from .container import Container from .lambda_image import Runtime @@ -71,11 +71,16 @@ def __init__( image = LambdaContainer._get_image(image_builder, runtime, layers) ports = LambdaContainer._get_exposed_ports(debug_options) - entry = LambdaContainer._get_entry_point(runtime, debug_options) + entry, debug_env_vars = LambdaContainer._get_debug_settings(runtime, debug_options) additional_options = LambdaContainer._get_additional_options(runtime, debug_options) additional_volumes = LambdaContainer._get_additional_volumes(debug_options) cmd = [handler] + if not env_vars: + env_vars = {} + + env_vars = {**env_vars, **debug_env_vars} + super(LambdaContainer, self).__init__( image, cmd, @@ -168,7 +173,7 @@ def _get_image(image_builder, runtime, layers): return image_builder.build(runtime, layers) @staticmethod - def _get_entry_point(runtime, debug_options=None): # pylint: disable=too-many-branches + def _get_debug_settings(runtime, debug_options=None): # pylint: disable=too-many-branches """ Returns the entry point for the container. The default value for the entry point is already configured in the Dockerfile. We override this default specifically when enabling debugging. The overridden entry point includes @@ -181,11 +186,11 @@ def _get_entry_point(runtime, debug_options=None): # pylint: disable=too-many-b """ if not debug_options: - return None + return None, {} debug_ports = debug_options.debug_ports if not debug_ports: - return None + return None, {} debug_port = debug_ports[0] debug_args_list = [] @@ -195,7 +200,7 @@ def _get_entry_point(runtime, debug_options=None): # pylint: disable=too-many-b # configs from: https://github.com/lambci/docker-lambda # to which we add the extra debug mode options - return LambdaDebugEntryPoint.get_entry_point( + return LambdaDebugSettings.get_debug_settings( debug_port=debug_port, debug_args_list=debug_args_list, runtime=runtime, diff --git a/samcli/local/docker/lambda_debug_entrypoint.py b/samcli/local/docker/lambda_debug_entrypoint.py deleted file mode 100644 index 9868652aea..0000000000 --- a/samcli/local/docker/lambda_debug_entrypoint.py +++ /dev/null @@ -1,143 +0,0 @@ -""" -Represents Lambda debug entrypoints. -""" - -import json - -from samcli.local.docker.lambda_image import Runtime - - -class DebuggingNotSupported(Exception): - pass - - -class LambdaDebugEntryPoint: - @staticmethod - def get_entry_point(debug_port, debug_args_list, runtime, options): - - entrypoint_mapping = { - Runtime.java8.value: ["/usr/bin/java"] - + debug_args_list - + [ - "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,quiet=y,address=" + str(debug_port), - "-XX:MaxHeapSize=2834432k", - "-XX:MaxMetaspaceSize=163840k", - "-XX:ReservedCodeCacheSize=81920k", - "-XX:+UseSerialGC", - # "-Xshare:on", doesn't work in conjunction with the debug options - "-XX:-TieredCompilation", - "-Djava.net.preferIPv4Stack=true", - "-jar", - "/var/runtime/lib/LambdaJavaRTEntry-1.0.jar", - ], - Runtime.dotnetcore20.value: ["/var/lang/bin/dotnet"] - + debug_args_list - + ["/var/runtime/MockBootstraps.dll", "--debugger-spin-wait"], - Runtime.dotnetcore21.value: ["/var/lang/bin/dotnet"] - + debug_args_list - + ["/var/runtime/MockBootstraps.dll", "--debugger-spin-wait"], - Runtime.go1x.value: ["/var/runtime/aws-lambda-go"] - + debug_args_list - + ["-debug=true", "-delvePort=" + str(debug_port), "-delvePath=" + options.get("delvePath")], - Runtime.nodejs.value: ["/usr/bin/node"] - + debug_args_list - + [ - "--debug-brk=" + str(debug_port), - "--nolazy", - "--max-old-space-size=1229", - "--max-new-space-size=153", - "--max-executable-size=153", - "--expose-gc", - "/var/runtime/node_modules/awslambda/bin/awslambda", - ], - Runtime.nodejs43.value: ["/usr/local/lib64/node-v4.3.x/bin/node"] - + debug_args_list - + [ - "--debug-brk=" + str(debug_port), - "--nolazy", - "--max-old-space-size=2547", - "--max-semi-space-size=150", - "--max-executable-size=160", - "--expose-gc", - "/var/runtime/node_modules/awslambda/index.js", - ], - Runtime.nodejs610.value: ["/var/lang/bin/node"] - + debug_args_list - + [ - "--debug-brk=" + str(debug_port), - "--nolazy", - "--max-old-space-size=2547", - "--max-semi-space-size=150", - "--max-executable-size=160", - "--expose-gc", - "/var/runtime/node_modules/awslambda/index.js", - ], - Runtime.nodejs810.value: ["/var/lang/bin/node"] - + debug_args_list - + [ - # Node8 requires the host to be explicitly set in order to bind to localhost - # instead of 127.0.0.1. https://github.com/nodejs/node/issues/11591#issuecomment-283110138 - "--inspect-brk=0.0.0.0:" + str(debug_port), - "--nolazy", - "--expose-gc", - "--max-semi-space-size=150", - "--max-old-space-size=2707", - "/var/runtime/node_modules/awslambda/index.js", - ], - Runtime.nodejs10x.value: [ - "/var/rapid/init", - "--bootstrap", - "/var/lang/bin/node", - "--bootstrap-args", - json.dumps( - debug_args_list - + [ - "--inspect-brk=0.0.0.0:" + str(debug_port), - "--nolazy", - "--expose-gc", - "--max-http-header-size", - "81920", - "/var/runtime/index.js", - ] - ), - ], - Runtime.nodejs12x.value: [ - "/var/rapid/init", - "--bootstrap", - "/var/lang/bin/node", - "--bootstrap-args", - json.dumps( - debug_args_list - + [ - "--inspect-brk=0.0.0.0:" + str(debug_port), - "--nolazy", - "--expose-gc", - "--max-http-header-size", - "81920", - "/var/runtime/index.js", - ] - ), - ], - Runtime.python27.value: ["/usr/bin/python2.7"] + debug_args_list + ["/var/runtime/awslambda/bootstrap.py"], - Runtime.python36.value: ["/var/lang/bin/python3.6"] - + debug_args_list - + ["/var/runtime/awslambda/bootstrap.py"], - Runtime.python37.value: [ - "/var/rapid/init", - "--bootstrap", - "/var/lang/bin/python3.7", - "--bootstrap-args", - json.dumps(debug_args_list + ["/var/runtime/bootstrap"]), - ], - Runtime.python38.value: [ - "/var/rapid/init", - "--bootstrap", - "/var/lang/bin/python3.8", - "--bootstrap-args", - json.dumps(debug_args_list + ["/var/runtime/bootstrap"]), - ], - } - try: - return entrypoint_mapping[runtime] - except KeyError: - raise DebuggingNotSupported("Debugging is not currently supported for {}".format(runtime)) diff --git a/samcli/local/docker/lambda_debug_settings.py b/samcli/local/docker/lambda_debug_settings.py new file mode 100644 index 0000000000..2eb53e058f --- /dev/null +++ b/samcli/local/docker/lambda_debug_settings.py @@ -0,0 +1,217 @@ +""" +Represents Lambda debug entrypoints. +""" + +import json +from collections import namedtuple + +from samcli.local.docker.lambda_image import Runtime + + +class DebuggingNotSupported(Exception): + pass + + +DebugSettings = namedtuple("DebugSettings", ["entrypoint", "debug_env_vars"]) + + +class LambdaDebugSettings: + @staticmethod + def get_debug_settings(debug_port, debug_args_list, runtime, options): + """ + Get Debug settings based on the Runtime + + Parameters + ---------- + debug_port int + Port to open for debugging in the container + debug_args_list list(str) + Additional debug args + runtime str + Lambda Function runtime + options dict + Additonal options needed (i.e delve Path) + + Returns + ------- + tuple:DebugSettings (list, dict) + Tuple of debug entrypoint and debug env vars + + """ + + entrypoint_mapping = { + Runtime.java8.value: DebugSettings( + entrypoint=["/usr/bin/java"] + + debug_args_list + + [ + "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,quiet=y,address=" + str(debug_port), + "-XX:MaxHeapSize=2834432k", + "-XX:MaxMetaspaceSize=163840k", + "-XX:ReservedCodeCacheSize=81920k", + "-XX:+UseSerialGC", + # "-Xshare:on", doesn't work in conjunction with the debug options + "-XX:-TieredCompilation", + "-Djava.net.preferIPv4Stack=true", + "-jar", + "/var/runtime/lib/LambdaJavaRTEntry-1.0.jar", + ], + debug_env_vars={}, + ), + Runtime.java11.value: DebugSettings( + None, + debug_env_vars={ + "_JAVA_OPTIONS": f"-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,quiet=y,address=*:{debug_port} -XX:MaxHeapSize=2834432k -XX:MaxMetaspaceSize=163840k -XX:ReservedCodeCacheSize=81920k -XX:+UseSerialGC -XX:-TieredCompilation -Djava.net.preferIPv4Stack=true" + + " ".join(debug_args_list) + }, + ), + Runtime.dotnetcore20.value: DebugSettings( + ["/var/lang/bin/dotnet"] + + debug_args_list + + ["/var/runtime/MockBootstraps.dll", "--debugger-spin-wait"], + debug_env_vars={}, + ), + Runtime.dotnetcore21.value: DebugSettings( + ["/var/lang/bin/dotnet"] + + debug_args_list + + ["/var/runtime/MockBootstraps.dll", "--debugger-spin-wait"], + debug_env_vars={}, + ), + Runtime.go1x.value: DebugSettings( + ["/var/runtime/aws-lambda-go"] + + debug_args_list + + ["-debug=true", "-delvePort=" + str(debug_port), "-delvePath=" + options.get("delvePath")], + debug_env_vars={}, + ), + Runtime.nodejs.value: DebugSettings( + ["/usr/bin/node"] + + debug_args_list + + [ + "--debug-brk=" + str(debug_port), + "--nolazy", + "--max-old-space-size=1229", + "--max-new-space-size=153", + "--max-executable-size=153", + "--expose-gc", + "/var/runtime/node_modules/awslambda/bin/awslambda", + ], + debug_env_vars={}, + ), + Runtime.nodejs43.value: DebugSettings( + ["/usr/local/lib64/node-v4.3.x/bin/node"] + + debug_args_list + + [ + "--debug-brk=" + str(debug_port), + "--nolazy", + "--max-old-space-size=2547", + "--max-semi-space-size=150", + "--max-executable-size=160", + "--expose-gc", + "/var/runtime/node_modules/awslambda/index.js", + ], + debug_env_vars={}, + ), + Runtime.nodejs610.value: DebugSettings( + ["/var/lang/bin/node"] + + debug_args_list + + [ + "--debug-brk=" + str(debug_port), + "--nolazy", + "--max-old-space-size=2547", + "--max-semi-space-size=150", + "--max-executable-size=160", + "--expose-gc", + "/var/runtime/node_modules/awslambda/index.js", + ], + debug_env_vars={}, + ), + Runtime.nodejs810.value: DebugSettings( + ["/var/lang/bin/node"] + + debug_args_list + + [ + # Node8 requires the host to be explicitly set in order to bind to localhost + # instead of 127.0.0.1. https://github.com/nodejs/node/issues/11591#issuecomment-283110138 + "--inspect-brk=0.0.0.0:" + str(debug_port), + "--nolazy", + "--expose-gc", + "--max-semi-space-size=150", + "--max-old-space-size=2707", + "/var/runtime/node_modules/awslambda/index.js", + ], + debug_env_vars={}, + ), + Runtime.nodejs10x.value: DebugSettings( + [ + "/var/rapid/init", + "--bootstrap", + "/var/lang/bin/node", + "--bootstrap-args", + json.dumps( + debug_args_list + + [ + "--inspect-brk=0.0.0.0:" + str(debug_port), + "--nolazy", + "--expose-gc", + "--max-http-header-size", + "81920", + "/var/runtime/index.js", + ] + ), + ], + debug_env_vars={ + "NODE_PATH": "/opt/nodejs/node_modules:/opt/nodejs/node10/node_modules:/var/runtime/node_modules" + }, + ), + Runtime.nodejs12x.value: DebugSettings( + [ + "/var/rapid/init", + "--bootstrap", + "/var/lang/bin/node", + "--bootstrap-args", + json.dumps( + debug_args_list + + [ + "--inspect-brk=0.0.0.0:" + str(debug_port), + "--nolazy", + "--expose-gc", + "--max-http-header-size", + "81920", + "/var/runtime/index.js", + ] + ), + ], + debug_env_vars={ + "NODE_PATH": "/opt/nodejs/node_modules:/opt/nodejs/node12/node_modules:/var/runtime/node_modules" + }, + ), + Runtime.python27.value: DebugSettings( + ["/usr/bin/python2.7"] + debug_args_list + ["/var/runtime/awslambda/bootstrap.py"], debug_env_vars={} + ), + Runtime.python36.value: DebugSettings( + ["/var/lang/bin/python3.6"] + debug_args_list + ["/var/runtime/awslambda/bootstrap.py"], + debug_env_vars={}, + ), + Runtime.python37.value: DebugSettings( + [ + "/var/rapid/init", + "--bootstrap", + "/var/lang/bin/python3.7", + "--bootstrap-args", + json.dumps(debug_args_list + ["/var/runtime/bootstrap"]), + ], + debug_env_vars={}, + ), + Runtime.python38.value: DebugSettings( + [ + "/var/rapid/init", + "--bootstrap", + "/var/lang/bin/python3.8", + "--bootstrap-args", + json.dumps(debug_args_list + ["/var/runtime/bootstrap"]), + ], + debug_env_vars={}, + ), + } + try: + return entrypoint_mapping[runtime] + except KeyError: + raise DebuggingNotSupported("Debugging is not currently supported for {}".format(runtime)) diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/.gitignore b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/.gitignore deleted file mode 100644 index 74ea25e0e5..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/.gitignore +++ /dev/null @@ -1,168 +0,0 @@ - -# Created by https://www.gitignore.io/api/osx,linux,python,windows - -### Linux ### -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - -# .nfs files are created when an open file is removed but is still being accessed -.nfs* - -### OSX ### -*.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -### Python ### -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -.pytest_cache/ -nosetests.xml -coverage.xml -*.cover -.hypothesis/ - -# Translations -*.mo -*.pot - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule.* - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ - -### Windows ### -# Windows thumbnail cache files -Thumbs.db -ehthumbs.db -ehthumbs_vista.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# Windows shortcuts -*.lnk - - -# End of https://www.gitignore.io/api/osx,linux,python,windows \ No newline at end of file diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/LICENSE b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/LICENSE deleted file mode 100644 index 14aabc346a..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ -Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this -software and associated documentation files (the "Software"), to deal in the Software -without restriction, including without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/README.md b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/README.md deleted file mode 100644 index 4f15d02ce8..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Cookiecutter legacy NodeJS Hello-world for SAM based Serverless App - -A cookiecutter template to create a legacy NodeJS Hello world boilerplate using [Serverless Application Model (SAM)](https://github.com/awslabs/serverless-application-model). - -## Requirements - -* [AWS SAM CLI](https://github.com/awslabs/aws-sam-cli) - -## Usage - -Generate a boilerplate template in your current project directory using the following syntax: - -* **NodeJS 6**: `sam init --runtime nodejs6.10` - -> **NOTE**: ``--name`` allows you to specify a different project folder name (`sam-app` is the default) - -# Credits - -* This project has been generated with [Cookiecutter](https://github.com/audreyr/cookiecutter) diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/cookiecutter.json b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/cookiecutter.json deleted file mode 100644 index 14bfbdc74f..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/cookiecutter.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "project_name": "Name of the project", - "runtime": "nodejs6.10" -} \ No newline at end of file diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/setup.cfg b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/setup.cfg deleted file mode 100644 index 6302b3a02b..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[install] -prefix= \ No newline at end of file diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/.gitignore b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/.gitignore deleted file mode 100644 index eb1db5fbec..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/.gitignore +++ /dev/null @@ -1,129 +0,0 @@ - -# Created by https://www.gitignore.io/api/osx,node,linux,windows - -### Linux ### -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - -# .nfs files are created when an open file is removed but is still being accessed -.nfs* - -### Node ### -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Typescript v1 declaration files -typings/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env - - -### OSX ### -*.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -### Windows ### -# Windows thumbnail cache files -Thumbs.db -ehthumbs.db -ehthumbs_vista.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# Windows shortcuts -*.lnk - - -# End of https://www.gitignore.io/api/osx,node,linux,windows \ No newline at end of file diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/README.md b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/README.md deleted file mode 100644 index 2bf44aa835..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/README.md +++ /dev/null @@ -1,211 +0,0 @@ -# {{ cookiecutter.project_name }} - -This is a sample template for {{ cookiecutter.project_name }} - Below is a brief explanation of what we have generated for you: - -```bash -. -├── README.MD <-- This instructions file -├── event.json <-- API Gateway Proxy Integration event payload -├── hello-world <-- Source code for a lambda function -│ └── app.js <-- Lambda function code -│ └── package.json <-- NodeJS dependencies and scripts -│ └── app-deps.js <-- Lambda function code with dependencies (Bringing to the next level section) -│ └── tests <-- Unit tests -│ └── unit -│ └── test-handler.js -├── template.yaml <-- SAM template -``` - -## Requirements - -* AWS CLI already configured with Administrator permission -* [{{ cookiecutter.runtime }} installed](https://nodejs.org/en/download/releases/) -* [Docker installed](https://www.docker.com/community-edition) - -## Setup process - -### Local development - -**Invoking function locally using a local sample payload** - -```bash -sam local invoke HelloWorldFunction --event event.json -``` - -**Invoking function locally through local API Gateway** - -```bash -sam local start-api -``` - -If the previous command ran successfully you should now be able to hit the following local endpoint to invoke your function `http://localhost:3000/hello` - -**SAM CLI** is used to emulate both Lambda and API Gateway locally and uses our `template.yaml` to understand how to bootstrap this environment (runtime, where the source code is, etc.) - The following excerpt is what the CLI will read in order to initialize an API and its routes: - -```yaml -... -Events: - HelloWorld: - Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api - Properties: - Path: /hello - Method: get -``` - -## Packaging and deployment - -AWS Lambda NodeJS runtime requires a flat folder with all dependencies including the application. SAM will use `CodeUri` property to know where to look up for both application and dependencies: - -```yaml -... - HelloWorldFunction: - Type: AWS::Serverless::Function - Properties: - CodeUri: hello-world/ - ... -``` - -Firstly, we need a `S3 bucket` where we can upload our Lambda functions packaged as ZIP before we deploy anything - If you don't have a S3 bucket to store code artifacts then this is a good time to create one: - -```bash -aws s3 mb s3://BUCKET_NAME -``` - -Next, run the following command to package our Lambda function to S3: - -```bash -sam package \ - --output-template-file packaged.yaml \ - --s3-bucket REPLACE_THIS_WITH_YOUR_S3_BUCKET_NAME -``` - -Next, the following command will create a Cloudformation Stack and deploy your SAM resources. - -```bash -sam deploy \ - --template-file packaged.yaml \ - --stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} \ - --capabilities CAPABILITY_IAM -``` - -> **See [Serverless Application Model (SAM) HOWTO Guide](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-quick-start.html) for more details in how to get started.** - -After deployment is complete you can run the following command to retrieve the API Gateway Endpoint URL: - -```bash -aws cloudformation describe-stacks \ - --stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} \ - --query 'Stacks[].Outputs[?OutputKey==`HelloWorldApi`]' \ - --output table -``` - -## Fetch, tail, and filter Lambda function logs - -To simplify troubleshooting, SAM CLI has a command called sam logs. sam logs lets you fetch logs generated by your Lambda function from the command line. In addition to printing the logs on the terminal, this command has several nifty features to help you quickly find the bug. - -`NOTE`: This command works for all AWS Lambda functions; not just the ones you deploy using SAM. - -```bash -sam logs -n HelloWorldFunction --stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} --tail -``` - -You can find more information and examples about filtering Lambda function logs in the [SAM CLI Documentation](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html). - -## Testing - -We use `mocha` for testing our code and it is already added in `package.json` under `scripts`, so that we can simply run the following command to run our tests: - -```bash -cd hello-world -npm install -npm run test -``` - -## Cleanup - -In order to delete our Serverless Application recently deployed you can use the following AWS CLI Command: - -```bash -aws cloudformation delete-stack --stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} -``` - -## Bringing to the next level - -Here are a few things you can try to get more acquainted with building serverless applications using SAM: - -### Learn how SAM Build can help you with dependencies - -* Delete `hello-world/app.js` -* Rename `hello-world/app-deps.js` to `hello-world/app.js` -* Build the project with ``sam build --use-container`` -* Invoke with ``sam local invoke HelloWorldFunction --event event.json`` -* Update tests - -### Create an additional API resource - -* Create a catch all resource (e.g. /hello/{proxy+}) and return the name requested through this new path -* Update tests - -### Step-through debugging - -* **[Enable step-through debugging docs for supported runtimes]((https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-debugging.html))** - -Next, you can use AWS Serverless Application Repository to deploy ready to use Apps that go beyond hello world samples and learn how authors developed their applications: [AWS Serverless Application Repository main page](https://aws.amazon.com/serverless/serverlessrepo/) - -# Appendix - -### Building the project - -[AWS Lambda requires a flat folder](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-create-deployment-pkg.html) with the application as well as its dependencies in a node_modules folder. When you make changes to your source code or dependency manifest, -run the following command to build your project local testing and deployment: - -```bash -sam build -``` - -If your dependencies contain native modules that need to be compiled specifically for the operating system running on AWS Lambda, use this command to build inside a Lambda-like Docker container instead: -```bash -sam build --use-container -``` - -By default, this command writes built artifacts to `.aws-sam/build` folder. - -## SAM and AWS CLI commands - -All commands used throughout this document - -```bash -# Generate event.json via generate-event command -sam local generate-event apigateway aws-proxy > event.json - -# Invoke function locally with event.json as an input -sam local invoke HelloWorldFunction --event event.json - -# Run API Gateway locally -sam local start-api - -# Create S3 bucket -aws s3 mb s3://BUCKET_NAME - -# Package Lambda function defined locally and upload to S3 as an artifact -sam package \ - --output-template-file packaged.yaml \ - --s3-bucket REPLACE_THIS_WITH_YOUR_S3_BUCKET_NAME - -# Deploy SAM template as a CloudFormation stack -sam deploy \ - --template-file packaged.yaml \ - --stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} \ - --capabilities CAPABILITY_IAM - -# Describe Output section of CloudFormation stack previously created -aws cloudformation describe-stacks \ - --stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} \ - --query 'Stacks[].Outputs[?OutputKey==`HelloWorldApi`]' \ - --output table - -# Tail Lambda function Logs using Logical name defined in SAM Template -sam logs -n HelloWorldFunction --stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} --tail -``` - -**NOTE**: Alternatively this could be part of package.json scripts section. diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/event.json b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/event.json deleted file mode 100644 index 070ad8e018..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/event.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "body": "{\"message\": \"hello world\"}", - "resource": "/{proxy+}", - "path": "/path/to/resource", - "httpMethod": "POST", - "isBase64Encoded": false, - "queryStringParameters": { - "foo": "bar" - }, - "pathParameters": { - "proxy": "/path/to/resource" - }, - "stageVariables": { - "baz": "qux" - }, - "headers": { - "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", - "Accept-Encoding": "gzip, deflate, sdch", - "Accept-Language": "en-US,en;q=0.8", - "Cache-Control": "max-age=0", - "CloudFront-Forwarded-Proto": "https", - "CloudFront-Is-Desktop-Viewer": "true", - "CloudFront-Is-Mobile-Viewer": "false", - "CloudFront-Is-SmartTV-Viewer": "false", - "CloudFront-Is-Tablet-Viewer": "false", - "CloudFront-Viewer-Country": "US", - "Host": "1234567890.execute-api.us-east-1.amazonaws.com", - "Upgrade-Insecure-Requests": "1", - "User-Agent": "Custom User Agent String", - "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", - "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", - "X-Forwarded-For": "127.0.0.1, 127.0.0.2", - "X-Forwarded-Port": "443", - "X-Forwarded-Proto": "https" - }, - "requestContext": { - "accountId": "123456789012", - "resourceId": "123456", - "stage": "prod", - "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", - "requestTime": "09/Apr/2015:12:34:56 +0000", - "requestTimeEpoch": 1428582896000, - "identity": { - "cognitoIdentityPoolId": null, - "accountId": null, - "cognitoIdentityId": null, - "caller": null, - "accessKey": null, - "sourceIp": "127.0.0.1", - "cognitoAuthenticationType": null, - "cognitoAuthenticationProvider": null, - "userArn": null, - "userAgent": "Custom User Agent String", - "user": null - }, - "path": "/prod/path/to/resource", - "resourcePath": "/{proxy+}", - "httpMethod": "POST", - "apiId": "1234567890", - "protocol": "HTTP/1.1" - } -} diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/.npmignore b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/.npmignore deleted file mode 100644 index e7e1fb04f4..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/.npmignore +++ /dev/null @@ -1 +0,0 @@ -tests/* diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/app-deps.js b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/app-deps.js deleted file mode 100644 index fb7470c3ae..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/app-deps.js +++ /dev/null @@ -1,34 +0,0 @@ -var axios = require('axios') -var url = 'http://checkip.amazonaws.com/'; -var response; - - -/** - * - * Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format - * @param {Object} event - API Gateway Lambda Proxy Input Format - * - * Context doc: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html - * @param {Object} context - * - * Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html - * @returns {Object} object - API Gateway Lambda Proxy Output Format - * - */ -exports.lambdaHandler = function (event, context, callback) { - axios(url) - .then(function (ret) { - response = { - 'statusCode': 200, - 'body': JSON.stringify({ - message: 'hello world', - location: ret.data.trim() - }) - } - callback(null, response); - }) - .catch(function (err) { - console.log(err); - callback(err); - }); -}; diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/app.js b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/app.js deleted file mode 100644 index cae4cec9a5..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/app.js +++ /dev/null @@ -1,23 +0,0 @@ - -/** - * - * Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format - * @param {Object} event - API Gateway Lambda Proxy Input Format - * - * Context doc: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html - * @param {Object} context - * - * Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html - * @returns {Object} object - API Gateway Lambda Proxy Output Format - * - */ -exports.lambdaHandler = function (event, context, callback) { - var response = { - statusCode: 200, - body: JSON.stringify({ - message: 'hello world' - }) - } - - callback(null, response); -}; diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/package.json b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/package.json deleted file mode 100644 index 80086fd6db..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "hello_world", - "version": "1.0.0", - "description": "hello world sample for NodeJS", - "main": "app.js", - "repository": "https://github.com/awslabs/aws-sam-cli/tree/develop/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs-legacy", - "author": "SAM CLI", - "license": "MIT", - "dependencies": { - "axios": "^0.18.0" - }, - "scripts": { - "test": "mocha tests/unit/" - }, - "devDependencies": { - "chai": "^4.1.2", - "mocha": "^5.1.1" - } -} diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/tests/unit/test-handler.js b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/tests/unit/test-handler.js deleted file mode 100644 index 19b617b9af..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/hello-world/tests/unit/test-handler.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; - -const app = require('../../app.js'); -const chai = require('chai'); -const expect = chai.expect; -var event, context; - -describe('Tests Handler', function () { - it('verifies successful response', function (done) { - app.lambdaHandler(event, context, function (err, result) { - try { - expect(result).to.be.an('object'); - expect(result.statusCode).to.equal(200); - expect(result.body).to.be.an('string'); - - let response = JSON.parse(result.body); - - expect(response).to.be.an('object'); - expect(response.message).to.be.equal("hello world"); - // expect(response.location).to.be.an("string"); - done(); - } catch (e) { - done(e); - } - }); - }); -}); diff --git a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/template.yaml b/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/template.yaml deleted file mode 100644 index 861221a315..0000000000 --- a/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs6/{{cookiecutter.project_name}}/template.yaml +++ /dev/null @@ -1,39 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: AWS::Serverless-2016-10-31 -Description: > - {{ cookiecutter.project_name }} - - Sample SAM Template for {{ cookiecutter.project_name }} - -# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst -Globals: - Function: - Timeout: 3 - -Resources: - HelloWorldFunction: - Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction - Properties: - CodeUri: hello-world/ - Handler: app.lambdaHandler - Runtime: {{ cookiecutter.runtime }} - Events: - HelloWorld: - Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api - Properties: - Path: /hello - Method: get - -Outputs: - # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function - # Find out more about other implicit resources you can reference within SAM - # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api - HelloWorldApi: - Description: "API Gateway endpoint URL for Prod stage for Hello World function" - Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" - HelloWorldFunction: - Description: "Hello World Lambda Function ARN" - Value: !GetAtt HelloWorldFunction.Arn - HelloWorldFunctionIamRole: - Description: "Implicit IAM Role created for Hello World function" - Value: !GetAtt HelloWorldFunctionRole.Arn diff --git a/samcli/local/services/base_local_service.py b/samcli/local/services/base_local_service.py index 0bdfd682b8..d518c9c5fc 100644 --- a/samcli/local/services/base_local_service.py +++ b/samcli/local/services/base_local_service.py @@ -150,15 +150,14 @@ def is_lambda_error_response(lambda_response): # This is a best effort attempt to determine if the output (lambda_response) from the container was an # Error/Exception that was raised/returned/thrown from the container. To ensure minimal false positives in - # this checking, we check for all three keys that can occur in Lambda raised/thrown/returned an + # this checking, we check for all the keys that can occur in Lambda raised/thrown/returned an # Error/Exception. This still risks false positives when the data returned matches exactly a dictionary with - # the keys 'errorMessage', 'errorType' and 'stackTrace'. + # the keys 'errorMessage' and 'errorType'. if ( isinstance(lambda_response_dict, dict) - and len(lambda_response_dict) == 3 + and len(lambda_response_dict) in [2, 3] and "errorMessage" in lambda_response_dict and "errorType" in lambda_response_dict - and "stackTrace" in lambda_response_dict ): is_lambda_user_error_response = True except ValueError: diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index 13e37aebb5..133f20c5d9 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -14,7 +14,7 @@ LOG = logging.getLogger(__name__) -TIMEOUT = 300 +TIMEOUT = 420 # 7 mins @skipIf( diff --git a/tests/integration/deploy/test_deploy_command.py b/tests/integration/deploy/test_deploy_command.py index b7e5c64fa0..6582fea5de 100644 --- a/tests/integration/deploy/test_deploy_command.py +++ b/tests/integration/deploy/test_deploy_command.py @@ -283,6 +283,7 @@ def test_deploy_with_s3_bucket_switch_region(self, template_file): template_path = self.test_data_path.joinpath(template_file) stack_name = "a" + str(uuid.uuid4()).replace("-", "")[:10] + self.stack_names.append(stack_name) # Package and Deploy in one go without confirming change set. deploy_command_list = self.get_deploy_command_list( @@ -349,6 +350,7 @@ def test_deploy_twice_with_no_fail_on_empty_changeset(self, template_file): template_path = self.test_data_path.joinpath(template_file) stack_name = "a" + str(uuid.uuid4()).replace("-", "")[:10] + self.stack_names.append(stack_name) kwargs = { "template_file": template_path, @@ -395,6 +397,7 @@ def test_deploy_twice_with_fail_on_empty_changeset(self, template_file): template_path = self.test_data_path.joinpath(template_file) stack_name = "a" + str(uuid.uuid4()).replace("-", "")[:10] + self.stack_names.append(stack_name) # Package and Deploy in one go without confirming change set. kwargs = { @@ -436,6 +439,25 @@ def test_deploy_twice_with_fail_on_empty_changeset(self, template_file): stderr = stderr.strip() self.assertIn(bytes(f"Error: No changes to deploy. Stack {stack_name} is up to date", encoding="utf-8"), stderr) + @parameterized.expand(["aws-serverless-inline.yaml"]) + def test_deploy_inline_no_package(self, template_file): + template_path = self.test_data_path.joinpath(template_file) + stack_name = "a" + str(uuid.uuid4()).replace("-", "")[:10] + self.stack_names.append(stack_name) + + deploy_command_list = self.get_deploy_command_list( + template_file=template_path, stack_name=stack_name, capabilities="CAPABILITY_IAM" + ) + deploy_process_execute = Popen(deploy_command_list, stdout=PIPE, stderr=PIPE, stdin=PIPE) + try: + _, stderr = deploy_process_execute.communicate(timeout=TIMEOUT) + except TimeoutExpired: + deploy_process_execute.kill() + raise + stderr = stderr.strip() + print(stderr) + self.assertEqual(deploy_process_execute.returncode, 0) + @parameterized.expand(["aws-serverless-function.yaml"]) def test_deploy_guided(self, template_file): template_path = self.test_data_path.joinpath(template_file) diff --git a/tests/integration/init/schemas/test_init_with_schemas_command.py b/tests/integration/init/schemas/test_init_with_schemas_command.py index 02ba9c60b8..cecc0e6b7b 100644 --- a/tests/integration/init/schemas/test_init_with_schemas_command.py +++ b/tests/integration/init/schemas/test_init_with_schemas_command.py @@ -18,7 +18,7 @@ class TestBasicInitWithEventBridgeCommand(SchemaTestDataSetup): def test_init_interactive_with_event_bridge_app_aws_registry(self): # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates - # 13: Java runtime + # 12: Java runtime # 1: dependency manager maven # eb-app-maven: response to name # N: clone/update the source repo @@ -29,7 +29,7 @@ def test_init_interactive_with_event_bridge_app_aws_registry(self): user_input = """ 1 -13 +12 1 eb-app-maven N @@ -54,7 +54,7 @@ def test_init_interactive_with_event_bridge_app_partner_registry(self): # setup schema data # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates - # 13: Java Runtime + # 12: Java Runtime # 1: dependency manager maven # eb-app-maven: response to name # N: clone/update the source repo @@ -65,7 +65,7 @@ def test_init_interactive_with_event_bridge_app_partner_registry(self): user_input = """ 1 -13 +12 1 eb-app-maven N @@ -101,7 +101,7 @@ def test_init_interactive_with_event_bridge_app_partner_registry(self): def test_init_interactive_with_event_bridge_app_pagination(self): # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates - # 13: Java Runtime + # 12: Java Runtime # 1: dependency manager maven # eb-app-maven: response to name # N: clone/update the source repo @@ -114,7 +114,7 @@ def test_init_interactive_with_event_bridge_app_pagination(self): user_input = """ 1 -13 +12 1 eb-app-maven N @@ -141,7 +141,7 @@ def test_init_interactive_with_event_bridge_app_pagination(self): def test_init_interactive_with_event_bridge_app_customer_registry(self): # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates - # 13: Java Runtime + # 12: Java Runtime # 1: dependency manager maven # eb-app-maven: response to name # N: lone/update the source repo @@ -152,7 +152,7 @@ def test_init_interactive_with_event_bridge_app_customer_registry(self): user_input = """ 1 -13 +12 1 eb-app-maven N @@ -188,7 +188,7 @@ def test_init_interactive_with_event_bridge_app_customer_registry(self): def test_init_interactive_with_event_bridge_app_aws_schemas_python(self): # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates - # 10: Python 3.7 + # 9: Python 3.7 # eb-app-maven: response to name # N: clone/update the source repo # 3: select event-bridge app from scratch @@ -198,7 +198,7 @@ def test_init_interactive_with_event_bridge_app_aws_schemas_python(self): user_input = """ 1 -10 +9 eb-app-python37 N 3 @@ -220,7 +220,7 @@ def test_init_interactive_with_event_bridge_app_non_default_profile_selection(se self._init_custom_config("mynewprofile", "us-west-2") # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates - # 10: Python 3.7 + # 9: Python 3.7 # eb-app-maven: response to name # N: clone/update the source repo # 3: select event-bridge app from scratch @@ -232,7 +232,7 @@ def test_init_interactive_with_event_bridge_app_non_default_profile_selection(se user_input = """ 1 -10 +9 eb-app-python37 N 3 @@ -258,7 +258,7 @@ def test_init_interactive_with_event_bridge_app_non_supported_schemas_region(sel self._init_custom_config("default", "cn-north-1") # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates - # 10: Python 3.7 + # 9: Python 3.7 # eb-app-maven: response to name # N: clone/update the source repo # 3: select event-bridge app from scratch @@ -268,7 +268,7 @@ def test_init_interactive_with_event_bridge_app_non_supported_schemas_region(sel user_input = """ 1 -10 +9 eb-app-python37 N 3 diff --git a/tests/integration/testdata/package/aws-serverless-inline.yaml b/tests/integration/testdata/package/aws-serverless-inline.yaml new file mode 100644 index 0000000000..b21dbf817a --- /dev/null +++ b/tests/integration/testdata/package/aws-serverless-inline.yaml @@ -0,0 +1,14 @@ +AWSTemplateFormatVersion : '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: A function with inline code. + +Resources: + InlineCodeFunction: + Type: AWS::Serverless::Function + Properties: + InlineCode: | + def handler(event, context): + print(event) + return {'body': 'Hello World 2!', 'statusCode': 200} + Handler: index.handler + Runtime: python3.7 diff --git a/tests/unit/commands/local/invoke/test_cli.py b/tests/unit/commands/local/invoke/test_cli.py index 935532771f..b6564ee9cc 100644 --- a/tests/unit/commands/local/invoke/test_cli.py +++ b/tests/unit/commands/local/invoke/test_cli.py @@ -13,7 +13,7 @@ from samcli.commands.local.invoke.cli import do_cli as invoke_cli, _get_event as invoke_cli_get_event from samcli.commands.local.lib.exceptions import OverridesNotWellDefinedError from samcli.local.docker.manager import DockerImagePullFailedException -from samcli.local.docker.lambda_debug_entrypoint import DebuggingNotSupported +from samcli.local.docker.lambda_debug_settings import DebuggingNotSupported STDIN_FILE_NAME = "-" diff --git a/tests/unit/commands/local/lib/test_local_lambda.py b/tests/unit/commands/local/lib/test_local_lambda.py index 9a81491980..89b12209ec 100644 --- a/tests/unit/commands/local/lib/test_local_lambda.py +++ b/tests/unit/commands/local/lib/test_local_lambda.py @@ -144,7 +144,7 @@ def test_must_work_with_no_credentials(self, boto3_mock): boto3_mock.session.Session.return_value = mock_session mock_session.get_credentials.return_value = None - expected = {} + expected = {"region": mock_session.region_name} actual = self.local_lambda.get_aws_creds() self.assertEqual(expected, actual) diff --git a/tests/unit/commands/local/start_api/test_cli.py b/tests/unit/commands/local/start_api/test_cli.py index 830cdbee1e..9db57f8126 100644 --- a/tests/unit/commands/local/start_api/test_cli.py +++ b/tests/unit/commands/local/start_api/test_cli.py @@ -12,7 +12,7 @@ from samcli.commands.exceptions import UserException from samcli.commands.validate.lib.exceptions import InvalidSamDocumentException from samcli.commands.local.lib.exceptions import OverridesNotWellDefinedError -from samcli.local.docker.lambda_debug_entrypoint import DebuggingNotSupported +from samcli.local.docker.lambda_debug_settings import DebuggingNotSupported class TestCli(TestCase): diff --git a/tests/unit/commands/local/start_lambda/test_cli.py b/tests/unit/commands/local/start_lambda/test_cli.py index d34b5d1c09..fd33bcdce8 100644 --- a/tests/unit/commands/local/start_lambda/test_cli.py +++ b/tests/unit/commands/local/start_lambda/test_cli.py @@ -8,7 +8,7 @@ from samcli.commands.local.cli_common.user_exceptions import UserException from samcli.commands.validate.lib.exceptions import InvalidSamDocumentException from samcli.commands.local.lib.exceptions import OverridesNotWellDefinedError -from samcli.local.docker.lambda_debug_entrypoint import DebuggingNotSupported +from samcli.local.docker.lambda_debug_settings import DebuggingNotSupported class TestCli(TestCase): diff --git a/tests/unit/lib/bootstrap/test_bootstrap.py b/tests/unit/lib/bootstrap/test_bootstrap.py index 9c17c198f0..091b395e8b 100644 --- a/tests/unit/lib/bootstrap/test_bootstrap.py +++ b/tests/unit/lib/bootstrap/test_bootstrap.py @@ -13,7 +13,7 @@ class TestBootstrapManagedStack(TestCase): def _stubbed_cf_client(self): - cf = botocore.session.get_session().create_client("cloudformation") + cf = botocore.session.get_session().create_client("cloudformation", region_name="us-west-2") return [cf, Stubber(cf)] @patch("boto3.Session") diff --git a/tests/unit/lib/package/test_artifact_exporter.py b/tests/unit/lib/package/test_artifact_exporter.py index 236fc28d9b..41f8a54fd9 100644 --- a/tests/unit/lib/package/test_artifact_exporter.py +++ b/tests/unit/lib/package/test_artifact_exporter.py @@ -84,6 +84,17 @@ def test_all_resources_export(self): test["class"], uploaded_s3_url, upload_local_artifacts_mock, test["expected_result"] ) + def test_invalid_export_resource(self): + with patch("samcli.lib.package.artifact_exporter.upload_local_artifacts") as upload_local_artifacts_mock: + s3_uploader_mock = Mock() + upload_local_artifacts_mock.reset_mock() + resource_obj = ServerlessFunctionResource(uploader=s3_uploader_mock) + resource_id = "id" + resource_dict = {"InlineCode": "code"} + parent_dir = "dir" + resource_obj.export(resource_id, resource_dict, parent_dir) + upload_local_artifacts_mock.assert_not_called() + def _helper_verify_export_resources( self, test_class, uploaded_s3_url, upload_local_artifacts_mock, expected_result ): diff --git a/tests/unit/local/docker/test_lambda_container.py b/tests/unit/local/docker/test_lambda_container.py index c20eb1de43..5185cf8885 100644 --- a/tests/unit/local/docker/test_lambda_container.py +++ b/tests/unit/local/docker/test_lambda_container.py @@ -8,7 +8,7 @@ from samcli.commands.local.lib.debug_context import DebugContext from samcli.local.docker.lambda_container import LambdaContainer, Runtime -from samcli.local.docker.lambda_debug_entrypoint import DebuggingNotSupported +from samcli.local.docker.lambda_debug_settings import DebuggingNotSupported RUNTIMES_WITH_ENTRYPOINT = [ Runtime.java8.value, @@ -23,10 +23,18 @@ Runtime.python27.value, ] -RUNTIMES_WITH_BOOTSTRAP_ENTRYPOINT = [Runtime.nodejs10x.value, Runtime.python37.value] +RUNTIMES_WITH_BOOTSTRAP_ENTRYPOINT = [ + Runtime.nodejs10x.value, + Runtime.nodejs12x.value, + Runtime.python37.value, + Runtime.python38.value, +] + +RUNTIMES_WITH_DEBUG_ENV_VARS_ONLY = [Runtime.java11.value] +RUNTIMES_WITH_ENTRYPOINT_OVERRIDES = RUNTIMES_WITH_ENTRYPOINT + RUNTIMES_WITH_BOOTSTRAP_ENTRYPOINT -ALL_RUNTIMES = [r for r in Runtime] +ALL_RUNTIMES = [r.value for r in Runtime] class TestLambdaContainer_init(TestCase): @@ -40,14 +48,14 @@ def setUp(self): @patch.object(LambdaContainer, "_get_image") @patch.object(LambdaContainer, "_get_exposed_ports") - @patch.object(LambdaContainer, "_get_entry_point") + @patch.object(LambdaContainer, "_get_debug_settings") @patch.object(LambdaContainer, "_get_additional_options") @patch.object(LambdaContainer, "_get_additional_volumes") def test_must_configure_container_properly( self, get_additional_volumes_mock, get_additional_options_mock, - get_entry_point_mock, + get_debug_settings_mock, get_exposed_ports_mock, get_image_mock, ): @@ -56,14 +64,15 @@ def test_must_configure_container_properly( ports = {"a": "b"} addtl_options = {} addtl_volumes = {} - entry = [1, 2, 3] + debug_settings = ([1, 2, 3], {"a": "b"}) expected_cmd = [self.handler] get_image_mock.return_value = image get_exposed_ports_mock.return_value = ports - get_entry_point_mock.return_value = entry + get_debug_settings_mock.return_value = debug_settings get_additional_options_mock.return_value = addtl_options get_additional_volumes_mock.return_value = addtl_volumes + expected_env_vars = {**self.env_var, **debug_settings[1]} image_builder_mock = Mock() @@ -83,13 +92,13 @@ def test_must_configure_container_properly( self.assertEqual("/var/task", container._working_dir) self.assertEqual(self.code_dir, container._host_dir) self.assertEqual(ports, container._exposed_ports) - self.assertEqual(entry, container._entrypoint) - self.assertEqual(self.env_var, container._env_vars) + self.assertEqual(debug_settings[0], container._entrypoint) + self.assertEqual(expected_env_vars, container._env_vars) self.assertEqual(self.memory_mb, container._memory_limit_mb) get_image_mock.assert_called_with(image_builder_mock, self.runtime, []) get_exposed_ports_mock.assert_called_with(self.debug_options) - get_entry_point_mock.assert_called_with(self.runtime, self.debug_options) + get_debug_settings_mock.assert_called_with(self.runtime, self.debug_options) get_additional_options_mock.assert_called_with(self.runtime, self.debug_options) get_additional_volumes_mock.assert_called_with(self.debug_options) @@ -152,7 +161,7 @@ def test_must_return_lambci_image(self): self.assertEqual(LambdaContainer._get_image(image_builder, "foo", []), expected) -class TestLambdaContainer_get_entry_point(TestCase): +class TestLambdaContainer_get_debug_settings(TestCase): def setUp(self): self.debug_ports = [1235] @@ -160,19 +169,31 @@ def setUp(self): self.debug_options = DebugContext(debug_ports=[1235], debug_args="a=b c=d e=f") def test_must_skip_if_debug_port_is_not_specified(self): - self.assertIsNone( - LambdaContainer._get_entry_point("runtime", None), "Must not provide entrypoint if debug port is not given" + self.assertEquals( + (None, {}), + LambdaContainer._get_debug_settings("runtime", None), + "Must not provide entrypoint if debug port is not given", ) @parameterized.expand([param(r) for r in ALL_RUNTIMES]) def test_must_provide_entrypoint_for_certain_runtimes_only(self, runtime): - - if runtime in RUNTIMES_WITH_ENTRYPOINT: - result = LambdaContainer._get_entry_point(runtime, self.debug_options) + if runtime in RUNTIMES_WITH_ENTRYPOINT_OVERRIDES: + result, _ = LambdaContainer._get_debug_settings(runtime, self.debug_options) self.assertIsNotNone(result, "{} runtime must provide entrypoint".format(runtime)) + + elif runtime in RUNTIMES_WITH_DEBUG_ENV_VARS_ONLY: + result, _ = LambdaContainer._get_debug_settings(runtime, self.debug_options) + self.assertIsNone(result, "{} runtime must not override entrypoint".format(runtime)) + else: with self.assertRaises(DebuggingNotSupported): - LambdaContainer._get_entry_point(runtime, self.debug_options) + LambdaContainer._get_debug_settings(runtime, self.debug_options) + + @parameterized.expand([param(r) for r in RUNTIMES_WITH_DEBUG_ENV_VARS_ONLY]) + def test_must_provide_debug_env_vars(self, runtime): + _, debug_env_vars = LambdaContainer._get_debug_settings(runtime, self.debug_options) + + self.assertIsNotNone(debug_env_vars) @parameterized.expand([param(r) for r in set(RUNTIMES_WITH_ENTRYPOINT)]) def test_debug_arg_must_be_split_by_spaces_and_appended_to_entrypoint(self, runtime): @@ -180,7 +201,7 @@ def test_debug_arg_must_be_split_by_spaces_and_appended_to_entrypoint(self, runt Debug args list is appended starting at second position in the array """ expected_debug_args = ["a=b", "c=d", "e=f"] - result = LambdaContainer._get_entry_point(runtime, self.debug_options) + result, _ = LambdaContainer._get_debug_settings(runtime, self.debug_options) actual = result[1:4] self.assertEqual(actual, expected_debug_args) @@ -191,7 +212,7 @@ def test_debug_arg_must_be_split_by_spaces_and_appended_to_bootstrap_based_entry Debug args list is appended as arguments to bootstrap-args, which is past the fourth position in the array """ expected_debug_args = ["a=b", "c=d", "e=f"] - result = LambdaContainer._get_entry_point(runtime, self.debug_options) + result, _ = LambdaContainer._get_debug_settings(runtime, self.debug_options) actual = result[4:5][0] self.assertTrue(all(debug_arg in actual for debug_arg in expected_debug_args)) @@ -199,7 +220,7 @@ def test_debug_arg_must_be_split_by_spaces_and_appended_to_bootstrap_based_entry @parameterized.expand([param(r) for r in RUNTIMES_WITH_ENTRYPOINT]) def test_must_provide_entrypoint_even_without_debug_args(self, runtime): debug_options = DebugContext(debug_ports=[1235], debug_args=None) - result = LambdaContainer._get_entry_point(runtime, debug_options) + result, _ = LambdaContainer._get_debug_settings(runtime, debug_options) self.assertIsNotNone(result) diff --git a/tests/unit/local/services/test_base_local_service.py b/tests/unit/local/services/test_base_local_service.py index 8ba46c7aa2..bf7b9faec2 100644 --- a/tests/unit/local/services/test_base_local_service.py +++ b/tests/unit/local/services/test_base_local_service.py @@ -98,6 +98,7 @@ def test_get_lambda_output_extracts_response(self, test_case_name, stdout_data, param( '{"errorMessage": "has a message", "stackTrace": "has a stacktrace", "errorType": "has a type"}', True ), + param('{"errorMessage": "has a message", "errorType": "has a type"}', True), param( '{"error message": "has a message", "stack Trace": "has a stacktrace", "error Type": "has a type"}', False,