test(clan/inventory): test deserialization of different inventories

This commit is contained in:
Johannes Kirschbauer
2025-04-09 10:29:53 +02:00
parent 1eb5423b6b
commit bfd2968509
3 changed files with 74 additions and 3 deletions

View File

@@ -39,6 +39,7 @@ def substitute(
file: Path,
clan_core_flake: Path | None = None,
flake: Path = Path(__file__).parent,
inventory_expr: str = r"{}",
) -> None:
sops_key = str(flake.joinpath("sops.key"))
buf = ""
@@ -54,6 +55,7 @@ def substitute(
"https://git.clan.lol/clan/clan-core/archive/main.tar.gz",
f"path:{clan_core_flake}",
)
line = line.replace("__INVENTORY_EXPR__", str(inventory_expr))
line = line.replace("__CLAN_SOPS_KEY_PATH__", sops_key)
line = line.replace("__CLAN_SOPS_KEY_DIR__", str(flake / "facts"))
buf += line
@@ -252,6 +254,7 @@ def create_flake(
machines: list[str] | None = None,
# alternatively specify the machines directly including their config
machine_configs: dict[str, dict] | None = None,
inventory_expr: str = r"{}",
) -> Iterator[FlakeForTest]:
"""
Creates a flake with the given name and machines.
@@ -279,7 +282,11 @@ def create_flake(
for machine_name in machines:
machine_path = Path(__file__).parent / "machines" / machine_name
shutil.copytree(machine_path, flake / "machines" / machine_name)
substitute(flake / "machines" / machine_name / "default.nix", flake)
substitute(
flake / "machines" / machine_name / "default.nix",
flake,
inventory_expr=inventory_expr,
)
# generate machines from machineConfigs
for machine_name, machine_config in machine_configs.items():
@@ -291,7 +298,7 @@ def create_flake(
# provided by get_test_flake_toplevel
flake_nix = flake / "flake.nix"
# this is where we would install the sops key to, when updating
substitute(flake_nix, clan_core_flake, flake)
substitute(flake_nix, clan_core_flake, flake, inventory_expr=inventory_expr)
nix_options = []
if tmp_store := nix_test_store():
nix_options += ["--store", str(tmp_store)]
@@ -345,8 +352,12 @@ def test_flake(
@pytest.fixture
def test_flake_with_core(
monkeypatch: pytest.MonkeyPatch, temporary_home: Path
request: pytest.FixtureRequest,
monkeypatch: pytest.MonkeyPatch,
temporary_home: Path,
) -> Iterator[FlakeForTest]:
test_params = getattr(request, "param", {}) # Default if not parametrized
inventory_expr = test_params.get("inventory_expr", r"{}") # Default empty inventory
if not (CLAN_CORE / "flake.nix").exists():
msg = "clan-core flake not found. This test requires the clan-core flake to be present"
raise FixtureError(msg)
@@ -355,4 +366,5 @@ def test_flake_with_core(
flake_template="test_flake_with_core",
clan_core_flake=CLAN_CORE,
monkeypatch=monkeypatch,
inventory_expr=inventory_expr,
)

View File

@@ -22,6 +22,9 @@
clan = clan-core.lib.buildClan {
inherit self;
meta.name = "test_flake_with_core";
# Don't quote this will be replaced by the inventory expression
# Not a string!
inventory = __INVENTORY_EXPR__;
machines = {
vm1 =
{ config, ... }:

View File

@@ -0,0 +1,56 @@
from typing import Any
import pytest
# Functions to test
from clan_cli.inventory import load_inventory_eval
from clan_cli.tests.fixtures_flakes import FlakeForTest
@pytest.mark.parametrize(
"test_flake_with_core",
[
# Emtpy inventory
{"inventory_expr": r"{ }"},
# Empty machines
{
"inventory_expr": r"""{
machines.jon = {};
machines.sara = {};
}"""
},
# TODO: Test
# - Function modules
# - Instances with non-deserializable settings ?
# - Tags function modules
# -
# {
# "inventory_expr": r"""{
# modules.messager = { ... }: { };
# }"""
# },
],
# Important!
# tells pytest to pass these values to the fixture
# So we can write it to the flake fixtures
indirect=True,
)
@pytest.mark.with_core
def test_inventory_deserialize_variants(
test_flake_with_core: FlakeForTest,
) -> None:
"""
Testing different inventory deserializations
Inventory should always be deserializable to a dict
"""
inventory: dict[str, Any] = load_inventory_eval(test_flake_with_core.path) # type: ignore
# Check that the inventory is a dict
assert isinstance(inventory, dict)
# Check that all keys are present
assert "meta" in inventory
assert "machines" in inventory
assert "services" in inventory
assert "tags" in inventory
assert "modules" in inventory
assert "instances" in inventory