def test_must_use_stderr_if_no_log_file_handle(self, SamFunctionProviderMock, StreamWriterMock, osutils_stderr_mock, ExitMock): stream_writer_mock = Mock() StreamWriterMock.return_value = stream_writer_mock stderr_mock = Mock() osutils_stderr_mock.return_value = stderr_mock context = InvokeContext(template_file="template") context._get_template_data = Mock() context._get_env_vars_value = Mock() context._setup_log_file = Mock(return_value=None) container_manager_mock = Mock() context._get_container_manager = Mock(return_value=container_manager_mock) with patch.object(type(container_manager_mock), "is_docker_reachable", create=True, return_value=True): with context: stderr = context.stderr StreamWriterMock.assert_called_once_with(stderr_mock, ANY) self.assertEqual(stream_writer_mock, stderr)
def test_debugger_path_not_found(self, pathlib_mock): error = OSError() error.errno = errno.ENOENT pathlib_mock.side_effect = error with self.assertRaises(DebugContextException): InvokeContext._get_debug_context(debug_port=1111, debug_args=None, debugger_path='somepath')
def test_must_return_template_file_dir_name(self): filename = "filename" context = InvokeContext(template_file=filename) expected = os.path.dirname(os.path.abspath(filename)) result = context.get_cwd() self.assertEquals(result, expected)
def test_must_open_file_for_writing(self): filename = "foo" m = mock_open() with patch("samcli.commands.local.cli_common.invoke_context.open", m): InvokeContext._setup_log_file(filename) m.assert_called_with(filename, 'wb')
def test_must_raise_if_more_than_one_function(self): context = InvokeContext(template_file="template_file") context._function_provider = Mock() context._function_provider.get_all.return_value = [Mock(), Mock(), Mock()] # Provider returns three functions with self.assertRaises(InvokeContextException): context.function_name
def test_debugger_path_not_dir(self, pathlib_mock): pathlib_path_mock = Mock() resolve_path_mock = Mock() pathlib_path_mock.resolve.return_value = resolve_path_mock resolve_path_mock.is_dir.return_value = False pathlib_mock.return_value = pathlib_path_mock with self.assertRaises(DebugContextException): InvokeContext._get_debug_context(debug_port=1111, debug_args=None, debugger_path='somepath')
def test_must_return_one_function_from_template(self): context = InvokeContext(template_file="template_file") function = Mock() function.name = "myname" context._function_provider = Mock() context._function_provider.get_all.return_value = [function] # Provider returns only one function self.assertEquals("myname", context.function_name)
def test_must_close_opened_logfile(self): context = InvokeContext(template_file="template") handle_mock = Mock() context._log_file_handle = handle_mock context.__exit__() handle_mock.close.assert_called_with() self.assertIsNone(context._log_file_handle)
def test_must_raise_if_failed_to_parse_json(self): filename = "filename" file_data = 'invalid json' m = mock_open(read_data=file_data) with patch("samcli.commands.local.cli_common.invoke_context.open", m): with self.assertRaises(InvokeContextException) as ex_ctx: InvokeContext._get_env_vars_value(filename) msg = str(ex_ctx.exception) self.assertTrue(msg.startswith("Could not read environment variables overrides from file {}".format( filename)))
def test_debug_port_given_without_debugger_path(self, debug_context_mock): debug_context_mock.return_value = "I am the DebugContext" debug_context = InvokeContext._get_debug_context(1111, None, None) self.assertEquals(debug_context, "I am the DebugContext") debug_context_mock.assert_called_once_with(debug_port=1111, debug_args=None, debugger_path=None)
def test_must_enable_auto_flush_if_debug(self, SamFunctionProviderMock, StreamWriterMock, osutils_stderr_mock, ExitMock): context = InvokeContext(template_file="template", debug_port=6000) context._get_template_data = Mock() context._get_env_vars_value = Mock() context._setup_log_file = Mock() container_manager_mock = Mock() context._get_container_manager = Mock(return_value=container_manager_mock) with patch.object(type(container_manager_mock), "is_docker_reachable", create=True, return_value=True): with context: context.stderr StreamWriterMock.assert_called_once_with(ANY, True)
def test_must_read_from_necessary_files(self, SamFunctionProviderMock): function_provider = Mock() SamFunctionProviderMock.return_value = function_provider template_file = "template_file" env_vars_file = "env_vars_file" log_file = "log_file" invoke_context = InvokeContext(template_file=template_file, function_identifier="id", env_vars_file=env_vars_file, docker_volume_basedir="volumedir", docker_network="network", log_file=log_file, skip_pull_image=True, debug_port=1111, debugger_path="path-to-debugger", debug_args='args', parameter_overrides={}, aws_region="region") template_dict = "template_dict" invoke_context._get_template_data = Mock() invoke_context._get_template_data.return_value = template_dict env_vars_value = "env_vars_value" invoke_context._get_env_vars_value = Mock() invoke_context._get_env_vars_value.return_value = env_vars_value log_file_handle = "handle" invoke_context._setup_log_file = Mock() invoke_context._setup_log_file.return_value = log_file_handle debug_context_mock = Mock() invoke_context._get_debug_context = Mock() invoke_context._get_debug_context.return_value = debug_context_mock container_manager_mock = Mock() container_manager_mock.is_docker_reachable = True invoke_context._get_container_manager = Mock(return_value=container_manager_mock) # Call Enter method manually for testing purposes result = invoke_context.__enter__() self.assertTrue(result is invoke_context, "__enter__() must return self") self.assertEqual(invoke_context._template_dict, template_dict) self.assertEqual(invoke_context._function_provider, function_provider) self.assertEqual(invoke_context._env_vars_value, env_vars_value) self.assertEqual(invoke_context._log_file_handle, log_file_handle) self.assertEqual(invoke_context._debug_context, debug_context_mock) self.assertEqual(invoke_context._container_manager, container_manager_mock) invoke_context._get_template_data.assert_called_with(template_file) SamFunctionProviderMock.assert_called_with(template_dict, {"AWS::Region": "region"}) invoke_context._get_env_vars_value.assert_called_with(env_vars_file) invoke_context._setup_log_file.assert_called_with(log_file) invoke_context._get_debug_context.assert_called_once_with(1111, "args", "path-to-debugger") invoke_context._get_container_manager.assert_called_once_with("network", True)
def test_must_read_file_and_parse_as_json(self): filename = "filename" file_data = '{"a": "b"}' expected = {"a": "b"} m = mock_open(read_data=file_data) with patch("samcli.commands.local.cli_common.invoke_context.open", m): result = InvokeContext._get_env_vars_value(filename) self.assertEquals(expected, result) m.assert_called_with(filename, 'r')
def test_debug_port_given_without_debugger_path(self, debug_context_mock): debug_context_mock.return_value = "I am the DebugContext" debug_context = InvokeContext._get_debug_context( debug_ports=1111, debug_args=None, debugger_path=None, container_env_vars={"env": "var"} ) self.assertEqual(debug_context, "I am the DebugContext") debug_context_mock.assert_called_once_with( debug_ports=1111, debug_args=None, debugger_path=None, debug_function=None, container_env_vars={"env": "var"}, )
def setUp(self): self.context = InvokeContext(template_file="template_file", function_identifier="id", env_vars_file="env_vars_file", docker_volume_basedir="volumedir", docker_network="network", log_file="log_file", skip_pull_image=True, force_image_build=True, debug_port=1111, debugger_path="path-to-debugger", debug_args='args', aws_profile="profile", aws_region="region")
def do_cli( ctx, host, port, template, env_vars, debug_port, debug_args, # pylint: disable=R0914 debugger_path, docker_volume_basedir, docker_network, log_file, skip_pull_image, profile, region, parameter_overrides): """ Implementation of the ``cli`` method, just separated out for unit testing purposes """ LOG.debug("local start_lambda command is called") # Pass all inputs to setup necessary context to invoke function locally. # Handler exception raised by the processor for invalid args and print errors try: with InvokeContext( template_file=template, function_identifier= None, # Don't scope to one particular function env_vars_file=env_vars, docker_volume_basedir=docker_volume_basedir, docker_network=docker_network, log_file=log_file, skip_pull_image=skip_pull_image, aws_profile=profile, debug_port=debug_port, debug_args=debug_args, debugger_path=debugger_path, aws_region=region, parameter_overrides=parameter_overrides) as invoke_context: service = LocalLambdaService(lambda_invoke_context=invoke_context, port=port, host=host) service.start() except (InvalidSamDocumentException, OverridesNotWellDefinedError) as ex: raise UserException(str(ex))
def do_cli( ctx, host, port, static_dir, template, env_vars, debug_port, debug_args, # pylint: disable=R0914 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") # Pass all inputs to setup necessary context to invoke function locally. # Handler exception raised by the processor for invalid args and print errors try: 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) as invoke_context: service = LocalApiService(lambda_invoke_context=invoke_context, port=port, host=host, static_dir=static_dir) service.start() except NoApisDefined: raise UserException( "Template does not have any APIs connected to Lambda functions") except InvalidSamDocumentException as ex: raise UserException(str(ex))
def test_must_use_container_manager_to_check_docker_connectivity(self, SamFunctionProviderMock): invoke_context = InvokeContext("template-file") invoke_context._get_template_data = Mock() invoke_context._get_env_vars_value = Mock() invoke_context._setup_log_file = Mock() invoke_context._get_debug_context = Mock() container_manager_mock = Mock() with patch.object(type(container_manager_mock), "is_docker_reachable", create=True, new_callable=PropertyMock, return_value=True) as is_docker_reachable_mock: invoke_context._get_container_manager = Mock() invoke_context._get_container_manager.return_value = container_manager_mock invoke_context.__enter__() is_docker_reachable_mock.assert_called_once_with()
def test_must_use_container_manager_to_check_docker_connectivity( self, SamFunctionProviderMock): invoke_context = InvokeContext("template-file") invoke_context._get_template_data = Mock() invoke_context._get_env_vars_value = Mock() invoke_context._setup_log_file = Mock() invoke_context._get_debug_context = Mock() container_manager_mock = Mock() with patch.object(type(container_manager_mock), "is_docker_reachable", create=True, new_callable=PropertyMock, return_value=True) as is_docker_reachable_mock: invoke_context._get_container_manager = Mock() invoke_context._get_container_manager.return_value = container_manager_mock invoke_context.__enter__() is_docker_reachable_mock.assert_called_once_with()
def test_must_read_from_necessary_files(self, SamFunctionProviderMock): function_provider = Mock() SamFunctionProviderMock.return_value = function_provider template_file = "template_file" env_vars_file = "env_vars_file" log_file = "log_file" 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") template_dict = "template_dict" invoke_context._get_template_data = Mock() invoke_context._get_template_data.return_value = template_dict env_vars_value = "env_vars_value" invoke_context._get_env_vars_value = Mock() invoke_context._get_env_vars_value.return_value = env_vars_value log_file_handle = "handle" invoke_context._setup_log_file = Mock() invoke_context._setup_log_file.return_value = log_file_handle invoke_context._check_docker_connectivity = Mock() # Call Enter method manually for testing purposes result = invoke_context.__enter__() self.assertTrue(result is invoke_context, "__enter__() must return self") self.assertEquals(invoke_context._template_dict, template_dict) self.assertEquals(invoke_context._function_provider, function_provider) self.assertEquals(invoke_context._env_vars_value, env_vars_value) self.assertEquals(invoke_context._log_file_handle, log_file_handle) invoke_context._get_template_data.assert_called_with(template_file) SamFunctionProviderMock.assert_called_with(template_dict) invoke_context._get_env_vars_value.assert_called_with(env_vars_file) invoke_context._setup_log_file.assert_called_with(log_file) invoke_context._check_docker_connectivity.assert_called_with()
def test_must_read_file_and_parse(self, os_mock, yaml_parse_mock): filename = "filename" file_data = "contents of the file" parse_result = "parse result" os_mock.patch.exists.return_value = True # Fake that the file exists m = mock_open(read_data=file_data) yaml_parse_mock.return_value = parse_result with patch("samcli.commands.local.cli_common.invoke_context.open", m): result = InvokeContext._get_template_data(filename) self.assertEquals(result, parse_result) m.assert_called_with(filename, 'r') yaml_parse_mock.assert_called_with(file_data)
def test_must_raise_if_docker_is_not_reachable(self, SamFunctionProviderMock): invoke_context = InvokeContext("template-file") invoke_context._get_template_data = Mock() invoke_context._get_env_vars_value = Mock() invoke_context._setup_log_file = Mock() invoke_context._get_debug_context = Mock() container_manager_mock = Mock() with patch.object(type(container_manager_mock), "is_docker_reachable", create=True, new_callable=PropertyMock, return_value=False): invoke_context._get_container_manager = Mock() invoke_context._get_container_manager.return_value = container_manager_mock with self.assertRaises(InvokeContextException) as ex_ctx: invoke_context.__enter__() self.assertEqual("Running AWS SAM projects locally requires Docker. Have you got it installed?", str(ex_ctx.exception))
def test_debugger_path_resolves(self, pathlib_mock, debug_context_mock): pathlib_path_mock = Mock() resolve_path_mock = Mock() pathlib_path_mock.resolve.return_value = resolve_path_mock resolve_path_mock.is_dir.return_value = True resolve_path_mock.__str__ = Mock() resolve_path_mock.__str__.return_value = "full/path" pathlib_mock.return_value = pathlib_path_mock debug_context_mock.return_value = "I am the DebugContext" debug_context = InvokeContext._get_debug_context(1111, "args", "./path") self.assertEquals(debug_context, "I am the DebugContext") debug_context_mock.assert_called_once_with(debug_port=1111, debug_args="args", debugger_path="full/path") resolve_path_mock.is_dir.assert_called_once() pathlib_path_mock.resolve.assert_called_once_with(strict=True) pathlib_mock.assert_called_once_with("./path")
def test_debugger_path_resolves(self, pathlib_mock, debug_context_mock): pathlib_path_mock = Mock() resolve_path_mock = Mock() pathlib_path_mock.resolve.return_value = resolve_path_mock resolve_path_mock.is_dir.return_value = True resolve_path_mock.__str__ = Mock() resolve_path_mock.__str__.return_value = "full/path" pathlib_mock.return_value = pathlib_path_mock debug_context_mock.return_value = "I am the DebugContext" debug_context = InvokeContext._get_debug_context(1111, "args", "./path") self.assertEqual(debug_context, "I am the DebugContext") debug_context_mock.assert_called_once_with(debug_ports=1111, debug_args="args", debugger_path="full/path") resolve_path_mock.is_dir.assert_called_once() pathlib_path_mock.resolve.assert_called_once_with(strict=True) pathlib_mock.assert_called_once_with("./path")
def test_must_work_in_with_statement(self, ExitMock, EnterMock): context_obj = Mock() EnterMock.return_value = context_obj 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") as context: self.assertEquals(context_obj, context) EnterMock.assert_called_with() self.assertEquals(1, ExitMock.call_count)
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, layer_cache_basedir, skip_pull_image, force_image_build, parameter_overrides): """ Implementation of the ``cli`` method, just separated out for unit testing purposes """ LOG.debug("local start-api command is called") # Pass all inputs to setup necessary context to invoke function locally. # Handler exception raised by the processor for invalid args and print errors try: with InvokeContext(template_file=template, function_identifier=None, # Don't scope to one particular function env_vars_file=env_vars, docker_volume_basedir=docker_volume_basedir, docker_network=docker_network, log_file=log_file, skip_pull_image=skip_pull_image, debug_port=debug_port, debug_args=debug_args, debugger_path=debugger_path, parameter_overrides=parameter_overrides, layer_cache_basedir=layer_cache_basedir, force_image_build=force_image_build, aws_region=ctx.region) as invoke_context: service = LocalApiService(lambda_invoke_context=invoke_context, port=port, host=host, static_dir=static_dir) service.start() except NoApisDefined: raise UserException("Template does not have any APIs connected to Lambda functions") except (InvalidSamDocumentException, OverridesNotWellDefinedError, InvalidLayerReference, DebuggingNotSupported) as ex: raise UserException(str(ex))
def test_enable_auto_flush_if_debug(self, SamFunctionProviderMock, StreamWriterMock, osutils_stdout_mock, ExitMock): context = InvokeContext(template_file="template", debug_ports=[6000]) context._get_template_data = Mock() context._get_env_vars_value = Mock() context._setup_log_file = Mock() container_manager_mock = Mock() context._get_container_manager = Mock(return_value=container_manager_mock) with patch.object(type(container_manager_mock), "is_docker_reachable", create=True, return_value=True): with context: context.stdout StreamWriterMock.assert_called_once_with(ANY, True)
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 """ LOG.debug("local invoke command is called") event_data = _get_event(event) # Pass all inputs to setup necessary context to invoke function locally. # Handler exception raised by the processor for invalid args and print errors try: 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) as context: # Invoke the function context.local_lambda_runner.invoke(context.function_name, event=event_data, stdout=context.stdout, stderr=context.stderr) except FunctionNotFound: raise UserException( "Function {} not found in template".format(function_identifier)) except InvalidSamDocumentException as ex: raise UserException(str(ex))
def test_must_use_log_file_handle(self, StreamWriterMock, SamFunctionProviderMock, ExitMock): stream_writer_mock = Mock() StreamWriterMock.return_value = stream_writer_mock context = InvokeContext(template_file="template") context._get_template_data = Mock() context._get_env_vars_value = Mock() log_file_handle_mock = Mock() context._setup_log_file = Mock(return_value=log_file_handle_mock) container_manager_mock = Mock() context._get_container_manager = Mock(return_value=container_manager_mock) with patch.object(type(container_manager_mock), "is_docker_reachable", create=True, return_value=True): with context: stderr = context.stderr StreamWriterMock.assert_called_once_with(log_file_handle_mock, ANY) self.assertEqual(stream_writer_mock, stderr)
def test_no_debug_port(self): debug_context = InvokeContext._get_debug_context(None, None, None) self.assertEquals(debug_context.debugger_path, None) self.assertEquals(debug_context.debug_port, None) self.assertEquals(debug_context.debug_args, None)
def test_must_return_log_file_handle(self): context = InvokeContext(template_file="template") context._log_file_handle = "handle" self.assertEquals("handle", context.stderr)
def test_must_return_sys_stderr(self): context = InvokeContext(template_file="template") self.assertEquals(sys.stderr, context.stderr)
def do_cli( # pylint: disable=R0914 ctx, host, port, static_dir, template, env_vars, debug_port, debug_args, debugger_path, container_env_vars, docker_volume_basedir, docker_network, log_file, layer_cache_basedir, skip_pull_image, force_image_build, parameter_overrides, warm_containers, debug_function, ): """ Implementation of the ``cli`` method, just separated out for unit testing purposes """ from samcli.commands.local.cli_common.invoke_context import InvokeContext from samcli.commands.local.lib.exceptions import NoApisDefined from samcli.lib.providers.exceptions import InvalidLayerReference from samcli.commands.exceptions import UserException 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_settings import DebuggingNotSupported LOG.debug("local start-api command is called") # Pass all inputs to setup necessary context to invoke function locally. # Handler exception raised by the processor for invalid args and print errors try: with InvokeContext( template_file=template, function_identifier= None, # Don't scope to one particular function env_vars_file=env_vars, docker_volume_basedir=docker_volume_basedir, docker_network=docker_network, log_file=log_file, skip_pull_image=skip_pull_image, debug_ports=debug_port, debug_args=debug_args, debugger_path=debugger_path, container_env_vars_file=container_env_vars, parameter_overrides=parameter_overrides, layer_cache_basedir=layer_cache_basedir, force_image_build=force_image_build, aws_region=ctx.region, aws_profile=ctx.profile, warm_container_initialization_mode=warm_containers, debug_function=debug_function, ) as invoke_context: service = LocalApiService(lambda_invoke_context=invoke_context, port=port, host=host, static_dir=static_dir) service.start() except NoApisDefined as ex: raise UserException( "Template does not have any APIs connected to Lambda functions", wrapped_from=ex.__class__.__name__) from ex except ( InvalidSamDocumentException, OverridesNotWellDefinedError, InvalidLayerReference, InvalidIntermediateImageError, DebuggingNotSupported, ) as ex: raise UserException(str(ex), wrapped_from=ex.__class__.__name__) from ex except ContainerNotStartableException as ex: raise UserException(str(ex), wrapped_from=ex.__class__.__name__) from ex
def test_must_return_function_name_if_present(self): id = "id" context = InvokeContext(template_file="template_file", function_identifier=id) self.assertEquals(id, context.function_name)
def test_must_return_if_no_file(self): result = InvokeContext._get_env_vars_value(filename=None) self.assertIsNone(result, "No value must be returned")
def test_must_create_runner_using_warm_containers( self, SamFunctionProviderMock, LocalLambdaMock, WarmLambdaRuntimeMock, download_layers_mock, lambda_image_patch ): runtime_mock = Mock() WarmLambdaRuntimeMock.return_value = runtime_mock runner_mock = Mock() LocalLambdaMock.return_value = runner_mock download_mock = Mock() download_layers_mock.return_value = download_mock image_mock = Mock() lambda_image_patch.return_value = image_mock cwd = "cwd" self.context = InvokeContext( template_file="template_file", function_identifier="id", env_vars_file="env_vars_file", docker_volume_basedir="volumedir", docker_network="network", log_file="log_file", skip_pull_image=True, force_image_build=True, debug_ports=[1111], debugger_path="path-to-debugger", debug_args="args", aws_profile="profile", aws_region="region", warm_container_initialization_mode=ContainersInitializationMode.EAGER, ) self.context.get_cwd = Mock() self.context.get_cwd.return_value = cwd self.context._get_template_data = Mock() self.context._get_env_vars_value = Mock() self.context._setup_log_file = Mock() self.context._get_debug_context = Mock(return_value=None) container_manager_mock = Mock() container_manager_mock.is_docker_reachable = PropertyMock(return_value=True) self.context._get_container_manager = Mock(return_value=container_manager_mock) with self.context: result = self.context.local_lambda_runner self.assertEqual(result, runner_mock) WarmLambdaRuntimeMock.assert_called_with(container_manager_mock, image_mock) lambda_image_patch.assert_called_once_with(download_mock, True, True) LocalLambdaMock.assert_called_with( local_runtime=runtime_mock, function_provider=ANY, cwd=cwd, debug_context=None, env_vars_values=ANY, aws_profile="profile", aws_region="region", ) result = self.context.local_lambda_runner self.assertEqual(result, runner_mock) # assert that lambda runner is created only one time, and the cached version used in the second call self.assertEqual(LocalLambdaMock.call_count, 1)
def do_cli( # pylint: disable=R0914 ctx, host, port, template, env_vars, debug_port, debug_args, debugger_path, docker_volume_basedir, docker_network, log_file, layer_cache_basedir, skip_pull_image, force_image_build, parameter_overrides, ): """ Implementation of the ``cli`` method, just separated out for unit testing purposes """ from samcli.commands.local.cli_common.invoke_context import InvokeContext from samcli.commands.local.cli_common.user_exceptions import UserException from samcli.commands.local.lib.exceptions import InvalidLayerReference 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 LOG.debug("local start_lambda command is called") # Pass all inputs to setup necessary context to invoke function locally. # Handler exception raised by the processor for invalid args and print errors try: with InvokeContext( template_file=template, function_identifier= None, # Don't scope to one particular function env_vars_file=env_vars, docker_volume_basedir=docker_volume_basedir, docker_network=docker_network, log_file=log_file, skip_pull_image=skip_pull_image, debug_ports=debug_port, debug_args=debug_args, debugger_path=debugger_path, parameter_overrides=parameter_overrides, layer_cache_basedir=layer_cache_basedir, force_image_build=force_image_build, aws_region=ctx.region, aws_profile=ctx.profile, ) as invoke_context: service = LocalLambdaService(lambda_invoke_context=invoke_context, port=port, host=host) service.start() except ( InvalidSamDocumentException, OverridesNotWellDefinedError, InvalidLayerReference, DebuggingNotSupported, ) as ex: raise UserException(str(ex))
def test_no_debug_port(self): debug_context = InvokeContext._get_debug_context(None, None, None) self.assertEquals(debug_context.debugger_path, None) self.assertEquals(debug_context.debug_port, None) self.assertEquals(debug_context.debug_args, None)
def test_must_return_if_no_file(self): result = InvokeContext._get_env_vars_value(filename=None) self.assertIsNone(result, "No value must be returned")
def test_must_ignore_if_handle_is_absent(self): context = InvokeContext(template_file="template") context._log_file_handle = None context.__exit__() self.assertIsNone(context._log_file_handle)
def test_must_ignore_if_handle_is_absent(self): context = InvokeContext(template_file="template") context._log_file_handle = None context.__exit__() self.assertIsNone(context._log_file_handle)
def test_must_call_ping(self): client = Mock() InvokeContext._check_docker_connectivity(client) client.ping.assert_called_with()
def test_non_path_not_found_oserror_is_thrown(self, pathlib_mock): pathlib_mock.side_effect = OSError() with self.assertRaises(OSError): InvokeContext._get_debug_context(debug_port=1111, debug_args=None, debugger_path='somepath')
def test_must_return_tempalte_dict(self): context = InvokeContext(template_file="file") context._template_dict = "My template" self.assertEquals("My template", context.template)
def do_cli( # pylint: disable=R0914 ctx, function_identifier, template, event, no_event, env_vars, debug_port, debug_args, debugger_path, docker_volume_basedir, docker_network, log_file, layer_cache_basedir, skip_pull_image, force_image_build, parameter_overrides, ): """ Implementation of the ``cli`` method, just separated out for unit testing purposes """ from samcli.commands.exceptions import UserException from samcli.lib.providers.exceptions import InvalidLayerReference from samcli.commands.local.cli_common.invoke_context import InvokeContext from samcli.local.lambdafn.exceptions import FunctionNotFound from samcli.commands.validate.lib.exceptions import InvalidSamDocumentException from samcli.commands.local.lib.exceptions import OverridesNotWellDefinedError, NoPrivilegeException from samcli.local.docker.manager import DockerImagePullFailedException from samcli.local.docker.lambda_debug_settings import DebuggingNotSupported LOG.debug("local invoke command is called") if event: event_data = _get_event(event) else: event_data = "{}" # Pass all inputs to setup necessary context to invoke function locally. # Handler exception raised by the processor for invalid args and print errors try: with InvokeContext( template_file=template, function_identifier=function_identifier, env_vars_file=env_vars, docker_volume_basedir=docker_volume_basedir, docker_network=docker_network, log_file=log_file, skip_pull_image=skip_pull_image, debug_ports=debug_port, debug_args=debug_args, debugger_path=debugger_path, parameter_overrides=parameter_overrides, layer_cache_basedir=layer_cache_basedir, force_image_build=force_image_build, aws_region=ctx.region, aws_profile=ctx.profile, ) as context: # Invoke the function context.local_lambda_runner.invoke(context.function_name, event=event_data, stdout=context.stdout, stderr=context.stderr) except FunctionNotFound as ex: raise UserException( "Function {} not found in template".format(function_identifier), wrapped_from=ex.__class__.__name__) except ( InvalidSamDocumentException, OverridesNotWellDefinedError, InvalidLayerReference, DebuggingNotSupported, NoPrivilegeException, ) as ex: raise UserException(str(ex), wrapped_from=ex.__class__.__name__) except DockerImagePullFailedException as ex: raise UserException(str(ex), wrapped_from=ex.__class__.__name__)
def test_must_return_docker_volume_dir(self): filename = "filename" context = InvokeContext(template_file=filename, docker_volume_basedir="basedir") result = context.get_cwd() self.assertEquals(result, "basedir")
def do_cli( ctx, function_identifier, template, event, no_event, env_vars, debug_port, # pylint: disable=R0914 debug_args, debugger_path, docker_volume_basedir, docker_network, log_file, skip_pull_image, profile, region, parameter_overrides): """ Implementation of the ``cli`` method, just separated out for unit testing purposes """ LOG.debug("local invoke command is called") if no_event and event != STDIN_FILE_NAME: # Do not know what the user wants. no_event and event both passed in. raise UserException( "no_event and event cannot be used together. Please provide only one." ) if no_event: event_data = "{}" else: event_data = _get_event(event) # Pass all inputs to setup necessary context to invoke function locally. # Handler exception raised by the processor for invalid args and print errors try: with InvokeContext(template_file=template, function_identifier=function_identifier, env_vars_file=env_vars, docker_volume_basedir=docker_volume_basedir, docker_network=docker_network, log_file=log_file, skip_pull_image=skip_pull_image, aws_profile=profile, debug_port=debug_port, debug_args=debug_args, debugger_path=debugger_path, aws_region=region, parameter_overrides=parameter_overrides) as context: # Invoke the function context.local_lambda_runner.invoke(context.function_name, event=event_data, stdout=context.stdout, stderr=context.stderr) except FunctionNotFound: raise UserException( "Function {} not found in template".format(function_identifier)) except (InvalidSamDocumentException, OverridesNotWellDefinedError) as ex: raise UserException(str(ex)) except DockerImagePullFailedException as ex: raise UserException(str(ex))
def test_must_return_if_file_not_given(self): result = InvokeContext._setup_log_file(log_file=None) self.assertIsNone(result, "Log file must not be setup")
def test_must_return_tempalte_dict(self): context = InvokeContext(template_file="file") context._template_dict = "My template" self.assertEquals("My template", context.template)
def test_must_call_ping_with_docker_client_from_env(self, docker_mock): client = Mock() docker_mock.from_env.return_value = client InvokeContext._check_docker_connectivity() client.ping.assert_called_with()
def test_must_return_docker_volume_dir(self): filename = "filename" context = InvokeContext(template_file=filename, docker_volume_basedir="basedir") result = context.get_cwd() self.assertEqual(result, "basedir")
def test_must_initialize_all_containers_if_warm_containers_is_enabled( self, SamFunctionProviderMock, ContainerManagerMock ): function_provider = Mock() function = Mock() function_provider.get_all.return_value = [function] function_provider.functions = {} SamFunctionProviderMock.return_value = function_provider template_file = "template_file" env_vars_file = "env_vars_file" log_file = "log_file" invoke_context = InvokeContext( template_file=template_file, function_identifier="id", env_vars_file=env_vars_file, docker_volume_basedir="volumedir", docker_network="network", log_file=log_file, skip_pull_image=True, debug_ports=[1111], debugger_path="path-to-debugger", debug_args="args", parameter_overrides={}, aws_region="region", aws_profile="profile", warm_container_initialization_mode=ContainersInitializationMode.EAGER.value, ) _initialize_all_functions_containers_mock = Mock() invoke_context._initialize_all_functions_containers = _initialize_all_functions_containers_mock template_dict = "template_dict" invoke_context._get_template_data = Mock() invoke_context._get_template_data.return_value = template_dict env_vars_value = "env_vars_value" invoke_context._get_env_vars_value = Mock() invoke_context._get_env_vars_value.return_value = env_vars_value log_file_handle = "handle" invoke_context._setup_log_file = Mock() invoke_context._setup_log_file.return_value = log_file_handle debug_context_mock = Mock() invoke_context._get_debug_context = Mock() invoke_context._get_debug_context.return_value = debug_context_mock container_manager_mock = Mock() container_manager_mock.is_docker_reachable = True ContainerManagerMock.return_value = container_manager_mock # Call Enter method manually for testing purposes result = invoke_context.__enter__() self.assertTrue(result is invoke_context, "__enter__() must return self") self.assertEqual(invoke_context._template_dict, template_dict) self.assertEqual(invoke_context._function_provider, function_provider) self.assertEqual(invoke_context._env_vars_value, env_vars_value) self.assertEqual(invoke_context._log_file_handle, log_file_handle) self.assertEqual(invoke_context._debug_context, debug_context_mock) self.assertEqual(invoke_context._container_manager, container_manager_mock) self.assertEqual(invoke_context._containers_mode, ContainersMode.WARM) self.assertEqual(invoke_context._containers_initializing_mode, ContainersInitializationMode.EAGER) invoke_context._get_template_data.assert_called_with(template_file) SamFunctionProviderMock.assert_called_with(template_dict, {"AWS::Region": "region"}) self.assertEqual(invoke_context._get_env_vars_value.call_count, 2) self.assertEqual(invoke_context._get_env_vars_value.call_args_list, [call(env_vars_file), call(None)]) invoke_context._setup_log_file.assert_called_with(log_file) invoke_context._get_debug_context.assert_called_once_with( None, "args", "path-to-debugger", "env_vars_value", None ) ContainerManagerMock.assert_called_once_with(docker_network_id="network", skip_pull_image=True) _initialize_all_functions_containers_mock.assert_called_once_with()
def test_must_return_if_file_not_given(self): result = InvokeContext._setup_log_file(log_file=None) self.assertIsNone(result, "Log file must not be setup")