Files
computer-playbook/tests/unit/python/roles/web-app-wordpress/test_plugin_install.py
T
kevinveenbirkenbachandClaude Opus 5.5 52fe3c9c2c style: apply make autoformat to the merged Stalwart and Tor files
Formatter output only: the parsed YAML and the Python AST of every touched file equal their previous versions.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-03 19:57:30 +02:00

189 lines
6.8 KiB
Python

"""The generic WordPress plugin installer decides by state, not by exit code.
WP-CLI can exit 255 after an install that finished, because WordPress' fatal
handler requires the ``.maintenance`` file the install has just removed. The
installer therefore never fails on the install's exit code: it stops retrying on
``Success:``, asks ``wp plugin is-installed`` afterwards, and only a required
plugin that is really missing fails the deploy. A pinned plugin is reinstalled
only when the installed version differs from its pin, so a redeploy neither
downloads it again nor reports a change.
Each case evaluates the conditions of
``roles/web-app-wordpress/tasks/utils/install/plugin.yml`` itself.
"""
from __future__ import annotations
import unittest
from ansible.parsing.dataloader import DataLoader
from ansible.template import Templar
from utils.cache.yaml import load_yaml_any
from utils.templating.ansible import _trust_as_template
from . import PROJECT_ROOT
TASK_FILE = PROJECT_ROOT / "roles/web-app-wordpress/tasks/utils/install/plugin.yml"
SKIPPED = {"skipped": True, "changed": False}
FINISHED_BUT_255 = {
"rc": 255,
"stdout": "Installing MCP Adapter\nPlugin installed successfully.\nSuccess: Installed 1 of 1 plugins.",
}
DOWNLOAD_FAILED = {"rc": 1, "stdout": "Error: Download failed. Not Found"}
def _tasks() -> list[dict]:
return load_yaml_any(str(TASK_FILE), default_if_missing=[])
def _task(fragment: str) -> dict:
return next(t for t in _tasks() if fragment in t["name"])
def _block_task(fragment: str) -> dict:
block = next(t for t in _tasks() if "block" in t)
return next(t for t in block["block"] if fragment in t["name"])
def _truthy(expression, **variables) -> bool:
expressions = expression if isinstance(expression, list) else [expression]
templar = Templar(loader=DataLoader(), variables=variables)
return all(
templar.template(_trust_as_template("{{ (" + str(e) + ") | bool }}"))
for e in expressions
)
def _installed(install: dict, verify_rc: int | None) -> bool:
expression = _task("Resolve whether")["ansible.builtin.set_fact"][
"wp_plugin_installed"
]
verified = SKIPPED if verify_rc is None else {"rc": verify_rc}
templar = Templar(
loader=DataLoader(),
variables={"wp_plugin_install": install, "wp_plugin_verified": verified},
)
return bool(templar.template(_trust_as_template(expression)))
class TestInstallDecision(unittest.TestCase):
def _installs(self, *, present_rc, pinned, installed_version, pin) -> bool:
return _truthy(
_task("Install WordPress plugin")["when"],
wp_plugin_present={"rc": present_rc},
wp_plugin_pinned=pinned,
wp_plugin_installed_version=installed_version,
wp_plugin_pinned_version=pin,
)
def test_a_missing_plugin_is_installed(self):
self.assertTrue(
self._installs(
present_rc=1, pinned=False, installed_version=SKIPPED, pin=""
)
)
def test_a_pinned_plugin_at_its_pin_is_left_alone(self):
self.assertFalse(
self._installs(
present_rc=0,
pinned=True,
installed_version={"stdout": "0.5.0\n"},
pin="0.5.0",
)
)
def test_a_pinned_plugin_behind_its_pin_is_upgraded(self):
self.assertTrue(
self._installs(
present_rc=0,
pinned=True,
installed_version={"stdout": "0.4.1"},
pin="0.5.0",
)
)
def test_an_unpinned_plugin_that_is_present_is_left_alone(self):
self.assertFalse(
self._installs(
present_rc=0, pinned=False, installed_version=SKIPPED, pin=""
)
)
def test_the_pin_is_compared_without_its_tag_prefix(self):
normalise = _task("Normalise the install contract")["ansible.builtin.set_fact"]
self.assertIn("regex_replace('^v', '')", normalise["wp_plugin_pinned_version"])
class TestExitCodeIsNotTheVerdict(unittest.TestCase):
def test_install_task_never_fails_on_its_exit_code(self):
self.assertIs(_task("Install WordPress plugin")["failed_when"], False)
def test_a_finished_install_that_exits_255_stops_retrying(self):
self.assertTrue(
_truthy(
_task("Install WordPress plugin")["until"],
wp_plugin_install=FINISHED_BUT_255,
)
)
def test_a_failed_download_is_retried(self):
self.assertFalse(
_truthy(
_task("Install WordPress plugin")["until"],
wp_plugin_install=DOWNLOAD_FAILED,
)
)
def test_the_verify_probe_only_fails_on_an_unexpected_exit_code(self):
failed_when = _task("Verify WordPress plugin")["failed_when"]
self.assertFalse(_truthy(failed_when, wp_plugin_verified={"rc": 1}))
self.assertTrue(_truthy(failed_when, wp_plugin_verified={"rc": 2}))
def test_a_255_install_that_landed_counts_as_installed(self):
self.assertTrue(_installed(FINISHED_BUT_255, verify_rc=0))
def test_a_skipped_install_counts_as_installed(self):
self.assertTrue(_installed(SKIPPED, verify_rc=None))
def test_a_failed_install_counts_as_missing(self):
self.assertFalse(_installed(DOWNLOAD_FAILED, verify_rc=1))
class TestMissingPluginOutcome(unittest.TestCase):
def _runs(self, fragment: str, *, installed: bool, required: bool) -> bool:
block = next(t for t in _tasks() if "block" in t)
variables = {"wp_plugin_installed": installed, "wp_plugin_required": required}
return _truthy(block["when"], **variables) and _truthy(
_block_task(fragment)["when"], **variables
)
def test_a_missing_required_plugin_fails_the_deploy(self):
self.assertTrue(
self._runs("Fail because required", installed=False, required=True)
)
self.assertFalse(self._runs("Skip optional", installed=False, required=True))
def test_a_missing_optional_plugin_only_warns(self):
self.assertFalse(
self._runs("Fail because required", installed=False, required=False)
)
self.assertTrue(self._runs("Skip optional", installed=False, required=False))
def test_an_installed_plugin_reaches_neither_branch(self):
self.assertFalse(
self._runs("Fail because required", installed=True, required=True)
)
self.assertFalse(self._runs("Skip optional", installed=True, required=False))
def test_only_an_installed_plugin_is_activated(self):
activate = _task("Activate WordPress plugin")["when"]
self.assertTrue(_truthy(activate, wp_plugin_installed=True))
self.assertFalse(_truthy(activate, wp_plugin_installed=False))
if __name__ == "__main__":
unittest.main()