Ctrl K
ComunidadGuías…

scripts/test_nix_package.py

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

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env python3
"""Smoke-test a built Nix package without cleanup, network or authorization."""

import fcntl
import json
import os
from pathlib import Path
import pty
import re
import select
import signal
import subprocess
import sys
import tempfile
import termios
import time


def check_menu(launcher, env):
    master, slave = pty.openpty()

    def own_terminal():
        os.setsid()
        fcntl.ioctl(0, termios.TIOCSCTTY, 0)

    # Keep the controlling terminal alive while Bash restores it on exit.
    keeper = (
        "import subprocess,time; "
        f"p=subprocess.run([{str(launcher)!r}]); "
        "print('MENU_EXIT='+str(p.returncode),flush=True); time.sleep(10)"
    )
    process = subprocess.Popen(
        [sys.executable, "-c", keeper], stdin=slave, stdout=slave, stderr=slave,
        env=env, preexec_fn=own_terminal,
    )
    output = b""
    try:
        deadline = time.monotonic() + 15
        while b"Q Quit" not in output or termios.tcgetattr(slave)[3] & termios.ECHO:
            if time.monotonic() >= deadline or process.poll() is not None:
                raise AssertionError(("menu failed to start", output))
            if select.select([master], [], [], 0.05)[0]:
                output += os.read(master, 65536)
        assert b"99.0.0" not in output, output
        previous_renders = output.count(b"Q Quit")
        os.write(master, b"u")
        deadline = time.monotonic() + 5
        while output.count(b"Q Quit") <= previous_renders:
            if time.monotonic() >= deadline or process.poll() is not None:
                raise AssertionError(("hidden update key dispatched", output))
            if select.select([master], [], [], 0.05)[0]:
                output += os.read(master, 65536)
        os.write(master, b"q")
        deadline = time.monotonic() + 5
        while b"MENU_EXIT=" not in output:
            assert time.monotonic() < deadline, ("menu failed to exit", output)
            if select.select([master], [], [], 0.05)[0]:
                output += os.read(master, 65536)
        assert b"MENU_EXIT=0" in output, output
    finally:
        if process.poll() is None:
            os.killpg(process.pid, signal.SIGKILL)
            process.wait(timeout=5)
        os.close(master)
        os.close(slave)


def main():
    package = Path(sys.argv[1]).resolve(strict=True)
    assert str(package).startswith("/nix/store/"), package
    root = Path(__file__).resolve().parents[1]
    version = re.search(r'^VERSION="([^"]+)"$', (root / "mole").read_text(), re.M)[1]
    entry = package / "share/mole/mole"
    assert entry.read_text().splitlines()[0] == "#!/bin/bash"
    for helper in ("analyze", "status"):
        assert (package / f"share/mole/bin/{helper}.sh").read_text().splitlines()[0] == "#!/bin/bash"
        assert os.access(package / f"share/mole/bin/{helper}-go", os.X_OK)

    with tempfile.TemporaryDirectory(prefix="mole-nix-smoke-") as scratch:
        home = Path(scratch)
        stubs = home / "stubs"
        stubs.mkdir()
        forbidden = home / "forbidden"
        for command in ("curl", "wget", "sudo", "osascript", "launchctl", "brew"):
            stub = stubs / command
            stub.write_text('#!/bin/bash\nprintf "%s\\n" "$0" >> "$MOLE_SMOKE_FORBIDDEN"\nexit 97\n')
            stub.chmod(0o755)
        env = dict(os.environ, HOME=str(home), TERM="xterm-256color",
                   MOLE_TEST_NO_AUTH="1", MOLE_SMOKE_FORBIDDEN=str(forbidden),
                   PATH=f"{stubs}:/usr/bin:/bin:/usr/sbin:/sbin")
        for key in ("MOLE_TEST_MODE", "MOLE_SKIP_MAIN", "MOLE_NIX_INSTALL"):
            env.pop(key, None)

        def run(launcher, args, status=0, text=None):
            result = subprocess.run([str(launcher), *args], env=env, cwd=home,
                                    text=True, capture_output=True, timeout=20)
            output = result.stdout + result.stderr
            assert result.returncode == status, (args, result.returncode, output)
            if text:
                assert text in output, (args, output)
            return result.stdout

        notice = home / ".cache/mole/update_message"
        notice.parent.mkdir(parents=True)
        notice.write_text("Mole 99.0.0 available. Run mo update")
        fixture = home / "analysis-fixture"
        fixture.mkdir()
        (fixture / "sample.txt").write_text("Nix package smoke fixture")
        for name in ("mo", "mole"):
            launcher = package / "bin" / name
            version_output = run(launcher, ["--version"], text=version)
            assert "Install: Nix" in version_output, version_output
            run(launcher, ["--help"], text="COMMANDS")
            run(launcher, ["history"], text="No operation history yet")
            history = json.loads(run(launcher, ["history", "--json"]))
            assert history["sessions"] == [] and history["deletions"] == [], history
            analysis = json.loads(run(launcher, ["analyze", "--json", str(fixture)]))
            assert any(row["name"] == "sample.txt" for row in analysis["entries"]), analysis
            run(launcher, ["analyze", "--help"], text="Usage:")
            run(launcher, ["status", "--help"], text="Usage:")
            for args in (["update"], ["update", "--nightly"],
                         ["update", "--force"], ["remove"], ["remove", "--dry-run"]):
                run(launcher, args, status=1, text="Nix")
            check_menu(launcher, env)
        assert notice.read_text() == "Mole 99.0.0 available. Run mo update"
        assert not forbidden.exists(), forbidden.read_text() if forbidden.exists() else ""
    print("Nix installed-package smoke checks passed")


if __name__ == "__main__":
    main()