From 5df7a0cbf7b62a2a875fc3e28510704e7cd409f6 Mon Sep 17 00:00:00 2001 From: Jacob Fuss Date: Tue, 3 Jul 2018 06:49:31 -0700 Subject: [PATCH] Revert "feat(debugging): Support debugging Golang functions. (#495)" This reverts commit 9ae4b80313d094d3eded4c5ca61731481b36c950. The commit breaks functional and integ tests. Reverting to make develop buildable --- README.rst | 41 ---------- .../local/cli_common/invoke_context.py | 11 ++- samcli/commands/local/cli_common/options.py | 3 - samcli/commands/local/invoke/cli.py | 33 +++----- samcli/commands/local/lib/debug_context.py | 15 ---- samcli/commands/local/lib/local_lambda.py | 14 ++-- samcli/commands/local/start_api/cli.py | 29 ++----- samcli/local/docker/container.py | 13 +-- samcli/local/docker/lambda_container.py | 79 ++++--------------- samcli/local/lambdafn/runtime.py | 12 ++- .../local/cli_common/test_invoke_context.py | 16 ++-- tests/unit/commands/local/invoke/test_cli.py | 15 +--- .../commands/local/lib/test_local_lambda.py | 68 +++++++++------- .../unit/commands/local/start_api/test_cli.py | 14 +--- .../local/docker/test_lambda_container.py | 36 +++------ tests/unit/local/lambdafn/test_runtime.py | 23 ++++-- 16 files changed, 144 insertions(+), 278 deletions(-) delete mode 100644 samcli/commands/local/lib/debug_context.py diff --git a/README.rst b/README.rst index 046709e14d..0c0ee55fae 100644 --- a/README.rst +++ b/README.rst @@ -395,47 +395,6 @@ port to your host machine. issue `__ for updates. -Debugging Golang functions -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Golang function debugging is slightly different when compared to Node.JS, -Java, and Python. We require `delve `__ -as the debugger, and wrap your function with it at runtime. The debugger -is run in headless mode, listening on the debug port. - -You must compile `delve` to run in the container and provide its local path -via the `--debugger-path` argument. Build delve locally as follows: - -`GOARCH=amd64 GOOS=linux go build -o github.com/derekparker/delve/cmd/dlv` - -Then invoke `sam` similar to the following: - -`sam local start-api -d 5986 --debugger-path ` - -The following is an example launch configuration for Visual Studio Code to -attach to a debug session. - -.. code:: bash - - { - "version": "0.2.0", - "configurations": [ - { - "name": "Connect to Lambda container", - "type": "go", - "request": "launch", - "mode": "remote", - "remotePath": "", - "port": , - "host": "127.0.0.1", - "program": "${workspaceRoot}", - "env": {}, - "args": [], - }, - ] - } - - Passing Additional Runtime Debug Arguments ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/samcli/commands/local/cli_common/invoke_context.py b/samcli/commands/local/cli_common/invoke_context.py index 8c14f73296..489ed604cb 100644 --- a/samcli/commands/local/cli_common/invoke_context.py +++ b/samcli/commands/local/cli_common/invoke_context.py @@ -38,12 +38,13 @@ def __init__(self, template_file, function_identifier=None, env_vars_file=None, + debug_port=None, + debug_args=None, docker_volume_basedir=None, docker_network=None, log_file=None, skip_pull_image=None, - aws_profile=None, - debug_context=None): + aws_profile=None): """ Initialize the context @@ -62,12 +63,13 @@ def __init__(self, self._template_file = template_file self._function_identifier = function_identifier self._env_vars_file = env_vars_file + self._debug_port = debug_port + self._debug_args = debug_args self._docker_volume_basedir = docker_volume_basedir self._docker_network = docker_network self._log_file = log_file self._skip_pull_image = skip_pull_image self._aws_profile = aws_profile - self._debug_context = debug_context self._template_dict = None self._function_provider = None @@ -144,7 +146,8 @@ def local_lambda_runner(self): function_provider=self._function_provider, cwd=self.get_cwd(), env_vars_values=self._env_vars_value, - debug_context=self._debug_context, + debug_port=self._debug_port, + debug_args=self._debug_args, aws_profile=self._aws_profile) @property diff --git a/samcli/commands/local/cli_common/options.py b/samcli/commands/local/cli_common/options.py index 594172cf78..d75f28ed48 100644 --- a/samcli/commands/local/cli_common/options.py +++ b/samcli/commands/local/cli_common/options.py @@ -74,9 +74,6 @@ def invoke_common_options(f): "port on localhost.", envvar="SAM_DEBUG_PORT"), - click.option('--debugger-path', - help="Host path to a debugger that will be mounted into the Lambda container."), - click.option('--debug-args', help="Additional arguments to be passed to the debugger", envvar="DEBUGGER_ARGS"), diff --git a/samcli/commands/local/invoke/cli.py b/samcli/commands/local/invoke/cli.py index b782ff1fa2..0bb8ae6353 100644 --- a/samcli/commands/local/invoke/cli.py +++ b/samcli/commands/local/invoke/cli.py @@ -9,7 +9,6 @@ from samcli.commands.local.cli_common.options import invoke_common_options from samcli.commands.local.cli_common.user_exceptions import UserException from samcli.commands.local.cli_common.invoke_context import InvokeContext -from samcli.commands.local.lib.debug_context import DebugContext from samcli.local.lambdafn.exceptions import FunctionNotFound from samcli.commands.validate.lib.exceptions import InvalidSamDocumentException @@ -36,17 +35,17 @@ @cli_framework_options @click.argument('function_identifier', required=False) @pass_context -def cli(ctx, function_identifier, template, event, env_vars, debug_port, debug_args, debugger_path, - docker_volume_basedir, docker_network, log_file, skip_pull_image, profile): +def cli(ctx, function_identifier, template, event, env_vars, debug_port, debug_args, docker_volume_basedir, + docker_network, log_file, skip_pull_image, profile): # All logic must be implemented in the ``do_cli`` method. This helps with easy unit testing - do_cli(ctx, function_identifier, template, event, env_vars, debug_port, debug_args, debugger_path, - docker_volume_basedir, docker_network, log_file, skip_pull_image, profile) # pragma: no cover + do_cli(ctx, function_identifier, template, event, env_vars, debug_port, debug_args, docker_volume_basedir, + docker_network, log_file, skip_pull_image, profile) # pragma: no cover -def do_cli(ctx, function_identifier, template, event, env_vars, debug_port, debug_args, # pylint: disable=R0914 - debugger_path, docker_volume_basedir, docker_network, log_file, skip_pull_image, profile): +def do_cli(ctx, function_identifier, template, event, env_vars, debug_port, debug_args, docker_volume_basedir, + docker_network, log_file, skip_pull_image, profile): """ Implementation of the ``cli`` method, just separated out for unit testing purposes """ @@ -54,7 +53,7 @@ def do_cli(ctx, function_identifier, template, event, env_vars, debug_port, debu LOG.debug("local invoke command is called") event_data = _get_event(event) - debug_context = _get_debug_context(debug_port, debug_args, debugger_path) + # Pass all inputs to setup necessary context to invoke function locally. # Handler exception raised by the processor for invalid args and print errors try: @@ -62,12 +61,13 @@ def do_cli(ctx, function_identifier, template, event, env_vars, debug_port, debu with InvokeContext(template_file=template, function_identifier=function_identifier, env_vars_file=env_vars, + debug_port=debug_port, + debug_args=debug_args, docker_volume_basedir=docker_volume_basedir, docker_network=docker_network, log_file=log_file, skip_pull_image=skip_pull_image, - aws_profile=profile, - debug_context=debug_context) as context: + aws_profile=profile) as context: # Invoke the function context.local_lambda_runner.invoke(context.function_name, @@ -97,16 +97,3 @@ def _get_event(event_file_name): # accidentally closing a standard stream with click.open_file(event_file_name, 'r') as fp: return fp.read() - - -def _get_debug_context(debug_port, debug_args, debugger_path): - """ - Returns a debug context from debug options; Separated out for unit testing. - :param int debug_port: Container debug port - :param string debug_args: Extra debug arguments for process - :param string debugger_path: Path to debugger on host - :return DebugContext: - """ - if not debug_port or debug_args or debugger_path: - return None - return DebugContext(debug_port=debug_port, debug_args=debug_args, debugger_path=debugger_path) diff --git a/samcli/commands/local/lib/debug_context.py b/samcli/commands/local/lib/debug_context.py deleted file mode 100644 index d694f59b13..0000000000 --- a/samcli/commands/local/lib/debug_context.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -Information and debug options for a specific runtime. -""" - - -class DebugContext(object): - - def __init__(self, - debug_port=None, - debugger_path=None, - debug_args=None): - - self.debug_port = debug_port - self.debugger_path = debugger_path - self.debug_args = debug_args diff --git a/samcli/commands/local/lib/local_lambda.py b/samcli/commands/local/lib/local_lambda.py index ec6df73b00..2e7c9805e1 100644 --- a/samcli/commands/local/lib/local_lambda.py +++ b/samcli/commands/local/lib/local_lambda.py @@ -25,8 +25,10 @@ def __init__(self, function_provider, cwd, env_vars_values=None, - aws_profile=None, - debug_context=None): + debug_port=None, + debug_args=None, + aws_profile=None + ): """ Initializes the class @@ -44,8 +46,9 @@ def __init__(self, self.provider = function_provider self.cwd = cwd self.env_vars_values = env_vars_values or {} + self.debug_port = debug_port + self.debug_args = debug_args self.aws_profile = aws_profile - self.debug_context = debug_context def invoke(self, function_name, event, stdout=None, stderr=None): """ @@ -73,7 +76,8 @@ def invoke(self, function_name, event, stdout=None, stderr=None): config = self._get_invoke_config(function) # Invoke the function - self.local_runtime.invoke(config, event, debug_context=self.debug_context, stdout=stdout, stderr=stderr) + self.local_runtime.invoke(config, event, debug_port=self.debug_port, debug_args=self.debug_args, + stdout=stdout, stderr=stderr) def is_debugging(self): """ @@ -85,7 +89,7 @@ def is_debugging(self): True, if we are debugging the invoke ie. the Docker container will break into the debugger and wait for attach """ - return bool(self.debug_context) + return bool(self.debug_port) def _get_invoke_config(self, function): """ diff --git a/samcli/commands/local/start_api/cli.py b/samcli/commands/local/start_api/cli.py index 8834fd84e3..2cb4e88fe3 100644 --- a/samcli/commands/local/start_api/cli.py +++ b/samcli/commands/local/start_api/cli.py @@ -8,7 +8,6 @@ from samcli.cli.main import pass_context, common_options as cli_framework_options from samcli.commands.local.cli_common.options import invoke_common_options from samcli.commands.local.cli_common.invoke_context import InvokeContext -from samcli.commands.local.lib.debug_context import DebugContext from samcli.commands.local.lib.exceptions import NoApisDefined from samcli.commands.local.cli_common.user_exceptions import UserException from samcli.commands.local.lib.local_api_service import LocalApiService @@ -48,25 +47,23 @@ def cli(ctx, host, port, static_dir, # Common Options for Lambda Invoke - template, env_vars, debug_port, debug_args, debugger_path, docker_volume_basedir, + template, env_vars, debug_port, debug_args, docker_volume_basedir, docker_network, log_file, skip_pull_image, profile ): # All logic must be implemented in the ``do_cli`` method. This helps with easy unit testing - do_cli(ctx, host, port, static_dir, template, env_vars, debug_port, debug_args, debugger_path, - docker_volume_basedir, docker_network, log_file, skip_pull_image, profile) # pragma: no cover + do_cli(ctx, host, port, static_dir, template, env_vars, debug_port, debug_args, docker_volume_basedir, + docker_network, log_file, skip_pull_image, profile) # pragma: no cover def do_cli(ctx, host, port, static_dir, template, env_vars, debug_port, debug_args, # pylint: disable=R0914 - debugger_path, docker_volume_basedir, docker_network, log_file, skip_pull_image, profile): + docker_volume_basedir, docker_network, log_file, skip_pull_image, profile): """ Implementation of the ``cli`` method, just separated out for unit testing purposes """ LOG.debug("local start-api command is called") - debug_context = _get_debug_context(debug_port, debug_args, debugger_path) - # Pass all inputs to setup necessary context to invoke function locally. # Handler exception raised by the processor for invalid args and print errors @@ -74,12 +71,13 @@ def do_cli(ctx, host, port, static_dir, template, env_vars, debug_port, debug_ar with InvokeContext(template_file=template, function_identifier=None, # Don't scope to one particular function env_vars_file=env_vars, + debug_port=debug_port, + debug_args=debug_args, docker_volume_basedir=docker_volume_basedir, docker_network=docker_network, log_file=log_file, skip_pull_image=skip_pull_image, - aws_profile=profile, - debug_context=debug_context) as invoke_context: + aws_profile=profile) as invoke_context: service = LocalApiService(lambda_invoke_context=invoke_context, port=port, @@ -91,16 +89,3 @@ def do_cli(ctx, host, port, static_dir, template, env_vars, debug_port, debug_ar raise UserException("Template does not have any APIs connected to Lambda functions") except InvalidSamDocumentException as ex: raise UserException(str(ex)) - - -def _get_debug_context(debug_port, debug_args, debugger_path): - """ - Returns a debug context from debug options; Separated out for unit testing. - :param int debug_port: Container debug port - :param string debug_args: Extra debug arguments for process - :param string debugger_path: Path to debugger on host - :return DebugContext: - """ - if not debug_port or debug_args or debugger_path: - return None - return DebugContext(debug_port=debug_port, debug_args=debug_args, debugger_path=debugger_path) diff --git a/samcli/local/docker/container.py b/samcli/local/docker/container.py index 09b73ff773..aa2357c5d7 100644 --- a/samcli/local/docker/container.py +++ b/samcli/local/docker/container.py @@ -33,9 +33,7 @@ def __init__(self, exposed_ports=None, entrypoint=None, env_vars=None, - docker_client=None, - container_opts=None, - additional_volumes=None): + docker_client=None): """ Initializes the class with given configuration. This does not automatically create or run the container. @@ -59,8 +57,6 @@ def __init__(self, self._env_vars = env_vars self._memory_limit_mb = memory_limit_mb self._network_id = None - self._container_opts = container_opts - self._additional_volumes = additional_volumes # Use the given Docker client or create new one self.docker_client = docker_client or docker.from_env() @@ -98,12 +94,6 @@ def create(self): "tty": False } - if self._container_opts: - kwargs.update(self._container_opts) - - if self._additional_volumes: - kwargs["volumes"].update(self._additional_volumes) - if self._env_vars: kwargs["environment"] = self._env_vars @@ -130,6 +120,7 @@ def delete(self): """ Removes a container that was created earlier. """ + if not self.is_created(): LOG.debug("Container was not created. Skipping deletion") return diff --git a/samcli/local/docker/lambda_container.py b/samcli/local/docker/lambda_container.py index 0a758eb86c..ac397e93c8 100644 --- a/samcli/local/docker/lambda_container.py +++ b/samcli/local/docker/lambda_container.py @@ -37,7 +37,6 @@ class LambdaContainer(Container): _IMAGE_REPO_NAME = "lambci/lambda" _WORKING_DIR = "/var/task" - _DEFAULT_CONTAINER_DEBUG_PATH = "/tmp/lambci_debug_files/dlv" def __init__(self, runtime, @@ -45,7 +44,8 @@ def __init__(self, code_dir, memory_mb=128, env_vars=None, - debug_options=None): + debug_port=None, + debug_args=None): """ Initializes the class @@ -55,17 +55,16 @@ def __init__(self, to the container to execute :param int memory_mb: Optional. Max limit of memory in MegaBytes this Lambda function can use. :param dict env_vars: Optional. Dictionary containing environment variables passed to container - :param DebugContext debug_options: Optional. Contains container debugging info (port, debugger path) + :param int debug_port: Optional. Bind the runtime's debugger to this port + :param string debug_args: Optional. Extra arguments passed to the entry point to setup debugging """ if not Runtime.has_value(runtime): raise ValueError("Unsupported Lambda runtime {}".format(runtime)) image = LambdaContainer._get_image(runtime) - ports = LambdaContainer._get_exposed_ports(debug_options) - entry = LambdaContainer._get_entry_point(runtime, debug_options) - additional_options = LambdaContainer._get_additional_options(runtime, debug_options) - additional_volumes = LambdaContainer._get_additional_volumes(debug_options) + ports = LambdaContainer._get_exposed_ports(debug_port) + entry = LambdaContainer._get_entry_point(runtime, debug_port, debug_args) cmd = [handler] super(LambdaContainer, self).__init__(image, @@ -75,12 +74,10 @@ def __init__(self, memory_limit_mb=memory_mb, exposed_ports=ports, entrypoint=entry, - env_vars=env_vars, - container_opts=additional_options, - additional_volumes=additional_volumes) + env_vars=env_vars) @staticmethod - def _get_exposed_ports(debug_options): + def _get_exposed_ports(debug_port): """ Return Docker container port binding information. If a debug port is given, then we will ask Docker to bind to same port both inside and outside the container ie. Runtime process is started in debug mode with @@ -89,51 +86,12 @@ def _get_exposed_ports(debug_options): :param int debug_port: Optional, integer value of debug port :return dict: Dictionary containing port binding information. None, if debug_port was not given """ - if not debug_options: + if not debug_port: return None return { # container port : host port - debug_options.debug_port: debug_options.debug_port - } - - @staticmethod - def _get_additional_options(runtime, debug_options): - """ - Return additional Docker container options. Used by container debug mode to enable certain container - security options. - :param DebugContext debug_options: DebugContext for the runtime of the container. - :return dict: Dictionary containing additional arguments to be passed to container creation. - """ - if not debug_options: - return None - - opts = {} - - if runtime == Runtime.go1x.value: - # These options are required for delve to function properly inside a docker container on docker < 1.12 - # See https://github.com/moby/moby/issues/21051 - opts["security_opt"] = ["seccomp:unconfined"] - opts["cap_add"] = ["SYS_PTRACE"] - - return opts - - @staticmethod - def _get_additional_volumes(debug_options): - """ - Return additional volumes to be mounted in the Docker container. Used by container debug for mapping - debugger executable into the container. - :param DebugContext debug_options: DebugContext for the runtime of the container. - :return dict: Dictionary containing volume map passed to container creation. - """ - if not debug_options.debugger_path: - return None - - return { - debug_options.debugger_path: { - "bind": "/tmp/lambci_debug_files", - "mode": "ro" - } + debug_port: debug_port } @staticmethod @@ -147,7 +105,7 @@ def _get_image(runtime): return "{}:{}".format(LambdaContainer._IMAGE_REPO_NAME, runtime) @staticmethod - def _get_entry_point(runtime, debug_options=None): + def _get_entry_point(runtime, debug_port=None, debug_args=None): """ 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 @@ -160,13 +118,12 @@ def _get_entry_point(runtime, debug_options=None): ie. if command is ``node index.js arg1 arg2``, then this list will be ["node", "index.js", "arg1", "arg2"] """ - if not debug_options: + if not debug_port: return None - debug_port = debug_options.debug_port debug_args_list = [] - if debug_options.debug_args: - debug_args_list = debug_options.debug_args.split(" ") + if debug_args: + debug_args_list = debug_args.split(" ") # configs from: https://github.com/lambci/docker-lambda # to which we add the extra debug mode options @@ -188,14 +145,6 @@ def _get_entry_point(runtime, debug_options=None): "/var/runtime/lib/LambdaJavaRTEntry-1.0.jar", ] - elif runtime == Runtime.go1x.value: - entrypoint = ["/var/runtime/aws-lambda-go"] \ - + [ - "-debug=true", - "-delvePort=" + str(debug_port), - "-delvePath=" + LambdaContainer._DEFAULT_CONTAINER_DEBUG_PATH, - ] - elif runtime == Runtime.nodejs.value: entrypoint = ["/usr/bin/node"] \ diff --git a/samcli/local/lambdafn/runtime.py b/samcli/local/lambdafn/runtime.py index 4f55134aab..d62188005c 100644 --- a/samcli/local/lambdafn/runtime.py +++ b/samcli/local/lambdafn/runtime.py @@ -37,7 +37,8 @@ def __init__(self, container_manager): def invoke(self, function_config, event, - debug_context=None, + debug_port=None, + debug_args=None, stdout=None, stderr=None): """ @@ -52,7 +53,8 @@ def invoke(self, :param FunctionConfig function_config: Configuration of the function to invoke :param event: String input event passed to Lambda function - :param DebugContext debug_context: Debugging context for the function (includes port, args, and path) + :param integer debug_port: Optional, port to attach debugger to + :param string debug_args: Optional, additional args to pass to debugger :param io.IOBase stdout: Optional. IO Stream to that receives stdout text from container. :param io.IOBase stderr: Optional. IO Stream that receives stderr text from container :raises Keyboard @@ -66,12 +68,14 @@ def invoke(self, env_vars = environ.resolve() with self._get_code_dir(function_config.code_abs_path) as code_dir: + container = LambdaContainer(function_config.runtime, function_config.handler, code_dir, memory_mb=function_config.memory, env_vars=env_vars, - debug_options=debug_context) + debug_port=debug_port, + debug_args=debug_args) try: @@ -86,7 +90,7 @@ def invoke(self, timer = self._configure_interrupt(function_config.name, function_config.timeout, container, - bool(debug_context)) + bool(debug_port)) # NOTE: BLOCKING METHOD # Block the thread waiting to fetch logs from the container. This method will return after container diff --git a/tests/unit/commands/local/cli_common/test_invoke_context.py b/tests/unit/commands/local/cli_common/test_invoke_context.py index 37a547399e..d0d8d9c34d 100644 --- a/tests/unit/commands/local/cli_common/test_invoke_context.py +++ b/tests/unit/commands/local/cli_common/test_invoke_context.py @@ -32,12 +32,13 @@ def test_must_read_from_necessary_files(self, SamFunctionProviderMock): invoke_context = InvokeContext(template_file=template_file, function_identifier="id", env_vars_file=env_vars_file, + debug_port=123, + debug_args="args", docker_volume_basedir="volumedir", docker_network="network", log_file=log_file, skip_pull_image=True, - aws_profile="profile", - debug_context=None) + aws_profile="profile") template_dict = "template_dict" invoke_context._get_template_data = Mock() @@ -104,12 +105,13 @@ def test_must_work_in_with_statement(self, ExitMock, EnterMock): with InvokeContext(template_file="template_file", function_identifier="id", env_vars_file="env_vars_file", + debug_port=123, + debug_args="args", docker_volume_basedir="volumedir", docker_network="network", log_file="log_file", skip_pull_image=True, - aws_profile="profile", - debug_context=None) as context: + aws_profile="profile") as context: self.assertEquals(context_obj, context) EnterMock.assert_called_with() @@ -150,7 +152,8 @@ def setUp(self): self.context = InvokeContext(template_file="template_file", function_identifier="id", env_vars_file="env_vars_file", - debug_context=None, + debug_port=123, + debug_args="args", docker_volume_basedir="volumedir", docker_network="network", log_file="log_file", @@ -184,8 +187,9 @@ def test_must_create_runner(self, LocalLambdaMock, LambdaRuntimeMock, ContainerM LocalLambdaMock.assert_called_with(local_runtime=runtime_mock, function_provider=ANY, cwd=cwd, - debug_context=None, env_vars_values=ANY, + debug_port=123, + debug_args="args", aws_profile="profile") diff --git a/tests/unit/commands/local/invoke/test_cli.py b/tests/unit/commands/local/invoke/test_cli.py index 995e6d8662..e635ef95ff 100644 --- a/tests/unit/commands/local/invoke/test_cli.py +++ b/tests/unit/commands/local/invoke/test_cli.py @@ -6,7 +6,6 @@ from mock import patch, Mock from parameterized import parameterized, param -from samcli.commands.local.lib.debug_context import DebugContext from samcli.local.lambdafn.exceptions import FunctionNotFound from samcli.commands.validate.lib.exceptions import InvalidSamDocumentException from samcli.commands.local.cli_common.user_exceptions import UserException @@ -22,7 +21,6 @@ def setUp(self): self.env_vars = "env-vars" self.debug_port = 123 self.debug_args = "args" - self.debugger_path = "/test/path" self.docker_volume_basedir = "basedir" self.docker_network = "network" self.log_file = "logfile" @@ -31,15 +29,10 @@ def setUp(self): @patch("samcli.commands.local.invoke.cli.InvokeContext") @patch("samcli.commands.local.invoke.cli._get_event") - @patch("samcli.commands.local.invoke.cli._get_debug_context") - def test_cli_must_setup_context_and_invoke(self, get_debug_context_mock, get_event_mock, InvokeContextMock): + def test_cli_must_setup_context_and_invoke(self, get_event_mock, InvokeContextMock): event_data = "data" get_event_mock.return_value = event_data - debug_context_data = DebugContext(debug_port=self.debug_port, debug_args=self.debug_args, - debugger_path=self.debugger_path) - get_debug_context_mock.return_value = debug_context_data - # Mock the __enter__ method to return a object inside a context manager context_mock = Mock() InvokeContextMock.return_value.__enter__.return_value = context_mock @@ -51,7 +44,6 @@ def test_cli_must_setup_context_and_invoke(self, get_debug_context_mock, get_eve env_vars=self.env_vars, debug_port=self.debug_port, debug_args=self.debug_args, - debugger_path=self.debugger_path, docker_volume_basedir=self.docker_volume_basedir, docker_network=self.docker_network, log_file=self.log_file, @@ -61,7 +53,8 @@ def test_cli_must_setup_context_and_invoke(self, get_debug_context_mock, get_eve InvokeContextMock.assert_called_with(template_file=self.template, function_identifier=self.function_id, env_vars_file=self.env_vars, - debug_context=debug_context_data, + debug_port=self.debug_port, + debug_args=self.debug_args, docker_volume_basedir=self.docker_volume_basedir, docker_network=self.docker_network, log_file=self.log_file, @@ -95,7 +88,6 @@ def test_must_raise_user_exception_on_function_not_found(self, get_event_mock, I env_vars=self.env_vars, debug_port=self.debug_port, debug_args=self.debug_args, - debugger_path=self.debugger_path, docker_volume_basedir=self.docker_volume_basedir, docker_network=self.docker_network, log_file=self.log_file, @@ -122,7 +114,6 @@ def test_must_raise_user_exception_on_invalid_sam_template(self, get_event_mock, env_vars=self.env_vars, debug_port=self.debug_port, debug_args=self.debug_args, - debugger_path=self.debugger_path, docker_volume_basedir=self.docker_volume_basedir, docker_network=self.docker_network, log_file=self.log_file, diff --git a/tests/unit/commands/local/lib/test_local_lambda.py b/tests/unit/commands/local/lib/test_local_lambda.py index 7a2245afae..812ce60daf 100644 --- a/tests/unit/commands/local/lib/test_local_lambda.py +++ b/tests/unit/commands/local/lib/test_local_lambda.py @@ -24,15 +24,17 @@ def setUp(self): self.function_provider_mock = Mock() self.cwd = "cwd" self.env_vars_values = {} - self.debug_context = None + self.debug_port = 123 + self.debug_args = "abc" self.aws_profile = "myprofile" self.local_lambda = LocalLambdaRunner(self.runtime_mock, self.function_provider_mock, self.cwd, - env_vars_values=self.env_vars_values, - debug_context=self.debug_context, - aws_profile=self.aws_profile) + self.env_vars_values, + self.debug_port, + self.debug_args, + self.aws_profile) @patch("samcli.commands.local.lib.local_lambda.boto3") def test_must_get_from_boto_session(self, boto3_mock): @@ -185,7 +187,8 @@ def setUp(self): self.function_provider_mock = Mock() self.cwd = "/my/current/working/directory" self.env_vars_values = {} - self.debug_context = None + self.debug_port = 123 + self.debug_args = "abc" self.aws_profile = "myprofile" self.relative_codeuri = "./my/path" @@ -195,9 +198,10 @@ def setUp(self): self.local_lambda = LocalLambdaRunner(self.runtime_mock, self.function_provider_mock, self.cwd, - env_vars_values=self.env_vars_values, - aws_profile=self.aws_profile, - debug_context=self.debug_context) + self.env_vars_values, + self.debug_port, + self.debug_args, + self.aws_profile) @parameterized.expand([ ("."), @@ -263,7 +267,8 @@ def setUp(self): self.runtime_mock = Mock() self.function_provider_mock = Mock() self.cwd = "/my/current/working/directory" - self.debug_context = None + self.debug_port = 123 + self.debug_args = "abc" self.aws_profile = "myprofile" self.env_vars_values = {} @@ -276,9 +281,10 @@ def setUp(self): self.local_lambda = LocalLambdaRunner(self.runtime_mock, self.function_provider_mock, self.cwd, - env_vars_values=self.env_vars_values, - debug_context=self.debug_context, - aws_profile=self.aws_profile) + self.env_vars_values, + self.debug_port, + self.debug_args, + self.aws_profile) self.aws_creds = {"key": "key"} self.local_lambda.get_aws_creds = Mock() @@ -361,16 +367,18 @@ def setUp(self): self.runtime_mock = Mock() self.function_provider_mock = Mock() self.cwd = "/my/current/working/directory" + self.debug_port = 123 + self.debug_args = "abc" self.aws_profile = "myprofile" - self.debug_context = None self.env_vars_values = {} self.local_lambda = LocalLambdaRunner(self.runtime_mock, self.function_provider_mock, self.cwd, - env_vars_values=self.env_vars_values, - aws_profile=self.aws_profile, - debug_context=self.debug_context) + self.env_vars_values, + self.debug_port, + self.debug_args, + self.aws_profile) @patch('samcli.commands.local.lib.local_lambda.FunctionConfig') def test_must_work(self, FunctionConfigMock): @@ -414,16 +422,18 @@ def setUp(self): self.runtime_mock = Mock() self.function_provider_mock = Mock() self.cwd = "/my/current/working/directory" - self.debug_context = None + self.debug_port = 123 + self.debug_args = "abc" self.aws_profile = "myprofile" self.env_vars_values = {} self.local_lambda = LocalLambdaRunner(self.runtime_mock, self.function_provider_mock, self.cwd, - env_vars_values=self.env_vars_values, - aws_profile=self.aws_profile, - debug_context=self.debug_context) + self.env_vars_values, + self.debug_port, + self.debug_args, + self.aws_profile) def test_must_work(self): name = "name" @@ -440,7 +450,8 @@ def test_must_work(self): self.local_lambda.invoke(name, event, stdout, stderr) self.runtime_mock.invoke.assert_called_with(invoke_config, event, - debug_context=None, + debug_port=self.debug_port, + debug_args=self.debug_args, stdout=stdout, stderr=stderr) def test_must_raise_if_function_not_found(self): @@ -456,16 +467,18 @@ def setUp(self): self.runtime_mock = Mock() self.function_provider_mock = Mock() self.cwd = "/my/current/working/directory" - self.debug_context = Mock() + self.debug_port = 123 + self.debug_args = "abc" self.aws_profile = "myprofile" self.env_vars_values = {} self.local_lambda = LocalLambdaRunner(self.runtime_mock, self.function_provider_mock, self.cwd, - env_vars_values=self.env_vars_values, - aws_profile=self.aws_profile, - debug_context=self.debug_context) + self.env_vars_values, + self.debug_port, + self.debug_args, + self.aws_profile) def test_must_be_on(self): self.assertTrue(self.local_lambda.is_debugging()) @@ -475,8 +488,9 @@ def test_must_be_off(self): self.local_lambda = LocalLambdaRunner(self.runtime_mock, self.function_provider_mock, self.cwd, - env_vars_values=self.env_vars_values, - debug_context=None, + self.env_vars_values, + debug_port=None, # No debug port + debug_args=self.debug_args, aws_profile=self.aws_profile) self.assertFalse(self.local_lambda.is_debugging()) diff --git a/tests/unit/commands/local/start_api/test_cli.py b/tests/unit/commands/local/start_api/test_cli.py index cf16c007e0..1e5d083519 100644 --- a/tests/unit/commands/local/start_api/test_cli.py +++ b/tests/unit/commands/local/start_api/test_cli.py @@ -5,7 +5,6 @@ from unittest import TestCase from mock import patch, Mock -from samcli.commands.local.lib.debug_context import DebugContext from samcli.commands.local.start_api.cli import do_cli as start_api_cli from samcli.commands.local.lib.exceptions import NoApisDefined from samcli.commands.local.cli_common.user_exceptions import UserException @@ -19,7 +18,6 @@ def setUp(self): self.env_vars = "env-vars" self.debug_port = 123 self.debug_args = "args" - self.debugger_path = "/test/path" self.docker_volume_basedir = "basedir" self.docker_network = "network" self.log_file = "logfile" @@ -32,9 +30,7 @@ def setUp(self): @patch("samcli.commands.local.start_api.cli.InvokeContext") @patch("samcli.commands.local.start_api.cli.LocalApiService") - @patch("samcli.commands.local.start_api.cli._get_debug_context") - def test_cli_must_setup_context_and_start_service(self, get_debug_context_mock, LocalApiServiceMock, - InvokeContextMock): + def test_cli_must_setup_context_and_start_service(self, LocalApiServiceMock, InvokeContextMock): # Mock the __enter__ method to return a object inside a context manager context_mock = Mock() @@ -43,16 +39,13 @@ def test_cli_must_setup_context_and_start_service(self, get_debug_context_mock, service_mock = Mock() LocalApiServiceMock.return_value = service_mock - debug_context_data = DebugContext(debug_port=self.debug_port, debug_args=self.debug_args, - debugger_path=self.debugger_path) - get_debug_context_mock.return_value = debug_context_data - self.call_cli() InvokeContextMock.assert_called_with(template_file=self.template, function_identifier=None, env_vars_file=self.env_vars, - debug_context=debug_context_data, + debug_port=self.debug_port, + debug_args=self.debug_args, docker_volume_basedir=self.docker_volume_basedir, docker_network=self.docker_network, log_file=self.log_file, @@ -107,7 +100,6 @@ def call_cli(self): env_vars=self.env_vars, debug_port=self.debug_port, debug_args=self.debug_args, - debugger_path=self.debugger_path, docker_volume_basedir=self.docker_volume_basedir, docker_network=self.docker_network, log_file=self.log_file, diff --git a/tests/unit/local/docker/test_lambda_container.py b/tests/unit/local/docker/test_lambda_container.py index 283bfd89a4..0fbaed363d 100644 --- a/tests/unit/local/docker/test_lambda_container.py +++ b/tests/unit/local/docker/test_lambda_container.py @@ -6,7 +6,6 @@ from mock import patch from parameterized import parameterized, param -from samcli.commands.local.lib.debug_context import DebugContext from samcli.local.docker.lambda_container import LambdaContainer, Runtime RUNTIMES_WITH_ENTRYPOINT = [Runtime.java8.value, @@ -28,39 +27,33 @@ def setUp(self): self.code_dir = "codedir" self.env_var = {"var": "value"} self.memory_mb = 1024 - self.debug_options = DebugContext(debug_args="a=b c=d e=f", debug_port=1235) + self.debug_port = 1235 + self.debug_arg = "a=b c=d e=f" @patch.object(LambdaContainer, "_get_image") @patch.object(LambdaContainer, "_get_exposed_ports") @patch.object(LambdaContainer, "_get_entry_point") - @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_exposed_ports_mock, get_image_mock): image = "image" ports = {"a": "b"} - addtl_options = {} - addtl_volumes = {} entry = [1, 2, 3] 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_additional_options_mock.return_value = addtl_options - get_additional_volumes_mock.return_value = addtl_volumes container = LambdaContainer(self.runtime, self.handler, self.code_dir, env_vars=self.env_var, memory_mb=self.memory_mb, - debug_options=self.debug_options) + debug_port=self.debug_port, + debug_args=self.debug_arg) self.assertEquals(image, container._image) self.assertEquals(expected_cmd, container._cmd) @@ -72,10 +65,8 @@ def test_must_configure_container_properly(self, self.assertEquals(self.memory_mb, container._memory_limit_mb) get_image_mock.assert_called_with(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_additional_options_mock.assert_called_with(self.runtime, self.debug_options) - get_additional_volumes_mock.assert_called_with(self.debug_options) + get_exposed_ports_mock.assert_called_with(self.debug_port) + get_entry_point_mock.assert_called_with(self.runtime, self.debug_port, self.debug_arg) def test_must_fail_for_unsupported_runtime(self): @@ -91,9 +82,9 @@ class TestLambdaContainer_get_exposed_ports(TestCase): def test_must_map_same_port_on_host_and_container(self): - debug_options = DebugContext(debug_port=12345) - expected = {debug_options.debug_port: debug_options.debug_port} - result = LambdaContainer._get_exposed_ports(debug_options) + port = 12345 + expected = {port: port} + result = LambdaContainer._get_exposed_ports(port) self.assertEquals(expected, result) @@ -118,16 +109,15 @@ def setUp(self): self.debug_port = 1235 self.debug_args = "a=b c=d e=f" - self.debug_options = DebugContext(debug_port=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), + self.assertIsNone(LambdaContainer._get_entry_point("runtime", None, self.debug_args), "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): - result = LambdaContainer._get_entry_point(runtime, self.debug_options) + result = LambdaContainer._get_entry_point(runtime, self.debug_port, self.debug_args) if runtime in RUNTIMES_WITH_ENTRYPOINT: self.assertIsNotNone(result, "{} runtime must provide entrypoint".format(runtime)) @@ -140,7 +130,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_entry_point(runtime, self.debug_port, self.debug_args) actual = result[1:4] self.assertEquals(actual, expected_debug_args) @@ -148,6 +138,6 @@ def test_debug_arg_must_be_split_by_spaces_and_appended_to_entrypoint(self, runt @parameterized.expand([param(r) for r in RUNTIMES_WITH_ENTRYPOINT]) def test_must_provide_entrypoint_even_without_debug_args(self, runtime): - result = LambdaContainer._get_entry_point(runtime, self.debug_options) + result = LambdaContainer._get_entry_point(runtime, self.debug_port) self.assertIsNotNone(result) diff --git a/tests/unit/local/lambdafn/test_runtime.py b/tests/unit/local/lambdafn/test_runtime.py index 6a6ef35a6d..9c0b714176 100644 --- a/tests/unit/local/lambdafn/test_runtime.py +++ b/tests/unit/local/lambdafn/test_runtime.py @@ -33,12 +33,13 @@ def setUp(self): @patch("samcli.local.lambdafn.runtime.LambdaContainer") def test_must_run_container_and_wait_for_logs(self, LambdaContainerMock): event = "event" + debug_port = 123 + debug_arg = "abc" code_dir = "some code dir" stdout = "stdout" stderr = "stderr" container = Mock() timer = Mock() - debug_options = Mock() self.runtime = LambdaRuntime(self.manager_mock) @@ -54,7 +55,8 @@ def test_must_run_container_and_wait_for_logs(self, LambdaContainerMock): self.runtime.invoke(self.func_config, event, - debug_context=debug_options, + debug_port=debug_port, + debug_args=debug_arg, stdout=stdout, stderr=stderr) @@ -70,7 +72,7 @@ def test_must_run_container_and_wait_for_logs(self, LambdaContainerMock): # Make sure the container is created with proper values LambdaContainerMock.assert_called_with(self.lang, self.handler, code_dir, memory_mb=self.DEFAULT_MEMORY, env_vars=self.env_var_value, - debug_options=debug_options) + debug_port=debug_port, debug_args=debug_arg) # Run the container and get results self.manager_mock.run.assert_called_with(container) @@ -84,6 +86,8 @@ def test_must_run_container_and_wait_for_logs(self, LambdaContainerMock): @patch("samcli.local.lambdafn.runtime.LambdaContainer") def test_exception_from_run_must_trigger_cleanup(self, LambdaContainerMock): event = "event" + debug_port = 123 + debug_arg = "abc" code_dir = "some code dir" stdout = "stdout" stderr = "stderr" @@ -105,7 +109,8 @@ def test_exception_from_run_must_trigger_cleanup(self, LambdaContainerMock): with self.assertRaises(ValueError): self.runtime.invoke(self.func_config, event, - debug_context=None, + debug_port=debug_port, + debug_args=debug_arg, stdout=stdout, stderr=stderr) @@ -123,12 +128,13 @@ def test_exception_from_run_must_trigger_cleanup(self, LambdaContainerMock): @patch("samcli.local.lambdafn.runtime.LambdaContainer") def test_exception_from_wait_for_logs_must_trigger_cleanup(self, LambdaContainerMock): event = "event" + debug_port = 123 + debug_arg = "abc" code_dir = "some code dir" stdout = "stdout" stderr = "stderr" container = Mock() timer = Mock() - debug_options = Mock() self.runtime = LambdaRuntime(self.manager_mock) @@ -145,7 +151,8 @@ def test_exception_from_wait_for_logs_must_trigger_cleanup(self, LambdaContainer with self.assertRaises(ValueError): self.runtime.invoke(self.func_config, event, - debug_context=debug_options, + debug_port=debug_port, + debug_args=debug_arg, stdout=stdout, stderr=stderr) @@ -163,6 +170,8 @@ def test_exception_from_wait_for_logs_must_trigger_cleanup(self, LambdaContainer @patch("samcli.local.lambdafn.runtime.LambdaContainer") def test_keyboard_interrupt_must_not_raise(self, LambdaContainerMock): event = "event" + debug_port = 123 + debug_arg = "abc" code_dir = "some code dir" stdout = "stdout" stderr = "stderr" @@ -181,6 +190,8 @@ def test_keyboard_interrupt_must_not_raise(self, LambdaContainerMock): self.runtime.invoke(self.func_config, event, + debug_port=debug_port, + debug_args=debug_arg, stdout=stdout, stderr=stderr)