From 20ae1200a965769b3e9e42f87e88fc39b194bb05 Mon Sep 17 00:00:00 2001 From: Aryan Date: Sat, 10 Oct 2026 23:55:20 -0400 Subject: [PATCH 1/3] ci: save mini-CTK cache only on default branch Signed-off-by: Aryan --- .github/actions/fetch_ctk/action.yml | 1 + tests/test_ctk_cache_save_gate.py | 59 ++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 tests/test_ctk_cache_save_gate.py diff --git a/.github/actions/fetch_ctk/action.yml b/.github/actions/fetch_ctk/action.yml index 994e35924fc..f18332acc68 100644 --- a/.github/actions/fetch_ctk/action.yml +++ b/.github/actions/fetch_ctk/action.yml @@ -136,6 +136,7 @@ runs: - name: Upload CTK cache if: ${{ !cancelled() && + github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && steps.ctk-get-cache.outputs.cache-hit != 'true' }} uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: diff --git a/tests/test_ctk_cache_save_gate.py b/tests/test_ctk_cache_save_gate.py new file mode 100644 index 00000000000..316b504603c --- /dev/null +++ b/tests/test_ctk_cache_save_gate.py @@ -0,0 +1,59 @@ +"""Regression coverage for the mini-CTK cache save boundary.""" + +from pathlib import Path +import re +import unittest + + +ACTION = Path(__file__).parents[1] / ".github/actions/fetch_ctk/action.yml" + + +def should_save(ref: str, default_branch: str, cancelled: bool, cache_hit: str) -> bool: + """Model the save condition using GitHub's full ref and cache-hit output.""" + return ( + not cancelled + and ref == f"refs/heads/{default_branch}" + and cache_hit != "true" + ) + + +class TestCtkCacheSaveGate(unittest.TestCase): + def test_workflow_condition_uses_full_default_branch_ref_and_preserves_guards(self): + action = ACTION.read_text() + match = re.search( + r"(?ms)^ - name: Upload CTK cache\n if: \$\{\{(.*?)\}\}", + action, + ) + self.assertIsNotNone(match) + expression = " ".join(match.group(1).split()) + self.assertIn("!cancelled()", expression) + self.assertIn( + "github.ref == format('refs/heads/{0}', github.event.repository.default_branch)", + expression, + ) + self.assertIn("steps.ctk-get-cache.outputs.cache-hit != 'true'", expression) + + def test_cache_save_ref_and_status_matrix(self): + cases = ( + # The default branch saves after a miss, including an empty output. + ("refs/heads/main", "main", False, "false", True), + ("refs/heads/main", "main", False, "", True), + # Other branches and PR merge refs restore but never save. + ("refs/heads/feature", "main", False, "false", False), + ("refs/pull/3071/merge", "main", False, "false", False), + # Full-ref comparison prevents a same-named tag from saving. + ("refs/tags/main", "main", False, "false", False), + # The repository's configured default branch may differ from main. + ("refs/heads/ctk-next", "ctk-next", False, "false", True), + ("refs/heads/main", "main", True, "false", False), + ("refs/heads/main", "main", False, "true", False), + ) + for ref, default_branch, cancelled, cache_hit, expected in cases: + with self.subTest(ref=ref, cancelled=cancelled, cache_hit=cache_hit): + self.assertEqual( + should_save(ref, default_branch, cancelled, cache_hit), expected + ) + + +if __name__ == "__main__": + unittest.main() From c1b3d0d4e31140c060b54f51af9bdc6f48d2b64d Mon Sep 17 00:00:00 2001 From: Aryan Date: Sat, 10 Oct 2026 23:56:39 -0400 Subject: [PATCH 2/3] test: place CTK cache gate coverage with CI tools Signed-off-by: Aryan --- {tests => ci/tools/tests}/test_ctk_cache_save_gate.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) rename {tests => ci/tools/tests}/test_ctk_cache_save_gate.py (85%) diff --git a/tests/test_ctk_cache_save_gate.py b/ci/tools/tests/test_ctk_cache_save_gate.py similarity index 85% rename from tests/test_ctk_cache_save_gate.py rename to ci/tools/tests/test_ctk_cache_save_gate.py index 316b504603c..5ec6eabe1e0 100644 --- a/tests/test_ctk_cache_save_gate.py +++ b/ci/tools/tests/test_ctk_cache_save_gate.py @@ -5,7 +5,7 @@ import unittest -ACTION = Path(__file__).parents[1] / ".github/actions/fetch_ctk/action.yml" +ACTION = Path(__file__).parents[3] / ".github/actions/fetch_ctk/action.yml" def should_save(ref: str, default_branch: str, cancelled: bool, cache_hit: str) -> bool: @@ -32,6 +32,14 @@ def test_workflow_condition_uses_full_default_branch_ref_and_preserves_guards(se expression, ) self.assertIn("steps.ctk-get-cache.outputs.cache-hit != 'true'", expression) + self.assertIn( + "- name: Get CUDA components\n if: ${{ steps.ctk-get-cache.outputs.cache-hit != 'true' }}", + action, + ) + self.assertIn( + "- name: Restore CTK cache\n if: ${{ steps.ctk-get-cache.outputs.cache-hit == 'true' }}", + action, + ) def test_cache_save_ref_and_status_matrix(self): cases = ( From b01fb5a0c768567182a7f2415230e9e7c0973dac Mon Sep 17 00:00:00 2001 From: Aryan Date: Sun, 11 Oct 2026 00:05:16 -0400 Subject: [PATCH 3/3] test: make CTK cache condition coverage mutation-sensitive Signed-off-by: Aryan --- ci/tools/tests/test_ctk_cache_save_gate.py | 99 ++++++++++------------ 1 file changed, 44 insertions(+), 55 deletions(-) diff --git a/ci/tools/tests/test_ctk_cache_save_gate.py b/ci/tools/tests/test_ctk_cache_save_gate.py index 5ec6eabe1e0..66e04e0abe3 100644 --- a/ci/tools/tests/test_ctk_cache_save_gate.py +++ b/ci/tools/tests/test_ctk_cache_save_gate.py @@ -1,67 +1,56 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + """Regression coverage for the mini-CTK cache save boundary.""" -from pathlib import Path import re -import unittest +from pathlib import Path +import pytest ACTION = Path(__file__).parents[3] / ".github/actions/fetch_ctk/action.yml" def should_save(ref: str, default_branch: str, cancelled: bool, cache_hit: str) -> bool: """Model the save condition using GitHub's full ref and cache-hit output.""" - return ( - not cancelled - and ref == f"refs/heads/{default_branch}" - and cache_hit != "true" - ) - + return not cancelled and ref == f"refs/heads/{default_branch}" and cache_hit != "true" -class TestCtkCacheSaveGate(unittest.TestCase): - def test_workflow_condition_uses_full_default_branch_ref_and_preserves_guards(self): - action = ACTION.read_text() - match = re.search( - r"(?ms)^ - name: Upload CTK cache\n if: \$\{\{(.*?)\}\}", - action, - ) - self.assertIsNotNone(match) - expression = " ".join(match.group(1).split()) - self.assertIn("!cancelled()", expression) - self.assertIn( - "github.ref == format('refs/heads/{0}', github.event.repository.default_branch)", - expression, - ) - self.assertIn("steps.ctk-get-cache.outputs.cache-hit != 'true'", expression) - self.assertIn( - "- name: Get CUDA components\n if: ${{ steps.ctk-get-cache.outputs.cache-hit != 'true' }}", - action, - ) - self.assertIn( - "- name: Restore CTK cache\n if: ${{ steps.ctk-get-cache.outputs.cache-hit == 'true' }}", - action, - ) - def test_cache_save_ref_and_status_matrix(self): - cases = ( - # The default branch saves after a miss, including an empty output. - ("refs/heads/main", "main", False, "false", True), - ("refs/heads/main", "main", False, "", True), - # Other branches and PR merge refs restore but never save. - ("refs/heads/feature", "main", False, "false", False), - ("refs/pull/3071/merge", "main", False, "false", False), - # Full-ref comparison prevents a same-named tag from saving. - ("refs/tags/main", "main", False, "false", False), - # The repository's configured default branch may differ from main. - ("refs/heads/ctk-next", "ctk-next", False, "false", True), - ("refs/heads/main", "main", True, "false", False), - ("refs/heads/main", "main", False, "true", False), - ) - for ref, default_branch, cancelled, cache_hit, expected in cases: - with self.subTest(ref=ref, cancelled=cancelled, cache_hit=cache_hit): - self.assertEqual( - should_save(ref, default_branch, cancelled, cache_hit), expected - ) - - -if __name__ == "__main__": - unittest.main() +@pytest.mark.agent_authored(model="gpt-6") +def test_workflow_condition_uses_full_default_branch_ref_and_preserves_guards(): + action = ACTION.read_text() + match = re.search( + r"(?ms)^ - name: Upload CTK cache\n if: \$\{\{(.*?)\}\}", + action, + ) + assert match is not None + expression = " ".join(match.group(1).split()) + assert expression == ( + "!cancelled() && " + "github.ref == format('refs/heads/{0}', " + "github.event.repository.default_branch) && " + "steps.ctk-get-cache.outputs.cache-hit != 'true'" + ) + assert ("- name: Get CUDA components\n if: ${{ steps.ctk-get-cache.outputs.cache-hit != 'true' }}") in action + assert ("- name: Restore CTK cache\n if: ${{ steps.ctk-get-cache.outputs.cache-hit == 'true' }}") in action + + +@pytest.mark.agent_authored(model="gpt-6") +def test_cache_save_ref_and_status_matrix(): + cases = ( + # The default branch saves after a miss, including an empty output. + ("refs/heads/main", "main", False, "false", True), + ("refs/heads/main", "main", False, "", True), + # Other branches and PR merge refs restore but never save. + ("refs/heads/feature", "main", False, "false", False), + ("refs/pull/3071/merge", "main", False, "false", False), + # Full-ref comparison prevents a same-named tag from saving. + ("refs/tags/main", "main", False, "false", False), + # The repository's configured default branch may differ from main. + ("refs/heads/ctk-next", "ctk-next", False, "false", True), + ("refs/heads/main", "main", True, "false", False), + ("refs/heads/main", "main", False, "true", False), + ) + for ref, default_branch, cancelled, cache_hit, expected in cases: + assert should_save(ref, default_branch, cancelled, cache_hit) == expected