Skip to content

Commit

Permalink
fix: Use container path for file observer in a container (#6702)
Browse files Browse the repository at this point in the history
* fix: Use container path for file observer in a container

* Fix existing tests
  • Loading branch information
mildaniel authored Mar 14, 2024
1 parent e4fe122 commit a9f2a2d
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 9 deletions.
3 changes: 3 additions & 0 deletions samcli/commands/local/cli_common/invoke_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,13 @@ def local_lambda_runner(self) -> LocalLambdaRunner:
if self._local_lambda_runner:
return self._local_lambda_runner

real_path = str(os.path.dirname(os.path.abspath(self._template_file)))

self._local_lambda_runner = LocalLambdaRunner(
local_runtime=self.lambda_runtime,
function_provider=self._function_provider,
cwd=self.get_cwd(),
real_path=real_path,
aws_profile=self._aws_profile,
aws_region=self._aws_region,
env_vars_values=self._env_vars_value,
Expand Down
5 changes: 5 additions & 0 deletions samcli/commands/local/lib/local_lambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def __init__(
local_runtime: LambdaRuntime,
function_provider: SamFunctionProvider,
cwd: str,
real_path: str,
aws_profile: Optional[str] = None,
aws_region: Optional[str] = None,
env_vars_values: Optional[Dict[Any, Any]] = None,
Expand Down Expand Up @@ -72,6 +73,7 @@ def __init__(
self.local_runtime = local_runtime
self.provider = function_provider
self.cwd = cwd
self.real_path = real_path
self.aws_profile = aws_profile
self.aws_region = aws_region
self.env_vars_values = env_vars_values or {}
Expand Down Expand Up @@ -198,6 +200,8 @@ def get_invoke_config(self, function: Function) -> FunctionConfig:
if function.packagetype == ZIP:
code_abs_path = resolve_code_path(self.cwd, function.codeuri)
LOG.debug("Resolved absolute path to code is %s", code_abs_path)
code_real_path = resolve_code_path(self.real_path, function.codeuri)
LOG.debug("Resolved real code path to %s", code_real_path)

function_timeout = function.timeout

Expand All @@ -222,6 +226,7 @@ def get_invoke_config(self, function: Function) -> FunctionConfig:
timeout=function_timeout,
env_vars=env_vars,
runtime_management_config=function.runtime_management_config,
code_real_path=code_real_path,
)

def _make_env_vars(self, function: Function) -> EnvironmentVariables:
Expand Down
2 changes: 1 addition & 1 deletion samcli/lib/utils/file_observer.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def _get_zip_lambda_function_paths(function_config: FunctionConfig) -> List[str]
list[str]
List of lambda functions' source code paths to be observed
"""
code_paths = [function_config.code_abs_path]
code_paths = [function_config.code_real_path]
if function_config.layers:
# Non-local layers will not have a codeuri property and don't need to be observed
code_paths += [layer.codeuri for layer in function_config.layers if layer.codeuri]
Expand Down
2 changes: 2 additions & 0 deletions samcli/local/lambdafn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def __init__(
timeout=None,
runtime_management_config=None,
env_vars=None,
code_real_path=None,
):
"""
Parameters
Expand Down Expand Up @@ -80,6 +81,7 @@ def __init__(
self.packagetype = packagetype
self.handler = handler
self.code_abs_path = code_abs_path
self.code_real_path = code_real_path
self.layers = layers
self.memory = memory or self._DEFAULT_MEMORY
self.architecture = architecture
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/commands/local/cli_common/test_invoke_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ def test_must_create_runner(
local_runtime=runtime_mock,
function_provider=ANY,
cwd=cwd,
real_path=ANY,
debug_context=None,
env_vars_values=ANY,
aws_profile="profile",
Expand Down Expand Up @@ -704,6 +705,7 @@ def test_must_create_runner_using_warm_containers(
local_runtime=runtime_mock,
function_provider=ANY,
cwd=cwd,
real_path=ANY,
debug_context=None,
env_vars_values=ANY,
aws_profile="profile",
Expand Down Expand Up @@ -789,6 +791,7 @@ def test_must_create_runner_with_container_host_option(
local_runtime=runtime_mock,
function_provider=ANY,
cwd=cwd,
real_path=ANY,
debug_context=None,
env_vars_values=ANY,
aws_profile="profile",
Expand Down Expand Up @@ -874,6 +877,7 @@ def test_must_create_runner_with_extra_hosts_option(
local_runtime=runtime_mock,
function_provider=ANY,
cwd=cwd,
real_path=ANY,
debug_context=None,
env_vars_values=ANY,
aws_profile="profile",
Expand Down Expand Up @@ -961,6 +965,7 @@ def test_must_create_runner_with_invoke_image_option(
local_runtime=runtime_mock,
function_provider=ANY,
cwd=cwd,
real_path=ANY,
debug_context=None,
env_vars_values=ANY,
aws_profile="profile",
Expand Down
19 changes: 17 additions & 2 deletions tests/unit/commands/local/lib/test_local_lambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ def setUp(self):
self.debug_context = None
self.aws_profile = "myprofile"
self.aws_region = "region"
self.real_path = "/real/path"

self.local_lambda = LocalLambdaRunner(
self.runtime_mock,
self.function_provider_mock,
self.cwd,
real_path=self.real_path,
env_vars_values=self.env_vars_values,
debug_context=self.debug_context,
aws_profile=self.aws_profile,
Expand Down Expand Up @@ -184,6 +186,7 @@ def setUp(self):
self.runtime_mock = Mock()
self.function_provider_mock = Mock()
self.cwd = "/my/current/working/directory"
self.real_path = "/real/path"
self.debug_context = None
self.aws_profile = "myprofile"
self.aws_region = "region"
Expand All @@ -195,6 +198,7 @@ def setUp(self):
self.runtime_mock,
self.function_provider_mock,
self.cwd,
real_path=self.real_path,
env_vars_values=self.env_vars_values,
debug_context=self.debug_context,
)
Expand Down Expand Up @@ -387,11 +391,13 @@ def setUp(self):
self.debug_context = None
self.env_vars_values = {}
self.aws_region = "region"
self.real_path = "/real/path"

self.local_lambda = LocalLambdaRunner(
self.runtime_mock,
self.function_provider_mock,
self.cwd,
real_path=self.real_path,
env_vars_values=self.env_vars_values,
debug_context=self.debug_context,
)
Expand Down Expand Up @@ -457,9 +463,10 @@ def test_must_work(self, FunctionConfigMock, is_debugging_mock, resolve_code_pat
architecture=ARM64,
full_path=function.full_path,
runtime_management_config=function.runtime_management_config,
code_real_path=codepath,
)

resolve_code_path_patch.assert_called_with(self.cwd, function.codeuri)
resolve_code_path_patch.assert_called_with(self.real_path, function.codeuri)
self.local_lambda._make_env_vars.assert_called_with(function)

@patch("samcli.commands.local.lib.local_lambda.resolve_code_path")
Expand Down Expand Up @@ -526,9 +533,10 @@ def test_timeout_set_to_max_during_debugging(
architecture=X86_64,
full_path=function.full_path,
runtime_management_config=function.runtime_management_config,
code_real_path=codepath,
)

resolve_code_path_patch.assert_called_with(self.cwd, "codeuri")
resolve_code_path_patch.assert_called_with(self.real_path, "codeuri")
self.local_lambda._make_env_vars.assert_called_with(function)


Expand All @@ -541,11 +549,13 @@ def setUp(self):
self.aws_profile = "myprofile"
self.aws_region = "region"
self.env_vars_values = {}
self.real_path = "/real/path"

self.local_lambda = LocalLambdaRunner(
self.runtime_mock,
self.function_provider_mock,
self.cwd,
real_path=self.real_path,
env_vars_values=self.env_vars_values,
debug_context=self.debug_context,
)
Expand Down Expand Up @@ -729,11 +739,13 @@ def setUp(self):
self.env_vars_values = {}
self.container_host = "localhost"
self.container_host_interface = "127.0.0.1"
self.real_path = "/real/path"

self.local_lambda = LocalLambdaRunner(
self.runtime_mock,
self.function_provider_mock,
self.cwd,
real_path=self.real_path,
env_vars_values=self.env_vars_values,
debug_context=self.debug_context,
container_host=self.container_host,
Expand Down Expand Up @@ -776,11 +788,13 @@ def setUp(self):
self.aws_profile = "myprofile"
self.aws_region = "region"
self.env_vars_values = {}
self.real_path = "/real/path"

self.local_lambda = LocalLambdaRunner(
self.runtime_mock,
self.function_provider_mock,
self.cwd,
real_path=self.real_path,
env_vars_values=self.env_vars_values,
debug_context=self.debug_context,
)
Expand All @@ -793,6 +807,7 @@ def test_must_be_off(self):
self.runtime_mock,
self.function_provider_mock,
self.cwd,
self.real_path,
env_vars_values=self.env_vars_values,
debug_context=None,
)
Expand Down
21 changes: 15 additions & 6 deletions tests/unit/lib/utils/test_file_observer.py
Original file line number Diff line number Diff line change
Expand Up @@ -738,21 +738,23 @@ def test_watch_ZIP_lambda_function(self):
lambda_function = Mock()
lambda_function.packagetype = ZIP
lambda_function.code_abs_path = "path1"
lambda_function.code_real_path = "path2"
lambda_function.layers = []
self.lambda_function_observer.watch(lambda_function)
self.assertEqual(
self.lambda_function_observer._observed_functions,
{
ZIP: {"path1": [lambda_function]},
ZIP: {"path2": [lambda_function]},
IMAGE: {},
},
)
self.file_observer_mock.watch.assert_called_with("path1")
self.file_observer_mock.watch.assert_called_with("path2")

def test_watch_ZIP_lambda_function_with_layers(self):
lambda_function = Mock()
lambda_function.packagetype = ZIP
lambda_function.code_abs_path = "path1"
lambda_function.code_real_path = "path2"
layer1_mock = Mock()
layer1_mock.codeuri = "layer1_path"
layer2_mock = Mock()
Expand All @@ -764,7 +766,7 @@ def test_watch_ZIP_lambda_function_with_layers(self):
self.lambda_function_observer._observed_functions,
{
ZIP: {
"path1": [lambda_function],
"path2": [lambda_function],
"layer1_path": [lambda_function],
"layer2_path": [lambda_function],
},
Expand All @@ -774,7 +776,7 @@ def test_watch_ZIP_lambda_function_with_layers(self):
self.assertEqual(
self.file_observer_mock.watch.call_args_list,
[
call("path1"),
call("path2"),
call("layer1_path"),
call("layer2_path"),
],
Expand All @@ -784,6 +786,7 @@ def test_watch_ZIP_lambda_function_with_non_local_layers(self):
lambda_function = Mock()
lambda_function.packagetype = ZIP
lambda_function.code_abs_path = "path1"
lambda_function.code_real_path = "path2"
layer1_mock = LayerVersion(arn="arn", codeuri="layer1_path")
layer2_mock = LayerVersion(arn="arn2", codeuri=None)

Expand All @@ -793,7 +796,7 @@ def test_watch_ZIP_lambda_function_with_non_local_layers(self):
self.lambda_function_observer._observed_functions,
{
ZIP: {
"path1": [lambda_function],
"path2": [lambda_function],
"layer1_path": [lambda_function],
},
IMAGE: {},
Expand All @@ -802,7 +805,7 @@ def test_watch_ZIP_lambda_function_with_non_local_layers(self):
self.assertEqual(
self.file_observer_mock.watch.call_args_list,
[
call("path1"),
call("path2"),
call("layer1_path"),
],
)
Expand Down Expand Up @@ -836,12 +839,14 @@ def setUp(self, ImageObserverMock, FileObserverMock):
self.zip_lambda_function1 = Mock()
self.zip_lambda_function1.packagetype = ZIP
self.zip_lambda_function1.code_abs_path = "path1"
self.zip_lambda_function1.code_real_path = "path1"
self.zip_lambda_function1.layers = []
self.lambda_function_observer.watch(self.zip_lambda_function1)

self.zip_lambda_function2 = Mock()
self.zip_lambda_function2.packagetype = ZIP
self.zip_lambda_function2.code_abs_path = "path2"
self.zip_lambda_function2.code_real_path = "path2"
layer1_mock = Mock()
layer1_mock.codeuri = "layer1_path1"
layer2_mock = Mock()
Expand All @@ -852,6 +857,7 @@ def setUp(self, ImageObserverMock, FileObserverMock):
self.zip_lambda_function3 = Mock()
self.zip_lambda_function3.packagetype = ZIP
self.zip_lambda_function3.code_abs_path = "path3"
self.zip_lambda_function3.code_real_path = "path3"
self.zip_lambda_function3.layers = [layer1_mock]
self.lambda_function_observer.watch(self.zip_lambda_function3)

Expand Down Expand Up @@ -996,12 +1002,14 @@ def setUp(self, ImageObserverMock, FileObserverMock):
self.zip_lambda_function1 = Mock()
self.zip_lambda_function1.packagetype = ZIP
self.zip_lambda_function1.code_abs_path = "path1"
self.zip_lambda_function1.code_real_path = "path1"
self.zip_lambda_function1.layers = []
self.lambda_function_observer.watch(self.zip_lambda_function1)

self.zip_lambda_function2 = Mock()
self.zip_lambda_function2.packagetype = ZIP
self.zip_lambda_function2.code_abs_path = "path2"
self.zip_lambda_function2.code_real_path = "path2"
layer1_mock = Mock()
layer1_mock.codeuri = "layer1_path1"
layer2_mock = Mock()
Expand All @@ -1012,6 +1020,7 @@ def setUp(self, ImageObserverMock, FileObserverMock):
self.zip_lambda_function3 = Mock()
self.zip_lambda_function3.packagetype = ZIP
self.zip_lambda_function3.code_abs_path = "path3"
self.zip_lambda_function3.code_real_path = "path3"
self.zip_lambda_function3.layers = [layer1_mock]
self.lambda_function_observer.watch(self.zip_lambda_function3)

Expand Down

0 comments on commit a9f2a2d

Please sign in to comment.