|
1 | 1 | import os |
2 | 2 | import sys |
3 | 3 | from pathlib import Path |
| 4 | +import subprocess |
4 | 5 |
|
5 | | -#example of use: |
6 | | -# on linux |
7 | | -#python regression_test.py /home/epernod/projects/regression_test_sofa/build/bin/Regression_test ~/projects/sofa-src ~/projects/regression_test_sofa/src/references ~/projects/sofa-build/ |
8 | | -# on windows |
9 | | -#python ./sofa-src/applications/projects/Regression/regression_test.py /c/projects/sofa-build/bin/Release/Regression_test.exe /c/projects/sofa-src/ /c/projects/sofa-src/applications/projects/Regression/references/ /c/projects/sofa-build/ |
| 6 | +def print_help(exit_code: int = 0) -> None: |
| 7 | + script = Path(__file__).name |
| 8 | + msg = f""" |
| 9 | +Usage: |
| 10 | + python {script} <Regression_test binary> <regression_scenes_dir> <sofa_root> [<reference_plugin_dir>] |
10 | 11 |
|
11 | | -#arguments: |
12 | | -# 0 - script name |
13 | | -# 1 - regression_test binary path |
14 | | -# 2 - regression scenes dir |
15 | | -# 3 - sofa build dir |
16 | | -# 4 (optional) - Refrence plugin directory. If not set, will take the parent dir of this file. |
| 12 | +Description: |
| 13 | + Prepares the environment variables needed to run the SOFA regression tests and launches the given Regression_test binary. |
17 | 14 |
|
| 15 | +Positional arguments: |
| 16 | + <Regression_test binary> Path to the Regression_test executable to run. |
| 17 | + <regression_scenes_dir> Directory containing the regression scenes. |
| 18 | + <sofa_root> Path to the SOFA build/install directory. |
| 19 | + [<reference_plugin_dir>] Optional. Directory of the reference plugin. Defaults to this script's parent directory. |
18 | 20 |
|
19 | | -os.environ["REGRESSION_SCENES_DIR"] = sys.argv[2] |
| 21 | +Examples: |
| 22 | + Linux: |
| 23 | + python {script} /home/user/build/bin/Regression_test ~/projects/sofa-src ~/projects/sofa-build ~/projects/regression/references |
| 24 | + Windows: |
| 25 | + python {script} C:\\projects\\sofa-build\\bin\\Release\\Regression_test.exe C:\\projects\\sofa-src C:\\projects\\sofa-build C:\\projects\\sofa-src\\applications\\projects\\Regression\\references |
| 26 | +""".strip() |
| 27 | + print(msg) |
| 28 | + sys.exit(exit_code) |
20 | 29 |
|
21 | | -os.environ["SOFA_ROOT"] = sys.argv[3] |
22 | | -os.environ["SOFA_PLUGIN_PATH"] = sys.argv[3] + '/lib' |
23 | 30 |
|
| 31 | +# Help flag handling and argument count validation |
| 32 | +if len(sys.argv) == 2 and sys.argv[1] in ("-h", "--help"): |
| 33 | + print_help(0) |
24 | 34 |
|
25 | | -if len(sys.argv) == 5: |
26 | | - os.environ["REGRESSION_DIR"] = sys.argv[4] |
27 | | -else: |
28 | | - script_dir = Path( __file__ ).parent.absolute() |
29 | | - os.environ["REGRESSION_DIR"] = script_dir |
| 35 | +# We expect 4 or 5 arguments total including the script name |
| 36 | +if len(sys.argv) not in (4, 5): |
| 37 | + print("Error: invalid number of arguments.\n", file=sys.stderr) |
| 38 | + print_help(1) |
30 | 39 |
|
| 40 | +# Securely access argv with bounds checks done above |
| 41 | +bin_path = Path(sys.argv[1]) |
| 42 | +scenes_dir = Path(sys.argv[2]) |
| 43 | +sofa_root = Path(sys.argv[3]) |
| 44 | +regression_dir = Path(sys.argv[4]) if len(sys.argv) == 5 else Path(__file__).parent.absolute() |
31 | 45 |
|
| 46 | +# Validate paths before using them |
| 47 | +errors = [] |
| 48 | +if not bin_path.exists(): |
| 49 | + errors.append(f"Regression_test binary not found: {bin_path}") |
| 50 | +elif bin_path.is_dir(): |
| 51 | + errors.append(f"Regression_test binary points to a directory, expected a file: {bin_path}") |
32 | 52 |
|
33 | | -os.system(sys.argv[1]) |
| 53 | +if not scenes_dir.exists() or not scenes_dir.is_dir(): |
| 54 | + errors.append(f"Invalid regression scenes directory: {scenes_dir}") |
| 55 | + |
| 56 | +if not sofa_root.exists() or not sofa_root.is_dir(): |
| 57 | + errors.append(f"Invalid SOFA root directory: {sofa_root}") |
| 58 | + |
| 59 | +if not regression_dir.exists() or not regression_dir.is_dir(): |
| 60 | + errors.append(f"Invalid reference plugin directory: {regression_dir}") |
| 61 | + |
| 62 | +if errors: |
| 63 | + print("\n".join(["Argument validation failed:"] + errors), file=sys.stderr) |
| 64 | + sys.exit(1) |
| 65 | + |
| 66 | +# Set required environment variables |
| 67 | +os.environ["REGRESSION_SCENES_DIR"] = str(scenes_dir) |
| 68 | +os.environ["SOFA_ROOT"] = str(sofa_root) |
| 69 | +os.environ["SOFA_PLUGIN_PATH"] = str(sofa_root / "lib") |
| 70 | +os.environ["REGRESSION_DIR"] = str(regression_dir) |
| 71 | + |
| 72 | +# Launch the binary without invoking a shell to avoid command injection issues |
| 73 | +try: |
| 74 | + result = subprocess.run([str(bin_path)], check=False) |
| 75 | + sys.exit(result.returncode) |
| 76 | +except FileNotFoundError: |
| 77 | + print(f"Failed to execute binary (not found): {bin_path}", file=sys.stderr) |
| 78 | + sys.exit(1) |
| 79 | +except PermissionError: |
| 80 | + print(f"Failed to execute binary (permission denied): {bin_path}", file=sys.stderr) |
| 81 | + sys.exit(1) |
0 commit comments