mirror of
https://github.com/spoopyghosty0/frameport.git
synced 2026-10-23 17:01:56 +02:00
53 lines
2.0 KiB
Python
53 lines
2.0 KiB
Python
"""One FramePort window at a time (core/instance.py)."""
|
|
import subprocess
|
|
import sys
|
|
import textwrap
|
|
|
|
from frameport.core import instance
|
|
|
|
|
|
def _hold_lock(path):
|
|
"""A separate process holding the GUI lock (like a running FramePort)."""
|
|
code = textwrap.dedent(f"""
|
|
import sys, time
|
|
sys.path.insert(0, {str(instance.__file__.rsplit('/frameport/', 1)[0])!r})
|
|
from pathlib import Path
|
|
from frameport.core import instance
|
|
assert instance.acquire(Path({str(path)!r}))
|
|
print("locked", flush=True)
|
|
time.sleep(30)
|
|
""")
|
|
p = subprocess.Popen([sys.executable, "-c", code], stdout=subprocess.PIPE, text=True)
|
|
assert p.stdout.readline().strip() == "locked"
|
|
return p
|
|
|
|
|
|
def test_second_start_is_refused_while_a_window_is_open(tmp_path, monkeypatch):
|
|
monkeypatch.setenv("FRAMEPORT_HOME", str(tmp_path))
|
|
holder = _hold_lock(instance.lock_file())
|
|
try:
|
|
assert instance.holder() == holder.pid
|
|
assert not instance.acquire()
|
|
assert instance.claim(lambda: True) is False # a window answers: it's asked to come to the front
|
|
assert instance.take_focus_request() and not instance.take_focus_request()
|
|
# no window answers, but the holder isn't a FramePort GUI (or is still starting): it's left alone
|
|
assert instance.claim(lambda: False, retries=1) is False
|
|
assert holder.poll() is None
|
|
finally:
|
|
holder.kill()
|
|
holder.wait()
|
|
assert instance.acquire() # released by the OS when the holder ends
|
|
|
|
|
|
def test_leftover_frameport_gui_is_ended(tmp_path, monkeypatch):
|
|
monkeypatch.setenv("FRAMEPORT_HOME", str(tmp_path))
|
|
holder = _hold_lock(instance.lock_file())
|
|
monkeypatch.setattr(instance, "_is_frameport_gui", lambda pid: pid == holder.pid)
|
|
monkeypatch.setattr(instance, "STARTUP_GRACE", 0.0)
|
|
try:
|
|
assert instance.claim(lambda: False) is True # no window: the leftover process is ended, the lock taken
|
|
assert holder.wait(5) is not None
|
|
finally:
|
|
if holder.poll() is None:
|
|
holder.kill()
|