Skip to content

Commit

Permalink
fix: Add error handling for provided runtime layer building (#5733)
Browse files Browse the repository at this point in the history
* fix: Add error handling for provided runtime layer building

* Format

* Default to runtime language instead of throwing an exception

* Add integration tests

* Fix template spacing
  • Loading branch information
mildaniel authored Aug 10, 2023
1 parent 17b25eb commit 19a0cae
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 1 deletion.
6 changes: 5 additions & 1 deletion samcli/lib/build/app_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@

LOG = logging.getLogger(__name__)

FIRST_COMPATIBLE_RUNTIME_INDEX = 0


class ApplicationBuildResult(NamedTuple):
"""
Expand Down Expand Up @@ -546,7 +548,9 @@ def _build_layer(
)
# Only set to this value if specified workflow is makefile
# which will result in config language as provided
build_runtime = compatible_runtimes[0]
build_runtime = (
compatible_runtimes[FIRST_COMPATIBLE_RUNTIME_INDEX] if compatible_runtimes else config.language
)
global_image = self._build_images.get(None)
image = self._build_images.get(layer_name, global_image)
# pass to container only when specified workflow is supported to overwrite runtime to get image
Expand Down
27 changes: 27 additions & 0 deletions tests/integration/buildcmd/test_build_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1753,6 +1753,8 @@ class TestBuildCommand_LayerBuilds(BuildIntegBase):
EXPECTED_FILES_PROJECT_MANIFEST = {"__init__.py", "main.py", "requirements.txt"}
EXPECTED_LAYERS_FILES_PROJECT_MANIFEST = {"__init__.py", "layer.py", "numpy", "requirements.txt"}

EXPECTED_LAYERS_FILES_NO_COMPATIBLE_RUNTIMES = {"__init__.py", "layer.py", "requirements.txt"}

@parameterized.expand(
[
("python3.7", False, "LayerOne", "ContentUri"),
Expand Down Expand Up @@ -1810,6 +1812,31 @@ def test_build_layer_with_makefile(self, build_method, use_container, layer_iden
"python",
)

@skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE)
def test_build_layer_with_makefile_no_compatible_runtimes(self):
build_method = "makefile"
use_container = True
layer_identifier = "LayerWithMakefileNoCompatibleRuntimes"

overrides = {"LayerBuildMethod": build_method, "LayerMakeContentUri": "PyLayerMake"}
cmdlist = self.get_command_list(
use_container=use_container, parameter_overrides=overrides, function_identifier=layer_identifier
)

LOG.info("Running Command: {}".format(cmdlist))

command_result = run_command(cmdlist, cwd=self.working_dir)
self.assertEqual(command_result.process.returncode, 0)

LOG.info("Default build dir: %s", self.default_build_dir)
self._verify_built_artifact(
self.default_build_dir,
layer_identifier,
self.EXPECTED_LAYERS_FILES_NO_COMPATIBLE_RUNTIMES,
"ContentUri",
"random",
)

@parameterized.expand([("python3.7", False, "LayerTwo"), ("python3.7", "use_container", "LayerTwo")])
def test_build_fails_with_missing_metadata(self, runtime, use_container, layer_identifier):
if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD):
Expand Down
5 changes: 5 additions & 0 deletions tests/integration/testdata/buildcmd/PyLayerMake/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@ build-LayerWithMakefile:
cp *.py "$(ARTIFACTS_DIR)/python"
cp *.txt "$(ARTIFACTS_DIR)/python"
python -m pip install -r requirements.txt -t "$(ARTIFACTS_DIR)/python"
build-LayerWithMakefileNoCompatibleRuntimes:
mkdir -p "$(ARTIFACTS_DIR)/random"
cp *.py "$(ARTIFACTS_DIR)/random"
cp *.txt "$(ARTIFACTS_DIR)/random"

Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,11 @@ Resources:
- python3.7
Metadata:
BuildMethod: !Ref LayerBuildMethod

LayerWithMakefileNoCompatibleRuntimes:
Type: AWS::Serverless::LayerVersion
Properties:
Description: Layer four
ContentUri: !Ref LayerMakeContentUri
Metadata:
BuildMethod: !Ref LayerBuildMethod
37 changes: 37 additions & 0 deletions tests/unit/lib/build_module/test_app_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,43 @@ def test_must_build_layer_in_process(self, get_layer_subfolder_mock, osutils_moc
is_building_layer=True,
)

@parameterized.expand([([],), (None,)])
@patch("samcli.lib.build.app_builder.get_workflow_config")
@patch("samcli.lib.build.app_builder.osutils")
@patch("samcli.lib.build.app_builder.get_layer_subfolder")
def test_must_handle_layer_build_compatible_runtimes_missing(
self, compatible_runtimes, get_layer_subfolder_mock, osutils_mock, get_workflow_config_mock
):
get_layer_subfolder_mock.return_value = "layer"
config_mock = Mock()
config_mock.manifest_name = "manifest_name"
config_mock.language = "provided"

scratch_dir = "scratch"
osutils_mock.mkdir_temp.return_value.__enter__ = Mock(return_value=scratch_dir)
osutils_mock.mkdir_temp.return_value.__exit__ = Mock()

get_workflow_config_mock.return_value = config_mock
build_function_on_container_mock = Mock()

self.builder._container_manager = Mock()
self.builder._build_function_on_container = build_function_on_container_mock
self.builder._build_layer("layer_name", "code_uri", "provided", compatible_runtimes, ARM64, "full_path")

build_function_on_container_mock.assert_called_once_with(
config_mock,
PathValidator("code_uri"),
PathValidator("layer"),
PathValidator("manifest_name"),
"provided",
ARM64,
{"build_logical_id": "layer_name"},
None,
None,
is_building_layer=True,
specified_workflow=None,
)

@patch("samcli.lib.build.app_builder.get_workflow_config")
@patch("samcli.lib.build.app_builder.osutils")
@patch("samcli.lib.build.app_builder.get_layer_subfolder")
Expand Down

0 comments on commit 19a0cae

Please sign in to comment.