Skip to content

Commit d9ac8c6

Browse files
committed
Add coverage test helper to run pytest using larger stack
1 parent 2137fed commit d9ac8c6

File tree

2 files changed

+67
-63
lines changed

2 files changed

+67
-63
lines changed

.github/workflows/coverage.yml

Lines changed: 13 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -346,75 +346,25 @@ jobs:
346346
cd "${{ steps.install-root.outputs.INSTALL_ROOT }}"
347347
"$GITHUB_WORKSPACE/.venv/Scripts/pytest" -v --cov=./cuda --cov-append --cov-context=test --cov-config="$GITHUB_WORKSPACE/.coveragerc" "$GITHUB_WORKSPACE/cuda_pathfinder/tests"
348348
349+
# Cython linetrace under coverage on Windows needs more stack than the
350+
# default 1 MB thread size. The helper runs pytest on an 8 MB thread.
349351
- name: Run cuda.bindings tests (with 8MB stack)
350352
continue-on-error: true
351353
run: |
352-
cd "${{ steps.install-root.outputs.INSTALL_ROOT }}"
353-
# Run pytest in 8MB stack thread (Cython linetrace requirement)
354-
"$GITHUB_WORKSPACE/.venv/Scripts/python" << PYTEST_EOF
355-
import os
356-
import sys
357-
import threading
358-
import pytest
359-
360-
os.chdir(r'${{ steps.install-root.outputs.INSTALL_ROOT }}')
361-
threading.stack_size(8 * 1024 * 1024)
362-
result = {'code': 1}
363-
364-
def _run():
365-
workspace = os.environ['GITHUB_WORKSPACE']
366-
result['code'] = pytest.main([
367-
'-v',
368-
'--cov=./cuda',
369-
'--cov-append',
370-
'--cov-context=test',
371-
f'--cov-config={workspace}/.coveragerc',
372-
f'{workspace}/cuda_bindings/tests'
373-
])
374-
375-
t = threading.Thread(target=_run)
376-
t.start()
377-
t.join()
378-
379-
print(f'Bindings tests exit code: {result["code"]}')
380-
# Exit with actual code (continue-on-error handles it)
381-
sys.exit(result['code'])
382-
PYTEST_EOF
383-
384-
# Same 8MB stack thread as bindings: Cython linetrace under coverage on Windows
385-
# can need a larger stack than the default thread size.
354+
"$GITHUB_WORKSPACE/.venv/Scripts/python" "$GITHUB_WORKSPACE/ci/tools/run_pytest_with_stack.py" \
355+
--cwd "${{ steps.install-root.outputs.INSTALL_ROOT }}" \
356+
-v --cov=./cuda --cov-append --cov-context=test \
357+
--cov-config="$GITHUB_WORKSPACE/.coveragerc" \
358+
"$GITHUB_WORKSPACE/cuda_bindings/tests"
359+
386360
- name: Run cuda.core tests (with 8MB stack)
387361
continue-on-error: true
388362
run: |
389-
cd "${{ steps.install-root.outputs.INSTALL_ROOT }}"
390-
"$GITHUB_WORKSPACE/.venv/Scripts/python" << PYTEST_EOF
391-
import os
392-
import sys
393-
import threading
394-
import pytest
395-
396-
os.chdir(r'${{ steps.install-root.outputs.INSTALL_ROOT }}')
397-
threading.stack_size(8 * 1024 * 1024)
398-
result = {'code': 1}
399-
400-
def _run():
401-
workspace = os.environ['GITHUB_WORKSPACE']
402-
result['code'] = pytest.main([
403-
'-v',
404-
'--cov=./cuda',
405-
'--cov-append',
406-
'--cov-context=test',
407-
f'--cov-config={workspace}/.coveragerc',
408-
f'{workspace}/cuda_core/tests'
409-
])
410-
411-
t = threading.Thread(target=_run)
412-
t.start()
413-
t.join()
414-
415-
print(f'cuda.core tests exit code: {result["code"]}')
416-
sys.exit(result['code'])
417-
PYTEST_EOF
363+
"$GITHUB_WORKSPACE/.venv/Scripts/python" "$GITHUB_WORKSPACE/ci/tools/run_pytest_with_stack.py" \
364+
--cwd "${{ steps.install-root.outputs.INSTALL_ROOT }}" \
365+
-v --cov=./cuda --cov-append --cov-context=test \
366+
--cov-config="$GITHUB_WORKSPACE/.coveragerc" \
367+
"$GITHUB_WORKSPACE/cuda_core/tests"
418368
419369
- name: Copy Windows coverage file to workspace
420370
run: |

ci/tools/run_pytest_with_stack.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env python3
2+
3+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
"""Run pytest on a thread with a larger stack size.
8+
9+
Cython linetrace instrumentation under coverage on Windows can exceed the
10+
default 1 MB thread stack. This helper spawns a single worker thread with
11+
a configurable stack (default 8 MB) so the rest of the CI workflow stays
12+
readable.
13+
14+
Usage:
15+
python run_pytest_with_stack.py [--stack-mb N] [--cwd DIR] [pytest args ...]
16+
"""
17+
18+
import argparse
19+
import concurrent.futures
20+
import os
21+
import sys
22+
import threading
23+
24+
import pytest
25+
26+
27+
def main():
28+
parser = argparse.ArgumentParser(description=__doc__)
29+
parser.add_argument(
30+
"--stack-mb",
31+
type=int,
32+
default=8,
33+
help="Thread stack size in megabytes (default: 8)",
34+
)
35+
parser.add_argument(
36+
"--cwd",
37+
default=None,
38+
help="Working directory for the test run",
39+
)
40+
args, pytest_args = parser.parse_known_args()
41+
42+
if args.cwd:
43+
os.chdir(args.cwd)
44+
45+
threading.stack_size(args.stack_mb * 1024 * 1024)
46+
47+
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool:
48+
code = pool.submit(pytest.main, pytest_args).result()
49+
50+
sys.exit(code)
51+
52+
53+
if __name__ == "__main__":
54+
main()

0 commit comments

Comments
 (0)