OXYGENHUB
◆ main retro-remote-debug-controller / conformance / conftest.py
1.7 KiB · Python · last changed Add conformance suite; client: raw PPM screenshot + PPM parser 3 months ago source blame history raw
1
"""Conformance harness fixtures.
2
3
Provides an `emu` fixture (an EmuControl client). Two modes:
4
5
- Attach: point RRDC_PORT at an already-running emulator's control port.
6
- Launch: set RRDC_EMU_CMD to a shell command that starts one (the literal
7
  {port} is substituted). The suite spawns it, waits for /status, and tears it
8
  down afterward.
9
10
If nothing is listening and no RRDC_EMU_CMD is set, the tests SKIP (so a bare
11
`pytest` in CI without an emulator is a skip, not a failure).
12
"""
13
import os
14
import signal
15
import subprocess
16
import sys
17
18
import pytest
19
20
HERE = os.path.dirname(os.path.abspath(__file__))
21
sys.path.insert(0, os.path.join(HERE, "..", "client"))
22
23
from emu_control import EmuControl  # noqa: E402
24
25
26
def _kill(proc):
27
    for sig in (signal.SIGTERM, signal.SIGKILL):
28
        try:
29
            os.killpg(os.getpgid(proc.pid), sig)
30
            proc.wait(timeout=5)
31
            return
32
        except Exception:
33
            continue
34
35
36
@pytest.fixture(scope="session")
37
def emu():
38
    port = int(os.environ.get("RRDC_PORT", "8080"))
39
    cmd = os.environ.get("RRDC_EMU_CMD")
40
    proc = None
41
    if cmd:
42
        proc = subprocess.Popen(
43
            cmd.replace("{port}", str(port)), shell=True, start_new_session=True,
44
            stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
45
46
    client = EmuControl(port)
47
    try:
48
        timeout = float(os.environ.get("RRDC_BOOT_TIMEOUT", "20"))
49
        client.wait_ready(tries=max(1, int(timeout / 0.1)), delay=0.1)
50
    except Exception as ex:
51
        if proc is not None:
52
            _kill(proc)
53
        pytest.skip(f"no emulator on control port {port}: {ex} "
54
                    f"(set RRDC_EMU_CMD to launch one, or RRDC_PORT to attach)")
55
56
    yield client
57
58
    if proc is not None:
59
        _kill(proc)