Skip to content

Commit 20d1eb2

Browse files
authored
feat: exclude k8 FT tests that need custom build from default run (#4017)
Signed-off-by: [email protected] <[email protected]>
1 parent 8bd37c9 commit 20d1eb2

File tree

5 files changed

+128
-6
lines changed

5 files changed

+128
-6
lines changed

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ markers = [
198198
"slow: marks tests as known to be slow",
199199
"h100: marks tests to run on H100",
200200
"kvbm: marks tests for KV behavior and model determinism",
201-
"model: model id used by a test or parameter"
201+
"model: model id used by a test or parameter",
202+
"custom_build: marks tests that require custom builds or special setup (e.g., MoE models)"
202203
]
203204

204205
# Linting/formatting

tests/fault_tolerance/deploy/README.md

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,18 @@ The combined results of these two phases demonstrate both the system's ability t
141141

142142
#### Example Scenario Execution:
143143

144-
Run all deployments and failure scenarios
144+
Run standard deployments and failure scenarios (excludes custom builds by default):
145145

146146
```bash
147147
pytest tests/fault_tolerance/deploy/test_deployment.py -s -v --namespace ${NAMESPACE}
148148
```
149149

150+
To include all scenarios including custom builds (e.g., MoE models):
151+
152+
```bash
153+
pytest tests/fault_tolerance/deploy/test_deployment.py -s -v --namespace ${NAMESPACE} --include-custom-build
154+
```
155+
150156
### Test Results Directory
151157

152158
For each test scenario a directory of log files is created and post-processed to summarize the test. The directory structure differs based on which client type is used.
@@ -490,10 +496,54 @@ Then run the development container mounting the workspace and your kube config.
490496

491497
### Run the tests
492498

499+
#### Default: Run Standard Tests Only
500+
501+
By default, tests requiring custom builds (e.g., MoE models) are **automatically excluded**:
502+
493503
```bash
494-
pytest tests/fault_tolerance/deploy/test_deployment.py -s -v --namespace ${NAMESPACE} --image ${IMAGE}
504+
# Standard tests only
505+
pytest tests/fault_tolerance/deploy/test_deployment.py -s -v \
506+
--namespace ${NAMESPACE} \
507+
--image ${IMAGE}
495508
```
496509

510+
#### Include Custom Build Tests
511+
512+
To run ALL tests including those requiring custom builds (e.g., MoE models):
513+
514+
```bash
515+
pytest tests/fault_tolerance/deploy/test_deployment.py -s -v \
516+
--namespace ${NAMESPACE} \
517+
--image ${IMAGE} \
518+
--include-custom-build
519+
```
520+
521+
#### Run Only Custom Build Tests
522+
523+
To run ONLY tests that require custom builds:
524+
525+
```bash
526+
pytest tests/fault_tolerance/deploy/test_deployment.py -s -v \
527+
--namespace ${NAMESPACE} \
528+
--image ${IMAGE} \
529+
-m "custom_build"
530+
```
531+
532+
#### List Available Tests
533+
534+
```bash
535+
# See which tests will run by default (excludes custom_build)
536+
pytest tests/fault_tolerance/deploy/test_deployment.py --collect-only -q
537+
538+
# See which tests are excluded
539+
pytest tests/fault_tolerance/deploy/test_deployment.py --collect-only -m "custom_build" -q
540+
```
541+
542+
> **Note:** Tests requiring custom builds are marked with `@pytest.mark.custom_build` and include:
543+
> - MoE (Mixture-of-Experts) models like DeepSeek-V2-Lite
544+
> - Tests requiring special Docker image configurations
545+
> - Any scenario with `requires_custom_build=True` in scenarios.py
546+
497547

498548
### Note on Running with Additional Credentials
499549

tests/fault_tolerance/deploy/conftest.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
import pytest
1717

18+
from tests.fault_tolerance.deploy.scenarios import scenarios
19+
1820

1921
def pytest_addoption(parser):
2022
parser.addoption("--image", type=str, default=None)
@@ -26,6 +28,71 @@ def pytest_addoption(parser):
2628
choices=["aiperf", "legacy"],
2729
help="Client type for load generation: 'aiperf' (default) or 'legacy'",
2830
)
31+
parser.addoption(
32+
"--include-custom-build",
33+
action="store_true",
34+
default=False,
35+
help="Include tests that require custom builds (e.g., MoE models). "
36+
"By default, these tests are excluded.",
37+
)
38+
39+
40+
def pytest_generate_tests(metafunc):
41+
"""Dynamically parametrize tests and apply markers based on scenario properties.
42+
43+
This hook applies markers to individual test instances based on their scenario:
44+
- @pytest.mark.custom_build: For MoE models and other tests requiring custom builds
45+
"""
46+
if "scenario" in metafunc.fixturenames:
47+
scenario_names = list(scenarios.keys())
48+
argvalues = []
49+
ids = []
50+
51+
for scenario_name in scenario_names:
52+
scenario_obj = scenarios[scenario_name]
53+
marks = []
54+
55+
if getattr(scenario_obj, "requires_custom_build", False):
56+
marks.append(pytest.mark.custom_build)
57+
58+
# Always use pytest.param for type consistency (even with empty marks)
59+
argvalues.append(pytest.param(scenario_name, marks=marks))
60+
ids.append(scenario_name)
61+
62+
metafunc.parametrize("scenario_name", argvalues, ids=ids)
63+
64+
65+
def pytest_collection_modifyitems(config, items):
66+
"""Automatically deselect custom_build tests unless --include-custom-build is specified.
67+
68+
This allows users to run tests without any special flags and automatically excludes
69+
tests that require custom builds. To include them, use --include-custom-build.
70+
71+
Note: If user explicitly uses -m marker filtering, we respect that and don't
72+
auto-deselect, allowing them to run custom_build tests with -m "custom_build".
73+
"""
74+
# If --include-custom-build flag is set, include all tests
75+
if config.getoption("--include-custom-build"):
76+
return
77+
78+
# If user explicitly used -m marker filtering, let pytest handle it
79+
# Don't auto-deselect in this case
80+
if config.option.markexpr:
81+
return
82+
83+
# Default case: auto-deselect custom_build tests
84+
deselected = []
85+
selected = []
86+
87+
for item in items:
88+
if "custom_build" in item.keywords:
89+
deselected.append(item)
90+
else:
91+
selected.append(item)
92+
93+
if deselected:
94+
config.hook.pytest_deselected(items=deselected)
95+
items[:] = selected
2996

3097

3198
@pytest.fixture

tests/fault_tolerance/deploy/scenarios.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ class Scenario:
184184
failures: list[Failure]
185185
model: Optional[str] = None
186186
backend: str = "vllm" # Backend type for tracking
187+
# When set to True, the test will be automatically marked with @pytest.mark.custom_build
188+
# and excluded from default test runs unless --include-custom-build flag is used
189+
requires_custom_build: bool = False # Flag for tests needing custom builds/setup
187190

188191

189192
# Helper functions to create deployment specs
@@ -572,6 +575,7 @@ def create_legacy_load(
572575
failures=failure,
573576
model=scenario_model,
574577
backend=backend,
578+
requires_custom_build=is_moe, # MoE models require custom builds
575579
)
576580

577581

tests/fault_tolerance/deploy/test_deployment.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222
from tests.utils.managed_deployment import ManagedDeployment
2323

2424

25-
@pytest.fixture(params=scenarios.keys())
26-
def scenario(request, client_type):
25+
@pytest.fixture
26+
def scenario(scenario_name, client_type):
2727
"""Get scenario and optionally override client type from command line.
2828
2929
If --client-type is specified, it overrides the scenario's default client type.
3030
"""
31-
scenario_obj = scenarios[request.param]
31+
scenario_obj = scenarios[scenario_name]
3232

3333
# Override client type if specified on command line
3434
if client_type is not None:

0 commit comments

Comments
 (0)