127 lines
4.1 KiB
Python
127 lines
4.1 KiB
Python
|
|
import sys
|
||
|
|
import os
|
||
|
|
import subprocess
|
||
|
|
import time
|
||
|
|
|
||
|
|
|
||
|
|
def run_integration_test(exe_path, output_ppm, gt_ppm, threshold, backend, timeout=120):
|
||
|
|
"""
|
||
|
|
Run a RHI integration test and compare output with golden template.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
exe_path: Path to the test executable
|
||
|
|
output_ppm: Filename of the output screenshot
|
||
|
|
gt_ppm: Path to the golden template PPM file
|
||
|
|
threshold: Pixel difference threshold for comparison
|
||
|
|
backend: Backend type (D3D12 or OpenGL)
|
||
|
|
timeout: Maximum time to wait for test completion (seconds)
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
0 on success, non-zero on failure
|
||
|
|
"""
|
||
|
|
exe_dir = os.path.dirname(os.path.abspath(exe_path))
|
||
|
|
output_path = os.path.join(exe_dir, output_ppm)
|
||
|
|
|
||
|
|
print(f"[Integration Test] Starting: {exe_path}")
|
||
|
|
print(f"[Integration Test] Working directory: {exe_dir}")
|
||
|
|
print(f"[Integration Test] Expected output: {output_path}")
|
||
|
|
print(f"[Integration Test] Backend: {backend}")
|
||
|
|
|
||
|
|
if not os.path.exists(exe_path):
|
||
|
|
print(f"[Integration Test] ERROR: Executable not found: {exe_path}")
|
||
|
|
return 1
|
||
|
|
|
||
|
|
if not os.path.exists(gt_ppm):
|
||
|
|
print(f"[Integration Test] ERROR: Golden template not found: {gt_ppm}")
|
||
|
|
return 1
|
||
|
|
|
||
|
|
if os.path.exists(output_path):
|
||
|
|
print(f"[Integration Test] Removing old output: {output_path}")
|
||
|
|
os.remove(output_path)
|
||
|
|
|
||
|
|
try:
|
||
|
|
print(f"[Integration Test] Launching process...")
|
||
|
|
start_time = time.time()
|
||
|
|
process = subprocess.Popen(
|
||
|
|
[exe_path, backend],
|
||
|
|
cwd=exe_dir,
|
||
|
|
stdout=subprocess.PIPE,
|
||
|
|
stderr=subprocess.PIPE,
|
||
|
|
creationflags=subprocess.CREATE_NEW_CONSOLE if os.name == "nt" else 0,
|
||
|
|
)
|
||
|
|
|
||
|
|
returncode = None
|
||
|
|
while time.time() - start_time < timeout:
|
||
|
|
returncode = process.poll()
|
||
|
|
if returncode is not None:
|
||
|
|
break
|
||
|
|
time.sleep(0.5)
|
||
|
|
|
||
|
|
if returncode is None:
|
||
|
|
print(f"[Integration Test] ERROR: Process timed out after {timeout}s")
|
||
|
|
process.kill()
|
||
|
|
return 1
|
||
|
|
|
||
|
|
elapsed = time.time() - start_time
|
||
|
|
print(
|
||
|
|
f"[Integration Test] Process finished in {elapsed:.1f}s with exit code: {returncode}"
|
||
|
|
)
|
||
|
|
|
||
|
|
if returncode != 0:
|
||
|
|
print(f"[Integration Test] ERROR: Process returned non-zero exit code")
|
||
|
|
stdout, stderr = process.communicate(timeout=5)
|
||
|
|
if stdout:
|
||
|
|
print(
|
||
|
|
f"[Integration Test] STDOUT:\n{stdout.decode('utf-8', errors='replace')}"
|
||
|
|
)
|
||
|
|
if stderr:
|
||
|
|
print(
|
||
|
|
f"[Integration Test] STDERR:\n{stderr.decode('utf-8', errors='replace')}"
|
||
|
|
)
|
||
|
|
return 1
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
print(f"[Integration Test] ERROR: Failed to run process: {e}")
|
||
|
|
return 1
|
||
|
|
|
||
|
|
if not os.path.exists(output_path):
|
||
|
|
print(f"[Integration Test] ERROR: Output file not created: {output_path}")
|
||
|
|
return 1
|
||
|
|
|
||
|
|
print(f"[Integration Test] Running image comparison...")
|
||
|
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||
|
|
compare_script = os.path.join(script_dir, "compare_ppm.py")
|
||
|
|
|
||
|
|
try:
|
||
|
|
result = subprocess.run(
|
||
|
|
[sys.executable, compare_script, output_path, gt_ppm, str(threshold)],
|
||
|
|
cwd=exe_dir,
|
||
|
|
capture_output=True,
|
||
|
|
text=True,
|
||
|
|
)
|
||
|
|
print(result.stdout)
|
||
|
|
if result.stderr:
|
||
|
|
print(f"[Integration Test] Comparison STDERR: {result.stderr}")
|
||
|
|
return result.returncode
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
print(f"[Integration Test] ERROR: Failed to run comparison: {e}")
|
||
|
|
return 1
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
if len(sys.argv) != 6:
|
||
|
|
print(
|
||
|
|
"Usage: run_integration_test.py <exe_path> <output_ppm> <gt_ppm> <threshold> <backend>"
|
||
|
|
)
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
exe_path = sys.argv[1]
|
||
|
|
output_ppm = sys.argv[2]
|
||
|
|
gt_ppm = sys.argv[3]
|
||
|
|
threshold = int(sys.argv[4])
|
||
|
|
backend = sys.argv[5]
|
||
|
|
|
||
|
|
exit_code = run_integration_test(exe_path, output_ppm, gt_ppm, threshold, backend)
|
||
|
|
sys.exit(exit_code)
|