| import io |
| import unittest |
|
|
| import requests |
|
|
| from sglang.srt.environ import envs |
| from sglang.srt.utils import kill_process_tree |
| from sglang.test.ci.ci_register import register_amd_ci, register_cuda_ci |
| from sglang.test.test_utils import ( |
| DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH, |
| DEFAULT_URL_FOR_TEST, |
| CustomTestCase, |
| popen_launch_server, |
| ) |
|
|
| register_cuda_ci(est_time=120, suite="nightly-1-gpu", nightly=True) |
| register_amd_ci(est_time=120, suite="nightly-amd-1-gpu", nightly=True) |
|
|
|
|
| class BaseTestSoftWatchdog: |
| env_override = None |
| expected_message = None |
|
|
| @classmethod |
| def setUpClass(cls): |
| cls.stdout = io.StringIO() |
| cls.stderr = io.StringIO() |
|
|
| with cls.env_override(): |
| cls.process = popen_launch_server( |
| "Qwen/Qwen3-0.6B", |
| DEFAULT_URL_FOR_TEST, |
| timeout=DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH, |
| other_args=[ |
| "--soft-watchdog-timeout", |
| "20", |
| "--skip-server-warmup", |
| ], |
| return_stdout_stderr=(cls.stdout, cls.stderr), |
| ) |
|
|
| @classmethod |
| def tearDownClass(cls): |
| kill_process_tree(cls.process.pid) |
| cls.stdout.close() |
| cls.stderr.close() |
|
|
| def test_watchdog_triggers(self): |
| print("Start call /generate API", flush=True) |
| try: |
| requests.post( |
| DEFAULT_URL_FOR_TEST + "/generate", |
| json={ |
| "text": "Hello, please repeat this sentence for 1000 times.", |
| "sampling_params": {"max_new_tokens": 100, "temperature": 0}, |
| }, |
| timeout=30, |
| ) |
| except requests.exceptions.ReadTimeout as e: |
| print(f"requests.post timeout (but expected): {e}") |
| print("End call /generate API", flush=True) |
|
|
| combined_output = self.stdout.getvalue() + self.stderr.getvalue() |
| self.assertIn(self.expected_message, combined_output) |
|
|
|
|
| class TestSoftWatchdogDetokenizer(BaseTestSoftWatchdog, CustomTestCase): |
| env_override = lambda: envs.SGLANG_TEST_STUCK_DETOKENIZER.override(30) |
| expected_message = "DetokenizerManager watchdog timeout" |
|
|
|
|
| class TestSoftWatchdogTokenizer(BaseTestSoftWatchdog, CustomTestCase): |
| env_override = lambda: envs.SGLANG_TEST_STUCK_TOKENIZER.override(30) |
| expected_message = "TokenizerManager watchdog timeout" |
|
|
|
|
| class TestSoftWatchdogSchedulerInit(BaseTestSoftWatchdog, CustomTestCase): |
| env_override = lambda: envs.SGLANG_TEST_STUCK_SCHEDULER_INIT.override(30) |
| expected_message = "Scheduler watchdog timeout" |
|
|
|
|
| if __name__ == "__main__": |
| unittest.main() |
|
|