mirror of
https://github.com/kuhyx/screen-locker.git
synced 2026-11-10 21:27:13 +01:00
verify_lock_popup_safety.py (318) -> _xvfb_reexec.py shared re-exec
_popup_form_check.py HostileLock, ticks,
the real-form check
verify_screen_fits.py (266) -> uses _xvfb_reexec too
conftest.py (329) -> _tk_mocks.py the tk mock + the
module patch list
_opt_in_fixtures.py requestable fixtures
three test modules -> _part4/_part5/_part15 siblings
conftest keeps every autouse fixture. pytest applies autouse fixtures from
conftest only, so one moved to a sibling would silently stop running and take
its safety guard with it -- verified by asserting the fixtures are still
listed, not just that the suite is green. The five near-identical _isolate_*
fixtures collapse into one table-driven _isolate_state_files, which also picks
up the _shutdown_sick_state binding an earlier split created.
scripts/ becomes a real package so the shared helpers are importable. Both
gates now run as `python3 -m scripts.<name>`, including CI -- the path form put
scripts/ on sys.path instead of the repo root, and the alternative was a
try/except ImportError that this repo's no-silent-failures hook rightly
rejects. Each gate was run in its exact invocation form.
Note: verify_lock_popup_safety still fails on
`RecoveryLoop.__init__() takes 3 positional arguments but 6 were given`. That
is pre-existing -- confirmed by running it at HEAD in a clean worktree before
touching it -- a gatelock API drift, not this refactor. Left as found.
978 tests at 100% branch coverage. Gate: 41 -> 22 files, all remaining ones
Dart plus DESIGN_AUDIT_TODO.md.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EveB813BQ8abAP68VSqZ5Y
73 lines
2.4 KiB
Python
73 lines
2.4 KiB
Python
"""Re-run a GUI check script on a throwaway X display.
|
|
|
|
Split out of ``verify_lock_popup_safety.py`` and ``verify_screen_fits.py``
|
|
to keep every file under the 250-line cap. Both had their own near-identical
|
|
copy; they differ only in the sentinel env var and how the inner process is
|
|
addressed, so both are parameters here.
|
|
|
|
Each script runs itself twice: the outer run starts ``xvfb-run`` and re-execs,
|
|
the inner run (marked by the sentinel) does the real work against that
|
|
display. Without the sentinel the inner process would start another Xvfb
|
|
forever.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
# Comfortably bigger than every size under test, so each surface is sized by
|
|
# the geometry the harness sets rather than clamped by the display.
|
|
_SCREEN_ARG = "-screen 0 1600x1200x24"
|
|
|
|
|
|
def reexec_under_xvfb(
|
|
*,
|
|
inner_env: str,
|
|
module: str | None = None,
|
|
script: Path | None = None,
|
|
) -> int:
|
|
"""Re-run this check on a throwaway X display, returning its exit code.
|
|
|
|
Exactly one of *module* (run as ``python -m module`` from the repo root)
|
|
or *script* (run as an absolute path) identifies the inner process; that
|
|
difference is why the two callers cannot share a single hardcoded form.
|
|
|
|
Args:
|
|
inner_env: Sentinel env var set for the inner run, so it knows not to
|
|
start another Xvfb.
|
|
module: Dotted module path to run with ``-m``.
|
|
script: Absolute path of the script file to run.
|
|
|
|
Returns:
|
|
The inner process's exit code, or 1 if ``xvfb-run`` is unavailable.
|
|
"""
|
|
if (module is None) == (script is None):
|
|
msg = "pass exactly one of module= or script="
|
|
raise ValueError(msg)
|
|
|
|
xvfb_run = shutil.which("xvfb-run")
|
|
if xvfb_run is None:
|
|
_logger.error(
|
|
"xvfb-run not found. Install it with: sudo pacman -S --needed "
|
|
"xorg-server-xvfb"
|
|
)
|
|
return 1
|
|
|
|
env = dict(os.environ, **{inner_env: "1"})
|
|
repo_root = Path(__file__).resolve().parent.parent
|
|
# Absolute argv, no shell.
|
|
target = ["-m", module] if module is not None else [str(script)]
|
|
return subprocess.run(
|
|
[xvfb_run, "-a", "-s", _SCREEN_ARG, sys.executable, *target],
|
|
check=False,
|
|
cwd=repo_root,
|
|
env=env,
|
|
).returncode
|