#[allow(unused_imports)]
use axum::{
body::Body,
http::{Request, StatusCode},
};
#[allow(unused_imports)]
use tower::util::ServiceExt;
#[allow(unused_imports)]
use crate::api::test_helpers::create_test_app_shared;
use crate::api::*;
#[test]
fn test_imp_134c_json_response_includes_min_max() {
use crate::gguf::DispatchMetrics;
use std::sync::Arc;
use std::time::Duration;
let metrics = Arc::new(DispatchMetrics::new());
metrics.record_cpu_latency(Duration::from_micros(100));
metrics.record_cpu_latency(Duration::from_micros(500));
let response = DispatchMetricsResponse {
cpu_dispatches: 0,
gpu_dispatches: 0,
total_dispatches: 0,
gpu_ratio: 0.0,
cpu_latency_p50_us: 0.0,
cpu_latency_p95_us: 0.0,
cpu_latency_p99_us: 0.0,
gpu_latency_p50_us: 0.0,
gpu_latency_p95_us: 0.0,
gpu_latency_p99_us: 0.0,
cpu_latency_mean_us: 0.0,
gpu_latency_mean_us: 0.0,
cpu_latency_min_us: metrics.cpu_latency_min_us(),
cpu_latency_max_us: metrics.cpu_latency_max_us(),
gpu_latency_min_us: metrics.gpu_latency_min_us(),
gpu_latency_max_us: metrics.gpu_latency_max_us(),
cpu_latency_variance_us: 0.0,
cpu_latency_stddev_us: 0.0,
gpu_latency_variance_us: 0.0,
gpu_latency_stddev_us: 0.0,
bucket_boundaries_us: vec![],
cpu_latency_bucket_counts: vec![],
gpu_latency_bucket_counts: vec![],
throughput_rps: 0.0,
elapsed_seconds: 0.0,
};
assert_eq!(
response.cpu_latency_min_us, 100,
"IMP-134c: Response CPU min should be 100µs"
);
assert_eq!(
response.cpu_latency_max_us, 500,
"IMP-134c: Response CPU max should be 500µs"
);
}
#[test]
fn test_imp_134d_min_max_single_sample() {
use crate::gguf::DispatchMetrics;
use std::time::Duration;
let metrics = DispatchMetrics::new();
metrics.record_cpu_latency(Duration::from_micros(42));
assert_eq!(
metrics.cpu_latency_min_us(),
42,
"IMP-134d: Min of single sample should be 42µs"
);
assert_eq!(
metrics.cpu_latency_max_us(),
42,
"IMP-134d: Max of single sample should be 42µs"
);
}
#[test]
fn test_imp_135a_dispatch_metrics_has_variance_stddev_methods() {
use crate::gguf::DispatchMetrics;
use std::time::Duration;
let metrics = DispatchMetrics::new();
metrics.record_cpu_latency(Duration::from_micros(100));
metrics.record_cpu_latency(Duration::from_micros(200));
metrics.record_cpu_latency(Duration::from_micros(300));
let cpu_var = metrics.cpu_latency_variance_us();
let cpu_std = metrics.cpu_latency_stddev_us();
assert!(
(cpu_var - 6666.67).abs() < 1.0,
"IMP-135a: CPU variance should be ~6666.67, got {}",
cpu_var
);
assert!(
(cpu_std - 81.65).abs() < 1.0,
"IMP-135a: CPU stddev should be ~81.65, got {}",
cpu_std
);
}
#[test]
fn test_imp_135b_variance_zero_edge_cases() {
use crate::gguf::DispatchMetrics;
use std::time::Duration;
let metrics = DispatchMetrics::new();
assert_eq!(
metrics.cpu_latency_variance_us(),
0.0,
"IMP-135b: CPU variance should be 0 when empty"
);
assert_eq!(
metrics.cpu_latency_stddev_us(),
0.0,
"IMP-135b: CPU stddev should be 0 when empty"
);
metrics.record_cpu_latency(Duration::from_micros(100));
assert_eq!(
metrics.cpu_latency_variance_us(),
0.0,
"IMP-135b: CPU variance should be 0 for single sample"
);
assert_eq!(
metrics.cpu_latency_stddev_us(),
0.0,
"IMP-135b: CPU stddev should be 0 for single sample"
);
}
#[test]
fn test_imp_135c_json_response_includes_variance_stddev() {
use crate::gguf::DispatchMetrics;
use std::sync::Arc;
use std::time::Duration;
let metrics = Arc::new(DispatchMetrics::new());
metrics.record_cpu_latency(Duration::from_micros(100));
metrics.record_cpu_latency(Duration::from_micros(200));
metrics.record_cpu_latency(Duration::from_micros(300));
let response = DispatchMetricsResponse {
cpu_dispatches: 0,
gpu_dispatches: 0,
total_dispatches: 0,
gpu_ratio: 0.0,
cpu_latency_p50_us: 0.0,
cpu_latency_p95_us: 0.0,
cpu_latency_p99_us: 0.0,
gpu_latency_p50_us: 0.0,
gpu_latency_p95_us: 0.0,
gpu_latency_p99_us: 0.0,
cpu_latency_mean_us: 0.0,
gpu_latency_mean_us: 0.0,
cpu_latency_min_us: 0,
cpu_latency_max_us: 0,
gpu_latency_min_us: 0,
gpu_latency_max_us: 0,
cpu_latency_variance_us: metrics.cpu_latency_variance_us(),
cpu_latency_stddev_us: metrics.cpu_latency_stddev_us(),
gpu_latency_variance_us: metrics.gpu_latency_variance_us(),
gpu_latency_stddev_us: metrics.gpu_latency_stddev_us(),
bucket_boundaries_us: vec![],
cpu_latency_bucket_counts: vec![],
gpu_latency_bucket_counts: vec![],
throughput_rps: 0.0,
elapsed_seconds: 0.0,
};
assert!(
(response.cpu_latency_variance_us - 6666.67).abs() < 1.0,
"IMP-135c: Response CPU variance should be ~6666.67"
);
assert!(
response.cpu_latency_stddev_us > 80.0,
"IMP-135c: Response CPU stddev should be > 80"
);
}
#[test]
fn test_imp_135d_gpu_variance_stddev() {
use crate::gguf::DispatchMetrics;
use std::time::Duration;
let metrics = DispatchMetrics::new();
metrics.record_gpu_latency(Duration::from_micros(500));
metrics.record_gpu_latency(Duration::from_micros(1000));
metrics.record_gpu_latency(Duration::from_micros(1500));
let gpu_var = metrics.gpu_latency_variance_us();
let gpu_std = metrics.gpu_latency_stddev_us();
assert!(
(gpu_var - 166666.67).abs() < 1.0,
"IMP-135d: GPU variance should be ~166666.67, got {}",
gpu_var
);
assert!(
(gpu_std - 408.25).abs() < 1.0,
"IMP-135d: GPU stddev should be ~408.25, got {}",
gpu_std
);
}
#[test]
fn test_imp_136a_dispatch_metrics_exposes_bucket_boundaries() {
use crate::gguf::DispatchMetrics;
let boundaries = DispatchMetrics::BUCKET_BOUNDARIES;
assert_eq!(
boundaries.len(),
4,
"IMP-136a: Should have 4 bucket boundaries for 5 buckets"
);
assert_eq!(
boundaries[0], 100,
"IMP-136a: Bucket 0 upper bound should be 100µs"
);
assert_eq!(
boundaries[1], 500,
"IMP-136a: Bucket 1 upper bound should be 500µs"
);
assert_eq!(
boundaries[2], 1000,
"IMP-136a: Bucket 2 upper bound should be 1000µs"
);
assert_eq!(
boundaries[3], 5000,
"IMP-136a: Bucket 3 upper bound should be 5000µs"
);
}
#[test]
fn test_imp_136b_bucket_boundaries_method() {
use crate::gguf::DispatchMetrics;
let metrics = DispatchMetrics::new();
let boundaries = metrics.bucket_boundaries_us();
assert_eq!(
boundaries.len(),
5,
"IMP-136b: Should have 5 bucket boundary strings"
);
assert_eq!(boundaries[0], "0-100", "IMP-136b: Bucket 0 range");
assert_eq!(boundaries[1], "100-500", "IMP-136b: Bucket 1 range");
assert_eq!(boundaries[2], "500-1000", "IMP-136b: Bucket 2 range");
assert_eq!(boundaries[3], "1000-5000", "IMP-136b: Bucket 3 range");
assert_eq!(
boundaries[4], "5000+",
"IMP-136b: Bucket 4 range (unbounded)"
);
}
#[test]
fn test_imp_136c_json_response_includes_bucket_boundaries() {
let response = DispatchMetricsResponse {
cpu_dispatches: 0,
gpu_dispatches: 0,
total_dispatches: 0,
gpu_ratio: 0.0,
cpu_latency_p50_us: 0.0,
cpu_latency_p95_us: 0.0,
cpu_latency_p99_us: 0.0,
gpu_latency_p50_us: 0.0,
gpu_latency_p95_us: 0.0,
gpu_latency_p99_us: 0.0,
cpu_latency_mean_us: 0.0,
gpu_latency_mean_us: 0.0,
cpu_latency_min_us: 0,
cpu_latency_max_us: 0,
gpu_latency_min_us: 0,
gpu_latency_max_us: 0,
cpu_latency_variance_us: 0.0,
cpu_latency_stddev_us: 0.0,
gpu_latency_variance_us: 0.0,
gpu_latency_stddev_us: 0.0,
bucket_boundaries_us: vec![
"0-100".to_string(),
"100-500".to_string(),
"500-1000".to_string(),
"1000-5000".to_string(),
"5000+".to_string(),
],
cpu_latency_bucket_counts: vec![0, 0, 0, 0, 0],
gpu_latency_bucket_counts: vec![0, 0, 0, 0, 0],
throughput_rps: 0.0,
elapsed_seconds: 0.0,
};
let json = serde_json::to_string(&response).expect("IMP-136c: Should serialize");
assert!(
json.contains("bucket_boundaries_us"),
"IMP-136c: JSON should contain bucket_boundaries_us field"
);
assert!(
json.contains("0-100"),
"IMP-136c: JSON should contain bucket range '0-100'"
);
}
#[test]
fn test_imp_136d_response_includes_bucket_counts() {
use crate::gguf::DispatchMetrics;
use std::sync::Arc;
use std::time::Duration;
let metrics = Arc::new(DispatchMetrics::new());
metrics.record_cpu_latency(Duration::from_micros(50)); metrics.record_cpu_latency(Duration::from_micros(200)); metrics.record_cpu_latency(Duration::from_micros(750));
let response = DispatchMetricsResponse {
cpu_dispatches: 0,
gpu_dispatches: 0,
total_dispatches: 0,
gpu_ratio: 0.0,
cpu_latency_p50_us: 0.0,
cpu_latency_p95_us: 0.0,
cpu_latency_p99_us: 0.0,
gpu_latency_p50_us: 0.0,
gpu_latency_p95_us: 0.0,
gpu_latency_p99_us: 0.0,
cpu_latency_mean_us: 0.0,
gpu_latency_mean_us: 0.0,
cpu_latency_min_us: 0,
cpu_latency_max_us: 0,
gpu_latency_min_us: 0,
gpu_latency_max_us: 0,
cpu_latency_variance_us: 0.0,
cpu_latency_stddev_us: 0.0,
gpu_latency_variance_us: 0.0,
gpu_latency_stddev_us: 0.0,
bucket_boundaries_us: metrics.bucket_boundaries_us(),
cpu_latency_bucket_counts: metrics.cpu_latency_buckets().to_vec(),
gpu_latency_bucket_counts: metrics.gpu_latency_buckets().to_vec(),
throughput_rps: 0.0,
elapsed_seconds: 0.0,
};
assert_eq!(
response.cpu_latency_bucket_counts[0], 1,
"IMP-136d: Bucket 0 should have 1 sample"
);
assert_eq!(
response.cpu_latency_bucket_counts[1], 1,
"IMP-136d: Bucket 1 should have 1 sample"
);
assert_eq!(
response.cpu_latency_bucket_counts[2], 1,
"IMP-136d: Bucket 2 should have 1 sample"
);
}
include!("imp_137a.rs");
include!("imp_140c.rs");
include!("chat_completion_03.rs");
include!("chat_completion_02_02.rs");