migrate CPU-only unit tests from openai_server to unit/ (#22965)

This commit is contained in:
Liangsheng Yin
2026-04-16 03:53:33 -07:00
committed by GitHub
parent 62309f09db
commit bbd8f9ba09
5 changed files with 92 additions and 93 deletions
@@ -1,6 +1,5 @@
import unittest import unittest
from sglang.srt.sampling.sampling_params import MAX_LEN, get_max_seq_length
from sglang.srt.utils import kill_process_tree from sglang.srt.utils import kill_process_tree
from sglang.test.ci.ci_register import register_amd_ci, register_cuda_ci from sglang.test.ci.ci_register import register_amd_ci, register_cuda_ci
from sglang.test.kits.matched_stop_kit import MatchedStopMixin from sglang.test.kits.matched_stop_kit import MatchedStopMixin
@@ -32,53 +31,5 @@ class TestMatchedStop(CustomTestCase, MatchedStopMixin):
kill_process_tree(cls.process.pid) kill_process_tree(cls.process.pid)
class TestRegexPatternMaxLength(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.regex_str_to_max_len = {
"((ab|cd(e|f){2}){3,5}g|hij)*k": MAX_LEN,
# - '*' → infinite tokens need to be stored
"abc*?k": MAX_LEN,
# - '*?' → infinite tokens still need to be stored even if lazy matching used
"^spec(foo|at)$": 7,
# - '^' and '$' don't add any characters to the max length
# "spec" → 4
# "(foo|at)" → max(3, 2) = 3
# Whole regex = 7
"(a(bca|de(fg|hi){2,3})j){2}kl": 22,
# - Innermost alt: "fg" vs "hi" → 2
# - Repeat {2,3}: max = 3 * 2 = 6
# - Inner group "de(...)": 2 (for "de") + 6 = 8.
# - "bca" or "de(...)" → max(3, 8) = 8
# - Whole group: "a" (1) + group (8) + "j"(1) = 10
# - Repeat {2} → 20
# - Add "kl"(2) → 22
"(foo(bar|baz(qux){1,2}))|(x(yz){5,10})": 21,
# Branch 1:
# "foo"(3) + max("bar"(3), "baz"(3)+"qux"{2} = 3 + 6 = 9) = 3 + 9 = 12
# Branch 2:
# "x"(1) + "yz"{10} = 1 + 20 =21
# Whole regex = max(12, 21) = 21
"(((a|bc){1,3}(d(e|f){2}|gh){2,4})|(ijk|lmp(no|p){3})){5}": 90,
# Branch A:
# (a|bc){1,3} → max = 3 * 2 = 6
# Inside: d(e|f){2} = 1 + 2 * 1 = 3 vs gh = 2 → max = 3
# Repeat {2,4} → 4 * 3 = 12
# Branch A total = 18
# Branch B:
# "ijk"(3) vs "lmp(no|p){3}" = 3 + 3 * max(2, 1) = 3 + 6 = 9 → max = 9
# Branch B total = 9
# Whole outer alt = max(18, 9) = 18
# Repeat {5} → 90
}
def test_get_max_length(self):
for regex_str, max_len in self.regex_str_to_max_len.items():
if max_len == MAX_LEN:
self.assertGreaterEqual(get_max_seq_length(regex_str), MAX_LEN)
else:
self.assertEqual(get_max_seq_length(regex_str), max_len)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
@@ -0,0 +1,58 @@
import unittest
from sglang.srt.sampling.sampling_params import MAX_LEN, get_max_seq_length
from sglang.test.ci.ci_register import register_cpu_ci
register_cpu_ci(est_time=2, suite="stage-a-test-cpu")
class TestRegexPatternMaxLength(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.regex_str_to_max_len = {
"((ab|cd(e|f){2}){3,5}g|hij)*k": MAX_LEN,
# - '*' -> infinite tokens need to be stored
"abc*?k": MAX_LEN,
# - '*?' -> infinite tokens still need to be stored even if lazy matching used
"^spec(foo|at)$": 7,
# - '^' and '$' don't add any characters to the max length
# "spec" -> 4
# "(foo|at)" -> max(3, 2) = 3
# Whole regex = 7
"(a(bca|de(fg|hi){2,3})j){2}kl": 22,
# - Innermost alt: "fg" vs "hi" -> 2
# - Repeat {2,3}: max = 3 * 2 = 6
# - Inner group "de(...)": 2 (for "de") + 6 = 8.
# - "bca" or "de(...)" -> max(3, 8) = 8
# - Whole group: "a" (1) + group (8) + "j"(1) = 10
# - Repeat {2} -> 20
# - Add "kl"(2) -> 22
"(foo(bar|baz(qux){1,2}))|(x(yz){5,10})": 21,
# Branch 1:
# "foo"(3) + max("bar"(3), "baz"(3)+"qux"{2} = 3 + 6 = 9) = 3 + 9 = 12
# Branch 2:
# "x"(1) + "yz"{10} = 1 + 20 =21
# Whole regex = max(12, 21) = 21
"(((a|bc){1,3}(d(e|f){2}|gh){2,4})|(ijk|lmp(no|p){3})){5}": 90,
# Branch A:
# (a|bc){1,3} -> max = 3 * 2 = 6
# Inside: d(e|f){2} = 1 + 2 * 1 = 3 vs gh = 2 -> max = 3
# Repeat {2,4} -> 4 * 3 = 12
# Branch A total = 18
# Branch B:
# "ijk"(3) vs "lmp(no|p){3}" = 3 + 3 * max(2, 1) = 3 + 6 = 9 -> max = 9
# Branch B total = 9
# Whole outer alt = max(18, 9) = 18
# Repeat {5} -> 90
}
def test_get_max_length(self):
for regex_str, max_len in self.regex_str_to_max_len.items():
if max_len == MAX_LEN:
self.assertGreaterEqual(get_max_seq_length(regex_str), MAX_LEN)
else:
self.assertEqual(get_max_seq_length(regex_str), max_len)
if __name__ == "__main__":
unittest.main()
@@ -28,10 +28,9 @@ from sglang.srt.entrypoints.openai.protocol import (
ModelList, ModelList,
UsageInfo, UsageInfo,
) )
from sglang.test.ci.ci_register import register_amd_ci, register_cuda_ci from sglang.test.ci.ci_register import register_cpu_ci
register_cuda_ci(est_time=2, suite="stage-b-test-1-gpu-small") register_cpu_ci(est_time=2, suite="stage-a-test-cpu")
register_amd_ci(est_time=10, suite="stage-b-test-1-gpu-small-amd")
class TestModelCard(unittest.TestCase): class TestModelCard(unittest.TestCase):
@@ -1,11 +1,15 @@
""" """
Unit-tests for OpenAIServingChat — rewritten to use only the std-lib 'unittest'. Unit-tests for OpenAIServingChat -- rewritten to use only the std-lib 'unittest'.
Run with either: Run with either:
python tests/test_serving_chat_unit.py -v python tests/test_serving_chat_unit.py -v
or or
python -m unittest discover -s tests -p "test_*unit.py" -v python -m unittest discover -s tests -p "test_*unit.py" -v
""" """
from sglang.test.test_utils import maybe_stub_sgl_kernel
maybe_stub_sgl_kernel() # must precede any import that pulls in sgl_kernel
import json import json
import unittest import unittest
import uuid import uuid
@@ -25,10 +29,9 @@ from sglang.srt.entrypoints.openai.serving_chat import (
) )
from sglang.srt.managers.io_struct import GenerateReqInput from sglang.srt.managers.io_struct import GenerateReqInput
from sglang.srt.utils import get_or_create_event_loop from sglang.srt.utils import get_or_create_event_loop
from sglang.test.ci.ci_register import register_amd_ci, register_cuda_ci from sglang.test.ci.ci_register import register_cpu_ci
register_cuda_ci(est_time=8, suite="stage-b-test-1-gpu-small") register_cpu_ci(est_time=8, suite="stage-a-test-cpu")
register_amd_ci(est_time=10, suite="stage-b-test-1-gpu-small-amd")
class _MockTokenizerManager: class _MockTokenizerManager:
@@ -670,44 +673,29 @@ class ServingChatTestCase(unittest.TestCase):
def test_dpsk_v32_encoding_path(self): def test_dpsk_v32_encoding_path(self):
"""Test DeepSeek V3.2 encoding path detection and application.""" """Test DeepSeek V3.2 encoding path detection and application."""
from sglang.srt.managers.template_manager import TemplateManager from sglang.srt.managers.template_manager import TemplateManager
from sglang.srt.server_args import PortArgs, ServerArgs
server_args = ServerArgs(model_path="deepseek-ai/DeepSeek-V3.2") # Only mock the fields that _use_dpsk_v32_encoding() actually reads:
port_args = PortArgs.init_new(server_args) # tokenizer.chat_template and hf_config.architectures
tm = _MockTokenizerManager()
# Use mocks for TokenizerManager components to avoid full initialization
with patch(
"sglang.srt.managers.tokenizer_manager.TokenizerManager"
) as MockTokenizerManager:
tokenizer_manager = MockTokenizerManager(server_args, port_args)
tokenizer_manager.server_args = server_args
tokenizer_manager.model_config = Mock()
tokenizer_manager.model_config.get_default_sampling_params.return_value = (
None
)
# Mock hf_config
mock_hf_config = Mock() mock_hf_config = Mock()
mock_hf_config.architectures = ["DeepseekV32ForCausalLM"] mock_hf_config.architectures = ["DeepseekV32ForCausalLM"]
tm.model_config.hf_config = mock_hf_config
tokenizer_manager.model_config.hf_config = mock_hf_config # Case 1: No chat template + DeepSeek V3.2 arch -> should use dpsk encoding
tm.tokenizer.chat_template = None
# Case 1: No chat template in tokenizer -> should use dpsk encoding serving_chat = OpenAIServingChat(tm, TemplateManager())
tokenizer_manager.tokenizer = Mock()
tokenizer_manager.tokenizer.chat_template = None
serving_chat = OpenAIServingChat(tokenizer_manager, TemplateManager())
self.assertTrue(serving_chat.use_dpsk_v32_encoding) self.assertTrue(serving_chat.use_dpsk_v32_encoding)
# Case 2: Chat template exists -> should NOT use dpsk encoding # Case 2: Chat template exists -> should NOT use dpsk encoding
tokenizer_manager.tokenizer.chat_template = "some template" tm.tokenizer.chat_template = "some template"
serving_chat = OpenAIServingChat(tokenizer_manager, TemplateManager()) serving_chat = OpenAIServingChat(tm, TemplateManager())
self.assertFalse(serving_chat.use_dpsk_v32_encoding) self.assertFalse(serving_chat.use_dpsk_v32_encoding)
# Case 3: Not DeepSeek V3.2 architecture -> should NOT use dpsk encoding # Case 3: Not DeepSeek V3.2 architecture -> should NOT use dpsk encoding
tokenizer_manager.tokenizer.chat_template = None tm.tokenizer.chat_template = None
mock_hf_config.architectures = ["LlamaForCausalLM"] mock_hf_config.architectures = ["LlamaForCausalLM"]
serving_chat = OpenAIServingChat(tokenizer_manager, TemplateManager()) serving_chat = OpenAIServingChat(tm, TemplateManager())
self.assertFalse(serving_chat.use_dpsk_v32_encoding) self.assertFalse(serving_chat.use_dpsk_v32_encoding)
def test_streaming_abort_yields_error(self): def test_streaming_abort_yields_error(self):
@@ -4,6 +4,10 @@ Run with:
python -m unittest tests.test_serving_completions_unit -v python -m unittest tests.test_serving_completions_unit -v
""" """
from sglang.test.test_utils import maybe_stub_sgl_kernel
maybe_stub_sgl_kernel() # must precede any import that pulls in sgl_kernel
import json import json
import unittest import unittest
from http import HTTPStatus from http import HTTPStatus
@@ -16,10 +20,9 @@ from sglang.srt.entrypoints.openai.protocol import CompletionRequest
from sglang.srt.entrypoints.openai.serving_completions import OpenAIServingCompletion from sglang.srt.entrypoints.openai.serving_completions import OpenAIServingCompletion
from sglang.srt.managers.tokenizer_manager import TokenizerManager from sglang.srt.managers.tokenizer_manager import TokenizerManager
from sglang.srt.utils import get_or_create_event_loop from sglang.srt.utils import get_or_create_event_loop
from sglang.test.ci.ci_register import register_amd_ci, register_cuda_ci from sglang.test.ci.ci_register import register_cpu_ci
register_cuda_ci(est_time=8, suite="stage-b-test-1-gpu-small") register_cpu_ci(est_time=8, suite="stage-a-test-cpu")
register_amd_ci(est_time=10, suite="stage-b-test-1-gpu-small-amd")
class _MockTemplateManager: class _MockTemplateManager: