From 35fa8bce31fed5edad6e12fa36df3bf7a4fdcdab Mon Sep 17 00:00:00 2001 From: yufeiwu-nv <230315618+yufeiwu-nv@users.noreply.github.com> Date: Tue, 8 Sep 2026 08:17:43 +0000 Subject: [PATCH 1/3] [None][fix] Narrow CBTS perf helper selection Map the PyTorch model config helper directly to its consumer so unrelated perf-sanity stages are not selected. Signed-off-by: yufeiwu-nv <230315618+yufeiwu-nv@users.noreply.github.com> --- jenkins/scripts/cbts/rules/tests_def_rule.py | 6 ++++ .../scripts/test_cbts_tests_def_rule.py | 33 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/jenkins/scripts/cbts/rules/tests_def_rule.py b/jenkins/scripts/cbts/rules/tests_def_rule.py index f948d05feb4a..660b5a0d5806 100644 --- a/jenkins/scripts/cbts/rules/tests_def_rule.py +++ b/jenkins/scripts/cbts/rules/tests_def_rule.py @@ -60,6 +60,9 @@ # `acceptance_length.yaml` keys tests directly (`TestC::test_m`) instead of # by HF model name, unlike every other reference YAML. _TEST_ID_KEY_RE = re.compile(r"^(Test\w+)::(\w+)$") +_DIRECT_TEST_CONSUMERS: dict[str, tuple[str, ...]] = { + "tests/integration/defs/perf/pytorch_model_config.py": ("perf/test_perf.py",), +} def _scope_start_line(node: ast.ClassDef | ast.FunctionDef | ast.AsyncFunctionDef) -> int: @@ -250,6 +253,9 @@ def _compute_anchors(self, git_path: str, yaml_path: str, diff: str) -> list[str class anchors via the model-name mapping in `_compute_accuracy_reference_anchors`. """ + direct_consumers = _DIRECT_TEST_CONSUMERS.get(git_path) + if direct_consumers is not None: + return list(direct_consumers) if git_path.startswith(ACCURACY_REFS_PREFIX) and git_path.endswith((".yaml", ".yml")): return self._compute_accuracy_reference_anchors(git_path, yaml_path, diff) if not diff: diff --git a/tests/unittest/scripts/test_cbts_tests_def_rule.py b/tests/unittest/scripts/test_cbts_tests_def_rule.py index 20a60c25cf79..9377cb9a1f94 100644 --- a/tests/unittest/scripts/test_cbts_tests_def_rule.py +++ b/tests/unittest/scripts/test_cbts_tests_def_rule.py @@ -27,7 +27,8 @@ CBTS_ROOT = REPO_ROOT / "jenkins/scripts/cbts" sys.path.insert(0, str(CBTS_ROOT)) -from blocks import YAMLIndex # noqa: E402 +from blocks import Stage, YAMLIndex # noqa: E402 +from rules.base import PRInputs # noqa: E402 from rules.tests_def_rule import ( # noqa: E402 ACCURACY_DIR, ACCURACY_REFS_PREFIX, @@ -44,6 +45,36 @@ def _make_rule(repo_root: Path) -> CbtsTestsDefRule: return CbtsTestsDefRule(YAMLIndex(), {}, repo_root) +def test_pytorch_model_config_only_selects_test_perf_consumers(tmp_path: Path) -> None: + test_db_dir = tmp_path / "test-db" + test_db_dir.mkdir() + (test_db_dir / "l0_perf.yml").write_text( + "l0_perf:\n- tests:\n - perf/test_perf.py::test_perf[case]\n", + encoding="utf-8", + ) + (test_db_dir / "l0_b200.yml").write_text( + "l0_b200:\n- tests:\n - perf/test_perf_sanity.py::test_e2e[case]\n", + encoding="utf-8", + ) + yaml_index = YAMLIndex.load(test_db_dir) + stages = { + "H100_PCIe-PyTorch-Perf-1": Stage("H100_PCIe-PyTorch-Perf-1", "l0_perf", "x86_64", 1, 1), + "DGX_B200-PyTorch-1": Stage("DGX_B200-PyTorch-1", "l0_b200", "x86_64", 1, 1), + } + rule = CbtsTestsDefRule(yaml_index, stages, tmp_path) + + result = rule.apply( + PRInputs( + changed_files=["tests/integration/defs/perf/pytorch_model_config.py"], + diffs={}, + ) + ) + + assert result is not None + assert result.affected_stages == {"H100_PCIe-PyTorch-Perf-1"} + assert set(result.block_filters) == {("l0_perf", 0)} + + def test_scope_start_line_includes_decorators() -> None: tree = ast.parse("@decorator\nclass TestExample:\n pass\n") node = tree.body[0] From 35e3e5cafe6d3dfc41467b2ee325b4f92eb87542 Mon Sep 17 00:00:00 2001 From: yufeiwu-nv <230315618+yufeiwu-nv@users.noreply.github.com> Date: Tue, 8 Sep 2026 09:10:03 +0000 Subject: [PATCH 2/3] fix(cbts): use direct imports for helper selection Signed-off-by: yufeiwu-nv <230315618+yufeiwu-nv@users.noreply.github.com> --- jenkins/scripts/cbts/rules/tests_def_rule.py | 157 ++++++++++++++++-- .../scripts/test_cbts_tests_def_rule.py | 135 ++++++++++++++- 2 files changed, 273 insertions(+), 19 deletions(-) diff --git a/jenkins/scripts/cbts/rules/tests_def_rule.py b/jenkins/scripts/cbts/rules/tests_def_rule.py index 660b5a0d5806..91adbdc2ab42 100644 --- a/jenkins/scripts/cbts/rules/tests_def_rule.py +++ b/jenkins/scripts/cbts/rules/tests_def_rule.py @@ -17,9 +17,9 @@ `tests/integration/defs/` strip) appears in some YAML entry's namespace. For `test_*.py` files, AST scope mapping yields function-level anchors (`file::TestC::test_m`) when every changed line lands in a pytest scope; -otherwise file-level. For non-test_*.py paths (conftest, helpers, data -files like `references/*.yaml` or `disaggregated/test_configs/*.yaml`), -`find_match_for_path` walks up enclosing directories to the narrowest +otherwise file-level. For Python helpers, direct static imports identify +their test-file consumers. Ambiguous helpers and other non-test paths +(conftest and data files) walk up enclosing directories to the narrowest YAML-covered ancestor. Paths matched by `out_of_scope_rule.is_out_of_scope` (QA / dev test @@ -32,7 +32,7 @@ import ast import re -from pathlib import Path +from pathlib import Path, PurePosixPath from typing import Optional from blocks import Stage, YAMLIndex @@ -55,14 +55,138 @@ ACCURACY_REFS_PREFIX = "tests/integration/defs/accuracy/references/" ACCURACY_DIR = "tests/integration/defs/accuracy" +DEFS_GIT_PREFIX = "tests/integration/defs/" _CLASS_RE = re.compile(r"class\s+(\w+)") # `acceptance_length.yaml` keys tests directly (`TestC::test_m`) instead of # by HF model name, unlike every other reference YAML. _TEST_ID_KEY_RE = re.compile(r"^(Test\w+)::(\w+)$") -_DIRECT_TEST_CONSUMERS: dict[str, tuple[str, ...]] = { - "tests/integration/defs/perf/pytorch_model_config.py": ("perf/test_perf.py",), -} + + +def _defs_module_name(relative_path: str) -> str: + parts = list(PurePosixPath(relative_path).with_suffix("").parts) + if parts and parts[-1] == "__init__": + parts.pop() + return ".".join(parts) + + +def _normalize_defs_module(module: str) -> str: + for prefix in ("tests.integration.defs.", "defs."): + if module.startswith(prefix): + return module.removeprefix(prefix) + return module + + +def _imported_modules( + node: ast.Import | ast.ImportFrom, + importer: str, +) -> set[str]: + if isinstance(node, ast.Import): + return {alias.name for alias in node.names} + + importer_module = _defs_module_name(importer) + if PurePosixPath(importer).name == "__init__.py": + package = importer_module + else: + package = importer_module.rpartition(".")[0] + if node.level: + package_parts = package.split(".") if package else [] + parents = node.level - 1 + if parents > len(package_parts): + return set() + base_parts = package_parts[: len(package_parts) - parents] + if node.module: + base_parts.extend(node.module.split(".")) + base = ".".join(base_parts) + else: + base = node.module or "" + + modules = {base} if base else set() + for alias in node.names: + if alias.name != "*": + modules.add(f"{base}.{alias.name}" if base else alias.name) + return modules + + +def _module_import_relation( + module: str, + target_module: str, + target_parent: str, + importer_parent: str, +) -> bool | None: + normalized = _normalize_defs_module(module) + if normalized == target_module: + return True + target_stem = target_module.rsplit(".", 1)[-1] + if normalized != target_stem or "." not in target_module: + return False + return True if importer_parent == target_parent else None + + +def _is_dynamic_import_call(node: ast.Call) -> bool: + if isinstance(node.func, ast.Name): + return node.func.id in {"__import__", "import_module"} + return isinstance(node.func, ast.Attribute) and node.func.attr == "import_module" + + +def _direct_test_importers(repo_root: Path, git_path: str) -> list[str] | None: + """Return direct static test importers or None for directory fallback.""" + if not git_path.startswith(DEFS_GIT_PREFIX) or not git_path.endswith(".py"): + return None + target = git_path.removeprefix(DEFS_GIT_PREFIX) + target_name = PurePosixPath(target).name + if target_name.startswith("test_") or target_name in {"__init__.py", "conftest.py"}: + return None + + defs_root = repo_root / DEFS_GIT_PREFIX + if not (defs_root / target).is_file(): + return None + target_module = _defs_module_name(target) + target_parent = PurePosixPath(target).parent.as_posix() + target_stem = PurePosixPath(target).stem + consumers: list[str] = [] + + for source_path in sorted(defs_root.rglob("*.py")): + importer = source_path.relative_to(defs_root).as_posix() + if importer == target: + continue + try: + source = source_path.read_text(encoding="utf-8") + tree = ast.parse(source) + except (OSError, SyntaxError, UnicodeDecodeError, ValueError): + return None + + importer_parent = PurePosixPath(importer).parent.as_posix() + imports_target = False + for node in ast.walk(tree): + if isinstance(node, (ast.Import, ast.ImportFrom)): + for module in _imported_modules(node, importer): + relation = _module_import_relation( + module, + target_module, + target_parent, + importer_parent, + ) + if relation is None: + return None + imports_target = imports_target or relation + elif isinstance(node, ast.Call) and _is_dynamic_import_call(node): + if ( + not node.args + or not isinstance(node.args[0], ast.Constant) + or not isinstance(node.args[0].value, str) + or target_stem in node.args[0].value + ): + return None + + if target_stem in source and not imports_target: + return None + if not imports_target: + continue + if not PurePosixPath(importer).name.startswith("test_"): + return None + consumers.append(importer) + return sorted(consumers) or None def _scope_start_line(node: ast.ClassDef | ast.FunctionDef | ast.AsyncFunctionDef) -> int: @@ -247,15 +371,18 @@ def __init__( def _compute_anchors(self, git_path: str, yaml_path: str, diff: str) -> list[str]: """Return lookup anchors for one file. - File-level fallback when no diff, file unreadable or not UTF-8 - (e.g. binary fixtures), AST parse fails, or any line is module- - level. accuracy/references/*.yaml diffs are refined to per-test- - class anchors via the model-name mapping in - `_compute_accuracy_reference_anchors`. + Python helpers use direct static, L0-covered test importers when safe. + Other files fall back to file-level when no diff, file unreadable + or not UTF-8, AST parse fails, or any line is module-level. + accuracy/references/*.yaml diffs are refined to per-test-class + anchors via the model-name mapping. """ - direct_consumers = _DIRECT_TEST_CONSUMERS.get(git_path) - if direct_consumers is not None: - return list(direct_consumers) + import_consumers = _direct_test_importers(self._repo_root, git_path) + if ( + import_consumers is not None + and lookup_paths_into_block_filters(self.yaml_index, import_consumers)[0] + ): + return import_consumers if git_path.startswith(ACCURACY_REFS_PREFIX) and git_path.endswith((".yaml", ".yml")): return self._compute_accuracy_reference_anchors(git_path, yaml_path, diff) if not diff: diff --git a/tests/unittest/scripts/test_cbts_tests_def_rule.py b/tests/unittest/scripts/test_cbts_tests_def_rule.py index 9377cb9a1f94..3f63fe6aa58d 100644 --- a/tests/unittest/scripts/test_cbts_tests_def_rule.py +++ b/tests/unittest/scripts/test_cbts_tests_def_rule.py @@ -32,6 +32,7 @@ from rules.tests_def_rule import ( # noqa: E402 ACCURACY_DIR, ACCURACY_REFS_PREFIX, + _direct_test_importers, _py_class_scopes_from_deletions, _scope_start_line, _yaml_top_keys_from_deletions, @@ -45,7 +46,13 @@ def _make_rule(repo_root: Path) -> CbtsTestsDefRule: return CbtsTestsDefRule(YAMLIndex(), {}, repo_root) -def test_pytorch_model_config_only_selects_test_perf_consumers(tmp_path: Path) -> None: +def _write_defs_file(tmp_path: Path, relative_path: str, content: str) -> None: + path = tmp_path / "tests/integration/defs" / relative_path + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content, encoding="utf-8") + + +def _make_perf_rule(tmp_path: Path) -> CbtsTestsDefRule: test_db_dir = tmp_path / "test-db" test_db_dir.mkdir() (test_db_dir / "l0_perf.yml").write_text( @@ -56,14 +63,92 @@ def test_pytorch_model_config_only_selects_test_perf_consumers(tmp_path: Path) - "l0_b200:\n- tests:\n - perf/test_perf_sanity.py::test_e2e[case]\n", encoding="utf-8", ) - yaml_index = YAMLIndex.load(test_db_dir) + (test_db_dir / "l0_other.yml").write_text( + "l0_other:\n- tests:\n - other/test_other.py::test_other\n", + encoding="utf-8", + ) stages = { "H100_PCIe-PyTorch-Perf-1": Stage("H100_PCIe-PyTorch-Perf-1", "l0_perf", "x86_64", 1, 1), "DGX_B200-PyTorch-1": Stage("DGX_B200-PyTorch-1", "l0_b200", "x86_64", 1, 1), } - rule = CbtsTestsDefRule(yaml_index, stages, tmp_path) + return CbtsTestsDefRule(YAMLIndex.load(test_db_dir), stages, tmp_path) + + +@pytest.mark.parametrize( + "import_statement", + ( + "from .helper import VALUE", + "from defs.perf.helper import VALUE", + "import helper", + ), +) +def test_direct_test_importers_resolve_static_imports( + tmp_path: Path, + import_statement: str, +) -> None: + _write_defs_file(tmp_path, "perf/helper.py", "VALUE = 1\n") + _write_defs_file(tmp_path, "perf/test_consumer.py", f"{import_statement}\n") + _write_defs_file(tmp_path, "perf/test_other.py", "VALUE = 2\n") + + assert _direct_test_importers(tmp_path, "tests/integration/defs/perf/helper.py") == [ + "perf/test_consumer.py" + ] + + +def test_direct_test_importers_fall_back_for_transitive_imports(tmp_path: Path) -> None: + _write_defs_file(tmp_path, "perf/helper.py", "VALUE = 1\n") + _write_defs_file(tmp_path, "perf/bridge.py", "from .helper import VALUE\n") + _write_defs_file(tmp_path, "perf/test_consumer.py", "from .bridge import VALUE\n") + + assert _direct_test_importers(tmp_path, "tests/integration/defs/perf/helper.py") is None + + +def test_direct_test_importers_fall_back_for_pytest_plugins(tmp_path: Path) -> None: + _write_defs_file(tmp_path, "disaggregated/plugin.py", "VALUE = 1\n") + _write_defs_file( + tmp_path, + "disaggregated/test_consumer.py", + "pytest_plugins = ['plugin']\n", + ) + + assert ( + _direct_test_importers(tmp_path, "tests/integration/defs/disaggregated/plugin.py") is None + ) + + +def test_direct_test_importers_fall_back_for_conftest_import(tmp_path: Path) -> None: + _write_defs_file(tmp_path, "perf/helper.py", "VALUE = 1\n") + _write_defs_file(tmp_path, "perf/conftest.py", "from .helper import VALUE\n") + + assert _direct_test_importers(tmp_path, "tests/integration/defs/perf/helper.py") is None + + +def test_direct_test_importers_fall_back_for_dynamic_import(tmp_path: Path) -> None: + _write_defs_file(tmp_path, "perf/helper.py", "VALUE = 1\n") + _write_defs_file( + tmp_path, + "perf/test_consumer.py", + "import importlib\nmodule_name = '.helper'\nimportlib.import_module(module_name)\n", + ) + + assert _direct_test_importers(tmp_path, "tests/integration/defs/perf/helper.py") is None + + +def test_pytorch_model_config_only_selects_test_perf_consumers(tmp_path: Path) -> None: + _write_defs_file(tmp_path, "perf/pytorch_model_config.py", "VALUE = 1\n") + _write_defs_file( + tmp_path, + "perf/test_perf.py", + "from .pytorch_model_config import VALUE\n", + ) + _write_defs_file(tmp_path, "perf/test_perf_sanity.py", "VALUE = 2\n") + _write_defs_file( + tmp_path, + "conftest.py", + "from .perf.test_perf import generate_perf_tests\n", + ) - result = rule.apply( + result = _make_perf_rule(tmp_path).apply( PRInputs( changed_files=["tests/integration/defs/perf/pytorch_model_config.py"], diffs={}, @@ -75,6 +160,48 @@ def test_pytorch_model_config_only_selects_test_perf_consumers(tmp_path: Path) - assert set(result.block_filters) == {("l0_perf", 0)} +def test_conftest_import_keeps_directory_fallback(tmp_path: Path) -> None: + _write_defs_file(tmp_path, "perf/helper.py", "VALUE = 1\n") + _write_defs_file(tmp_path, "perf/conftest.py", "from .helper import VALUE\n") + + result = _make_perf_rule(tmp_path).apply( + PRInputs( + changed_files=["tests/integration/defs/perf/helper.py"], + diffs={}, + ) + ) + + assert result is not None + assert result.affected_stages == { + "DGX_B200-PyTorch-1", + "H100_PCIe-PyTorch-Perf-1", + } + assert set(result.block_filters) == {("l0_b200", 0), ("l0_perf", 0)} + + +def test_uncovered_import_consumers_keep_directory_fallback(tmp_path: Path) -> None: + _write_defs_file(tmp_path, "perf/helper.py", "VALUE = 1\n") + _write_defs_file( + tmp_path, + "other/test_consumer.py", + "from defs.perf.helper import VALUE\n", + ) + + result = _make_perf_rule(tmp_path).apply( + PRInputs( + changed_files=["tests/integration/defs/perf/helper.py"], + diffs={}, + ) + ) + + assert result is not None + assert result.affected_stages == { + "DGX_B200-PyTorch-1", + "H100_PCIe-PyTorch-Perf-1", + } + assert set(result.block_filters) == {("l0_b200", 0), ("l0_perf", 0)} + + def test_scope_start_line_includes_decorators() -> None: tree = ast.parse("@decorator\nclass TestExample:\n pass\n") node = tree.body[0] From 34598c5d4b705b6977010e62e66b3be43539bfe0 Mon Sep 17 00:00:00 2001 From: yufeiwu-nv <230315618+yufeiwu-nv@users.noreply.github.com> Date: Tue, 8 Sep 2026 14:53:39 +0000 Subject: [PATCH 3/3] fix(cbts): avoid forcing unrelated perf sanity stages Signed-off-by: yufeiwu-nv <230315618+yufeiwu-nv@users.noreply.github.com> --- jenkins/scripts/cbts/rules/tests_def_rule.py | 3 +- .../scripts/test_cbts_tests_def_rule.py | 44 ++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/jenkins/scripts/cbts/rules/tests_def_rule.py b/jenkins/scripts/cbts/rules/tests_def_rule.py index 91adbdc2ab42..d550be9e6189 100644 --- a/jenkins/scripts/cbts/rules/tests_def_rule.py +++ b/jenkins/scripts/cbts/rules/tests_def_rule.py @@ -38,7 +38,6 @@ from blocks import Stage, YAMLIndex from ._helpers import ( - is_perf_stem, iter_diff_added_post_line_numbers, iter_diff_post_line_numbers, iter_diff_pre_image, @@ -636,7 +635,7 @@ def apply(self, pr: PRInputs) -> Optional[RuleResult]: block_filters, self.yaml_index, self._stages_by_yaml ) sanity_relevant = any(stem == "l0_sanity_check" for stem, _ in block_filters) - perfsanity_relevant = any(is_perf_stem(stem) for stem, _ in block_filters) + perfsanity_relevant = any("perf_sanity" in stem for stem, _ in block_filters) nonarrow_note = "" if no_match: diff --git a/tests/unittest/scripts/test_cbts_tests_def_rule.py b/tests/unittest/scripts/test_cbts_tests_def_rule.py index 3f63fe6aa58d..7eb0e27291fd 100644 --- a/tests/unittest/scripts/test_cbts_tests_def_rule.py +++ b/tests/unittest/scripts/test_cbts_tests_def_rule.py @@ -63,6 +63,12 @@ def _make_perf_rule(tmp_path: Path) -> CbtsTestsDefRule: "l0_b200:\n- tests:\n - perf/test_perf_sanity.py::test_e2e[case]\n", encoding="utf-8", ) + (test_db_dir / "l0_gb200_multi_gpus_perf_sanity.yml").write_text( + "l0_gb200_multi_gpus_perf_sanity:\n" + "- tests:\n" + " - perf/test_perf_sanity.py::test_e2e[case]\n", + encoding="utf-8", + ) (test_db_dir / "l0_other.yml").write_text( "l0_other:\n- tests:\n - other/test_other.py::test_other\n", encoding="utf-8", @@ -70,6 +76,13 @@ def _make_perf_rule(tmp_path: Path) -> CbtsTestsDefRule: stages = { "H100_PCIe-PyTorch-Perf-1": Stage("H100_PCIe-PyTorch-Perf-1", "l0_perf", "x86_64", 1, 1), "DGX_B200-PyTorch-1": Stage("DGX_B200-PyTorch-1", "l0_b200", "x86_64", 1, 1), + "GB200-4_GPUs-PyTorch-PerfSanity-1": Stage( + "GB200-4_GPUs-PyTorch-PerfSanity-1", + "l0_gb200_multi_gpus_perf_sanity", + "x86_64", + 1, + 1, + ), } return CbtsTestsDefRule(YAMLIndex.load(test_db_dir), stages, tmp_path) @@ -158,6 +171,23 @@ def test_pytorch_model_config_only_selects_test_perf_consumers(tmp_path: Path) - assert result is not None assert result.affected_stages == {"H100_PCIe-PyTorch-Perf-1"} assert set(result.block_filters) == {("l0_perf", 0)} + assert result.perfsanity_relevant is False + + +def test_perf_sanity_definition_keeps_perfsanity_required(tmp_path: Path) -> None: + result = _make_perf_rule(tmp_path).apply( + PRInputs( + changed_files=["tests/integration/defs/perf/test_perf_sanity.py"], + diffs={}, + ) + ) + + assert result is not None + assert result.affected_stages == { + "DGX_B200-PyTorch-1", + "GB200-4_GPUs-PyTorch-PerfSanity-1", + } + assert result.perfsanity_relevant is True def test_conftest_import_keeps_directory_fallback(tmp_path: Path) -> None: @@ -174,9 +204,14 @@ def test_conftest_import_keeps_directory_fallback(tmp_path: Path) -> None: assert result is not None assert result.affected_stages == { "DGX_B200-PyTorch-1", + "GB200-4_GPUs-PyTorch-PerfSanity-1", "H100_PCIe-PyTorch-Perf-1", } - assert set(result.block_filters) == {("l0_b200", 0), ("l0_perf", 0)} + assert set(result.block_filters) == { + ("l0_b200", 0), + ("l0_gb200_multi_gpus_perf_sanity", 0), + ("l0_perf", 0), + } def test_uncovered_import_consumers_keep_directory_fallback(tmp_path: Path) -> None: @@ -197,9 +232,14 @@ def test_uncovered_import_consumers_keep_directory_fallback(tmp_path: Path) -> N assert result is not None assert result.affected_stages == { "DGX_B200-PyTorch-1", + "GB200-4_GPUs-PyTorch-PerfSanity-1", "H100_PCIe-PyTorch-Perf-1", } - assert set(result.block_filters) == {("l0_b200", 0), ("l0_perf", 0)} + assert set(result.block_filters) == { + ("l0_b200", 0), + ("l0_gb200_multi_gpus_perf_sanity", 0), + ("l0_perf", 0), + } def test_scope_start_line_includes_decorators() -> None: