Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions samcli/local/lambdafn/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,7 @@ def _get_code_dir(self, code_path: str) -> str:
This method handles a few different cases for ``code_path``:
- ``code_path``is a existent zip/jar file: Unzip in a temp directory and return the temp directory
- ``code_path`` is a existent directory: Return this immediately
- ``code_path`` is a file/dir that does not exist: Return it as is. May be this method is not clever to
detect the existence of the path
- ``code_path`` is a file/dir that does not exist: Log a warning and return it as is

Parameters
----------
Expand All @@ -441,6 +440,14 @@ def _get_code_dir(self, code_path: str) -> str:
Directory containing Lambda function code. It can be mounted directly in container
"""

if code_path and not os.path.exists(code_path):
LOG.warning(
"Local code path '%s' does not exist. It will be mounted as an empty directory in the "
"container, which will likely cause the invocation to fail. Verify the CodeUri/ContentUri "
"of your function or layer, or run 'sam build' if the path is a build artifact.",
code_path,
)

if code_path and os.path.isfile(code_path) and code_path.endswith(self.SUPPORTED_ARCHIVE_EXTENSIONS):
decompressed_dir: str = _unzip_file(code_path, mount_symlinks=self._mount_symlinks)
self._temp_uncompressed_paths_to_be_cleaned += [decompressed_dir]
Expand Down
40 changes: 40 additions & 0 deletions tests/unit/local/lambdafn/test_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,46 @@ def test_must_return_a_valid_file(self, unzip_file_mock, shutil_mock, os_mock):
# Because we never unzipped anything, we should never delete
shutil_mock.rmtree.assert_not_called()

@patch("samcli.local.lambdafn.runtime.LOG")
@patch("samcli.local.lambdafn.runtime.os")
@patch("samcli.local.lambdafn.runtime.shutil")
@patch("samcli.local.lambdafn.runtime._unzip_file")
def test_must_warn_when_code_path_does_not_exist(self, unzip_file_mock, shutil_mock, os_mock, log_mock):
"""
Input is a path that does not exist on the local machine
"""
code_path = "/nonexistent/path"

os_mock.path.exists.return_value = False
os_mock.path.isfile.return_value = False

result = self.runtime._get_code_dir(code_path)
# code path must still be returned as is
self.assertEqual(result, code_path)

unzip_file_mock.assert_not_called()
log_mock.warning.assert_called_once()
# The warning must include the offending path
self.assertIn(code_path, log_mock.warning.call_args[0])

@patch("samcli.local.lambdafn.runtime.LOG")
@patch("samcli.local.lambdafn.runtime.os")
@patch("samcli.local.lambdafn.runtime.shutil")
@patch("samcli.local.lambdafn.runtime._unzip_file")
def test_must_not_warn_when_code_path_exists(self, unzip_file_mock, shutil_mock, os_mock, log_mock):
"""
Input is a directory that exists, no warning must be logged
"""
code_path = "codedir"

os_mock.path.exists.return_value = True
os_mock.path.isfile.return_value = False

result = self.runtime._get_code_dir(code_path)
self.assertEqual(result, code_path)

log_mock.warning.assert_not_called()


class TestLambdaRuntime_unarchived_layer(TestCase):
def setUp(self):
Expand Down