Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
change
sglang
Commits
2f86f3ad
Unverified
Commit
2f86f3ad
authored
Jul 23, 2025
by
Simo Lin
Committed by
GitHub
Jul 23, 2025
Browse files
[router] add endpoint unit test (#8298)
parent
bfb118c0
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1374 additions
and
7 deletions
+1374
-7
sgl-router/tests/api_endpoints_test.rs
sgl-router/tests/api_endpoints_test.rs
+1309
-0
sgl-router/tests/common/mock_worker.rs
sgl-router/tests/common/mock_worker.rs
+65
-7
No files found.
sgl-router/tests/api_endpoints_test.rs
0 → 100644
View file @
2f86f3ad
This diff is collapsed.
Click to expand it.
sgl-router/tests/common/mock_worker.rs
View file @
2f86f3ad
...
@@ -99,9 +99,17 @@ impl MockWorker {
...
@@ -99,9 +99,17 @@ impl MockWorker {
// Handler implementations
// Handler implementations
/// Check if request should fail based on configured fail_rate
async
fn
should_fail
(
config
:
&
MockWorkerConfig
)
->
bool
{
rand
::
random
::
<
f32
>
()
<
config
.fail_rate
}
async
fn
health_handler
(
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
async
fn
health_handler
(
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
let
config
=
config
.read
()
.await
;
let
config
=
config
.read
()
.await
;
// Note: We don't apply fail_rate to health endpoint to allow workers to be added successfully
// fail_rate is only applied to actual request endpoints
match
config
.health_status
{
match
config
.health_status
{
HealthStatus
::
Healthy
=>
HttpResponse
::
Ok
()
.json
(
json!
({
HealthStatus
::
Healthy
=>
HttpResponse
::
Ok
()
.json
(
json!
({
"status"
:
"healthy"
,
"status"
:
"healthy"
,
...
@@ -122,6 +130,13 @@ async fn health_handler(config: web::Data<Arc<RwLock<MockWorkerConfig>>>) -> Htt
...
@@ -122,6 +130,13 @@ async fn health_handler(config: web::Data<Arc<RwLock<MockWorkerConfig>>>) -> Htt
async
fn
health_generate_handler
(
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
async
fn
health_generate_handler
(
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
let
config
=
config
.read
()
.await
;
let
config
=
config
.read
()
.await
;
// Simulate failure based on fail_rate
if
should_fail
(
&
config
)
.await
{
return
HttpResponse
::
InternalServerError
()
.json
(
json!
({
"error"
:
"Random failure for testing"
}));
}
if
matches!
(
config
.health_status
,
HealthStatus
::
Healthy
)
{
if
matches!
(
config
.health_status
,
HealthStatus
::
Healthy
)
{
HttpResponse
::
Ok
()
.json
(
json!
({
HttpResponse
::
Ok
()
.json
(
json!
({
"status"
:
"ok"
,
"status"
:
"ok"
,
...
@@ -138,6 +153,13 @@ async fn health_generate_handler(config: web::Data<Arc<RwLock<MockWorkerConfig>>
...
@@ -138,6 +153,13 @@ async fn health_generate_handler(config: web::Data<Arc<RwLock<MockWorkerConfig>>
async
fn
server_info_handler
(
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
async
fn
server_info_handler
(
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
let
config
=
config
.read
()
.await
;
let
config
=
config
.read
()
.await
;
// Simulate failure based on fail_rate
if
should_fail
(
&
config
)
.await
{
return
HttpResponse
::
InternalServerError
()
.json
(
json!
({
"error"
:
"Random failure for testing"
}));
}
// Return response matching actual sglang server implementation
// Return response matching actual sglang server implementation
HttpResponse
::
Ok
()
.json
(
json!
({
HttpResponse
::
Ok
()
.json
(
json!
({
// Server args fields
// Server args fields
...
@@ -182,7 +204,16 @@ async fn server_info_handler(config: web::Data<Arc<RwLock<MockWorkerConfig>>>) -
...
@@ -182,7 +204,16 @@ async fn server_info_handler(config: web::Data<Arc<RwLock<MockWorkerConfig>>>) -
}))
}))
}
}
async
fn
model_info_handler
(
_
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
async
fn
model_info_handler
(
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
let
config
=
config
.read
()
.await
;
// Simulate failure based on fail_rate
if
should_fail
(
&
config
)
.await
{
return
HttpResponse
::
InternalServerError
()
.json
(
json!
({
"error"
:
"Random failure for testing"
}));
}
// Return response matching actual sglang server implementation
// Return response matching actual sglang server implementation
HttpResponse
::
Ok
()
.json
(
json!
({
HttpResponse
::
Ok
()
.json
(
json!
({
"model_path"
:
"mock-model-path"
,
"model_path"
:
"mock-model-path"
,
...
@@ -205,7 +236,7 @@ async fn generate_handler(
...
@@ -205,7 +236,7 @@ async fn generate_handler(
let
config
=
config
.read
()
.await
;
let
config
=
config
.read
()
.await
;
// Simulate failure based on fail_rate
// Simulate failure based on fail_rate
if
rand
::
random
::
<
f32
>
()
<
config
.fail_rate
{
if
should_fail
(
&
config
)
.await
{
return
HttpResponse
::
InternalServerError
()
.json
(
json!
({
return
HttpResponse
::
InternalServerError
()
.json
(
json!
({
"error"
:
"Random failure for testing"
"error"
:
"Random failure for testing"
}));
}));
...
@@ -229,7 +260,10 @@ async fn generate_handler(
...
@@ -229,7 +260,10 @@ async fn generate_handler(
tokio
::
spawn
(
async
move
{
tokio
::
spawn
(
async
move
{
let
tokens
=
vec!
[
"This "
,
"is "
,
"a "
,
"mock "
,
"response."
];
let
tokens
=
vec!
[
"This "
,
"is "
,
"a "
,
"mock "
,
"response."
];
let
timestamp_start
=
SystemTime
::
now
()
.duration_since
(
UNIX_EPOCH
)
.unwrap
()
.as_secs_f64
();
let
timestamp_start
=
SystemTime
::
now
()
.duration_since
(
UNIX_EPOCH
)
.unwrap
()
.as_secs_f64
();
for
(
i
,
token
)
in
tokens
.iter
()
.enumerate
()
{
for
(
i
,
token
)
in
tokens
.iter
()
.enumerate
()
{
let
chunk
=
json!
({
let
chunk
=
json!
({
...
@@ -248,7 +282,14 @@ async fn generate_handler(
...
@@ -248,7 +282,14 @@ async fn generate_handler(
}
}
});
});
if
tx
.send
(
format!
(
"data: {}
\n\n
"
,
serde_json
::
to_string
(
&
chunk
)
.unwrap
()))
.await
.is_err
()
{
if
tx
.send
(
format!
(
"data: {}
\n\n
"
,
serde_json
::
to_string
(
&
chunk
)
.unwrap
()
))
.await
.is_err
()
{
break
;
break
;
}
}
...
@@ -269,7 +310,6 @@ async fn generate_handler(
...
@@ -269,7 +310,6 @@ async fn generate_handler(
}
else
{
}
else
{
// Return non-streaming response matching sglang format
// Return non-streaming response matching sglang format
let
request_id
=
format!
(
"mock-req-{}"
,
rand
::
random
::
<
u32
>
());
let
request_id
=
format!
(
"mock-req-{}"
,
rand
::
random
::
<
u32
>
());
let
timestamp_start
=
SystemTime
::
now
()
.duration_since
(
UNIX_EPOCH
)
.unwrap
()
.as_secs_f64
();
HttpResponse
::
Ok
()
.json
(
json!
({
HttpResponse
::
Ok
()
.json
(
json!
({
"text"
:
"Mock generated response for the input"
,
"text"
:
"Mock generated response for the input"
,
...
@@ -567,7 +607,16 @@ async fn completions_handler(
...
@@ -567,7 +607,16 @@ async fn completions_handler(
}
}
}
}
async
fn
flush_cache_handler
(
_
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
async
fn
flush_cache_handler
(
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
let
config
=
config
.read
()
.await
;
// Simulate failure based on fail_rate
if
should_fail
(
&
config
)
.await
{
return
HttpResponse
::
InternalServerError
()
.json
(
json!
({
"error"
:
"Random failure for testing"
}));
}
HttpResponse
::
Ok
()
.json
(
json!
({
HttpResponse
::
Ok
()
.json
(
json!
({
"status"
:
"success"
,
"status"
:
"success"
,
"message"
:
"Cache flushed"
,
"message"
:
"Cache flushed"
,
...
@@ -575,7 +624,16 @@ async fn flush_cache_handler(_config: web::Data<Arc<RwLock<MockWorkerConfig>>>)
...
@@ -575,7 +624,16 @@ async fn flush_cache_handler(_config: web::Data<Arc<RwLock<MockWorkerConfig>>>)
}))
}))
}
}
async
fn
v1_models_handler
(
_
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
async
fn
v1_models_handler
(
config
:
web
::
Data
<
Arc
<
RwLock
<
MockWorkerConfig
>>>
)
->
HttpResponse
{
let
config
=
config
.read
()
.await
;
// Simulate failure based on fail_rate
if
should_fail
(
&
config
)
.await
{
return
HttpResponse
::
InternalServerError
()
.json
(
json!
({
"error"
:
"Random failure for testing"
}));
}
HttpResponse
::
Ok
()
.json
(
json!
({
HttpResponse
::
Ok
()
.json
(
json!
({
"object"
:
"list"
,
"object"
:
"list"
,
"data"
:
[{
"data"
:
[{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment