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
4 changes: 3 additions & 1 deletion .github/workflows/pr-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,9 @@ jobs:
timeout-minutes: 10
run: |
cd test/
python3 run_suite.py
python3 run_suite.py --hw cuda --suite stage-a-test-1
# temporarily put backend-independent cpu tests here
python3 run_suite.py --hw cpu --suite default

unit-test-backend-1-gpu:
needs: [check-changes, stage-a-test-1, sgl-kernel-build-wheels]
Expand Down
29 changes: 17 additions & 12 deletions python/sglang/test/ci/ci_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


class HWBackend(Enum):
CPU = auto()
CUDA = auto()
AMD = auto()

Expand All @@ -14,19 +15,24 @@ class HWBackend(Enum):
class CIRegistry:
backend: HWBackend
filename: str
estimation_time: float
stage: str
est_time: float
suite: str


def register_cuda_ci(estimation_time: float, ci_stage: str):
def register_cpu_ci(est_time: float, suite: str):
pass


def register_amd_ci(estimation_time: float, ci_stage: str):
def register_cuda_ci(est_time: float, suite: str):
pass


def register_amd_ci(est_time: float, suite: str):
pass


REGISTER_MAPPING = {
"register_cpu_ci": HWBackend.CPU,
"register_cuda_ci": HWBackend.CUDA,
"register_amd_ci": HWBackend.AMD,
}
Expand All @@ -45,28 +51,27 @@ def _collect_ci_registry(self, func_call: ast.Call):
return None

hw = REGISTER_MAPPING[func_call.func.id]
est_time = None
ci_stage = None
est_time, suite = None, None
for kw in func_call.keywords:
if kw.arg == "estimation_time":
if kw.arg == "est_time":
if isinstance(kw.value, ast.Constant):
est_time = kw.value.value
elif kw.arg == "ci_stage":
elif kw.arg == "suite":
if isinstance(kw.value, ast.Constant):
ci_stage = kw.value.value
suite = kw.value.value

for i, arg in enumerate(func_call.args):
if isinstance(arg, ast.Constant):
if i == 0:
est_time = arg.value
elif i == 1:
ci_stage = arg.value
suite = arg.value
assert (
est_time is not None
), "esimation_time is required and should be a constant"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's a typo in the assertion message. esimation_time should be estimation_time.

Suggested change
), "esimation_time is required and should be a constant"
), "estimation_time is required and should be a constant"

assert ci_stage is not None, "ci_stage is required and should be a constant"
assert suite is not None, "suite is required and should be a constant"
return CIRegistry(
backend=hw, filename=self.filename, estimation_time=est_time, stage=ci_stage
backend=hw, filename=self.filename, est_time=est_time, suite=suite
)

def visit_Module(self, node):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
from sglang.srt.function_call.mistral_detector import MistralDetector
from sglang.srt.function_call.pythonic_detector import PythonicDetector
from sglang.srt.function_call.qwen3_coder_detector import Qwen3CoderDetector
from sglang.test.ci.ci_register import register_cpu_ci

register_cpu_ci(1.0, "default")


class TestPythonicDetector(unittest.TestCase):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
_get_tool_schema_defs,
get_json_schema_constraint,
)
from sglang.test.ci.ci_register import register_cpu_ci

register_cpu_ci(1.0, "default")


class TestJsonSchemaConstraint(unittest.TestCase):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import json
import logging

import pytest

from sglang.srt.entrypoints.openai.protocol import Function, Tool
from sglang.srt.environ import envs
from sglang.srt.function_call.base_format_detector import BaseFormatDetector
from sglang.srt.function_call.core_types import StreamingParseResult
from sglang.test.ci.ci_register import register_cpu_ci

register_cpu_ci(1.0, "default")


class DummyDetector(BaseFormatDetector):
Expand All @@ -17,6 +22,9 @@ def detect_and_parse(self, text: str, tools):
normal_text="", calls=self.parse_base_json(action, tools)
)

def structure_info(self):
pass


def test_unknown_tool_name_dropped_default(caplog):
"""Test that unknown tools are dropped by default (legacy behavior)."""
Expand Down Expand Up @@ -67,3 +75,7 @@ def test_unknown_tool_name_forwarded(caplog):
assert result.calls[0].name == "unknown_tool"
assert result.calls[0].tool_index == -1
assert json.loads(result.calls[0].parameters)["city"] == "Paris"


if __name__ == "__main__":
pytest.main([__file__])
2 changes: 1 addition & 1 deletion test/per_commit/test_srt_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
)
from sglang.test.test_utils import DEFAULT_MODEL_NAME_FOR_TEST, CustomTestCase

register_cuda_ci(estimation_time=80, ci_stage="stage-a-test-1")
register_cuda_ci(est_time=80, suite="stage-a-test-1")


class TestSRTBackend(CustomTestCase):
Expand Down
35 changes: 30 additions & 5 deletions test/run_suite.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import argparse
import glob
from typing import List

from sglang.test.ci.ci_register import CIRegistry, HWBackend, collect_tests
from sglang.test.ci.ci_utils import TestFile, run_unittest_files

LABEL_MAPPING = {HWBackend.CUDA: ["stage-a-test-1"]}
HW_MAPPING = {
"cpu": HWBackend.CPU,
"cuda": HWBackend.CUDA,
}

LABEL_MAPPING = {
HWBackend.CUDA: ["stage-a-test-1"],
HWBackend.CPU: ["default"],
}


def _filter_tests(
Expand All @@ -13,16 +22,16 @@ def _filter_tests(
ci_tests = [t for t in ci_tests if t.backend == hw]
ret = []
for t in ci_tests:
assert t.stage in LABEL_MAPPING[hw], f"Unknown stage {t.stage} for backend {hw}"
if t.stage == suite:
assert t.suite in LABEL_MAPPING[hw], f"Unknown stage {t.suite} for backend {hw}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The assertion message uses the old term 'stage', but the concept has been renamed to 'suite'. For consistency, it would be better to update the message to use 'suite' as well.

Suggested change
assert t.suite in LABEL_MAPPING[hw], f"Unknown stage {t.suite} for backend {hw}"
assert t.suite in LABEL_MAPPING[hw], f"Unknown suite {t.suite} for backend {hw}"

if t.suite == suite:
ret.append(t)
return ret


def run_per_commit(hw: HWBackend, suite: str):
files = glob.glob("per_commit/**/*.py", recursive=True)
ci_tests = _filter_tests(collect_tests(files), hw, suite)
test_files = [TestFile(t.filename, t.estimation_time) for t in ci_tests]
test_files = [TestFile(t.filename, t.est_time) for t in ci_tests]

run_unittest_files(
test_files,
Expand All @@ -32,7 +41,23 @@ def run_per_commit(hw: HWBackend, suite: str):


def main():
run_per_commit(HWBackend.CUDA, "stage-a-test-1")
parser = argparse.ArgumentParser()
parser.add_argument(
"--hw",
type=str,
choices=["cpu", "cuda"],
required=True,
help="Hardware backend to run tests on.",
)
parser.add_argument(
"--suite",
type=str,
required=True,
help="Test suite to run.",
)
args = parser.parse_args()
hw = HW_MAPPING[args.hw]
run_per_commit(hw, args.suite)


if __name__ == "__main__":
Expand Down
5 changes: 0 additions & 5 deletions test/srt/run_suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
suites = {
"per-commit-1-gpu": [
TestFile("debug_utils/test_tensor_dump_forward_hook.py", 15),
TestFile("function_call/test_json_schema_constraint.py", 1),
TestFile("hicache/test_hicache_storage.py", 127),
TestFile("hicache/test_hicache_variants.py", 393),
TestFile("layers/attention/mamba/test_causal_conv1d.py", 25),
Expand Down Expand Up @@ -70,7 +69,6 @@
TestFile("test_flashmla.py", 230),
TestFile("test_fp8_utils.py", 5),
TestFile("rotary_embedding/test_mrope.py", 10),
TestFile("test_function_call_parser.py", 10),
TestFile("test_fused_moe.py", 80),
TestFile("test_gpt_oss_1gpu.py", 750),
TestFile("test_harmony_parser.py", 20),
Expand Down Expand Up @@ -239,7 +237,6 @@
TestFile("ep/test_hybrid_dp_ep_tp_mtp.py"),
TestFile("ep/test_moe_deepep.py"),
TestFile("ep/test_moe_deepep_eval_accuracy_large.py"),
TestFile("function_call/test_unknown_tool_name.py"),
TestFile("hicache/test_disaggregation_hicache.py"),
TestFile("hicache/test_hicache_storage_benchmark.py"),
TestFile("hicache/test_hicache_storage_e2e.py"),
Expand Down Expand Up @@ -381,7 +378,6 @@
# NOTE: please sort the test cases alphabetically by the test file name
suite_amd = {
"per-commit-amd": [
TestFile("function_call/test_json_schema_constraint.py", 1),
# TestFile("hicache/test_hicache.py", 116), # Disabled temporarily, see https://github.com/sgl-project/sglang/issues/12575
# TestFile("hicache/test_hicache_mla.py", 127), # Disabled temporarily, # Temporarily disabled, see https://github.com/sgl-project/sglang/issues/12574
# TestFile("hicache/test_hicache_storage.py", 127), # Disabled temporarily, see https://github.com/sgl-project/sglang/issues/12575
Expand Down Expand Up @@ -421,7 +417,6 @@
TestFile("test_chunked_prefill.py", 410),
TestFile("test_create_kvindices.py", 2),
TestFile("test_eval_fp8_accuracy.py", 303),
TestFile("test_function_call_parser.py", 10),
TestFile("test_fused_moe.py", 30),
TestFile("test_harmony_parser.py", 20),
TestFile("test_input_embeddings.py", 38),
Expand Down
Loading