From 92767e74e190386b8364129e03eb1e6583f3b435 Mon Sep 17 00:00:00 2001 From: Bowen Fu <5812640+BowenFu@users.noreply.github.com> Date: Thu, 13 Aug 2026 16:42:11 +0000 Subject: [PATCH 1/5] [https://nvbugs/5547275][test] Restore stage mapping coverage Signed-off-by: Bowen Fu <5812640+BowenFu@users.noreply.github.com> --- tests/unittest/tools/test_test_to_stage_mapping.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unittest/tools/test_test_to_stage_mapping.py b/tests/unittest/tools/test_test_to_stage_mapping.py index 18c982bab4ec..b62c52a1dd8d 100644 --- a/tests/unittest/tools/test_test_to_stage_mapping.py +++ b/tests/unittest/tools/test_test_to_stage_mapping.py @@ -158,7 +158,6 @@ def test_known_stage_without_tests_is_reported(tmp_path): assert 'no tests mapped to: Empty-PyTorch-1' in proc.stderr.decode() -@pytest.mark.skip(reason="https://nvbugs/5547275") @pytest.mark.parametrize("direction", ["test_to_stage", "stage_to_test", "roundtrip"]) def test_bidirectional_mapping_consistency(stage_query, sample_test_cases, From 7abee4c3c92b4f50e2e6d3ed401f17983903cccd Mon Sep 17 00:00:00 2001 From: Bowen Fu <5812640+BowenFu@users.noreply.github.com> Date: Thu, 13 Aug 2026 16:47:11 +0000 Subject: [PATCH 2/5] [https://nvbugs/5547275][test] Scope mapping invariant to staged tests Signed-off-by: Bowen Fu <5812640+BowenFu@users.noreply.github.com> --- .../tools/test_test_to_stage_mapping.py | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/tests/unittest/tools/test_test_to_stage_mapping.py b/tests/unittest/tools/test_test_to_stage_mapping.py index b62c52a1dd8d..e2613ecc6e90 100644 --- a/tests/unittest/tools/test_test_to_stage_mapping.py +++ b/tests/unittest/tools/test_test_to_stage_mapping.py @@ -25,6 +25,16 @@ MIN_PATTERN_LENGTH = 3 # Minimum length for search patterns +def _stage_backed_tests(stage_query): + """Return tests from YAML files that are wired to a Jenkins stage.""" + return [ + test + for test, mappings in stage_query.test_map.items() + if any(yml in stage_query.yaml_to_stages + for yml, _stage, _backend in mappings) + ] + + @pytest.fixture(scope="module") def stage_query(): """Fixture that provides a StageQuery instance.""" @@ -33,16 +43,14 @@ def stage_query(): @pytest.fixture(scope="module") def sample_test_cases(stage_query): - """Fixture that provides sample test cases from actual data.""" + """Fixture that samples tests backed by a live Jenkins stage.""" random.seed(0) # Ensure deterministic test results - all_tests = list(stage_query.test_map.keys()) + all_tests = _stage_backed_tests(stage_query) if not all_tests: raise RuntimeError( - "No tests found in test mapping. This indicates a configuration " - "issue - either the test database YAML files are missing/empty " - "or the StageQuery is not parsing them correctly. Please check " - "that the test database directory exists and contains valid YAML " - "files with test definitions.") + "No tests are backed by a live Jenkins stage. Check that the " + "Groovy stage map and test database reference the same YAML files." + ) # Return up to MAX_SAMPLES tests randomly selected if len(all_tests) <= MAX_SAMPLES: @@ -82,6 +90,19 @@ def test_data_availability(stage_query): print(f"Max samples configured: {MAX_SAMPLES}") +def test_all_stage_backed_tests_map(stage_query): + """Every test in a Jenkins-wired YAML must resolve to a live stage.""" + stage_backed_tests = _stage_backed_tests(stage_query) + assert stage_backed_tests, "No tests are backed by a live Jenkins stage" + + unmapped = [ + test for test in stage_backed_tests + if not stage_query.tests_to_stages([test]) + ] + assert not unmapped, \ + f"Stage-backed tests should map to at least one stage: {unmapped}" + + def test_documented_stage_examples_are_live(stage_query): """Documented --stages examples must name stages that still exist in CI.""" sources = [ @@ -163,7 +184,6 @@ def test_known_stage_without_tests_is_reported(tmp_path): def test_bidirectional_mapping_consistency(stage_query, sample_test_cases, sample_stages, direction): """Test mapping consistency in both directions with roundtrip validation.""" - if direction == "test_to_stage": if not sample_test_cases: pytest.skip("No test cases available") From 055b85ca6035005ec828a2538ad90b755c34109b Mon Sep 17 00:00:00 2001 From: Bowen Fu <5812640+BowenFu@users.noreply.github.com> Date: Thu, 13 Aug 2026 16:51:37 +0000 Subject: [PATCH 3/5] [https://nvbugs/5547275][test] Apply repository formatting Signed-off-by: Bowen Fu <5812640+BowenFu@users.noreply.github.com> --- tests/unittest/tools/test_test_to_stage_mapping.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/unittest/tools/test_test_to_stage_mapping.py b/tests/unittest/tools/test_test_to_stage_mapping.py index e2613ecc6e90..7b0367ff2f63 100644 --- a/tests/unittest/tools/test_test_to_stage_mapping.py +++ b/tests/unittest/tools/test_test_to_stage_mapping.py @@ -28,8 +28,7 @@ def _stage_backed_tests(stage_query): """Return tests from YAML files that are wired to a Jenkins stage.""" return [ - test - for test, mappings in stage_query.test_map.items() + test for test, mappings in stage_query.test_map.items() if any(yml in stage_query.yaml_to_stages for yml, _stage, _backend in mappings) ] @@ -49,8 +48,7 @@ def sample_test_cases(stage_query): if not all_tests: raise RuntimeError( "No tests are backed by a live Jenkins stage. Check that the " - "Groovy stage map and test database reference the same YAML files." - ) + "Groovy stage map and test database reference the same YAML files.") # Return up to MAX_SAMPLES tests randomly selected if len(all_tests) <= MAX_SAMPLES: From 0f07e68f55bf2eb5c286fdcd4d932455b8d81d25 Mon Sep 17 00:00:00 2001 From: Bowen Fu <5812640+BowenFu@users.noreply.github.com> Date: Thu, 13 Aug 2026 17:16:24 +0000 Subject: [PATCH 4/5] [https://nvbugs/5547275][test] Make mapping samples deterministic Signed-off-by: Bowen Fu <5812640+BowenFu@users.noreply.github.com> --- .../tools/test_test_to_stage_mapping.py | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/tests/unittest/tools/test_test_to_stage_mapping.py b/tests/unittest/tools/test_test_to_stage_mapping.py index 7b0367ff2f63..6737edf02c4e 100644 --- a/tests/unittest/tools/test_test_to_stage_mapping.py +++ b/tests/unittest/tools/test_test_to_stage_mapping.py @@ -25,13 +25,11 @@ MIN_PATTERN_LENGTH = 3 # Minimum length for search patterns -def _stage_backed_tests(stage_query): +def _stage_backed_tests(stage_query: StageQuery) -> list[str]: """Return tests from YAML files that are wired to a Jenkins stage.""" - return [ - test for test, mappings in stage_query.test_map.items() - if any(yml in stage_query.yaml_to_stages - for yml, _stage, _backend in mappings) - ] + return sorted(test for test, mappings in stage_query.test_map.items() + if any(yml in stage_query.yaml_to_stages + for yml, _stage, _backend in mappings)) @pytest.fixture(scope="module") @@ -41,9 +39,8 @@ def stage_query(): @pytest.fixture(scope="module") -def sample_test_cases(stage_query): +def sample_test_cases(stage_query: StageQuery) -> list[str]: """Fixture that samples tests backed by a live Jenkins stage.""" - random.seed(0) # Ensure deterministic test results all_tests = _stage_backed_tests(stage_query) if not all_tests: raise RuntimeError( @@ -54,14 +51,13 @@ def sample_test_cases(stage_query): if len(all_tests) <= MAX_SAMPLES: return all_tests - return random.sample(all_tests, MAX_SAMPLES) + return random.Random(0).sample(all_tests, MAX_SAMPLES) @pytest.fixture(scope="module") -def sample_stages(stage_query): +def sample_stages(stage_query: StageQuery) -> list[str]: """Fixture that provides sample stages from actual data.""" - random.seed(0) # Ensure deterministic test results - all_stages = list(stage_query.stage_to_yaml.keys()) + all_stages = sorted(stage_query.stage_to_yaml) if not all_stages: raise RuntimeError( "No stages found in stage mapping. This indicates a configuration " @@ -74,7 +70,7 @@ def sample_stages(stage_query): if len(all_stages) <= MAX_SAMPLES: return all_stages - return random.sample(all_stages, MAX_SAMPLES) + return random.Random(0).sample(all_stages, MAX_SAMPLES) def test_data_availability(stage_query): @@ -88,7 +84,7 @@ def test_data_availability(stage_query): print(f"Max samples configured: {MAX_SAMPLES}") -def test_all_stage_backed_tests_map(stage_query): +def test_all_stage_backed_tests_map(stage_query: StageQuery) -> None: """Every test in a Jenkins-wired YAML must resolve to a live stage.""" stage_backed_tests = _stage_backed_tests(stage_query) assert stage_backed_tests, "No tests are backed by a live Jenkins stage" From a1c0e9f2cd879ea69052f08b2615e8e562f045f0 Mon Sep 17 00:00:00 2001 From: Bowen Fu <5812640+BowenFu@users.noreply.github.com> Date: Thu, 13 Aug 2026 20:06:32 +0000 Subject: [PATCH 5/5] test: tighten live-stage mapping samples Signed-off-by: Bowen Fu <5812640+BowenFu@users.noreply.github.com> --- .../tools/test_test_to_stage_mapping.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tests/unittest/tools/test_test_to_stage_mapping.py b/tests/unittest/tools/test_test_to_stage_mapping.py index 6737edf02c4e..19fb16b7a11e 100644 --- a/tests/unittest/tools/test_test_to_stage_mapping.py +++ b/tests/unittest/tools/test_test_to_stage_mapping.py @@ -4,6 +4,7 @@ import subprocess import sys from collections import defaultdict +from types import SimpleNamespace import pytest @@ -28,10 +29,24 @@ def _stage_backed_tests(stage_query: StageQuery) -> list[str]: """Return tests from YAML files that are wired to a Jenkins stage.""" return sorted(test for test, mappings in stage_query.test_map.items() - if any(yml in stage_query.yaml_to_stages + if all(yml in stage_query.yaml_to_stages for yml, _stage, _backend in mappings)) +def test_stage_backed_tests_exclude_mixed_mappings() -> None: + """A test in any unwired YAML is not a live-stage sampling candidate.""" + stage_query = SimpleNamespace( + test_map={ + 'mixed': [('l0_wired.yml', 'pre_merge', 'pytorch'), + ('perf.yml', 'post_merge', 'pytorch')], + 'wired': [('l0_wired.yml', 'pre_merge', 'pytorch')], + }, + yaml_to_stages={'l0_wired.yml': ['L0-PyTorch']}, + ) + + assert _stage_backed_tests(stage_query) == ['wired'] + + @pytest.fixture(scope="module") def stage_query(): """Fixture that provides a StageQuery instance.""" @@ -184,8 +199,6 @@ def test_bidirectional_mapping_consistency(stage_query, sample_test_cases, for test_case in sample_test_cases: stages = stage_query.tests_to_stages([test_case]) - assert stages, \ - f"Test '{test_case}' should map to at least one stage" # Verify all returned stages are valid for stage in stages: