Skip to content

Conversation

@bdice
Copy link
Contributor

@bdice bdice commented Dec 16, 2025

Description

This PR creates separate test run scripts like ci/run_ctests.sh. This aligns with the pattern used in RAPIDS libraries. I am exploring adding devcontainers to cuOpt (rapidsai/devcontainers#637), and this change would help with allowing tests to run in both CI and devcontainer environments.

Checklist

  • I am familiar with the Contributing Guidelines.
  • Testing
    • New or existing tests cover these changes
    • Added tests
    • Created an issue to follow-up
    • NA
  • Documentation
    • The documentation is up to date with these changes
    • Added new documentation
    • NA

Summary by CodeRabbit

  • Chores
    • Refactored continuous integration test execution workflow by introducing dedicated test runner scripts for C++ and Python test suites, improving test execution consistency and maintainability across different testing environments.

✏️ Tip: You can customize this high-level summary in your review settings.

@bdice bdice requested a review from a team as a code owner December 16, 2025 22:28
@bdice bdice requested a review from vyasr December 16, 2025 22:28
@bdice bdice added non-breaking Introduces a non-breaking change improvement Improves an existing functionality labels Dec 16, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 16, 2025

📝 Walkthrough

Walkthrough

New Bash wrapper scripts are added to encapsulate test execution for Google Test binaries and Python test suites. Existing CI test scripts are refactored to delegate test execution to these wrapper scripts instead of performing inline execution, improving modularity and consistency across the CI pipeline.

Changes

Cohort / File(s) Summary
New test runner scripts
ci/run_ctests.sh, ci/run_cuopt_pytests.sh, ci/run_cuopt_server_pytests.sh
Adds three new Bash scripts to encapsulate test execution. run_ctests.sh discovers and runs Google Test binaries sequentially from INSTALL_PREFIX or CONDA_PREFIX. run_cuopt_pytests.sh and run_cuopt_server_pytests.sh execute pytest with cache clearing in their respective package directories. All enable strict shell options and forward arguments to underlying test commands.
C++ test CI runner
ci/test_cpp.sh
Refactors to invoke ./ci/run_ctests.sh instead of inline GTest loop execution. Sets GTEST_OUTPUT=xml environment variable. Increases timeout from 20m to 40m.
Python test CI runners
ci/test_python.sh, ci/test_wheel_cuopt.sh, ci/test_wheel_cuopt_server.sh
Refactor to delegate test execution to wrapper scripts (run_cuopt_pytests.sh and run_cuopt_server_pytests.sh) instead of direct pytest invocations. Removes explicit directory changes and redundant flag specifications previously handled inline.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • New scripts are straightforward bash wrappers with consistent patterns (shebang, strict options, directory changes, command delegation).
  • Modifications across existing test scripts follow a homogeneous refactoring pattern (replacing inline execution with wrapper script calls).
  • All changes are in CI/shell scripting with minimal logic density and no complex control flow.
  • High repetition of similar changes reduces per-file review cognitive load.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: introducing separate test run scripts (ci/run_ctests.sh, ci/run_cuopt_pytests.sh, ci/run_cuopt_server_pytests.sh) to consolidate test execution logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
ci/run_ctests.sh (1)

24-28: Consider adding glob failure handling for edge cases.

If GTEST_DIR exists but contains no *_TEST files, the glob won't expand and the loop will attempt to execute a literal *_TEST command, producing an unclear error message. This is unlikely in practice but could be handled for robustness.

Add this check before the loop:

+# Ensure test binaries exist
+shopt -s nullglob
 for gt in "${GTEST_DIR}"/*_TEST; do
     test_name=$(basename "${gt}")
     echo "Running gtest ${test_name}"
     "${gt}" "$@"
 done
+shopt -u nullglob

Or alternatively, add an explicit check:

+if ! compgen -G "${GTEST_DIR}/*_TEST" > /dev/null; then
+    echo "Error: No test binaries found matching ${GTEST_DIR}/*_TEST" >&2
+    exit 1
+fi
 for gt in "${GTEST_DIR}"/*_TEST; do
     test_name=$(basename "${gt}")
     echo "Running gtest ${test_name}"
     "${gt}" "$@"
 done
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f44e3ec and 21df01f.

📒 Files selected for processing (7)
  • ci/run_ctests.sh (1 hunks)
  • ci/run_cuopt_pytests.sh (1 hunks)
  • ci/run_cuopt_server_pytests.sh (1 hunks)
  • ci/test_cpp.sh (1 hunks)
  • ci/test_python.sh (1 hunks)
  • ci/test_wheel_cuopt.sh (1 hunks)
  • ci/test_wheel_cuopt_server.sh (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*test*.{cpp,cu,py} : Ensure test isolation: prevent GPU state, cached memory, and global variables from leaking between test cases; verify each test independently initializes its environment
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*test*.{cpp,cu,py} : Ensure test isolation: prevent GPU state, cached memory, and global variables from leaking between test cases; verify each test independently initializes its environment

Applied to files:

  • ci/test_wheel_cuopt.sh
  • ci/run_cuopt_server_pytests.sh
  • ci/run_ctests.sh
  • ci/test_python.sh
  • ci/test_cpp.sh
  • ci/run_cuopt_pytests.sh
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*benchmark*.{cpp,cu,py} : Include performance benchmarks and regression detection for GPU operations; verify near real-time performance on million-variable problems

Applied to files:

  • ci/test_wheel_cuopt.sh
  • ci/run_ctests.sh
  • ci/test_cpp.sh
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*test*.{cpp,cu,py} : Write tests validating numerical correctness of optimization results (not just 'runs without error'); test degenerate cases (infeasible, unbounded, empty, singleton problems)

Applied to files:

  • ci/test_wheel_cuopt.sh
  • ci/run_ctests.sh
  • ci/run_cuopt_pytests.sh
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*test*.{cpp,cu,py} : Add tests for algorithm phase transitions: verify correct initialization of bounds and state when transitioning from presolve to simplex to diving to crossover

Applied to files:

  • ci/run_ctests.sh
  • ci/test_cpp.sh
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*test*.{cpp,cu,py} : Add tests for problem transformations: verify correctness of original→transformed→postsolve mappings and index consistency across problem representations

Applied to files:

  • ci/run_ctests.sh
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*test*.{cpp,cu,py} : Test with free variables, singleton problems, and extreme problem dimensions near resource limits to validate edge case handling

Applied to files:

  • ci/test_cpp.sh
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.10, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.12, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.10, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.11, amd64, rockylinux8
  • GitHub Check: checks / check-style
🔇 Additional comments (12)
ci/run_cuopt_pytests.sh (2)

1-10: LGTM! Robust path resolution and strict error handling.

The script correctly uses set -euo pipefail for strict error handling, and the path resolution with realpath and BASH_SOURCE[0] ensures the script works when invoked from any location. The cd will fail fast if the target directory doesn't exist, thanks to the -e flag.


12-12: LGTM! Proper argument forwarding.

The "$@" forwarding allows callers to pass additional pytest flags (e.g., coverage, JUnit XML output) while --cache-clear ensures consistent test runs.

ci/run_cuopt_server_pytests.sh (1)

1-12: LGTM! Consistent with cuopt pytest wrapper.

This script follows the same pattern as ci/run_cuopt_pytests.sh, ensuring consistent behavior across test suites. The structure, error handling, and argument forwarding are all appropriate.

ci/test_wheel_cuopt_server.sh (1)

31-31: LGTM! Clean delegation to wrapper script.

The change correctly delegates test execution to the new run_cuopt_server_pytests.sh wrapper while preserving the timeout and pytest flags. This aligns with the PR's goal of centralizing test execution logic.

ci/test_cpp.sh (2)

51-52: LGTM! Proper gtest XML output configuration.

The GTEST_OUTPUT environment variable is correctly exported before invoking the test runner, ensuring all gtests generate XML reports in the specified directory.


55-55: Note the timeout semantic change: from per-test 20m to total wrapper 40m. The timeout changed from an individual limit per test (20m per ${gt} in the loop) to a total limit for all tests combined (40m for ./ci/run_ctests.sh). Since the wrapper script runs tests sequentially without per-test timeouts, verify that 40m total accommodates all tests' actual execution time plus a reasonable buffer.

ci/test_wheel_cuopt.sh (1)

65-65: LGTM! Consistent delegation to wrapper script.

The change correctly delegates to run_cuopt_pytests.sh while preserving timeout and pytest flags. The RAPIDS_DATASET_ROOT_DIR environment variable set at line 55 is properly inherited by the wrapper script.

ci/test_python.sh (2)

61-67: LGTM! Cleaner test invocation with wrapper.

The refactoring correctly delegates to run_cuopt_pytests.sh, eliminating manual directory changes and redundant --cache-clear flags. Coverage and JUnit XML configurations are properly forwarded.


70-75: LGTM! Consistent wrapper delegation.

The cuopt_server test invocation follows the same clean pattern as the cuopt tests, with proper forwarding of coverage and reporting configurations to the wrapper script.

ci/run_ctests.sh (3)

1-5: LGTM! Standard script setup.

The script uses appropriate strict error handling with set -euo pipefail, consistent with the other test wrapper scripts.


7-22: LGTM! Robust multi-environment path resolution.

The script correctly handles both CI (conda/installed) and devcontainer (build directory) environments. The error message clearly lists all searched locations, and the fallback logic prioritizes the installed location over the build directory, which is the correct ordering for CI environments.


24-28: LGTM! Clean sequential test execution.

The test discovery via glob pattern and sequential execution with argument forwarding is straightforward and correct. The echo statement before each test execution aids debugging and provides clear progress indication.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improves an existing functionality non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant