Add integration tests for RHI module: - Add tests/RHI/integration/ directory with CMakeLists.txt - Add RHIIntegrationFixture for shared test utilities - Add minimal integration test (window creation, basic rendering) - Add compare_ppm.py for image comparison - Add run_integration_test.py test runner script These integration tests verify the complete rendering pipeline by comparing rendered output against ground truth PPM files.
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)
|