Skip to content

Commit 31c019f

Browse files
Chunk Ctests so we dont run into large number of tests error (#3050)
* Chunk Ctests so we dont run into large number of tests error * Addressing feedback from copilot
1 parent 5abe410 commit 31c019f

File tree

1 file changed

+78
-10
lines changed

1 file changed

+78
-10
lines changed

script/launch_tests.sh

Lines changed: 78 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,88 @@ python3 "$SCRIPT_DIR/dependency-parser/main.py" select "$JSON_FILE" origin/devel
4040
# Path to tests_to_run.json in the same directory
4141
TEST_FILE="tests_to_run.json"
4242

43-
command=$(python3 -c "
43+
# Configuration: Adjust these defaults as needed
44+
# Number of tests per ctest command (can be overridden with CTEST_CHUNK_SIZE env var)
45+
DEFAULT_CHUNK_SIZE=10
46+
# Whether to stop on first failure (can be overridden with CTEST_FAIL_FAST env var)
47+
DEFAULT_FAIL_FAST=false
48+
49+
# Split tests into chunks and run multiple ctest commands
50+
# Export variables so Python subprocess can access them
51+
export CHUNK_SIZE=${CTEST_CHUNK_SIZE:-$DEFAULT_CHUNK_SIZE}
52+
export FAIL_FAST=${CTEST_FAIL_FAST:-$DEFAULT_FAIL_FAST}
53+
54+
python3 -c "
4455
import json
4556
import os
57+
import sys
58+
import subprocess
59+
60+
CHUNK_SIZE = int(os.environ.get('CHUNK_SIZE', '10'))
61+
FAIL_FAST = os.environ.get('FAIL_FAST', 'false').lower() == 'true'
62+
4663
with open('$TEST_FILE', 'r') as f:
4764
data = json.load(f)
4865
tests = data.get('tests_to_run', [])
49-
if tests:
50-
# Extract just the filename after the last '/'
51-
clean_tests = [os.path.basename(test) for test in tests]
52-
print('ctest --output-on-failure -R \"' + '|'.join(clean_tests) + '\"')
53-
else:
66+
67+
if not tests:
5468
print('# No tests to run')
55-
")
56-
57-
echo "$command"
69+
sys.exit(0)
70+
71+
# Extract just the filename after the last '/'
72+
clean_tests = [os.path.basename(test) for test in tests]
73+
74+
total_tests = len(clean_tests)
75+
total_chunks = (total_tests + CHUNK_SIZE - 1) // CHUNK_SIZE
76+
77+
print(f'# Total tests to run: {total_tests}')
78+
print(f'# Running in {total_chunks} chunk(s) of up to {CHUNK_SIZE} tests each')
79+
print(f'# Fail-fast mode: {FAIL_FAST}')
80+
print()
81+
82+
failed_chunks = []
83+
84+
# Split into chunks
85+
for i in range(0, total_tests, CHUNK_SIZE):
86+
chunk = clean_tests[i:i+CHUNK_SIZE]
87+
chunk_num = (i // CHUNK_SIZE) + 1
88+
89+
print(f'Running test chunk {chunk_num}/{total_chunks} ({len(chunk)} tests)...')
90+
sys.stdout.flush()
91+
92+
# Run ctest command, don't raise exception on failure
93+
cmd = ['ctest', '--output-on-failure', '-R', '|'.join(chunk)]
94+
try:
95+
result = subprocess.run(cmd, cwd='$BUILD_DIR', check=False)
96+
97+
if result.returncode != 0:
98+
failed_chunks.append(chunk_num)
99+
print(f'WARNING: Chunk {chunk_num} had test failures (exit code: {result.returncode})')
100+
101+
# If fail-fast is enabled, exit immediately
102+
if FAIL_FAST:
103+
print(f'FAIL-FAST: Stopping at chunk {chunk_num} due to failures')
104+
sys.exit(1)
105+
except Exception as e:
106+
print(f'ERROR: Failed to run chunk {chunk_num}: {e}')
107+
failed_chunks.append(chunk_num)
108+
if FAIL_FAST:
109+
sys.exit(1)
110+
111+
print()
112+
sys.stdout.flush()
113+
114+
# Print summary
115+
print('=' * 60)
116+
if failed_chunks:
117+
print(f'SUMMARY: {len(failed_chunks)} of {total_chunks} chunk(s) had failures: {failed_chunks}')
118+
print('=' * 60)
119+
sys.exit(1)
120+
else:
121+
print(f'SUMMARY: All {total_chunks} chunk(s) passed successfully!')
122+
print('=' * 60)
123+
sys.exit(0)
124+
"
125+
PYTHON_EXIT=$?
58126

59-
eval "$command"
127+
exit $PYTHON_EXIT

0 commit comments

Comments
 (0)