1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
"""Exercise bootstrap/config routing without downloading or changing the real runtime."""
import json
import os
from pathlib import Path
import subprocess
import sys
import pytest
from producer import cli
LAUNCHER = Path(__file__).resolve().parents[3] / "producer.sh"
def test_cli_gui_dispatch_preserves_configuration_flags(tmp_path, monkeypatch):
from producer import gui
config = tmp_path / "config.toml"
config.write_text('profile = "narrator"\n')
received = []
monkeypatch.setattr(gui, "serve", lambda *args, **kwargs: received.append((args, kwargs)))
monkeypatch.setattr(sys, "argv", ["producer", "gui", "--root", str(tmp_path), "--port", "9001",
"--config", str(config), "--profile", "radio", "--target-lufs", "-21", "--set", "target_lufs=-18"])
cli.main()
assert received == [((tmp_path, 9001), {"config": config, "profile": "radio", "overrides": {"target_lufs": -18}})]
def test_launcher_only_gui_installs_extra_and_preserves_config_injection(tmp_path):
checkout = tmp_path / "checkout"
checkout.mkdir()
launcher = checkout / "producer.sh"
launcher.write_text(LAUNCHER.read_text())
launcher.chmod(0o755)
(checkout / "config.toml").write_text('profile = "narrator"\n')
(checkout / "lib/project").mkdir(parents=True)
tools = tmp_path / "tools"
tools.mkdir()
log, forwarded = tmp_path / "install.jsonl", tmp_path / "forwarded.json"
fake_python = (f"#!{sys.executable}\nimport json,sys\nfrom pathlib import Path\n"
f"if '-m' in sys.argv: Path({str(forwarded)!r}).write_text(json.dumps(sys.argv[1:]))\n")
uv = tools / "uv"
uv.write_text(f"#!{sys.executable}\n"
"import json,sys\nfrom pathlib import Path\n"
f"with Path({str(log)!r}).open('a') as out: out.write(json.dumps(sys.argv[1:])+'\\n')\n"
"if sys.argv[1] == 'venv':\n"
" python = Path(sys.argv[-1]) / 'bin/python'\n"
" python.parent.mkdir(parents=True, exist_ok=True)\n"
f" python.write_text({fake_python!r})\n"
" python.chmod(0o755)\n")
uv.chmod(0o755)
env = os.environ.copy() | {"PATH": f"{tools}:{os.environ['PATH']}"}
def launch(*args):
result = subprocess.run([str(launcher), *args], cwd=checkout, env=env,
capture_output=True, text=True, timeout=15)
assert result.returncode == 0, result.stderr
return json.loads(forwarded.read_text())
args = launch("config", "--json")
assert args == ["-I", "-m", "producer", "config", f"--config={checkout / 'config.toml'}", "--json"]
calls = [json.loads(line) for line in log.read_text().splitlines()]
installs = [call for call in calls if call[0] == "pip"]
assert len(installs) == 1 and installs[0][-1].endswith("[bundled-ffmpeg]")
args = launch("gui", "--root", str(checkout), "--port", "8766")
assert args[3:5] == ["gui", f"--config={checkout / 'config.toml'}"]
calls = [json.loads(line) for line in log.read_text().splitlines()]
installs = [call for call in calls if call[0] == "pip"]
assert len(installs) == 2 and installs[1][-1].endswith("[bundled-ffmpeg,gui]")
before = log.read_text()
args = launch("gui", "--config=custom.toml")
assert args[-2:] == ["gui", "--config=custom.toml"]
launch("config")
assert log.read_text() == before # GUI/core marker reuse, no extra installs.
def test_cli_commands_import_without_optional_web_dependencies():
# A fresh interpreter explicitly denies optional imports, even if installed.
code = """
import sys
class Deny:
def find_spec(self, fullname, *args):
if fullname.split('.')[0] in ('fastapi', 'uvicorn', 'starlette'):
raise AssertionError('CLI imported optional GUI dependency: ' + fullname)
sys.meta_path.insert(0, Deny())
from producer.cli import parser
assert parser().parse_args(['config']).command == 'config'
"""
result = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True)
assert result.returncode == 0, result.stderr
def test_server_binds_only_loopback_and_prints_fragment_token(tmp_path, monkeypatch, capsys):
pytest.importorskip("fastapi")
uvicorn = pytest.importorskip("uvicorn")
import socket
from producer import gui
with socket.socket() as reservation:
reservation.bind(("127.0.0.1", 0))
port = reservation.getsockname()[1]
seen = []
class Server:
def __init__(self, config):
assert config.host == "127.0.0.1"
assert config.proxy_headers is False
assert config.access_log is False
def run(self, sockets):
seen.append(sockets[0].getsockname())
monkeypatch.setattr(uvicorn, "Server", Server)
gui.serve(tmp_path, port)
assert seen == [("127.0.0.1", port)]
output = capsys.readouterr().out
assert f"http://127.0.0.1:{port}/#token=" in output
assert len(output.split("#token=")[1].splitlines()[0]) >= 43
for invalid in (0, -1, 65536):
with pytest.raises(ValueError):
gui.serve(tmp_path, invalid)
|