refactor(management): replace curses TUIs with API-backed ncp subcommands; panel/autostart/install integration
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
"""Guard against the crash-on-close regression.
|
||||
|
||||
The panel's worker/monitor threads schedule Tk callbacks via _safe_after. During
|
||||
shutdown that .after() raises (thread + dying interpreter); if it escaped, the
|
||||
worker's `finally` aborted before unlinking its PID file -> stale runtime/pids/*.
|
||||
These asserts pin the two invariants that prevent that. Run: python test_controlpanel_close.py
|
||||
"""
|
||||
from types import SimpleNamespace
|
||||
from controlpanel import NexusControlPanel
|
||||
|
||||
|
||||
def _fake(closing, after_raises):
|
||||
def after(_delay, _fn):
|
||||
if after_raises:
|
||||
raise RuntimeError("main thread is not in main loop")
|
||||
return SimpleNamespace(_closing=closing, root=SimpleNamespace(after=after))
|
||||
|
||||
|
||||
# 1. A raising .after() (teardown condition) must NOT propagate.
|
||||
NexusControlPanel._safe_after(_fake(closing=False, after_raises=True), 0, lambda: None)
|
||||
|
||||
# 2. Once closing, we must not touch Tk at all — schedule is skipped.
|
||||
scheduled = []
|
||||
obj = SimpleNamespace(_closing=True, root=SimpleNamespace(after=lambda d, f: scheduled.append(f)))
|
||||
NexusControlPanel._safe_after(obj, 0, lambda: None)
|
||||
assert scheduled == [], "closing panel must not schedule Tk callbacks"
|
||||
|
||||
print("ok")
|
||||
Reference in New Issue
Block a user