from pathlib import Path import unittest ROOT = Path(__file__).resolve().parents[1] PLAYBOOK = ROOT / "deploy" / "ansible" / "guestops.yml" class AnsibleHandoffTests(unittest.TestCase): def test_release_is_verified_before_build_and_start(self): text = PLAYBOOK.read_text(encoding="utf-8") controller_verify = text.index("Verify source package on the Ansible controller") target_verify = text.index("Verify transferred package and record on the target") api_build = text.index("Build API image from the verified source") preflight = text.index("Run offline deployment preflight") compose_start = text.index("Start the verified release without rebuilding") readiness = text.index("Wait for loopback readiness") public_readiness = text.index("Verify public HTTPS readiness and certificate trust") current = text.index("Select the current successful release") self.assertLess(controller_verify, target_verify) self.assertLess(target_verify, api_build) self.assertLess(api_build, preflight) self.assertLess(preflight, compose_start) self.assertLess(compose_start, readiness) self.assertLess(readiness, public_readiness) self.assertLess(public_readiness, current) def test_playbook_uses_safe_release_controls(self): text = PLAYBOOK.read_text(encoding="utf-8") for required in ( "guestops_release_commit is match('^[0-9a-f]{40}$')", "checksum_algorithm: sha256", "deploy/verify_source_package.py", "deploy/release_record.py", "deploy/ops.py", "--offline", "--no-build", "GOOGLE_ENABLE_SENDING", "AUTO_REPLY_ENABLE_LIVE", "no_log: true", "http://127.0.0.1:8080/health/ready", "Reject public API or MongoDB listeners", "Validate Nginx configuration", "validate_certs: true", "enabled: true", ): self.assertIn(required, text) self.assertNotIn("ansible.builtin.shell", text) self.assertNotIn("password=", text.lower()) if __name__ == "__main__": unittest.main()