mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 11:46:35 +00:00
An image bump in a provider redeployed every variant of every consumer, including the variants that switch that provider off and therefore never deploy the bumped image at all. The diff-derived whitelist now narrows each affected role to the variants whose own round closure still reaches a seed, emitted as `role#0,2` selection tokens. That closure is walked on the same variant-merged services maps the matrix planner builds its rounds from, so the narrowing follows a parent's variant choice across every generation of the chain. It covers every auto-derived whitelist: the weekly update PRs, Dependabot, and any other diff-driven run. The narrowing never shrinks the matrix on partial information. A seed role keeps every variant, because its own files changed. A role reached only through a run_after edge keeps every variant too, because the round closure does not follow that edge and a role whose hits are empty is therefore unnarrowed rather than dropped. A pinned token naming a role the discovery query does not return now warns instead of aborting the run. The diff-derived whitelist legitimately names roles the lifecycle envelope filters out, and once it pins variants such a token would abort every chunk; role names are still checked against roles/ before the run starts, so a typo is caught one layer earlier. The round's variant merge moves out of the deploy inventory package into utils/roles/applications/variants.py. The CI selection has to build the same maps, and importing the deploy package for them pulls in a module that reads INFINITO_SRC_DIR at import time, which the runner host does not set. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
89 lines
3.2 KiB
Python
89 lines
3.2 KiB
Python
"""Unit tests for `utils.roles.applications.variants`' provider overrides.
|
|
|
|
The service registry is stubbed: what matters is which role a claim is
|
|
attributed to, not how a service key resolves to its provider.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
from utils.roles.applications.variants import (
|
|
NestedOverrideConflictError,
|
|
collect_provider_overrides,
|
|
)
|
|
|
|
_REGISTRY = {
|
|
"openwebui": {"role": "web-app-openwebui"},
|
|
"gitea": {"role": "web-app-gitea"},
|
|
}
|
|
|
|
_PATCH = "utils.roles.applications.variants.build_service_registry_from_roles_dir"
|
|
|
|
|
|
class TestCollectProviderOverrides(unittest.TestCase):
|
|
def _collect(self, payloads, registry=None):
|
|
with patch(_PATCH, autospec=True) as build:
|
|
build.return_value = _REGISTRY if registry is None else registry
|
|
return collect_provider_overrides(payloads, roles_dir="/roles")
|
|
|
|
def test_a_named_topic_reaches_its_provider(self) -> None:
|
|
payloads = {
|
|
"web-app-moodle": {"services": {"openwebui": {"services": None}}},
|
|
}
|
|
self.assertEqual(
|
|
{"web-app-openwebui": {"services": None}}, self._collect(payloads)
|
|
)
|
|
|
|
def test_several_topics_of_one_provider_are_collected_together(self) -> None:
|
|
payloads = {
|
|
"web-app-moodle": {
|
|
"services": {
|
|
"openwebui": {"services": None, "addons": {"whisper": False}},
|
|
},
|
|
},
|
|
}
|
|
self.assertEqual(
|
|
{"web-app-openwebui": {"services": None, "addons": {"whisper": False}}},
|
|
self._collect(payloads),
|
|
)
|
|
|
|
def test_a_roles_own_entry_is_not_an_override(self) -> None:
|
|
payloads = {"web-app-gitea": {"services": {"gitea": {"users": {"a": 1}}}}}
|
|
self.assertEqual({}, self._collect(payloads))
|
|
|
|
def test_an_unregistered_service_key_is_skipped(self) -> None:
|
|
payloads = {"web-app-moodle": {"services": {"nowhere": {"services": None}}}}
|
|
self.assertEqual({}, self._collect(payloads))
|
|
|
|
def test_two_roles_agreeing_is_not_a_conflict(self) -> None:
|
|
payloads = {
|
|
"web-app-moodle": {"services": {"openwebui": {"services": None}}},
|
|
"web-app-gitea": {"services": {"openwebui": {"services": None}}},
|
|
}
|
|
self.assertEqual(
|
|
{"web-app-openwebui": {"services": None}}, self._collect(payloads)
|
|
)
|
|
|
|
def test_two_roles_demanding_different_values_raises(self) -> None:
|
|
payloads = {
|
|
"web-app-moodle": {"services": {"openwebui": {"services": None}}},
|
|
"web-app-gitea": {"services": {"openwebui": {"services": {"a": 1}}}},
|
|
}
|
|
with self.assertRaises(NestedOverrideConflictError):
|
|
self._collect(payloads)
|
|
|
|
def test_a_round_without_overrides_never_builds_the_registry(self) -> None:
|
|
payloads = {"web-app-moodle": {"services": {"openwebui": {"enabled": True}}}}
|
|
with patch(_PATCH, autospec=True) as build:
|
|
build.return_value = _REGISTRY
|
|
self.assertEqual(
|
|
{}, collect_provider_overrides(payloads, roles_dir="/roles")
|
|
)
|
|
build.assert_not_called()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|