mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-13 06:06:38 +00:00
categories.yml moves from roles/ to the repository-root meta/, joining packages.yml. utils/roles/categories.py owns its location plus the tree-walking helpers that were stranded in entity/name.py, so no caller spells the path or duplicates the lookup. meta/distros.yml becomes the SPOT for every distribution: os_family, Galaxy platform name, dev-environment base image, and the pkgmgr/pkgmgr-virgin/environment reference templates. It replaces seven scattered copies (DISTRO_FAMILY, VALID_DISTROS, _DISTROS, _CANONICAL_PLATFORMS, two shell arrays, a Makefile literal). INFINITO_DISTROS is no longer a static default but generated by utils/env/handlers/infinito/distros.py; the shell consumers read it through the env layer. Drops dead CLI surface found along the way: --categories-file and --roles-dir on the provision CLI plus three unused parameters of generate_dynamic_inventory, and the positional roles_file of the invokable categories command. tests/lint/repository/test_distros_spot.py pins the copies that cannot call the SPOT (workflow literals, docs table) and forbids composing a pkgmgr reference outside it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
97 lines
3.3 KiB
Python
97 lines
3.3 KiB
Python
"""Unit tests for `utils.roles.entity.apps.apps_for_entity`."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import shutil
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
from utils.cache.yaml import _reset_cache_for_tests, dump_yaml
|
|
from utils.roles.categories import categories_file
|
|
from utils.roles.entity.apps import apps_for_entity
|
|
from utils.roles.mapping import ROLE_FILE_VARS_MAIN
|
|
|
|
|
|
class TestAppsForEntity(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
_reset_cache_for_tests()
|
|
self.tmp = Path(tempfile.mkdtemp(prefix="apps_for_entity_test_"))
|
|
self.roles_dir = self.tmp / "roles"
|
|
self.roles_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
dump_yaml(
|
|
categories_file(self.tmp),
|
|
{
|
|
"roles": {
|
|
"web": {
|
|
"app": {"title": "Applications", "invokable": True},
|
|
"svc": {"title": "Services", "invokable": True},
|
|
}
|
|
}
|
|
},
|
|
)
|
|
|
|
root = patch("utils.roles.categories.PROJECT_ROOT", self.tmp)
|
|
root.start()
|
|
self.addCleanup(root.stop)
|
|
self.addCleanup(lambda: shutil.rmtree(self.tmp, ignore_errors=True))
|
|
|
|
def _mk_role(self, name: str, application_id: str | None) -> None:
|
|
rd = self.roles_dir / name
|
|
(rd / "vars").mkdir(parents=True, exist_ok=True)
|
|
payload: dict = {}
|
|
if application_id is not None:
|
|
payload["application_id"] = application_id
|
|
dump_yaml(rd / ROLE_FILE_VARS_MAIN, payload)
|
|
|
|
def test_returns_apps_under_entity(self) -> None:
|
|
self._mk_role("web-app-matomo", "web-app-matomo")
|
|
self._mk_role("web-app-dashboard", "web-app-dashboard")
|
|
self._mk_role("web-svc-cdn", "web-svc-cdn")
|
|
|
|
self.assertEqual(
|
|
apps_for_entity("matomo", roles_dir=self.roles_dir),
|
|
["web-app-matomo"],
|
|
)
|
|
self.assertEqual(
|
|
apps_for_entity("cdn", roles_dir=self.roles_dir),
|
|
["web-svc-cdn"],
|
|
)
|
|
|
|
def test_falls_back_to_role_dir_name_when_application_id_missing(self) -> None:
|
|
self._mk_role("web-app-foo", None)
|
|
self.assertEqual(
|
|
apps_for_entity("foo", roles_dir=self.roles_dir),
|
|
["web-app-foo"],
|
|
)
|
|
|
|
def test_unknown_entity_returns_empty(self) -> None:
|
|
self._mk_role("web-app-matomo", "web-app-matomo")
|
|
self.assertEqual(
|
|
apps_for_entity("does-not-exist", roles_dir=self.roles_dir),
|
|
[],
|
|
)
|
|
|
|
def test_blank_entity_returns_empty(self) -> None:
|
|
self._mk_role("web-app-matomo", "web-app-matomo")
|
|
self.assertEqual(apps_for_entity("", roles_dir=self.roles_dir), [])
|
|
self.assertEqual(apps_for_entity(" ", roles_dir=self.roles_dir), [])
|
|
|
|
def test_missing_roles_dir_returns_empty(self) -> None:
|
|
ghost = self.tmp / "ghost-roles"
|
|
self.assertEqual(apps_for_entity("matomo", roles_dir=ghost), [])
|
|
|
|
def test_result_is_sorted_and_unique(self) -> None:
|
|
self._mk_role("web-app-matomo", "web-app-matomo")
|
|
self._mk_role("web-svc-matomo", "web-svc-matomo")
|
|
|
|
got = apps_for_entity("matomo", roles_dir=self.roles_dir)
|
|
self.assertEqual(got, sorted(got))
|
|
self.assertEqual(len(got), len(set(got)))
|
|
|
|
|
|
if __name__ == "__main__": # pragma: no cover
|
|
unittest.main()
|