Unverified Commit 2f86f3ad authored by Simo Lin's avatar Simo Lin Committed by GitHub
Browse files

[router] add endpoint unit test (#8298)

parent bfb118c0
This diff is collapsed.
...@@ -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": [{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment