Files
computer-playbook/tests/unit/python/plugins/lookup/test_package_batch.py
T
kevinveenbirkenbachandClaude Opus 5.5 18ea75049e perf(packages): install every role's packages per host in one run at deploy start
A constructor task after the update role and the swarm auto-placement installs,
in one package-manager call, every package id of every role the host's groups
may run: meta dependencies, service edges and every role invocation readable
from tasks and handlers, conditions ignored. Ids that must stay with their role
(a conditional install, a repository added first, a need before update) carry
batch: false in meta/packages.yml and keep their task; roles reference shared
root ids with shared: true. 42 per-role install tasks go, and a lint keeps the
split: no batched id in a role task, none in a role run ahead of the batch.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-28 22:54:36 +01:00

53 lines
2.1 KiB
Python

import unittest
from unittest import mock
from ansible.errors import AnsibleError
from plugins.lookup.package_batch import LookupModule
from utils.packages.schema import PackagesShapeError
MODULE = "plugins.lookup.package_batch"
class TestPackageBatchLookup(unittest.TestCase):
def _run(self, terms, group_names, closure=None, side_effect=None):
applications = mock.Mock()
applications.run.return_value = [{"web-app-x": {}}]
with (
mock.patch(f"{MODULE}.lookup_loader.get", return_value=applications),
mock.patch(f"{MODULE}.types_from_group_names", return_value=["server"]),
mock.patch(
f"{MODULE}.deploy_closure",
return_value=closure or {"web-app-x"},
side_effect=side_effect,
) as closure_mock,
mock.patch(f"{MODULE}.batch_ids", return_value=["git"]) as ids_mock,
):
lookup = LookupModule()
result = lookup.run(terms, variables={"group_names": group_names})
return result, closure_mock, ids_mock
def test_returns_the_batch_ids_of_the_closure(self):
result, _closure, ids = self._run([["web-app-x"]], ["web-app-x"])
self.assertEqual(result, [["git"]])
self.assertEqual(ids.call_args.args[0], {"web-app-x"})
def test_nested_and_scalar_terms_become_one_seed_list(self):
_result, closure, _ids = self._run([["web-app-x"], "role-b"], ["web-app-x"])
self.assertEqual(closure.call_args.args[1], ["web-app-x", "role-b"])
def test_the_host_groups_select_types_and_gates(self):
_result, closure, _ids = self._run([["web-app-x"]], ["web-app-x", "servers"])
self.assertEqual(closure.call_args.kwargs["host_types"], ["server"])
self.assertEqual(
closure.call_args.kwargs["group_names"], ["web-app-x", "servers"]
)
def test_a_registry_error_becomes_an_ansible_error(self):
with self.assertRaises(AnsibleError):
self._run([["web-app-x"]], [], side_effect=PackagesShapeError("broken"))
if __name__ == "__main__":
unittest.main()