65 lines
3 KiB
Python
65 lines
3 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Exercise the real GUI's default ~/.xtc.conf lifecycle in an isolated child HOME."""
|
||
|
|
import configparser
|
||
|
|
import os
|
||
|
|
from pathlib import Path
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
import tempfile
|
||
|
|
import time
|
||
|
|
|
||
|
|
binary = str(Path(sys.argv[1]).resolve())
|
||
|
|
with tempfile.TemporaryDirectory(prefix="xtc-config-startup-") as directory:
|
||
|
|
configuration = Path(directory) / ".xtc.conf"
|
||
|
|
environment = dict(os.environ)
|
||
|
|
environment["HOME"] = directory # Child only; never reads/writes the user's config.
|
||
|
|
|
||
|
|
def run_window(expected_width):
|
||
|
|
process = subprocess.Popen([binary], env=environment, stdout=subprocess.PIPE,
|
||
|
|
stderr=subprocess.PIPE, text=True)
|
||
|
|
try:
|
||
|
|
window = None
|
||
|
|
deadline = time.monotonic() + 15
|
||
|
|
while time.monotonic() < deadline:
|
||
|
|
if process.poll() is not None:
|
||
|
|
raise AssertionError(f"GUI exited early: {process.communicate()}")
|
||
|
|
found = subprocess.run(["xdotool", "search", "--onlyvisible", "--pid",
|
||
|
|
str(process.pid), "--name", "xtc"],
|
||
|
|
capture_output=True, text=True)
|
||
|
|
if found.returncode == 0:
|
||
|
|
window = found.stdout.splitlines()[0]
|
||
|
|
geometry = subprocess.check_output(
|
||
|
|
["xdotool", "getwindowgeometry", "--shell", window], text=True)
|
||
|
|
if f"WIDTH={expected_width}\n" in geometry:
|
||
|
|
break
|
||
|
|
time.sleep(.05)
|
||
|
|
else:
|
||
|
|
raise AssertionError(f"Expected startup width {expected_width}; window={window}")
|
||
|
|
subprocess.run(["xdotool", "windowfocus", window], check=True)
|
||
|
|
subprocess.run(["xdotool", "key", "--window", window, "ctrl+q"], check=True)
|
||
|
|
output, error = process.communicate(timeout=15)
|
||
|
|
assert process.returncode == 0, (output, error)
|
||
|
|
finally:
|
||
|
|
if process.poll() is None:
|
||
|
|
process.kill()
|
||
|
|
process.communicate()
|
||
|
|
|
||
|
|
run_window(1280)
|
||
|
|
assert configuration.exists() and configuration.stat().st_mode & 0o777 == 0o600
|
||
|
|
saved = configparser.ConfigParser()
|
||
|
|
saved.read(configuration)
|
||
|
|
assert saved["midi"]["midi_input_channel"] == "-1"
|
||
|
|
assert saved["editing"]["note_velocity"] == "100"
|
||
|
|
configuration.write_text("[interface]\nwidth=1360\nheight=860\n"
|
||
|
|
"[midi]\nmidi_input_channel=5\nmidi_output_channel=7\n"
|
||
|
|
"[project_defaults]\ntempo=137000\n")
|
||
|
|
run_window(1360)
|
||
|
|
saved.read(configuration)
|
||
|
|
assert saved["midi"]["midi_input_channel"] == "5"
|
||
|
|
assert saved["midi"]["midi_output_channel"] == "7"
|
||
|
|
assert saved["project_defaults"]["tempo"] == "137000"
|
||
|
|
invalid = "[unknown]\nkeep_this_file=1\n"
|
||
|
|
configuration.write_text(invalid)
|
||
|
|
run_window(1280)
|
||
|
|
assert configuration.read_text() == invalid
|
||
|
|
print("Real startup ~/.xtc.conf creation, defaults, reload and malformed-file preservation passed.")
|