mirror of
https://github.com/kvcache-ai/sglang.git
synced 2026-07-16 08:54:20 +00:00
261 lines
7.1 KiB
Rust
261 lines
7.1 KiB
Rust
use serde_json::json;
|
|
|
|
use crate::common::{
|
|
mock_worker::{HealthStatus, MockWorkerConfig, WorkerType},
|
|
WorkerTestContext,
|
|
};
|
|
|
|
#[cfg(test)]
|
|
mod request_format_tests {
|
|
use super::*;
|
|
|
|
#[tokio::test]
|
|
async fn test_generate_request_formats() {
|
|
let ctx = WorkerTestContext::new(vec![MockWorkerConfig {
|
|
port: 19001,
|
|
worker_type: WorkerType::Regular,
|
|
health_status: HealthStatus::Healthy,
|
|
response_delay_ms: 0,
|
|
fail_rate: 0.0,
|
|
}])
|
|
.await;
|
|
|
|
let payload = json!({
|
|
"text": "Hello, world!",
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/generate", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
let payload = json!({
|
|
"text": "Tell me a story",
|
|
"sampling_params": {
|
|
"temperature": 0.7,
|
|
"max_new_tokens": 100,
|
|
"top_p": 0.9
|
|
},
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/generate", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
let payload = json!({
|
|
"input_ids": [1, 2, 3, 4, 5],
|
|
"sampling_params": {
|
|
"temperature": 0.0,
|
|
"max_new_tokens": 50
|
|
},
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/generate", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
ctx.shutdown().await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_v1_chat_completions_formats() {
|
|
let ctx = WorkerTestContext::new(vec![MockWorkerConfig {
|
|
port: 19002,
|
|
worker_type: WorkerType::Regular,
|
|
health_status: HealthStatus::Healthy,
|
|
response_delay_ms: 0,
|
|
fail_rate: 0.0,
|
|
}])
|
|
.await;
|
|
|
|
let payload = json!({
|
|
"model": "test-model",
|
|
"messages": [
|
|
{"role": "system", "content": "You are a helpful assistant."},
|
|
{"role": "user", "content": "Hello!"}
|
|
],
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/v1/chat/completions", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
let response = result.unwrap();
|
|
assert!(response.get("choices").is_some());
|
|
assert!(response.get("id").is_some());
|
|
assert_eq!(
|
|
response.get("object").and_then(|v| v.as_str()),
|
|
Some("chat.completion")
|
|
);
|
|
|
|
let payload = json!({
|
|
"model": "test-model",
|
|
"messages": [
|
|
{"role": "user", "content": "Tell me a joke"}
|
|
],
|
|
"temperature": 0.8,
|
|
"max_tokens": 150,
|
|
"top_p": 0.95,
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/v1/chat/completions", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
ctx.shutdown().await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_v1_completions_formats() {
|
|
let ctx = WorkerTestContext::new(vec![MockWorkerConfig {
|
|
port: 19003,
|
|
worker_type: WorkerType::Regular,
|
|
health_status: HealthStatus::Healthy,
|
|
response_delay_ms: 0,
|
|
fail_rate: 0.0,
|
|
}])
|
|
.await;
|
|
|
|
let payload = json!({
|
|
"model": "test-model",
|
|
"prompt": "Once upon a time",
|
|
"max_tokens": 50,
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/v1/completions", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
let response = result.unwrap();
|
|
assert!(response.get("choices").is_some());
|
|
assert_eq!(
|
|
response.get("object").and_then(|v| v.as_str()),
|
|
Some("text_completion")
|
|
);
|
|
|
|
let payload = json!({
|
|
"model": "test-model",
|
|
"prompt": ["First prompt", "Second prompt"],
|
|
"temperature": 0.5,
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/v1/completions", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
let payload = json!({
|
|
"model": "test-model",
|
|
"prompt": "The capital of France is",
|
|
"max_tokens": 10,
|
|
"logprobs": 5,
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/v1/completions", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
ctx.shutdown().await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_batch_requests() {
|
|
let ctx = WorkerTestContext::new(vec![MockWorkerConfig {
|
|
port: 19004,
|
|
worker_type: WorkerType::Regular,
|
|
health_status: HealthStatus::Healthy,
|
|
response_delay_ms: 0,
|
|
fail_rate: 0.0,
|
|
}])
|
|
.await;
|
|
|
|
let payload = json!({
|
|
"text": ["First text", "Second text", "Third text"],
|
|
"sampling_params": {
|
|
"temperature": 0.7,
|
|
"max_new_tokens": 50
|
|
},
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/generate", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
let payload = json!({
|
|
"input_ids": [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/generate", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
ctx.shutdown().await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_special_parameters() {
|
|
let ctx = WorkerTestContext::new(vec![MockWorkerConfig {
|
|
port: 19005,
|
|
worker_type: WorkerType::Regular,
|
|
health_status: HealthStatus::Healthy,
|
|
response_delay_ms: 0,
|
|
fail_rate: 0.0,
|
|
}])
|
|
.await;
|
|
|
|
let payload = json!({
|
|
"text": "Test",
|
|
"return_logprob": true,
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/generate", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
let payload = json!({
|
|
"text": "Generate JSON",
|
|
"sampling_params": {
|
|
"temperature": 0.0,
|
|
"json_schema": "$$ANY$$"
|
|
},
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/generate", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
let payload = json!({
|
|
"text": "Continue forever",
|
|
"sampling_params": {
|
|
"temperature": 0.7,
|
|
"max_new_tokens": 100,
|
|
"ignore_eos": true
|
|
},
|
|
"stream": false
|
|
});
|
|
|
|
let result = ctx.make_request("/generate", payload).await;
|
|
assert!(result.is_ok());
|
|
|
|
ctx.shutdown().await;
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_error_handling() {
|
|
let ctx = WorkerTestContext::new(vec![MockWorkerConfig {
|
|
port: 19006,
|
|
worker_type: WorkerType::Regular,
|
|
health_status: HealthStatus::Healthy,
|
|
response_delay_ms: 0,
|
|
fail_rate: 0.0,
|
|
}])
|
|
.await;
|
|
|
|
let payload = json!({});
|
|
|
|
let result = ctx.make_request("/generate", payload).await;
|
|
// Mock worker accepts empty body
|
|
assert!(result.is_ok());
|
|
|
|
ctx.shutdown().await;
|
|
}
|
|
}
|