Files
computer-playbook/tests/unit/python/library/test_stack_host_contents.py
T
kevinveenbirkenbachandClaude Opus 5.5 cfb2f9c70b perf(web-opt-rdr-domains): check every certificate in one task and write every file in one call
Each redirect source went through the full TLS layer on its own: cert check,
CA environment cleanup, re-check, HTTP handler and vhost template, about
nine seconds per source. echoserver has 85 sources, so the role took
thirteen minutes of every deploy.

The role now resolves the tls state and renders both files of every source
on the controller, finds the certificates of all sources in one find, and
includes sys-front-tls only for a source whose certificate is missing, so
issuance still works in every mode. library/stack_host_contents.py writes
all files in one module call, atomically and only where the content
differs, and keeps one file per source under http/ and https/. Its action
plugin carries the IS_STACK_HOST gate like stack_host_template.

The name differs from the stack_host_files module of feature/store-i18n on
purpose: that one syncs a single directory of YAML documents and prunes
what it does not write, which would delete every other vhost here.

HTTPS_REDIRECT_ENABLED is gone: nothing set it, it was true everywhere,
and the redirect role could no longer see the sys-front-tls default it
lived in. Whether a domain gets its HTTP to HTTPS handler now follows from
lookup('tls', domain, 'enabled') alone, in sys-front-tls and here.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-23 16:35:45 +02:00

101 lines
3.1 KiB
Python

from __future__ import annotations
import importlib.util
import stat
import sys
import tempfile
import unittest
from pathlib import Path
from typing import TYPE_CHECKING
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.testing import patch_module_args
from . import PROJECT_ROOT
if TYPE_CHECKING:
from types import ModuleType
sys.path.insert(0, str(PROJECT_ROOT))
MODULE_PATH = PROJECT_ROOT / "library" / "stack_host_contents.py"
def _load_stack_host_contents() -> ModuleType:
spec = importlib.util.spec_from_file_location(
"library_stack_host_contents", str(MODULE_PATH)
)
if spec is None or spec.loader is None:
raise ImportError(f"Could not load: {MODULE_PATH}")
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod) # type: ignore[attr-defined]
return mod
_MOD = _load_stack_host_contents()
class WriteFileTests(unittest.TestCase):
def setUp(self):
self._tmp = tempfile.TemporaryDirectory()
self.path = Path(self._tmp.name) / "redirect.conf"
def tearDown(self):
self._tmp.cleanup()
def _module(self, *, check_mode=False):
args = {"files": [], "mode": "0644", "_ansible_check_mode": check_mode}
with patch_module_args(args):
return AnsibleModule(
argument_spec=_MOD.ARGUMENT_SPEC, supports_check_mode=True
)
def _write(self, content, *, check_mode=False):
return _MOD.write_file(
self._module(check_mode=check_mode), str(self.path), content, "0644"
)
def _mode(self):
return stat.S_IMODE(self.path.stat().st_mode)
def _content(self):
return self.path.read_text(
encoding="utf-8"
) # nocheck: cache-read the file under test changes between reads
def test_creates_missing_file_with_mode(self):
self.assertTrue(self._write("server {}\n"))
self.assertEqual(self._content(), "server {}\n")
self.assertEqual(self._mode(), 0o644)
def test_unchanged_content_reports_no_change(self):
self._write("server {}\n")
self.assertFalse(self._write("server {}\n"))
def test_replaces_differing_content(self):
self._write("server {}\n")
self.assertTrue(self._write("server { listen 80; }\n"))
self.assertEqual(self._content(), "server { listen 80; }\n")
def test_repairs_mode_drift(self):
self._write("server {}\n")
self.path.chmod(0o600)
self.assertTrue(self._write("server {}\n"))
self.assertEqual(self._mode(), 0o644)
def test_check_mode_reports_without_writing(self):
self.assertTrue(self._write("server {}\n", check_mode=True))
self.assertFalse(self.path.exists())
self._write("server {}\n")
self.assertTrue(self._write("other\n", check_mode=True))
self.assertEqual(self._content(), "server {}\n")
def test_leaves_no_staging_file_behind(self):
self._write("server {}\n")
self._write("other\n")
self.assertEqual([p.name for p in self.path.parent.iterdir()], [self.path.name])
if __name__ == "__main__":
unittest.main()