artifacts

This commit is contained in:
ed
2026-07-02 19:03:49 -04:00
parent 2b4c6c7a56
commit b9228f3ca4
6 changed files with 467 additions and 0 deletions
@@ -0,0 +1,138 @@
"""Verify runtime dock state by monkey-patching and registering a custom callback."""
import sys, time, subprocess, shutil, urllib.request, json
from pathlib import Path
PROJ = Path("C:/projects/manual_slop_tier2")
WORK = PROJ / "tests" / "artifacts" / "diag6_runtime_state"
LOG = PROJ / "tests" / "artifacts" / "diag6_runtime_state.log"
RUNTIME_INI = PROJ / "tests" / "artifacts" / "diag6_runtime_ini.txt"
# Clean
if WORK.exists():
shutil.rmtree(WORK)
WORK.mkdir(parents=True, exist_ok=True)
if LOG.exists():
LOG.unlink()
if RUNTIME_INI.exists():
RUNTIME_INI.unlink()
# Wrapper that registers a custom callback BEFORE the app launches
WRAPPER = PROJ / "tests" / "artifacts" / "diag6_wrapper.py"
WRAPPER.write_text('''
import sys, json
sys.path.insert(0, "C:/projects/manual_slop_tier2")
sys.argv = ["sloppy.py", "--enable-test-hooks"]
# Import imgui and patch save_ini_settings_to_disk to also write to a known file
from imgui_bundle import imgui
_orig_save_disk = imgui.save_ini_settings_to_disk
def _hooked_save_disk(path):
res = _orig_save_disk(path)
try:
mem = imgui.save_ini_settings_to_memory()
with open("C:/projects/manual_slop_tier2/tests/artifacts/diag6_runtime_ini.txt", "w", encoding="utf-8") as f:
f.write(str(mem) if mem else "")
except Exception as e:
with open("C:/projects/manual_slop_tier2/tests/artifacts/diag6_runtime_ini.txt", "w", encoding="utf-8") as f:
f.write(f"ERR: {e}")
return res
imgui.save_ini_settings_to_disk = _hooked_save_disk
# Also patch save_ini_settings_to_memory to capture runtime state
def _hooked_save_mem():
res = imgui.save_ini_settings_to_memory()
try:
with open("C:/projects/manual_slop_tier2/tests/artifacts/diag6_runtime_ini.txt", "w", encoding="utf-8") as f:
f.write(str(res) if res else "")
except Exception:
pass
return res
# Now import app
from src.gui_2 import App as _App
_orig_init = _App.__init__
def _patched_init(self, *a, **kw):
_orig_init(self, *a, **kw)
# Register a custom callback that saves the runtime INI to a known location
self.controller._predefined_callbacks["_diag_save_runtime_ini"] = lambda: _hooked_save_mem()
_App.__init__ = _patched_init
import argparse
from pathlib import Path
from src.paths import initialize_paths
initialize_paths(None)
from src.gui_2 import main as _sloppy_main
_sloppy_main()
''')
# Spawn
print("Launching with patched callback...", flush=True)
proc = subprocess.Popen(
["uv", "run", "python", "-u", str(WRAPPER.absolute())],
stdout=open(LOG, "w"),
stderr=subprocess.STDOUT,
cwd=str(WORK),
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0,
)
ready = False
for i in range(30):
time.sleep(0.5)
try:
urllib.request.urlopen("http://127.0.0.1:8999/status", timeout=1)
ready = True
break
except Exception:
pass
if not ready:
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
print("NO_HOOK", flush=True)
sys.exit(1)
print(f"Hook ready. Waiting 15s for first frame + dock layout to settle...", flush=True)
time.sleep(15)
# Trigger the custom callback to save runtime INI
print("Triggering _diag_save_runtime_ini callback...", flush=True)
try:
req = urllib.request.Request(
"http://127.0.0.1:8999/api/gui",
data=json.dumps({"action": "custom_callback", "callback": "_diag_save_runtime_ini", "args": []}).encode(),
headers={"Content-Type": "application/json"},
method="POST",
)
r = urllib.request.urlopen(req, timeout=5)
print(f" POST response: {r.read().decode()}", flush=True)
except Exception as e:
print(f" POST failed: {e}", flush=True)
time.sleep(2)
# Read runtime INI
if RUNTIME_INI.exists():
runtime_text = RUNTIME_INI.read_text(encoding="utf-8", errors="replace")
print(f"\n=== RUNTIME INI ({len(runtime_text)} bytes) ===", flush=True)
for line in runtime_text.splitlines()[:60]:
print(f" {line}", flush=True)
print("=== END ===", flush=True)
else:
print(f"\nRUNTIME_INI not written to {RUNTIME_INI}", flush=True)
# Compare with bundled
bundled = (PROJ / "layouts" / "default.ini").read_text(encoding="utf-8")
if RUNTIME_INI.exists():
runtime_text = RUNTIME_INI.read_text(encoding="utf-8", errors="replace")
if runtime_text == bundled:
print("\n=> RUNTIME INI == BUNDLED INI (HelloImGui honored the layout)", flush=True)
else:
print("\n=> RUNTIME INI != BUNDLED INI (HelloImGui rebuilt the dock)", flush=True)
# Show diff
bundled_lines = bundled.splitlines()
runtime_lines = runtime_text.splitlines()
print(f" bundled: {len(bundled_lines)} lines", flush=True)
print(f" runtime: {len(runtime_lines)} lines", flush=True)
# Kill
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
time.sleep(1)
@@ -0,0 +1,102 @@
"""Regression test: verify the auto-dock layout actually takes effect at runtime.
Launches sloppy.py, waits for first frame + a few seconds, then triggers
imgui.save_ini_settings_to_disk via custom callback. If HelloImGui honored
the bundled INI's dock structure, the saved INI matches the bundled one.
If HelloImGui rebuilt the dock (because runtime DockSpace ID didn't match
or windows weren't yet created when INI was read), the saved INI differs.
"""
import os, sys, time, subprocess, shutil, json, urllib.request
from pathlib import Path
PROJ = Path("C:/projects/manual_slop_tier2")
WORK = PROJ / "tests" / "artifacts" / "diag5_verify_autodock"
LOG = PROJ / "tests" / "artifacts" / "diag5_verify_autodock.log"
INI_INSTALLED = WORK / "manualslop_layout.ini"
INI_AFTER_SAVE = WORK / "manualslop_layout.ini" # same path, post-save
# Clean workspace
if WORK.exists():
shutil.rmtree(WORK)
WORK.mkdir(parents=True, exist_ok=True)
if LOG.exists():
LOG.unlink()
# Bundle the layout INI for comparison (this is what gets installed)
BUNDLED_INI = (PROJ / "layouts" / "default.ini").read_text(encoding="utf-8")
# Spawn sloppy.py with --enable-test-hooks so we can call API
print("Launching sloppy.py...", flush=True)
proc = subprocess.Popen(
["uv", "run", "python", "-u", str(PROJ / "sloppy.py"), "--enable-test-hooks"],
stdout=open(LOG, "w"),
stderr=subprocess.STDOUT,
cwd=str(WORK),
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0,
)
ready = False
for i in range(30):
time.sleep(0.5)
try:
urllib.request.urlopen("http://127.0.0.1:8999/status", timeout=1)
ready = True
break
except Exception:
pass
if not ready:
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
print("NO_HOOK: hook server never started", flush=True)
sys.exit(1)
print(f"Hook ready, waiting 5s for first frame + dock layout to settle...", flush=True)
time.sleep(5)
# Check that the install wrote the INI
assert INI_INSTALLED.exists(), f"pre-run install did not write INI to {INI_INSTALLED}"
installed_size = INI_INSTALLED.stat().st_size
print(f"Installed INI: {installed_size} bytes at {INI_INSTALLED}", flush=True)
# Now trigger save_ini_settings_to_disk via a custom callback
print("Triggering save_ini_settings_to_disk via custom callback...", flush=True)
# Push a callback that calls imgui.save_ini_settings_to_disk
payload = {
"callback": "_trigger_save_ini",
"args": ["manualslop_layout.ini"]
}
# Try direct POST to /api/gui
try:
req = urllib.request.Request(
"http://127.0.0.1:8999/api/gui",
data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"},
method="POST",
)
r = urllib.request.urlopen(req, timeout=5)
print(f" POST /api/gui response: {r.read().decode()}", flush=True)
except Exception as e:
print(f" POST /api/gui failed: {e}", flush=True)
# Wait for save to complete
time.sleep(2)
# Check the INI after save
if not INI_AFTER_SAVE.exists():
print(f"NO_INI: file not found at {INI_AFTER_SAVE}", flush=True)
else:
after_text = INI_AFTER_SAVE.read_text(encoding="utf-8")
after_size = INI_AFTER_SAVE.stat().st_size
print(f"Post-save INI: {after_size} bytes", flush=True)
print(f"Same as bundled? {after_text == BUNDLED_INI}", flush=True)
# Show first 20 lines of post-save INI
print("\n--- POST-SAVE INI (first 20 lines) ---", flush=True)
for line in after_text.splitlines()[:20]:
print(f" {line}", flush=True)
print("--- END ---", flush=True)
# Kill
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
@@ -0,0 +1,69 @@
"""Check what windows are visible in the runtime via the live_gui fixture."""
import subprocess, time, urllib.request, json, sys
from pathlib import Path
PROJ = Path("C:/projects/manual_slop_tier2")
WORK = PROJ / "tests" / "artifacts" / "diag7_visible"
LOG = PROJ / "tests" / "artifacts" / "diag7_visible.log"
if WORK.exists():
import shutil
shutil.rmtree(WORK)
WORK.mkdir(parents=True, exist_ok=True)
if LOG.exists():
LOG.unlink()
# Spawn
print("Launching...", flush=True)
proc = subprocess.Popen(
["uv", "run", "python", "-u", str(PROJ / "sloppy.py"), "--enable-test-hooks"],
stdout=open(LOG, "w"),
stderr=subprocess.STDOUT,
cwd=str(WORK),
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0,
)
ready = False
for i in range(30):
time.sleep(0.5)
try:
urllib.request.urlopen("http://127.0.0.1:8999/status", timeout=1)
ready = True
break
except Exception:
pass
if not ready:
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
print("NO_HOOK", flush=True)
sys.exit(1)
print(f"Ready, waiting 10s...", flush=True)
time.sleep(10)
# Query /api/gui/state for show_windows
try:
r = urllib.request.urlopen("http://127.0.0.1:8999/api/gui/state", timeout=2)
state = json.loads(r.read().decode())
print(f"\nshow_windows state:", flush=True)
if "show_windows" in state:
for k, v in sorted(state["show_windows"].items()):
print(f" {k}: {v}", flush=True)
except Exception as e:
print(f"ERROR: {e}", flush=True)
# Trigger save_ini to memory to capture runtime state
import json
try:
req = urllib.request.Request(
"http://127.0.0.1:8999/api/gui",
data=json.dumps({"action": "custom_callback", "callback": "noop", "args": []}).encode(),
headers={"Content-Type": "application/json"},
method="POST",
)
urllib.request.urlopen(req, timeout=2)
except: pass
# Kill
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
time.sleep(1)
@@ -0,0 +1,23 @@
import json
import subprocess
import sys
result = subprocess.run(
["uv", "run", "python", "scripts/audit_exception_handling.py", "--src", "src", "--json"],
capture_output=True, text=True, cwd=r"C:\projects\manual_slop_tier2",
)
if result.returncode != 0:
print("AUDIT FAILED:", result.stderr[:1000])
sys.exit(1)
data = json.loads(result.stdout)
gui = [f for f in data.get("files", []) if "gui_2" in f.get("filename", "")][0]
broad = [f for f in gui.get("findings", []) if f.get("category") == "INTERNAL_BROAD_CATCH"]
silent = [f for f in gui.get("findings", []) if f.get("category") == "INTERNAL_SILENT_SWALLOW"]
print("BROAD CATCHES:")
for f in broad:
print(f" L{f['line']} {f['context']}")
print("SILENT SWALLOWS:")
for f in silent:
print(f" L{f['line']} {f['context']}")
print(f"TOTAL: {len(broad)} broad, {len(silent)} silent")
@@ -0,0 +1,27 @@
import json
import subprocess
import sys
result = subprocess.run(
["uv", "run", "python", "scripts/audit_exception_handling.py", "--src", "src", "--json"],
capture_output=True, text=True, cwd=r"C:\projects\manual_slop_tier2",
)
data = json.loads(result.stdout)
# Check all categories for the helpers we care about
gui = [f for f in data.get("files", []) if "gui_2" in f.get("filename", "")][0]
all_findings = gui.get("findings", [])
# Group by context
by_context = {}
for f in all_findings:
ctx = f.get("context", "")
by_context.setdefault(ctx, []).append(f)
# Check the existing helper
for ctx in ["_tier_stream_scroll_sync_result", "_tier_stream_scroll_sync_result.dispatcher", "_install_default_layout_if_empty", "_install_default_layout_if_empty_result", "render_tier_stream_panel"]:
print(f"=== {ctx} ===")
findings = by_context.get(ctx, [])
for f in findings:
print(f" L{f['line']} [{f['category']}] {f['kind']}: {f.get('context_extra', '')}")
if not findings:
print(" (no findings)")