Skip to content

Commit

Permalink
Merge 7.5 hotfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiusens authored Nov 30, 2023
2 parents 5ad3824 + 400e40b commit e1a671a
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 24 deletions.
2 changes: 1 addition & 1 deletion requirements-devel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ craft-cli==2.4.0
craft-grammar==1.1.1
craft-parts==1.25.1
craft-providers==1.19.2
craft-store==2.4.0
craft-store==2.5.0
cryptography==41.0.4
Deprecated==1.2.13
dill==0.3.6
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ craft-cli==2.4.0
craft-grammar==1.1.1
craft-parts==1.25.1
craft-providers==1.19.2
craft-store==2.4.0
craft-store==2.5.0
cryptography==41.0.4
Deprecated==1.2.13
distro==1.8.0
Expand Down
15 changes: 15 additions & 0 deletions snapcraft/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
convert_architecture_deb_to_platform,
get_effective_base,
get_host_architecture,
get_supported_architectures,
is_architecture_supported,
)


Expand Down Expand Up @@ -119,6 +121,19 @@ def _validate_architectures(architectures):
)
unique_build_fors.add(architecture)

# validate architectures are supported
if len(architectures):
for element in architectures:
for arch in element.build_for + element.build_on:
if arch != "all" and not is_architecture_supported(arch):
supported_archs = utils.humanize_list(
get_supported_architectures(), "and"
)
raise ValueError(
f"Architecture {arch!r} is not supported. Supported "
f"architectures are {supported_archs}."
)

return architectures


Expand Down
18 changes: 18 additions & 0 deletions snapcraft/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,24 @@ def get_host_architecture():
)


def is_architecture_supported(architecture: str) -> bool:
"""Check if an debian-syntax architecture is supported.
:param architecture: architecture to check
:returns: True if the architecture is supported by snapcraft.
"""
return architecture in list(_ARCH_TRANSLATIONS_DEB_TO_PLATFORM)


def get_supported_architectures() -> List[str]:
"""Get a list of architectures supported by snapcraft.
:returns: A list of architectures.
"""
return list(_ARCH_TRANSLATIONS_DEB_TO_PLATFORM.keys())


def convert_architecture_deb_to_platform(architecture: str) -> str:
"""Convert an architecture from deb/snap syntax to platform syntax.
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ def name(self) -> str:
@property
@override
def install_recommendation(self) -> str:
return "uninstallable"
return "snap"

def clean_project_environments(self, *, instance_name: str):
pass
Expand Down
42 changes: 21 additions & 21 deletions tests/unit/parts/test_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -1620,49 +1620,49 @@ def test_lifecycle_run_in_provider_devel_base(
def test_get_build_plan_single_element_matching(snapcraft_yaml, mocker, new_dir):
"""Test get_build_plan with a single matching element."""
mocker.patch(
"snapcraft.parts.lifecycle.get_host_architecture", return_value="aarch64"
"snapcraft.parts.lifecycle.get_host_architecture", return_value="arm64"
)
yaml_data = {
"base": "core22",
"architectures": [{"build-on": "aarch64", "build-for": "aarch64"}],
"architectures": [{"build-on": "arm64", "build-for": "arm64"}],
}

snapcraft_yaml_data = snapcraft_yaml(**yaml_data)

assert parts_lifecycle.get_build_plan(
snapcraft_yaml_data, parsed_args=argparse.Namespace(build_for=None)
) == [("aarch64", "aarch64")]
) == [("arm64", "arm64")]


def test_get_build_plan_build_for_all(snapcraft_yaml, mocker, new_dir):
"""Test get_build_plan with `build-for: all`."""
mocker.patch(
"snapcraft.parts.lifecycle.get_host_architecture", return_value="aarch64"
"snapcraft.parts.lifecycle.get_host_architecture", return_value="arm64"
)
yaml_data = {
"base": "core22",
"architectures": [{"build-on": "aarch64", "build-for": "all"}],
"architectures": [{"build-on": "arm64", "build-for": "all"}],
}

snapcraft_yaml_data = snapcraft_yaml(**yaml_data)

assert parts_lifecycle.get_build_plan(
snapcraft_yaml_data, parsed_args=argparse.Namespace(build_for=None)
) == [("aarch64", "all")]
) == [("arm64", "all")]


def test_get_build_plan_with_matching_elements(snapcraft_yaml, mocker, new_dir):
"""The build plan should only contain builds where `build-on` matches
the host architecture.
"""
mocker.patch(
"snapcraft.parts.lifecycle.get_host_architecture", return_value="aarch64"
"snapcraft.parts.lifecycle.get_host_architecture", return_value="arm64"
)
yaml_data = {
"base": "core22",
"architectures": [
{"build-on": "aarch64", "build-for": "aarch64"},
{"build-on": "aarch64", "build-for": "arm64"},
{"build-on": "arm64", "build-for": "amd64"},
{"build-on": "arm64", "build-for": "arm64"},
{"build-on": "armhf", "build-for": "armhf"},
],
}
Expand All @@ -1672,8 +1672,8 @@ def test_get_build_plan_with_matching_elements(snapcraft_yaml, mocker, new_dir):
assert parts_lifecycle.get_build_plan(
snapcraft_yaml_data, parsed_args=argparse.Namespace(build_for=None)
) == [
("aarch64", "aarch64"),
("aarch64", "arm64"),
("arm64", "amd64"),
("arm64", "arm64"),
]


Expand All @@ -1682,7 +1682,7 @@ def test_get_build_plan_list_without_matching_element(snapcraft_yaml, mocker, ne
the host architecture.
"""
mocker.patch(
"snapcraft.parts.lifecycle.get_host_architecture", return_value="aarch64"
"snapcraft.parts.lifecycle.get_host_architecture", return_value="arm64"
)
yaml_data = {
"base": "core22",
Expand All @@ -1704,21 +1704,21 @@ def test_get_build_plan_list_with_matching_element_and_env_var(
):
"""The build plan should be filtered down when `SNAPCRAFT_BUILD_FOR` is defined."""
mocker.patch(
"snapcraft.parts.lifecycle.get_host_architecture", return_value="aarch64"
"snapcraft.parts.lifecycle.get_host_architecture", return_value="arm64"
)
yaml_data = {
"base": "core22",
"architectures": [
{"build-on": "aarch64", "build-for": "aarch64"},
{"build-on": "aarch64", "build-for": "armhf"},
{"build-on": "arm64", "build-for": "arm64"},
{"build-on": "arm64", "build-for": "armhf"},
],
}

snapcraft_yaml_data = snapcraft_yaml(**yaml_data)

assert parts_lifecycle.get_build_plan(
snapcraft_yaml_data, parsed_args=argparse.Namespace(build_for="aarch64")
) == [("aarch64", "aarch64")]
snapcraft_yaml_data, parsed_args=argparse.Namespace(build_for="arm64")
) == [("arm64", "arm64")]


def test_get_build_plan_list_without_matching_element_and_build_for_arg(
Expand All @@ -1727,21 +1727,21 @@ def test_get_build_plan_list_without_matching_element_and_build_for_arg(
"""The build plan should be empty when no plan has a matching `build_for`
matching `SNAPCRAFT_BUILD_FOR.`"""
mocker.patch(
"snapcraft.parts.lifecycle.get_host_architecture", return_value="aarch64"
"snapcraft.parts.lifecycle.get_host_architecture", return_value="arm64"
)
yaml_data = {
"base": "core22",
"architectures": [
{"build-on": "aarch64", "build-for": "aarch64"},
{"build-on": "aarch64", "build-for": "armhf"},
{"build-on": "arm64", "build-for": "arm64"},
{"build-on": "arm64", "build-for": "armhf"},
],
}

snapcraft_yaml_data = snapcraft_yaml(**yaml_data)

assert (
parts_lifecycle.get_build_plan(
snapcraft_yaml_data, parsed_args=argparse.Namespace(build_for="arm64")
snapcraft_yaml_data, parsed_args=argparse.Namespace(build_for="amd64")
)
== []
)
Expand Down
18 changes: 18 additions & 0 deletions tests/unit/test_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -1710,6 +1710,24 @@ def test_architecture_multiple_build_for_same_architecture_implicit(
error.value
)

@pytest.mark.parametrize(
"architectures",
[
"unknown",
{"build-on": ["unknown"]},
{"build-on": ["unknown"], "build-for": ["amd64"]},
{"build-on": ["amd64"], "build-for": ["unknown"]},
],
)
def test_architecture_unsupported(self, architectures, project_yaml_data):
"""Raise an error for unsupported architectures."""
data = project_yaml_data(architectures=[architectures])

with pytest.raises(errors.ProjectValidationError) as error:
Project.unmarshal(data)

assert "Architecture 'unknown' is not supported." in str(error.value)

def test_project_get_build_on(self, project_yaml_data):
"""Test `get_build_on()` returns the build-on string."""
data = project_yaml_data(
Expand Down
32 changes: 32 additions & 0 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,38 @@ def test_process_version_git(mocker):
assert utils.process_version("git") == "1.2.3-dirty"


###########################
# Supported architectures #
###########################


@pytest.mark.parametrize("arch", utils.get_supported_architectures())
def test_is_architecture_supported(arch):
"""Supported architectures should return true."""
assert utils.is_architecture_supported(arch)


def test_is_architecture_not_supported():
"""Unsupported architectures should return false."""
assert not utils.is_architecture_supported("unknown")


def get_supported_architectures():
"""Validate list of supported architectures."""
supported_archs = utils.get_supported_architectures()

assert supported_archs == [
"arm64",
"armhf",
"i386",
"powerpc",
"ppc64el",
"amd64",
"s390x",
"riscv64",
]


#########################
# Convert Architectures #
#########################
Expand Down

0 comments on commit e1a671a

Please sign in to comment.