Files
manual_slop/tests/test_gui2_performance.py

79 lines
3.0 KiB
Python

"""
ANTI-SIMPLIFICATION: These tests verify that the GUI maintains a strict performance baseline.
They MUST NOT be simplified. Removing assertions or adding arbitrary skips when metrics fail to collect defeats the purpose of the test.
If the GUI cannot sustain 30 FPS, it indicates a critical performance regression in the render loop.
"""
import pytest
import time
import sys
import os
# Ensure project root is in path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src")))
from src.api_hook_client import ApiHookClient
# Session-wide storage for comparing metrics
_shared_metrics = {}
def test_performance_benchmarking(live_gui: tuple) -> None:
"""
Collects performance metrics for the current GUI script over a 5-second window.
Ensures the application does not lock up and can report its internal state.
"""
process, gui_script = live_gui
client = ApiHookClient()
# Wait for app to stabilize and render some frames
time.sleep(3.0)
# Collect metrics over 5 seconds
fps_values = []
cpu_values = []
frame_time_values = []
start_time = time.time()
while time.time() - start_time < 5:
try:
perf_data = client.get_performance()
metrics = perf_data.get('performance', {})
if metrics:
fps = metrics.get('fps', 0.0)
cpu = metrics.get('cpu_percent', 0.0)
ft = metrics.get('last_frame_time_ms', 0.0)
if fps > 0:
fps_values.append(fps)
cpu_values.append(cpu)
frame_time_values.append(ft)
time.sleep(0.1)
except Exception:
break
avg_fps = sum(fps_values) / len(fps_values) if fps_values else 0
avg_cpu = sum(cpu_values) / len(cpu_values) if cpu_values else 0
avg_ft = sum(frame_time_values) / len(frame_time_values) if frame_time_values else 0
_shared_metrics[gui_script] = {
"avg_fps": avg_fps,
"avg_cpu": avg_cpu,
"avg_ft": avg_ft
}
print(f"\n[Test] Results for {gui_script}: FPS={avg_fps:.2f}, CPU={avg_cpu:.2f}%, FT={avg_ft:.2f}ms")
# Absolute minimum requirements
if avg_fps > 0:
# ANTI-SIMPLIFICATION: 30 FPS threshold ensures the app remains interactive.
assert avg_fps >= 30, f"{gui_script} FPS {avg_fps:.2f} is below 30 FPS threshold"
assert avg_ft <= 33.3, f"{gui_script} Frame time {avg_ft:.2f}ms is above 33.3ms threshold"
def test_performance_baseline_check() -> None:
"""
Verifies that we have successfully collected performance metrics for sloppy.py
and that they meet the minimum 30 FPS baseline.
"""
# Key is full path, find it by basename
gui_key = next((k for k in _shared_metrics if "sloppy.py" in k), None)
if not gui_key:
pytest.skip("Metrics for sloppy.py not yet collected.")
gui2_m = _shared_metrics[gui_key]
# ANTI-SIMPLIFICATION: If avg_fps is 0, the test MUST fail, not skip.
# A 0 FPS indicates the render loop is completely frozen or the API hook is dead.
assert gui2_m["avg_fps"] > 0, "No performance metrics collected - GUI may be frozen"
assert gui2_m["avg_fps"] >= 30
assert gui2_m["avg_ft"] <= 33.3