diff --git a/ci/run_ctests.sh b/ci/run_ctests.sh index fc1de8e1b4..3d77d3ae29 100755 --- a/ci/run_ctests.sh +++ b/ci/run_ctests.sh @@ -21,8 +21,14 @@ else exit 1 fi +# Skip ROUTING_* gtests when CUOPT_RUN_ROUTING_TESTS is false (e.g. PRs that don't touch routing) +RUN_ROUTING_TESTS="${CUOPT_RUN_ROUTING_TESTS:-true}" for gt in "${GTEST_DIR}"/*_TEST; do test_name=$(basename "${gt}") + if [[ "${RUN_ROUTING_TESTS}" == "false" ]] && [[ "${test_name}" == ROUTING_* ]]; then + echo "Skipping gtest ${test_name} (routing tests not requested)" + continue + fi echo "Running gtest ${test_name}" "${gt}" "$@" done diff --git a/ci/run_cuopt_pytests.sh b/ci/run_cuopt_pytests.sh index 66e996715a..05d08aac46 100755 --- a/ci/run_cuopt_pytests.sh +++ b/ci/run_cuopt_pytests.sh @@ -9,4 +9,9 @@ set -euo pipefail # Support invoking run_cuopt_pytests.sh outside the script directory cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../python/cuopt/cuopt/ -pytest -s --cache-clear "$@" tests +# Skip routing tests when CUOPT_RUN_ROUTING_TESTS is false (e.g. PRs that don't touch routing) +if [[ "${CUOPT_RUN_ROUTING_TESTS:-true}" == "false" ]]; then + pytest -s --cache-clear "$@" --ignore=tests/routing tests +else + pytest -s --cache-clear "$@" tests +fi diff --git a/ci/test_cpp.sh b/ci/test_cpp.sh index 653c44133a..c849ed0d4e 100755 --- a/ci/test_cpp.sh +++ b/ci/test_cpp.sh @@ -1,6 +1,6 @@ #!/bin/bash -# SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 set -euo pipefail @@ -48,6 +48,13 @@ EXITCODE=0 trap "EXITCODE=1" ERR set +e +# Only in PR workflow: skip routing tests when PR doesn't touch routing code. Other runs (nightly, manual) run all tests. +if [[ -z "${CUOPT_RUN_ROUTING_TESTS:-}" ]] && [[ "${GITHUB_REF:-}" == refs/heads/pull-request/* ]]; then + CI_DIR="$(cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")" && pwd)" + CUOPT_RUN_ROUTING_TESTS=$(bash "${CI_DIR}/utils/routing_changed.sh") + export CUOPT_RUN_ROUTING_TESTS +fi + # Run gtests from libcuopt-tests package export GTEST_OUTPUT=xml:${RAPIDS_TESTS_DIR}/ diff --git a/ci/test_python.sh b/ci/test_python.sh index 0a70e56fa7..0e96de69fd 100755 --- a/ci/test_python.sh +++ b/ci/test_python.sh @@ -1,6 +1,6 @@ #!/bin/bash -# SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 set -euo pipefail @@ -54,6 +54,13 @@ set +e # Due to race condition in certain cases UCX might not be able to cleanup properly, so we set the number of threads to 1 export OMP_NUM_THREADS=1 +# Only in PR workflow: skip routing tests when PR doesn't touch routing code. Other runs (nightly, manual) run all tests. +if [[ -z "${CUOPT_RUN_ROUTING_TESTS:-}" ]] && [[ "${GITHUB_REF:-}" == refs/heads/pull-request/* ]]; then + CI_DIR="$(cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")" && pwd)" + CUOPT_RUN_ROUTING_TESTS=$(bash "${CI_DIR}/utils/routing_changed.sh") + export CUOPT_RUN_ROUTING_TESTS +fi + rapids-logger "Test cuopt_cli" timeout 10m bash ./python/libcuopt/libcuopt/tests/test_cli.sh diff --git a/ci/test_wheel_cuopt.sh b/ci/test_wheel_cuopt.sh index d761b27214..839d698fa7 100755 --- a/ci/test_wheel_cuopt.sh +++ b/ci/test_wheel_cuopt.sh @@ -53,6 +53,13 @@ cd - RAPIDS_DATASET_ROOT_DIR="$(realpath datasets)" export RAPIDS_DATASET_ROOT_DIR +# Only in PR workflow: skip routing tests when PR doesn't touch routing code. Other runs (nightly, manual) run all tests. +if [[ -z "${CUOPT_RUN_ROUTING_TESTS:-}" ]] && [[ "${GITHUB_REF:-}" == refs/heads/pull-request/* ]]; then + CI_DIR="$(cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")" && pwd)" + CUOPT_RUN_ROUTING_TESTS=$(bash "${CI_DIR}/utils/routing_changed.sh") + export CUOPT_RUN_ROUTING_TESTS +fi + # Run CLI tests timeout 10m bash ./python/libcuopt/libcuopt/tests/test_cli.sh diff --git a/ci/utils/routing_changed.sh b/ci/utils/routing_changed.sh new file mode 100755 index 0000000000..2d9ddd92cf --- /dev/null +++ b/ci/utils/routing_changed.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Prints "true" if routing-related files changed vs origin/main, else "false". +# Only used when running under the PR workflow (refs/heads/pull-request/*); other +# workflows (nightly, manual test.yaml) run all tests and do not call this script. +# Must be run from the repository root. + +set -euo pipefail + +ROUTING_PATTERNS=( + 'python/cuopt/cuopt/routing/' + 'python/cuopt/cuopt/tests/routing/' + 'cpp/src/routing/' + 'cpp/include/cuopt/routing/' + 'cpp/tests/routing/' +) + +# If explicitly set by caller, respect it +if [[ -n "${CUOPT_RUN_ROUTING_TESTS:-}" ]]; then + if [[ "${CUOPT_RUN_ROUTING_TESTS}" == "false" ]]; then + echo "false" + exit 0 + fi + echo "true" + exit 0 +fi + +# Not in a git repo or no merge base: run routing tests to be safe +if ! git rev-parse --is-inside-work-tree &>/dev/null; then + echo "true" + exit 0 +fi + +MB="" +if git fetch origin main --depth=500 2>/dev/null; then + MB=$(git merge-base HEAD origin/main 2>/dev/null) || true +fi +if [[ -z "${MB:-}" ]]; then + echo "true" + exit 0 +fi + +CHANGED=$(git diff --name-only "${MB}...HEAD" 2>/dev/null) || { echo "true"; exit 0; } +for pat in "${ROUTING_PATTERNS[@]}"; do + if echo "${CHANGED}" | grep -qE "^${pat}"; then + echo "true" + exit 0 + fi +done +echo "false"