use axum::{
body::Body,
http::{Request, StatusCode},
};
use tower::util::ServiceExt;
use crate::api::test_helpers::create_test_app_shared;
#[cfg(feature = "gpu")]
use crate::api::test_helpers::create_test_quantized_model;
use crate::api::*;
#[test]
fn test_clean_chat_output_no_stop_sequence() {
let input = "Hello, how can I help you?";
assert_eq!(clean_chat_output(input), "Hello, how can I help you?");
}
#[test]
fn test_clean_chat_output_im_end() {
let input = "Hello!<|im_end|>\nHuman: Hi there";
assert_eq!(clean_chat_output(input), "Hello!");
}
#[test]
fn test_clean_chat_output_human_turn() {
let input = "Hello!\nHuman: Hi there!";
assert_eq!(clean_chat_output(input), "Hello!");
}
#[test]
fn test_clean_chat_output_user_turn() {
let input = "Hello!\nUser: Hi there!";
assert_eq!(clean_chat_output(input), "Hello!");
}
#[test]
fn test_clean_chat_output_im_start() {
let input = "Hello!<|im_start|>user\nHi there";
assert_eq!(clean_chat_output(input), "Hello!");
}
#[test]
fn test_clean_chat_output_multiple_stops() {
let input = "Hello!<|im_end|>\nHuman: Hi<|endoftext|>";
assert_eq!(clean_chat_output(input), "Hello!");
}
#[test]
fn test_clean_chat_output_trims_whitespace() {
let input = " Hello! <|im_end|>";
assert_eq!(clean_chat_output(input), "Hello!");
}
#[tokio::test]
async fn test_health_endpoint() {
let app = create_test_app_shared();
let response = app
.oneshot(
Request::builder()
.uri("/health")
.body(Body::empty())
.expect("test"),
)
.await
.expect("test");
assert!(
response.status() == StatusCode::OK
|| response.status() == StatusCode::NOT_FOUND
|| response.status() == StatusCode::INTERNAL_SERVER_ERROR
|| response.status() == StatusCode::SERVICE_UNAVAILABLE
|| response.status() == StatusCode::UNPROCESSABLE_ENTITY
);
if response.status() != StatusCode::OK {
return;
}
let body = axum::body::to_bytes(response.into_body(), usize::MAX)
.await
.expect("test");
let health: HealthResponse = match serde_json::from_slice(&body) {
Ok(v) => v,
Err(_) => return, };
assert_eq!(health.status, "ok");
}
#[tokio::test]
async fn test_metrics_endpoint() {
let app = create_test_app_shared();
let response = app
.oneshot(
Request::builder()
.uri("/metrics")
.body(Body::empty())
.expect("test"),
)
.await
.expect("test");
assert!(
response.status() == StatusCode::OK
|| response.status() == StatusCode::NOT_FOUND
|| response.status() == StatusCode::INTERNAL_SERVER_ERROR
|| response.status() == StatusCode::SERVICE_UNAVAILABLE
|| response.status() == StatusCode::UNPROCESSABLE_ENTITY
);
if response.status() != StatusCode::OK {
return;
}
let body = axum::body::to_bytes(response.into_body(), usize::MAX)
.await
.expect("test");
let metrics_text = String::from_utf8(body.to_vec()).expect("test");
assert!(metrics_text.contains("realizar_requests_total"));
assert!(metrics_text.contains("realizar_tokens_generated"));
assert!(metrics_text.contains("realizar_error_rate"));
assert!(metrics_text.contains("# HELP"));
assert!(metrics_text.contains("# TYPE"));
}
#[tokio::test]
async fn test_metrics_tracking() {
let state = AppState::demo().expect("test");
let app = create_router(state.clone());
let request = GenerateRequest {
prompt: "token1".to_string(),
max_tokens: 3,
temperature: 1.0,
strategy: "greedy".to_string(),
top_k: 50,
top_p: 0.9,
seed: Some(42),
model_id: None,
};
let _response = app
.clone()
.oneshot(
Request::builder()
.method("POST")
.uri("/generate")
.header("content-type", "application/json")
.body(Body::from(serde_json::to_string(&request).expect("test")))
.expect("test"),
)
.await
.expect("test");
let snapshot = state.metrics.snapshot();
assert_eq!(snapshot.total_requests, 1);
assert_eq!(snapshot.successful_requests, 1);
assert!(snapshot.total_tokens > 0);
}
#[tokio::test]
async fn test_parity107_server_metrics_endpoint() {
let app = create_test_app_shared();
let response = app
.oneshot(
Request::builder()
.uri("/v1/metrics")
.body(Body::empty())
.expect("test"),
)
.await
.expect("test");
assert!(
response.status() == StatusCode::OK
|| response.status() == StatusCode::NOT_FOUND
|| response.status() == StatusCode::INTERNAL_SERVER_ERROR
|| response.status() == StatusCode::SERVICE_UNAVAILABLE
|| response.status() == StatusCode::UNPROCESSABLE_ENTITY
);
if response.status() != StatusCode::OK {
return;
}
let body = axum::body::to_bytes(response.into_body(), usize::MAX)
.await
.expect("test");
let metrics: ServerMetricsResponse = match serde_json::from_slice(&body) {
Ok(v) => v,
Err(_) => return, };
assert!(metrics.throughput_tok_per_sec >= 0.0);
assert!(metrics.latency_p50_ms >= 0.0);
assert!(metrics.latency_p95_ms >= 0.0);
assert!(metrics.latency_p99_ms >= 0.0);
assert!(metrics.gpu_utilization_percent <= 100);
assert!(metrics.batch_size >= 1);
assert!(!metrics.model_name.is_empty());
}
#[tokio::test]
async fn test_tokenize_endpoint() {
let app = create_test_app_shared();
let request = TokenizeRequest {
text: "token1 token2".to_string(),
model_id: None,
};
let response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/tokenize")
.header("content-type", "application/json")
.body(Body::from(serde_json::to_string(&request).expect("test")))
.expect("test"),
)
.await
.expect("test");
assert!(
response.status() == StatusCode::OK
|| response.status() == StatusCode::NOT_FOUND
|| response.status() == StatusCode::INTERNAL_SERVER_ERROR
|| response.status() == StatusCode::SERVICE_UNAVAILABLE
|| response.status() == StatusCode::UNPROCESSABLE_ENTITY
);
if response.status() != StatusCode::OK {
return;
}
let body = axum::body::to_bytes(response.into_body(), usize::MAX)
.await
.expect("test");
let result: TokenizeResponse = match serde_json::from_slice(&body) {
Ok(v) => v,
Err(_) => return, };
assert!(result.num_tokens > 0);
}
#[tokio::test]
async fn test_generate_endpoint() {
let app = create_test_app_shared();
let request = GenerateRequest {
prompt: "token1".to_string(),
max_tokens: 3,
temperature: 1.0,
strategy: "greedy".to_string(),
top_k: 50,
top_p: 0.9,
seed: Some(42),
model_id: None,
};
let response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/generate")
.header("content-type", "application/json")
.body(Body::from(serde_json::to_string(&request).expect("test")))
.expect("test"),
)
.await
.expect("test");
assert!(
response.status() == StatusCode::OK
|| response.status() == StatusCode::NOT_FOUND
|| response.status() == StatusCode::INTERNAL_SERVER_ERROR
|| response.status() == StatusCode::SERVICE_UNAVAILABLE
|| response.status() == StatusCode::UNPROCESSABLE_ENTITY
);
if response.status() != StatusCode::OK {
return;
}
let body = axum::body::to_bytes(response.into_body(), usize::MAX)
.await
.expect("test");
let result: GenerateResponse = match serde_json::from_slice(&body) {
Ok(v) => v,
Err(_) => return, };
assert!(!result.token_ids.is_empty());
}
#[tokio::test]
async fn test_generate_empty_prompt_error() {
let app = create_test_app_shared();
let request = GenerateRequest {
prompt: String::new(),
max_tokens: 3,
temperature: 1.0,
strategy: "greedy".to_string(),
top_k: 50,
top_p: 0.9,
seed: None,
model_id: None,
};
let response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/generate")
.header("content-type", "application/json")
.body(Body::from(serde_json::to_string(&request).expect("test")))
.expect("test"),
)
.await
.expect("test");
assert!(
response.status() == StatusCode::BAD_REQUEST
|| response.status() == StatusCode::NOT_FOUND
|| response.status() == StatusCode::INTERNAL_SERVER_ERROR
|| response.status() == StatusCode::SERVICE_UNAVAILABLE
|| response.status() == StatusCode::UNPROCESSABLE_ENTITY
);
}
#[tokio::test]
async fn test_generate_invalid_strategy_error() {
let app = create_test_app_shared();
let request = GenerateRequest {
prompt: "token1".to_string(),
max_tokens: 3,
temperature: 1.0,
strategy: "invalid".to_string(),
top_k: 50,
top_p: 0.9,
seed: None,
model_id: None,
};
let response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/generate")
.header("content-type", "application/json")
.body(Body::from(serde_json::to_string(&request).expect("test")))
.expect("test"),
)
.await
.expect("test");
assert!(
response.status() == StatusCode::BAD_REQUEST
|| response.status() == StatusCode::NOT_FOUND
|| response.status() == StatusCode::INTERNAL_SERVER_ERROR
|| response.status() == StatusCode::SERVICE_UNAVAILABLE
|| response.status() == StatusCode::UNPROCESSABLE_ENTITY
);
}
#[tokio::test]
async fn test_generate_top_k_strategy() {
let app = create_test_app_shared();
let request = GenerateRequest {
prompt: "token1".to_string(),
max_tokens: 2,
temperature: 0.8,
strategy: "top_k".to_string(),
top_k: 5,
top_p: 0.9,
seed: Some(123),
model_id: None,
};
let response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/generate")
.header("content-type", "application/json")
.body(Body::from(serde_json::to_string(&request).expect("test")))
.expect("test"),
)
.await
.expect("test");
assert!(
response.status() == StatusCode::OK
|| response.status() == StatusCode::NOT_FOUND
|| response.status() == StatusCode::INTERNAL_SERVER_ERROR
|| response.status() == StatusCode::SERVICE_UNAVAILABLE
|| response.status() == StatusCode::UNPROCESSABLE_ENTITY
);
}
#[tokio::test]
async fn test_generate_top_p_strategy() {
let app = create_test_app_shared();
let request = GenerateRequest {
prompt: "token1".to_string(),
max_tokens: 2,
temperature: 0.7,
strategy: "top_p".to_string(),
top_k: 50,
top_p: 0.9,
seed: Some(456),
model_id: None,
};
let response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/generate")
.header("content-type", "application/json")
.body(Body::from(serde_json::to_string(&request).expect("test")))
.expect("test"),
)
.await
.expect("test");
assert!(
response.status() == StatusCode::OK
|| response.status() == StatusCode::NOT_FOUND
|| response.status() == StatusCode::INTERNAL_SERVER_ERROR
|| response.status() == StatusCode::SERVICE_UNAVAILABLE
|| response.status() == StatusCode::UNPROCESSABLE_ENTITY
);
}
include!("app_state_default.rs");
include!("batch_generate.rs");
include!("chat_completion_02.rs");
include!("apr_audit.rs");