Skip to content

Commit

Permalink
add arch constraint to each application
Browse files Browse the repository at this point in the history
  • Loading branch information
addyess committed Oct 31, 2024
1 parent 7ffcab0 commit 05be923
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 23 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/integration_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,16 @@ jobs:
arch:
- {id: amd64, builder-label: ubuntu-22.04, tester-arch: x64}
- {id: arm64, builder-label: ARM64, tester-arch: ARM64}
suite: ["k8s", "etcd", "ceph"]
suite: [k8s, etcd, ceph]
exclude:
- {id: {arch: arm64}, suite: ceph}
with:
identifier: ${{ matrix.arch.id }}-${{ matrix.suite }}
builder-runner-label: ${{ matrix.arch.builder-label }}
charmcraft-channel: ${{ needs.charmcraft-channel.outputs.channel }}
extra-arguments: ${{needs.extra-args.outputs.args}} -k test_${{ matrix.suite }}
extra-arguments: >-
${{needs.extra-args.outputs.args}} -k test_${{ matrix.suite }}
${{ matrix.arch.id == 'arm64' && ' --lxd-containers' || '' }}
juju-channel: 3/stable
load-test-enabled: false
provider: lxd
Expand Down
2 changes: 2 additions & 0 deletions charms/worker/k8s/templates/snap_installation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ amd64:
- name: k8s
install-type: store
channel: edge
classic: true
arm64:
- name: k8s
install-type: store
channel: edge
classic: true
66 changes: 45 additions & 21 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import contextlib
import json
import logging
import re
import shlex
from dataclasses import dataclass, field
from itertools import chain
Expand Down Expand Up @@ -92,6 +93,23 @@ class Charm:
arch: str
path: Path
_charmfile: Optional[Path] = None
_URL_RE = re.compile(r"ch:(?P<arch>\w+)/(?P<series>\w+)/(?P<charm>.+)")

@staticmethod
def craft_url(charm: str, series: str, arch: str) -> str:
"""Craft a charm URL.
Args:
charm: Charm name
series: Cloud series
arch: Cloud architecture
Returns:
string: URL to the charm
"""
if m := Charm._URL_RE.match(charm):
charm = m.group("charm")
return f"ch:{arch}/{series}/{charm}"

@property
def metadata(self) -> dict:
Expand Down Expand Up @@ -145,19 +163,25 @@ class Bundle:
ops_test: Instance of the pytest-operator plugin
path: Path to the bundle file
content: Loaded content from the path
arch: Cloud Architecture
render: Path to a rendered bundle
applications: Mapping of applications in the bundle.
"""

ops_test: OpsTest
path: Path
arch: str
_content: Mapping = field(default_factory=dict)

@property
def content(self) -> Mapping:
"""Yaml content of the bundle loaded into a dict"""
if not self._content:
self._content = yaml.safe_load(self.path.read_bytes())
loaded = yaml.safe_load(self.path.read_bytes())
series = loaded.get("series", "focal")
for app in loaded["applications"].values():
app["charm"] = Charm.craft_url(app["charm"], series=series, arch=self.arch)
self._content = loaded
return self._content

@property
Expand All @@ -168,6 +192,7 @@ def applications(self) -> Mapping[str, dict]:
@property
def render(self) -> Path:
"""Path to written bundle config to be deployed."""
self.add_constraints({"arch": self.arch})
target = self.ops_test.tmp_path / "bundles" / self.path.name
target.parent.mkdir(exist_ok=True, parents=True)
yaml.safe_dump(self.content, target.open("w"))
Expand Down Expand Up @@ -204,18 +229,6 @@ def add_constraints(self, constraints: Dict[str, str]):
existing.update(constraints)
app["constraints"] = " ".join(f"{k}={v}" for k, v in existing.items())

def add_constraints(self, constraints: Dict[str, str]):
"""Add constraints to applications.
Args:
constraints: Mapping of constraints to add to applications.
"""
for app in self.applications.values():
val: str = app["constraints"]
existing = dict(kv.split("=", 1) for kv in val.split())
existing.update(constraints)
app["constraints"] = " ".join(f"{k}={v}" for k, v in existing.items())


async def cloud_arch(ops_test: OpsTest) -> str:
"""Return current architecture of the selected controller
Expand Down Expand Up @@ -338,14 +351,26 @@ async def deploy_model(
log.fatal("Failed to determine model: model_name=%s", model_name)


def bundle_file(request) -> Path:
"""Fixture to get bundle file.
Args:
request: pytest request object
Returns:
path to test's bundle file
"""
_file = "test-bundle.yaml"
bundle_marker = request.node.get_closest_marker("bundle_file")
if bundle_marker:
_file = bundle_marker.args[0]
return Path(__file__).parent / "data" / _file


@pytest_asyncio.fixture(scope="module")
async def kubernetes_cluster(request: pytest.FixtureRequest, ops_test: OpsTest):
"""Deploy local kubernetes charms."""
bundle_file = "test-bundle.yaml"
bundle_marker = request.node.get_closest_marker("bundle_file")
if bundle_marker:
bundle_file = bundle_marker.args[0]
bundle_path = Path(__file__).parent / "data" / bundle_file
bundle_path = bundle_file(request)
model = "main"

with ops_test.model_context(model) as the_model:
Expand All @@ -362,7 +387,7 @@ async def kubernetes_cluster(request: pytest.FixtureRequest, ops_test: OpsTest):
charm_files = await asyncio.gather(
*[charm.resolve(request.config.option.charm_files) for charm in charms]
)
bundle = Bundle(ops_test, bundle_path)
bundle = Bundle(ops_test, bundle_path, arch)
_type, _vms = await cloud_type(ops_test)
if _type == "lxd" and not _vms:
log.info("Drop lxd machine constraints")
Expand All @@ -372,7 +397,6 @@ async def kubernetes_cluster(request: pytest.FixtureRequest, ops_test: OpsTest):
bundle.add_constraints({"virt-type": "virtual-machine"})
if request.config.option.apply_proxy:
await cloud_proxied(ops_test)
bundle.add_constraints({"arch": arch})
for path, charm in zip(charm_files, charms):
bundle.switch(charm.app_name, path)
async with deploy_model(request, ops_test, model, bundle) as the_model:
Expand All @@ -388,7 +412,7 @@ async def grafana_agent(kubernetes_cluster: Model):
machine_series = juju.utils.get_version_series(data["base"].split("@")[1])

await kubernetes_cluster.deploy(
f"ch:{machine_arch}/{machine_series}/grafana-agent",
Charm.craft_url("grafana-agent", machine_series, machine_arch),
channel="stable",
series=machine_series,
)
Expand Down

0 comments on commit 05be923

Please # to comment.