mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 11:46:35 +00:00
The entity name keys a role's instance directory, its compose project and its container name, and was derived only by stripping the longest matching category prefix. Two roles under different categories whose names share a suffix therefore collapse onto one entity and overwrite each other's rendered stack, which no provides: can repair. A literal entity_name in vars/main.yml now wins over the derivation. web-app-seaweedfs-console takes its shorter name back and declares the entity seaweedfs-console, which frees the seaweedfs key in its own services map for the engine consumer and removes the provides:, covers: and alias entries that stood in for it. A new lint pairs the declaration with the primary key it has to match, because a drift between them would drop the role from the provider set in silence. Compared across all 288 roles, exactly one entity changes, and it restores what main already keeps on disk, so no instance directory moves. The function and the filter lose their get_ prefix. Two lints read that prefix as the discriminator between the variable and the filter that fills it; both discriminate on the pipe now. Ansible's templar resolves a filter and a same-named variable independently, verified against ansible-core 2.20.2. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
71 lines
2.3 KiB
Python
71 lines
2.3 KiB
Python
import unittest
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from ansible.errors import AnsibleError
|
|
|
|
from plugins.lookup.bounded_name import LookupModule
|
|
|
|
ONION = "x.wiki." + "a" * 56 + ".onion"
|
|
|
|
|
|
class TestBoundedNameLookup(unittest.TestCase):
|
|
def setUp(self):
|
|
self.lookup = LookupModule()
|
|
|
|
def _get(name, *args, **kwargs):
|
|
plugin = MagicMock()
|
|
|
|
def _run(terms, variables=None, **_kwargs):
|
|
return [(variables or {}).get("domains", {})]
|
|
|
|
plugin.run.side_effect = _run
|
|
return plugin
|
|
|
|
self._patchers = [
|
|
patch("plugins.lookup.bounded_name.lookup_loader.get", side_effect=_get),
|
|
patch(
|
|
"plugins.lookup.bounded_name.get_domain",
|
|
side_effect=lambda domains, app: domains[app],
|
|
),
|
|
patch(
|
|
"plugins.lookup.bounded_name.entity_name",
|
|
side_effect=lambda app: app.rsplit("-", 1)[-1],
|
|
),
|
|
]
|
|
for p in self._patchers:
|
|
p.start()
|
|
self.addCleanup(lambda: [p.stop() for p in self._patchers])
|
|
|
|
def _run(self, domain, limit, app="web-app-xwiki"):
|
|
return self.lookup.run([app, limit], variables={"domains": {app: domain}})[0]
|
|
|
|
def test_a_fitting_domain_is_kept(self):
|
|
self.assertEqual(self._run("wiki.example.org", 63), "wiki.example.org")
|
|
|
|
def test_a_domain_at_the_limit_is_kept(self):
|
|
self.assertEqual(self._run("a" * 27, 27), "a" * 27)
|
|
|
|
def test_a_longer_domain_falls_back_to_the_entity(self):
|
|
self.assertEqual(self._run(ONION, 63), "xwiki")
|
|
self.assertEqual(self._run("a" * 28, 27), "xwiki")
|
|
|
|
def test_an_empty_domain_falls_back_to_the_entity(self):
|
|
self.assertEqual(self._run("", 63), "xwiki")
|
|
|
|
def test_bad_arity_raises(self):
|
|
with self.assertRaises(AnsibleError):
|
|
self.lookup.run(["web-app-xwiki"], variables={})
|
|
|
|
def test_an_empty_application_raises(self):
|
|
with self.assertRaises(AnsibleError):
|
|
self.lookup.run([" ", 63], variables={})
|
|
|
|
def test_a_non_positive_or_non_integer_limit_raises(self):
|
|
for limit in (0, -1, "many"):
|
|
with self.subTest(limit=limit), self.assertRaises(AnsibleError):
|
|
self.lookup.run(["web-app-xwiki", limit], variables={})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|