Exemplo n.º 1
0
class TestWarmLambdaRuntime_get_code_dir(TestCase):
    def setUp(self):
        self.manager_mock = Mock()

    @patch("samcli.local.lambdafn.runtime.os")
    def test_must_return_same_path_if_path_is_not_compressed_file(self, os_mock):
        lambda_image_mock = Mock()
        os_mock.path.isfile.return_value = False
        code_path = "path"

        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)
        res = self.runtime._get_code_dir(code_path)
        self.assertEqual(self.runtime._temp_uncompressed_paths_to_be_cleaned, [])
        self.assertEqual(res, code_path)

    @patch("samcli.local.lambdafn.runtime._unzip_file")
    @patch("samcli.local.lambdafn.runtime.os")
    def test_must_cache_temp_uncompressed_dirs_to_be_cleared_later(self, os_mock, _unzip_file_mock):
        lambda_image_mock = Mock()
        os_mock.path.isfile.return_value = True
        uncompressed_dir_mock = Mock()
        _unzip_file_mock.return_value = uncompressed_dir_mock
        code_path = "path.zip"

        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)
        res = self.runtime._get_code_dir(code_path)
        self.assertEqual(self.runtime._temp_uncompressed_paths_to_be_cleaned, [uncompressed_dir_mock])
        self.assertEqual(res, uncompressed_dir_mock)
Exemplo n.º 2
0
class TestWarmLambdaRuntime_clean_warm_containers_related_resources(TestCase):
    def setUp(self):
        self.manager_mock = Mock()
        lambda_image_mock = Mock()
        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)
        self.observer_mock = Mock()
        self.func1_container_mock = Mock()
        self.func2_container_mock = Mock()
        self.runtime._containers = {
            "func_name1": self.func1_container_mock,
            "func_name2": self.func2_container_mock,
        }
        self.runtime._observer = self.observer_mock
        self.runtime._observer.is_alive.return_value = True
        self.runtime._temp_uncompressed_paths_to_be_cleaned = ["path1", "path2"]

    @patch("samcli.local.lambdafn.runtime.shutil")
    def test_must_container_stopped_when_its_code_dir_got_changed(self, shutil_mock):

        self.runtime.clean_running_containers_and_related_resources()
        self.assertEquals(
            self.runtime._container_manager.stop.call_args_list,
            [
                call(self.func1_container_mock),
                call(self.func2_container_mock),
            ],
        )
        self.assertEquals(
            shutil_mock.rmtree.call_args_list,
            [
                call("path1"),
                call("path2"),
            ],
        )
        self.runtime._observer.stop.assert_called_once_with()
Exemplo n.º 3
0
    def test_must_run_container_then_wait_for_result_and_container_not_stopped(
        self, LambdaContainerMock, LambdaFunctionObserverMock
    ):
        event = "event"
        code_dir = "some code dir"
        stdout = "stdout"
        stderr = "stderr"
        container = Mock()
        timer = Mock()
        debug_options = Mock()
        debug_options.debug_function = self.name
        lambda_image_mock = Mock()

        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)

        # Using MagicMock to mock the context manager
        self.runtime._get_code_dir = MagicMock()
        self.runtime._get_code_dir.return_value = code_dir

        # Configure interrupt handler
        self.runtime._configure_interrupt = Mock()
        self.runtime._configure_interrupt.return_value = timer

        LambdaContainerMock.return_value = container
        container.is_running.return_value = False

        self.runtime.invoke(self.func_config, event, debug_context=debug_options, stdout=stdout, stderr=stderr)

        # Verify if Lambda Event data is set
        self.env_vars.add_lambda_event_body.assert_not_called()

        # Make sure env-vars get resolved
        self.env_vars.resolve.assert_called_with()

        # Make sure the context manager is called to return the code directory
        self.runtime._get_code_dir.assert_called_with(self.code_path)

        # Make sure the container is created with proper values
        LambdaContainerMock.assert_called_with(
            self.lang,
            self.imageuri,
            self.handler,
            self.packagetype,
            self.imageconfig,
            code_dir,
            self.layers,
            lambda_image_mock,
            debug_options=debug_options,
            env_vars=self.env_var_value,
            memory_mb=self.DEFAULT_MEMORY,
        )

        # Run the container and get results
        self.manager_mock.run.assert_called_with(container)
        self.runtime._configure_interrupt.assert_called_with(self.name, self.DEFAULT_TIMEOUT, container, True)
        container.wait_for_result.assert_called_with(event=event, name=self.name, stdout=stdout, stderr=stderr)

        # Finally block
        timer.cancel.assert_called_with()
        self.manager_mock.stop.assert_not_called()
Exemplo n.º 4
0
    def test_must_return_same_path_if_path_is_not_compressed_file(self, os_mock):
        lambda_image_mock = Mock()
        os_mock.path.isfile.return_value = False
        code_path = "path"

        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)
        res = self.runtime._get_code_dir(code_path)
        self.assertEqual(self.runtime._temp_uncompressed_paths_to_be_cleaned, [])
        self.assertEqual(res, code_path)
Exemplo n.º 5
0
    def test_must_cache_temp_uncompressed_dirs_to_be_cleared_later(self, os_mock, _unzip_file_mock):
        lambda_image_mock = Mock()
        os_mock.path.isfile.return_value = True
        uncompressed_dir_mock = Mock()
        _unzip_file_mock.return_value = uncompressed_dir_mock
        code_path = "path.zip"

        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)
        res = self.runtime._get_code_dir(code_path)
        self.assertEqual(self.runtime._temp_uncompressed_paths_to_be_cleaned, [uncompressed_dir_mock])
        self.assertEqual(res, uncompressed_dir_mock)
Exemplo n.º 6
0
    def setUp(self):
        self.manager_mock = Mock()
        lambda_image_mock = Mock()
        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)

        self.observer_mock = Mock()
        self.runtime._observer = self.observer_mock

        self.lang = "runtime"
        self.handler = "handler"
        self.imageuri = None
        self.imageconfig = None

        self.func1_name = "func1_name"
        self.func1_code_path = "func1_code_path"

        self.func2_name = "func2_name"
        self.func2_code_path = "func2_code_path"

        self.common_layer_code_path = "layer1-code-path"
        self.common_layer_arn = "layer1-arn"
        self.common_layers = [
            LayerVersion(arn=self.common_layer_arn,
                         codeuri=self.common_layer_code_path,
                         compatible_runtimes=self.lang)
        ]

        self.func_config1 = FunctionConfig(
            self.func1_name,
            self.lang,
            self.handler,
            self.imageuri,
            self.imageconfig,
            ZIP,
            self.func1_code_path,
            self.common_layers,
        )
        self.func_config2 = FunctionConfig(
            self.func2_name,
            self.lang,
            self.handler,
            self.imageuri,
            self.imageconfig,
            IMAGE,
            self.func2_code_path,
            self.common_layers,
        )

        self.func1_container_mock = Mock()
        self.func2_container_mock = Mock()
        self.runtime._containers = {
            self.func1_name: self.func1_container_mock,
            self.func2_name: self.func2_container_mock,
        }
Exemplo n.º 7
0
class TestWarmLambdaRuntime_add_function_to_observer(TestCase):
    def setUp(self):
        self.manager_mock = Mock()

        self.name = "name"
        self.lang = "runtime"
        self.handler = "handler"
        self.code_path = "code-path"

        self.layer1_code_path = "layer1-code-path"
        self.layer1_arn = "layer1-arn"
        self.layers = [
            LayerVersion(arn=self.layer1_arn,
                         codeuri=self.layer1_code_path,
                         compatible_runtimes=self.lang)
        ]
        self.imageuri = None
        self.packagetype = ZIP
        self.imageconfig = None
        self.func_config = FunctionConfig(
            self.name,
            self.lang,
            self.handler,
            self.imageuri,
            self.imageconfig,
            self.packagetype,
            self.code_path,
            self.layers,
        )

    @patch("samcli.local.lambdafn.runtime.FileObserver")
    def test_must_observe_function_code_path_and_layers_paths(
            self, FileObserverMock):
        lambda_image_mock = Mock()
        observer_mock = Mock()
        FileObserverMock.return_value = observer_mock
        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)
        self.runtime._add_function_to_observer(self.func_config)

        self.assertEqual(
            self.runtime._observed_paths,
            {
                "code-path": [self.func_config],
                "layer1-code-path": [self.func_config],
            },
        )
        self.assertEqual(
            observer_mock.watch.call_args_list,
            [
                call("code-path"),
                call("layer1-code-path"),
            ],
        )
        observer_mock.start.assert_called_once_with()
Exemplo n.º 8
0
 def setUp(self):
     self.manager_mock = Mock()
     lambda_image_mock = Mock()
     self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)
     self.observer_mock = Mock()
     self.func1_container_mock = Mock()
     self.func2_container_mock = Mock()
     self.runtime._containers = {
         "func_name1": self.func1_container_mock,
         "func_name2": self.func2_container_mock,
     }
     self.runtime._observer = self.observer_mock
     self.runtime._observer.is_alive.return_value = True
     self.runtime._temp_uncompressed_paths_to_be_cleaned = ["path1", "path2"]
Exemplo n.º 9
0
    def test_must_create_non_cached_container(self, LambdaContainerMock,
                                              LambdaFunctionObserverMock):
        code_dir = "some code dir"
        container = Mock()
        debug_options = Mock()
        debug_options.debug_function = self.name
        lambda_image_mock = Mock()

        lambda_function_observer_mock = Mock()
        LambdaFunctionObserverMock.return_value = lambda_function_observer_mock

        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)

        # Using MagicMock to mock the context manager
        self.runtime._get_code_dir = MagicMock()
        self.runtime._get_code_dir.return_value = code_dir

        LambdaContainerMock.return_value = container

        self.runtime.create(self.func_config, debug_context=debug_options)

        # Make sure the container is created with proper values
        LambdaContainerMock.assert_called_with(
            self.lang,
            self.imageuri,
            self.handler,
            self.packagetype,
            self.imageconfig,
            code_dir,
            self.layers,
            lambda_image_mock,
            debug_options=debug_options,
            env_vars=self.env_var_value,
            memory_mb=self.DEFAULT_MEMORY,
            container_host=None,
            container_host_interface=None,
        )

        self.manager_mock.create.assert_called_with(container)
        # validate that the created container got cached
        self.assertEqual(self.runtime._containers[self.name], container)
        lambda_function_observer_mock.watch.assert_called_with(
            self.func_config)
        lambda_function_observer_mock.start.assert_called_with()
Exemplo n.º 10
0
    def lambda_runtime(self) -> LambdaRuntime:
        if not self._lambda_runtimes:
            layer_downloader = LayerDownloader(self._layer_cache_basedir, self.get_cwd(), self._stacks)
            image_builder = LambdaImage(layer_downloader, self._skip_pull_image, self._force_image_build)
            self._lambda_runtimes = {
                ContainersMode.WARM: WarmLambdaRuntime(self._container_manager, image_builder),
                ContainersMode.COLD: LambdaRuntime(self._container_manager, image_builder),
            }

        return self._lambda_runtimes[self._containers_mode]
Exemplo n.º 11
0
    def test_must_return_cached_container(self, LambdaContainerMock, LambdaFunctionObserverMock):
        code_dir = "some code dir"
        container = Mock()
        debug_options = Mock()
        debug_options.debug_function = self.name
        lambda_image_mock = Mock()

        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)

        # Using MagicMock to mock the context manager
        self.runtime._get_code_dir = MagicMock()
        self.runtime._get_code_dir.return_value = code_dir

        LambdaContainerMock.return_value = container
        self.runtime.create(self.func_config, debug_context=debug_options)
        result = self.runtime.create(self.func_config, debug_context=debug_options)

        # validate that the manager.create method got called only one time
        self.manager_mock.create.assert_called_once_with(container)
        self.assertEqual(result, container)
Exemplo n.º 12
0
    def test_must_observe_function_code_path_and_layers_paths(
            self, FileObserverMock):
        lambda_image_mock = Mock()
        observer_mock = Mock()
        FileObserverMock.return_value = observer_mock
        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)
        self.runtime._add_function_to_observer(self.func_config)

        self.assertEqual(
            self.runtime._observed_paths,
            {
                "code-path": [self.func_config],
                "layer1-code-path": [self.func_config],
            },
        )
        self.assertEqual(
            observer_mock.watch.call_args_list,
            [
                call("code-path"),
                call("layer1-code-path"),
            ],
        )
        observer_mock.start.assert_called_once_with()
Exemplo n.º 13
0
    def test_must_ignore_debug_options_if_function_name_is_not_debug_function(
            self, LambdaContainerMock):
        code_dir = "some code dir"
        container = Mock()
        debug_options = Mock()
        debug_options.debug_function = "name2"
        lambda_image_mock = Mock()

        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)
        self.runtime._add_function_to_observer = Mock()

        # Using MagicMock to mock the context manager
        self.runtime._get_code_dir = MagicMock()
        self.runtime._get_code_dir.return_value = code_dir

        LambdaContainerMock.return_value = container

        self.runtime.create(self.func_config, debug_context=debug_options)

        # Make sure the container is created with proper values
        LambdaContainerMock.assert_called_with(
            self.lang,
            self.imageuri,
            self.handler,
            self.packagetype,
            self.imageconfig,
            code_dir,
            self.layers,
            lambda_image_mock,
            debug_options=None,
            env_vars=self.env_var_value,
            memory_mb=self.DEFAULT_MEMORY,
        )
        self.manager_mock.create.assert_called_with(container)
        # validate that the created container got cached
        self.assertEqual(self.runtime._containers[self.name], container)
Exemplo n.º 14
0
class TestWarmLambdaRuntime_on_code_change(TestCase):
    def setUp(self):
        self.manager_mock = Mock()
        lambda_image_mock = Mock()
        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)

        self.observer_mock = Mock()
        self.runtime._observer = self.observer_mock

        self.lang = "runtime"
        self.handler = "handler"
        self.imageuri = None
        self.imageconfig = None

        self.func1_name = "func1_name"
        self.func1_code_path = "func1_code_path"

        self.func2_name = "func2_name"
        self.func2_code_path = "func2_code_path"

        self.common_layer_code_path = "layer1-code-path"
        self.common_layer_arn = "layer1-arn"
        self.common_layers = [
            LayerVersion(arn=self.common_layer_arn, codeuri=self.common_layer_code_path, compatible_runtimes=self.lang)
        ]

        self.func_config1 = FunctionConfig(
            self.func1_name,
            self.lang,
            self.handler,
            self.imageuri,
            self.imageconfig,
            ZIP,
            self.func1_code_path,
            self.common_layers,
        )
        self.func_config2 = FunctionConfig(
            self.func2_name,
            self.lang,
            self.handler,
            self.imageuri,
            self.imageconfig,
            IMAGE,
            self.func2_code_path,
            self.common_layers,
        )

        self.func1_container_mock = Mock()
        self.func2_container_mock = Mock()
        self.runtime._containers = {
            self.func1_name: self.func1_container_mock,
            self.func2_name: self.func2_container_mock,
        }

    def test_only_one_container_get_stopped_when_its_code_dir_got_changed(self):
        self.runtime._on_code_change([self.func_config1])

        self.manager_mock.stop.assert_called_with(self.func1_container_mock)
        self.assertEqual(
            self.runtime._containers,
            {
                self.func2_name: self.func2_container_mock,
            },
        )

        self.observer_mock.unwatch.assert_called_with(self.func_config1)

    def test_both_containers_get_stopped_when_both_functions_got_updated(self):
        self.runtime._on_code_change([self.func_config1, self.func_config2])

        self.assertEqual(
            self.manager_mock.stop.call_args_list,
            [
                call(self.func1_container_mock),
                call(self.func2_container_mock),
            ],
        )
        self.assertEqual(self.runtime._containers, {})

        self.assertEqual(
            self.observer_mock.unwatch.call_args_list,
            [
                call(self.func_config1),
                call(self.func_config2),
            ],
        )
Exemplo n.º 15
0
class TestWarmLambdaRuntime_create(TestCase):
    DEFAULT_MEMORY = 128
    DEFAULT_TIMEOUT = 3

    def setUp(self):
        self.manager_mock = Mock()
        self.name = "name"
        self.lang = "runtime"
        self.handler = "handler"
        self.code_path = "code-path"
        self.layers = []
        self.imageuri = None
        self.packagetype = ZIP
        self.imageconfig = None
        self.func_config = FunctionConfig(
            self.name,
            self.lang,
            self.handler,
            self.imageuri,
            self.imageconfig,
            self.packagetype,
            self.code_path,
            self.layers,
        )

        self.env_vars = Mock()
        self.func_config.env_vars = self.env_vars
        self.env_var_value = {"a": "b"}
        self.env_vars.resolve.return_value = self.env_var_value

    @patch("samcli.local.lambdafn.runtime.LambdaFunctionObserver")
    @patch("samcli.local.lambdafn.runtime.LambdaContainer")
    def test_must_create_non_cached_container(self, LambdaContainerMock, LambdaFunctionObserverMock):
        code_dir = "some code dir"
        container = Mock()
        debug_options = Mock()
        debug_options.debug_function = self.name
        lambda_image_mock = Mock()

        lambda_function_observer_mock = Mock()
        LambdaFunctionObserverMock.return_value = lambda_function_observer_mock

        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)

        # Using MagicMock to mock the context manager
        self.runtime._get_code_dir = MagicMock()
        self.runtime._get_code_dir.return_value = code_dir

        LambdaContainerMock.return_value = container

        self.runtime.create(self.func_config, debug_context=debug_options)

        # Make sure the container is created with proper values
        LambdaContainerMock.assert_called_with(
            self.lang,
            self.imageuri,
            self.handler,
            self.packagetype,
            self.imageconfig,
            code_dir,
            self.layers,
            lambda_image_mock,
            debug_options=debug_options,
            env_vars=self.env_var_value,
            memory_mb=self.DEFAULT_MEMORY,
        )

        self.manager_mock.create.assert_called_with(container)
        # validate that the created container got cached
        self.assertEqual(self.runtime._containers[self.name], container)
        lambda_function_observer_mock.watch.assert_called_with(self.func_config)
        lambda_function_observer_mock.start.assert_called_with()

    @patch("samcli.local.lambdafn.runtime.LambdaFunctionObserver")
    @patch("samcli.local.lambdafn.runtime.LambdaContainer")
    def test_must_return_cached_container(self, LambdaContainerMock, LambdaFunctionObserverMock):
        code_dir = "some code dir"
        container = Mock()
        debug_options = Mock()
        debug_options.debug_function = self.name
        lambda_image_mock = Mock()

        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)

        # Using MagicMock to mock the context manager
        self.runtime._get_code_dir = MagicMock()
        self.runtime._get_code_dir.return_value = code_dir

        LambdaContainerMock.return_value = container
        self.runtime.create(self.func_config, debug_context=debug_options)
        result = self.runtime.create(self.func_config, debug_context=debug_options)

        # validate that the manager.create method got called only one time
        self.manager_mock.create.assert_called_once_with(container)
        self.assertEqual(result, container)

    @patch("samcli.local.lambdafn.runtime.LambdaFunctionObserver")
    @patch("samcli.local.lambdafn.runtime.LambdaContainer")
    def test_must_ignore_debug_options_if_function_name_is_not_debug_function(
        self, LambdaContainerMock, LambdaFunctionObserverMock
    ):
        code_dir = "some code dir"
        container = Mock()
        debug_options = Mock()
        debug_options.debug_function = "name2"
        lambda_image_mock = Mock()

        self.runtime = WarmLambdaRuntime(self.manager_mock, lambda_image_mock)

        # Using MagicMock to mock the context manager
        self.runtime._get_code_dir = MagicMock()
        self.runtime._get_code_dir.return_value = code_dir

        LambdaContainerMock.return_value = container

        self.runtime.create(self.func_config, debug_context=debug_options)

        # Make sure the container is created with proper values
        LambdaContainerMock.assert_called_with(
            self.lang,
            self.imageuri,
            self.handler,
            self.packagetype,
            self.imageconfig,
            code_dir,
            self.layers,
            lambda_image_mock,
            debug_options=None,
            env_vars=self.env_var_value,
            memory_mb=self.DEFAULT_MEMORY,
        )
        self.manager_mock.create.assert_called_with(container)
        # validate that the created container got cached
        self.assertEqual(self.runtime._containers[self.name], container)