Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ workflow:
UNIT_TEST: "no"
INTEGRATION_TEST: "no"
FUNCTIONAL_TEST: "yes"
FUNCTIONAL_TEST_SCOPE: mr
FUNCTIONAL_TEST_SCOPE: L1,L2
FUNCTIONAL_TEST_REPEAT: 5
FUNCTIONAL_TEST_RECORD_CHECKPOINTS: "no"
FUNCTIONAL_TEST_TIME_LIMIT: 3600
Expand Down Expand Up @@ -126,7 +126,7 @@ workflow:
UNIT_TEST_TIMEOUT: 30
INTEGRATION_TEST: "no"
FUNCTIONAL_TEST: "yes"
FUNCTIONAL_TEST_SCOPE: mr
FUNCTIONAL_TEST_SCOPE: L1,L2
FUNCTIONAL_TEST_REPEAT: 1
FUNCTIONAL_TEST_TIME_LIMIT: 2700
CLUSTER_A100: ""
Expand Down Expand Up @@ -204,9 +204,10 @@ variables:
- "no"
description: To run the funtional test suite
FUNCTIONAL_TEST_SCOPE:
value: "mr"
value: "L1,L2"
options:
- "mr"
- "L1,L2"
- "mr-slim"
- "nightly"
- "weekly"
- "pre-release"
Expand Down
52 changes: 34 additions & 18 deletions .gitlab/stages/04.functional-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,28 @@ functional:configure:
RELEASE_ARGS=()
fi
- |
# NOTE: $FUNCTIONAL_TEST_SCOPE is supplied by external scheduled-pipeline
# configurations and uses the GitLab-side legacy values: `mr`, `mr-slim`,
# `nightly`, `weekly`, `unit-tests`, `release`.
# - `mr` / `mr-slim` / `unit-tests` / `release` pass through verbatim
# and match recipe rows tagged with the same string. They are
# intentionally NOT aliased (see LEGACY_SCOPE_ALIASES in
# tests/test_utils/python_scripts/recipe_parser.py) so the GitLab
# and GitHub matrices stay decoupled.
# - `nightly` / `weekly` are aliased to L2 / L3 by the parser and also
# inject a default cadence when the recipe has no explicit one.
ARGS=(
"--scope $FUNCTIONAL_TEST_SCOPE"
# NOTE: $FUNCTIONAL_TEST_SCOPE is supplied by workflow rules, scheduled
# pipelines, or manual dispatch. Legacy GitLab values (`mr-slim`, `mr`,
# `nightly`, `weekly`) and L-tier names (`L0`–`L4`) are accepted; comma-
# separated tiers union, e.g. `L1,L2` for the full MR functional suite.
#
# Recipe rows use the L-tier vocabulary; recipe_parser.py resolves filter
# input (tests/test_utils/python_scripts/recipe_parser.py):
# - `mr-github-slim` -> `L0`
# - `mr-github` -> `L1`
# - `mr` -> `L2`
# - `nightly` -> `L3`; `weekly` -> `L4`
# `unit-tests` and `release` are not aliased and match recipe rows verbatim.
#
# For the full MR suite (`L1,L2`), GB200 keeps the legacy GitLab `mr`
# footprint (`L2` only) rather than unioning L1 rows that were never in the
# old GB200 MR matrix.
SCOPE_A100_H100="$FUNCTIONAL_TEST_SCOPE"
SCOPE_GB200="$FUNCTIONAL_TEST_SCOPE"
if [[ "$FUNCTIONAL_TEST_SCOPE" == "L1,L2" ]]; then
SCOPE_GB200="L2"
fi
COMMON_ARGS=(
"--n-repeat $FUNCTIONAL_TEST_REPEAT"
"--time-limit $FUNCTIONAL_TEST_TIME_LIMIT"
"--test-cases $FUNCTIONAL_TEST_CASES"
Expand Down Expand Up @@ -121,7 +131,8 @@ functional:configure:
- |
export PYTHONPATH=$(pwd)
python tests/test_utils/python_scripts/generate_jet_trigger_job.py \
${ARGS[@]} \
${COMMON_ARGS[@]} \
--scope "$SCOPE_A100_H100" \
--environment dev \
--platform dgx_a100 \
--cluster $A100_CLUSTER \
Expand All @@ -130,7 +141,8 @@ functional:configure:
- |
export PYTHONPATH=$(pwd)
python tests/test_utils/python_scripts/generate_jet_trigger_job.py \
${ARGS[@]} \
${COMMON_ARGS[@]} \
--scope "$SCOPE_A100_H100" \
--environment dev \
--platform dgx_h100 \
--cluster $H100_CLUSTER \
Expand All @@ -139,7 +151,8 @@ functional:configure:
- |
export PYTHONPATH=$(pwd)
python tests/test_utils/python_scripts/generate_jet_trigger_job.py \
${ARGS[@]} \
${COMMON_ARGS[@]} \
--scope "$SCOPE_A100_H100" \
--environment lts \
--platform dgx_a100 \
--cluster $A100_CLUSTER \
Expand All @@ -148,7 +161,8 @@ functional:configure:
- |
export PYTHONPATH=$(pwd)
python tests/test_utils/python_scripts/generate_jet_trigger_job.py \
${ARGS[@]} \
${COMMON_ARGS[@]} \
--scope "$SCOPE_A100_H100" \
--environment lts \
--platform dgx_h100 \
--cluster $H100_CLUSTER \
Expand All @@ -157,7 +171,8 @@ functional:configure:
- |
export PYTHONPATH=$(pwd)
python tests/test_utils/python_scripts/generate_jet_trigger_job.py \
${ARGS[@]} \
${COMMON_ARGS[@]} \
--scope "$SCOPE_GB200" \
--environment dev \
--platform dgx_gb200 \
--cluster $GB200_CLUSTER \
Expand All @@ -166,7 +181,8 @@ functional:configure:
- |
export PYTHONPATH=$(pwd)
python tests/test_utils/python_scripts/generate_jet_trigger_job.py \
${ARGS[@]} \
${COMMON_ARGS[@]} \
--scope "$SCOPE_GB200" \
--environment lts \
--platform dgx_gb200 \
--cluster $GB200_CLUSTER \
Expand Down
64 changes: 37 additions & 27 deletions tests/test_utils/python_scripts/recipe_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import itertools
import logging
import pathlib
from typing import List, Optional
from typing import List, Optional, Set

import click
import yaml
Expand All @@ -20,42 +20,53 @@
# trigger, a default cadence. The tier acts purely as a suite/cost label;
# cadence remains the trigger axis.
#
# Only GitHub-side scopes (`mr-github-slim`, `mr-github`) are aliased onto the
# L-tier names. GitLab-only scopes (`mr`, `mr-slim`, `unit-tests`) are
# intentionally left as pass-through so GitLab `--scope mr*` / `--scope
# unit-tests` continue to match recipes verbatim and don't bleed into the
# GitHub L0 / L1 matrix.
# All legacy `scope` names (both GitHub-side `mr-github*` and GitLab-side
# `mr*`) are aliased onto the unified L-tier vocabulary so legacy callers and
# scheduled pipelines keep working: a `--scope mr-github` filter and a recipe
# row tagged `scope: [L1]` match the same tier. A literal `mr` tag or filter
# means a GitLab-only extra and resolves to the single tier `L2`. The slim PR
# sets (`mr-slim`, `mr-github-slim`) both map to `L0`.
#
# L-tier vocabulary (cost class, ascending): `L0` (slim PR) < `L1` (full PR /
# merge queue) < `L2` (nightly) < `L3` (weekly). `L0-smoke` is a sub-L0 tier
# for fast lightweight smoke tests (cheaper than `L0`); it is GitLab-only and
# passes through verbatim (not aliased here). Recipes tag rows with
# `scope: [L0-smoke]` and GitLab selects them via `--scope L0-smoke`.
# merge queue) < `L2` (GitLab MR extra) < `L3` (nightly) < `L4` (weekly).
# `L0-smoke` is a sub-L0 tier for fast lightweight smoke tests; it passes
# through verbatim and GitLab selects it via `--scope L0-smoke`.
LEGACY_SCOPE_ALIASES = {
# GitHub-only scopes are aliased onto the L-tier vocabulary so the GH CI
# workflow can filter on `L0` / `L1`. GitLab-only scopes (`mr`, `mr-slim`)
# are intentionally NOT aliased: they pass through to recipe rows verbatim
# and remain matchable by GitLab's `--scope mr-slim` / `--scope mr` calls,
# without bleeding into the GitHub `L0` / `L1` matrix.
"mr-slim": ("L0", None),
"mr-github-slim": ("L0", None),
"mr-github": ("L1", None),
"nightly": ("L2", ["nightly"]),
"weekly": ("L3", ["weekly"]),
"mr": ("L2", None),
"nightly": ("L3", ["nightly"]),
"weekly": ("L4", ["weekly"]),
}


def _resolve_scope_alias(scope_value: str) -> str:
"""Resolve a legacy scope value to its L-tier alias (or return it unchanged).

Applied both to recipe rows when flattening and to the `--scope` filter
input, so callers can pass either the legacy name (e.g. `nightly`) or the
new L-tier name (e.g. `L2`) and hit the same recipe rows.
Applied when flattening recipe rows. For `--scope` filters, use
`_resolve_scope_filter` so comma-separated values (e.g. `L1,L2`) work.
"""
if scope_value in LEGACY_SCOPE_ALIASES:
return LEGACY_SCOPE_ALIASES[scope_value][0]
return scope_value


def _resolve_scope_filter(scope: str) -> Set[str]:
"""Resolve a `--scope` filter to the set of L-tier names to match.

Supports comma-separated tiers, e.g. ``--scope L1,L2`` for a union. Each
token is legacy-aliased to a single tier.
"""
tiers: Set[str] = set()
for part in scope.split(","):
part = part.strip()
if not part:
continue
tiers.add(_resolve_scope_alias(part))
return tiers


def _apply_scope_alias(scope_value: str, explicit_cadence: Optional[List[str]]) -> tuple:
"""Resolve a legacy scope value to (new_scope, cadence).

Expand Down Expand Up @@ -232,18 +243,17 @@ def filter_by_test_case(workload_manifests: List[dotdict], test_case: str) -> Op


def filter_by_scope(workload_manifests: List[dotdict], scope: str) -> List[dotdict]:
"""Returns all workload with matching scope.
"""Returns all workloads whose scope is in the resolved filter tier set.

The filter input is run through the same legacy-scope alias as recipe
rows, so callers passing the legacy name (e.g. `--scope nightly`,
`--scope mr-github`) match recipes that have already been rewritten to
the new L-tier vocabulary (e.g. `scope: [L2]`, `scope: [L1]`).
The filter input is legacy-aliased per token. Pass comma-separated tiers for a
union, e.g. ``--scope L1,L2`` (full GitLab MR) or legacy names such as
``--scope mr-github``.
"""
resolved_scope = _resolve_scope_alias(scope)
resolved_scopes = _resolve_scope_filter(scope)
workload_manifests = list(
workload_manifest
for workload_manifest in workload_manifests
if workload_manifest.spec["scope"] == resolved_scope
if workload_manifest.spec["scope"] in resolved_scopes
)

if len(workload_manifests) == 0:
Expand Down
Loading
Loading