mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
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>
189 lines
6.8 KiB
Python
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()
|