Ctrl K
ComunidadGuías…

scripts/test-micromanager-update.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env python3
"""Exercise managed updates without a VM, systemd, or modifying host files."""

import hashlib
import os
from pathlib import Path
import subprocess
import tempfile
import unittest

SCRIPT = Path(__file__).parent / "micromanager/update-guest.sh"


class ManagedUpdateTest(unittest.TestCase):
    def setUp(self):
        self.directory = tempfile.TemporaryDirectory()
        self.addCleanup(self.directory.cleanup)
        self.root = Path(self.directory.name)
        self.units = self.root / "units"
        self.data = self.root / "data"
        self.data.mkdir()
        (self.data / "queue.db").write_bytes(b"queue data created by development API")
        self.override = self.units / "firecrab-api.service.d/90-firecrab-dev.conf"
        self.override.parent.mkdir(parents=True)
        self.override.write_text("[Service]\nExecStart=/development/firecrab-api\n")
        self.commands = self.root / "commands"
        self.commands.mkdir()
        self.environment = dict(os.environ, PATH=f"{self.commands}:{os.environ['PATH']}")
        self.stub("flock", "exit 0")
        self.stub("systemctl", f"echo \"$*\" >>'{self.root / 'systemctl.log'}'\nexit 0")
        self.stub("curl", "printf '%s' '{\"version\":\"0.4.1\"}'")
        self.stub("jq", "cat >/dev/null\nexit 0")

    def stub(self, name, body):
        path = self.commands / name
        path.write_text(f"#!/bin/sh\nset -eu\n{body}\n")
        path.chmod(0o755)

    def run_update(self, installer, digest=None):
        script = SCRIPT.read_text().replace("/var/lib/firecrab/dev", str(self.data / "dev"))
        script = script.replace("/etc/systemd/system", str(self.units))
        return subprocess.run(
            ["bash", "-c", script, "--", "v0.4.1", digest or hashlib.sha256(installer).hexdigest()],
            input=installer,
            capture_output=True,
            env=self.environment,
            timeout=10,
        )

    def test_updates_before_starting_release_api_and_keeps_queue_data(self):
        installer = (
            f"#!/bin/bash\nset -eu\ntest \"$*\" = '--version v0.4.1'\n"
            f"test ! -f '{self.override}'\n"
            f"echo installer >>'{self.root / 'systemctl.log'}'\n"
        ).encode()
        result = self.run_update(installer)
        self.assertEqual(result.returncode, 0, result.stderr.decode())
        self.assertFalse(self.override.exists())
        events = (self.root / "systemctl.log").read_text()
        self.assertLess(events.index("installer"), events.index("restart firecrab-helper firecrab-api"))
        self.assertNotIn("stop firecrab-api", events)
        self.assertEqual((self.data / "queue.db").read_bytes(), b"queue data created by development API")

    def test_failed_install_restores_development_settings_and_keeps_diagnostics(self):
        before = self.override.read_bytes()
        result = self.run_update(b"#!/bin/bash\nexit 23\n")
        self.assertEqual(result.returncode, 23, result.stderr.decode())
        self.assertEqual(self.override.read_bytes(), before)
        self.assertTrue(list((self.data / "dev").glob("update.*/install.sh")))
        self.assertIn(b"[ROLLBACK]", result.stderr)

    def test_corrupt_installer_does_not_change_running_services(self):
        before = self.override.read_bytes()
        result = self.run_update(b"#!/bin/bash\nexit 0\n", "0" * 64)
        self.assertNotEqual(result.returncode, 0)
        self.assertEqual(self.override.read_bytes(), before)
        self.assertFalse((self.root / "systemctl.log").exists())

    def test_active_deployment_is_not_interrupted(self):
        self.stub("flock", "exit 1")
        result = self.run_update(b"#!/bin/bash\nexit 0\n")
        self.assertNotEqual(result.returncode, 0)
        self.assertTrue(self.override.exists())
        self.assertIn(b"cancel it before updating", result.stderr)


if __name__ == "__main__":
    unittest.main()