From 273ddb644007aa586af4bfd9fcf37281a4f3b5b3 Mon Sep 17 00:00:00 2001 From: Ramakrishna Prabhu Date: Tue, 3 Mar 2026 23:28:33 -0600 Subject: [PATCH 1/5] Add tests --- .github/workflows/pr.yaml | 8 ++++++ ci/run_ctests.sh | 6 +++++ ci/run_cuopt_pytests.sh | 7 ++++- ci/test_cpp.sh | 7 +++++ ci/test_python.sh | 7 +++++ ci/test_wheel_cuopt.sh | 7 +++++ ci/utils/routing_changed.sh | 52 +++++++++++++++++++++++++++++++++++++ 7 files changed, 93 insertions(+), 1 deletion(-) create mode 100755 ci/utils/routing_changed.sh diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 4862fb890c..585400c670 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -253,6 +253,14 @@ jobs: - '!sonarqube/**' - '!ucf/**' - '!utilities/**' + # Routing: used for path-based skip of routing tests when unchanged (see ci/utils/routing_changed.sh) + routing: + - 'python/cuopt/cuopt/routing/**' + - 'python/cuopt/cuopt/tests/routing/**' + - 'cpp/src/routing/**' + - 'cpp/include/cuopt/routing/**' + - 'cpp/tests/routing/**' + - 'regression/routing*' checks: secrets: inherit uses: rapidsai/shared-workflows/.github/workflows/checks.yaml@main 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..fa966f13d9 100755 --- a/ci/test_cpp.sh +++ b/ci/test_cpp.sh @@ -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..956a8818ad 100755 --- a/ci/test_python.sh +++ b/ci/test_python.sh @@ -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..fa67f16651 --- /dev/null +++ b/ci/utils/routing_changed.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# SPDX-FileCopyrightText: Copyright (c) 2025-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) || true +for pat in "${ROUTING_PATTERNS[@]}"; do + if echo "${CHANGED}" | grep -qE "^${pat}"; then + echo "true" + exit 0 + fi +done +echo "false" From 6fecaf7dfafc08a48179886f448fa5e00f2b5a5c Mon Sep 17 00:00:00 2001 From: Ramakrishna Prabhu Date: Tue, 3 Mar 2026 23:31:36 -0600 Subject: [PATCH 2/5] fixt style --- ci/test_cpp.sh | 2 +- ci/test_python.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/test_cpp.sh b/ci/test_cpp.sh index fa966f13d9..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 diff --git a/ci/test_python.sh b/ci/test_python.sh index 956a8818ad..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 From 0d6b3f3ae92d2c5f5031393261d567710015d10c Mon Sep 17 00:00:00 2001 From: Ramakrishna Prabhu Date: Wed, 4 Mar 2026 00:49:34 -0600 Subject: [PATCH 3/5] address review --- ci/utils/routing_changed.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/utils/routing_changed.sh b/ci/utils/routing_changed.sh index fa67f16651..3b151cf4cb 100755 --- a/ci/utils/routing_changed.sh +++ b/ci/utils/routing_changed.sh @@ -42,7 +42,7 @@ if [[ -z "${MB:-}" ]]; then exit 0 fi -CHANGED=$(git diff --name-only "${MB}...HEAD" 2>/dev/null) || true +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" From ca1a0bbd7a740cf4b9fcf4baad6c59af5bcd004e Mon Sep 17 00:00:00 2001 From: Ramakrishnap <42624703+rgsl888prabhu@users.noreply.github.com> Date: Wed, 4 Mar 2026 14:38:34 +0530 Subject: [PATCH 4/5] Update routing_changed.sh --- ci/utils/routing_changed.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/utils/routing_changed.sh b/ci/utils/routing_changed.sh index 3b151cf4cb..2d9ddd92cf 100755 --- a/ci/utils/routing_changed.sh +++ b/ci/utils/routing_changed.sh @@ -1,5 +1,5 @@ #!/bin/bash -# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# 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". From 2c4a1fae04efffacad6df8269c892a328892172e Mon Sep 17 00:00:00 2001 From: Ramakrishna Prabhu Date: Wed, 4 Mar 2026 10:31:34 -0600 Subject: [PATCH 5/5] remove redundant partws --- .github/workflows/pr.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 585400c670..4862fb890c 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -253,14 +253,6 @@ jobs: - '!sonarqube/**' - '!ucf/**' - '!utilities/**' - # Routing: used for path-based skip of routing tests when unchanged (see ci/utils/routing_changed.sh) - routing: - - 'python/cuopt/cuopt/routing/**' - - 'python/cuopt/cuopt/tests/routing/**' - - 'cpp/src/routing/**' - - 'cpp/include/cuopt/routing/**' - - 'cpp/tests/routing/**' - - 'regression/routing*' checks: secrets: inherit uses: rapidsai/shared-workflows/.github/workflows/checks.yaml@main