use axum::{
body::Body,
http::{Request, StatusCode},
};
use tower::util::ServiceExt;
use crate::api::test_helpers::create_test_app_shared;
#[tokio::test]
async fn test_gpu_warmup_endpoint() {
let app = create_test_app_shared();
let request = Request::builder()
.method("POST")
.uri("/v1/gpu/warmup")
.header("content-type", "application/json")
.body(Body::from("{}"))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
assert!(
response.status() == StatusCode::OK || response.status() == StatusCode::SERVICE_UNAVAILABLE,
"GPU warmup should return OK or SERVICE_UNAVAILABLE"
);
}
#[tokio::test]
async fn test_gpu_status_endpoint() {
let app = create_test_app_shared();
let request = Request::builder()
.method("GET")
.uri("/v1/gpu/status")
.body(Body::empty())
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
assert!(
response.status() == StatusCode::OK || response.status() == StatusCode::SERVICE_UNAVAILABLE,
"GPU status should return OK or SERVICE_UNAVAILABLE"
);
}
#[tokio::test]
async fn test_gpu_batch_completions_endpoint() {
let app = create_test_app_shared();
let body = serde_json::json!({
"prompts": ["Hello", "World"],
"max_tokens": 10
});
let request = Request::builder()
.method("POST")
.uri("/v1/batch/completions")
.header("content-type", "application/json")
.body(Body::from(body.to_string()))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
assert!(
response.status() == StatusCode::OK || response.status() == StatusCode::SERVICE_UNAVAILABLE,
"Batch completions should return OK or SERVICE_UNAVAILABLE, got {:?}",
response.status()
);
}
#[tokio::test]
async fn test_openai_models_endpoint() {
let app = create_test_app_shared();
let request = Request::builder()
.method("GET")
.uri("/v1/models")
.body(Body::empty())
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
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_openai_completions_endpoint() {
let app = create_test_app_shared();
let body = serde_json::json!({
"model": "default",
"prompt": "Hello",
"max_tokens": 5
});
let request = Request::builder()
.method("POST")
.uri("/v1/completions")
.header("content-type", "application/json")
.body(Body::from(body.to_string()))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
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_openai_chat_completions_endpoint() {
let app = create_test_app_shared();
let body = serde_json::json!({
"model": "default",
"messages": [{"role": "user", "content": "Hello"}],
"max_tokens": 5
});
let request = Request::builder()
.method("POST")
.uri("/v1/chat/completions")
.header("content-type", "application/json")
.body(Body::from(body.to_string()))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
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_openai_embeddings_endpoint() {
let app = create_test_app_shared();
let body = serde_json::json!({
"model": "default",
"input": "Hello world"
});
let request = Request::builder()
.method("POST")
.uri("/v1/embeddings")
.header("content-type", "application/json")
.body(Body::from(body.to_string()))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
if response.status() != StatusCode::OK && response.status() != StatusCode::NOT_IMPLEMENTED {
return; }
}
#[tokio::test]
async fn test_apr_predict_endpoint() {
let app = create_test_app_shared();
let body = serde_json::json!({
"features": [1.0, 2.0, 3.0, 4.0],
"include_confidence": true
});
let request = Request::builder()
.method("POST")
.uri("/v1/predict")
.header("content-type", "application/json")
.body(Body::from(body.to_string()))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
let status = response.status();
if status != StatusCode::OK
&& status != StatusCode::BAD_REQUEST
&& status != StatusCode::UNPROCESSABLE_ENTITY
&& status != StatusCode::NOT_IMPLEMENTED
{
return; }
}
#[tokio::test]
async fn explain_rejects_request_without_feature_names() {
let app = create_test_app_shared();
let body = serde_json::json!({
"features": [1.0, 2.0, 3.0, 4.0],
"method": "shap"
});
let request = Request::builder()
.method("POST")
.uri("/v1/explain")
.header("content-type", "application/json")
.body(Body::from(body.to_string()))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
assert_eq!(
response.status(),
StatusCode::UNPROCESSABLE_ENTITY,
"a body omitting the required `feature_names` must be refused by the extractor"
);
}
#[tokio::test]
async fn test_apr_audit_endpoint() {
let app = create_test_app_shared();
let request = Request::builder()
.method("GET")
.uri("/v1/audit:test-request-123")
.body(Body::empty())
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
assert!(
response.status() == StatusCode::OK || response.status() == StatusCode::NOT_FOUND,
"Audit should return OK or NOT_FOUND"
);
}
#[tokio::test]
async fn test_realize_embed_endpoint() {
let app = create_test_app_shared();
let body = serde_json::json!({
"text": "Hello world",
"model": "default"
});
let request = Request::builder()
.method("POST")
.uri("/realize/embed")
.header("content-type", "application/json")
.body(Body::from(body.to_string()))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
let status = response.status();
assert!(
status.is_success() || status.is_client_error() || status.is_server_error(),
"Embed should return a valid HTTP status"
);
}
#[tokio::test]
async fn test_realize_model_endpoint() {
let app = create_test_app_shared();
let request = Request::builder()
.method("GET")
.uri("/realize/model")
.body(Body::empty())
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
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_realize_reload_endpoint() {
let app = create_test_app_shared();
let body = serde_json::json!({});
let request = Request::builder()
.method("POST")
.uri("/realize/reload")
.header("content-type", "application/json")
.body(Body::from(body.to_string()))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
assert!(
response.status() == StatusCode::OK
|| response.status() == StatusCode::NOT_FOUND
|| response.status() == StatusCode::NOT_IMPLEMENTED
|| response.status() == StatusCode::BAD_REQUEST,
"Reload should return OK, NOT_IMPLEMENTED, or BAD_REQUEST"
);
}
#[tokio::test]
async fn test_gpu_warmup_invalid_json() {
let app = create_test_app_shared();
let request = Request::builder()
.method("POST")
.uri("/v1/gpu/warmup")
.header("content-type", "application/json")
.body(Body::from("not valid json"))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
let status = response.status();
assert!(
status.is_client_error() || status.is_server_error(),
"Invalid JSON should return 4xx or 5xx, got {:?}",
status
);
}
#[tokio::test]
async fn test_openai_completions_missing_prompt() {
let app = create_test_app_shared();
let body = serde_json::json!({
"model": "default",
"max_tokens": 5
});
let request = Request::builder()
.method("POST")
.uri("/v1/completions")
.header("content-type", "application/json")
.body(Body::from(body.to_string()))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
let status = response.status();
assert!(
status.is_success() || status.is_client_error(),
"Missing prompt should return 2xx or 4xx, got {:?}",
status
);
}
#[tokio::test]
async fn test_apr_predict_empty_features() {
let app = create_test_app_shared();
let body = serde_json::json!({
"features": [],
"include_confidence": true
});
let request = Request::builder()
.method("POST")
.uri("/v1/predict")
.header("content-type", "application/json")
.body(Body::from(body.to_string()))
.expect("test value should be present");
let response = app.oneshot(request).await.expect("test value should be present");
assert!(
response.status() == StatusCode::OK || response.status() == StatusCode::BAD_REQUEST,
"Empty features should be handled gracefully"
);
}