#[test]
#[ignore = "wall-time perf SLA — flaky under CI contention; run --ignored to verify"]
fn test_qa_011_throughput_regression_detection() {
use std::time::Instant;
let layer_norm = LayerNorm::new(256, 1e-5).expect("test");
let input = Tensor::from_vec(vec![32, 256], vec![0.1; 32 * 256]).expect("test");
let warmup_iterations = 50;
for _ in 0..warmup_iterations {
let _ = layer_norm.forward(&input).expect("test");
}
let iterations = 100;
let mut baseline_times = Vec::with_capacity(5);
for _ in 0..5 {
let start = Instant::now();
for _ in 0..iterations {
let _ = layer_norm.forward(&input).expect("test");
}
baseline_times.push(start.elapsed().as_secs_f64());
}
baseline_times.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
let baseline_time = baseline_times[2];
let mut current_times = Vec::with_capacity(5);
for _ in 0..5 {
let start = Instant::now();
for _ in 0..iterations {
let _ = layer_norm.forward(&input).expect("test");
}
current_times.push(start.elapsed().as_secs_f64());
}
current_times.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
let current_time = current_times[2];
let regression_threshold = 10.0;
let ratio = current_time / baseline_time;
assert!(
ratio < regression_threshold,
"QA-011: Throughput regression detected: {ratio:.2}x slower (threshold: {regression_threshold}x)",
);
}
#[test]
fn test_qa_013_memory_usage_bounded() {
let vocab_size = 1000;
let hidden_dim = 128;
let num_heads = 4;
let num_layers = 4;
let intermediate_dim = 512;
let config = ModelConfig {
vocab_size,
hidden_dim,
num_heads,
num_layers,
intermediate_dim,
eps: 1e-5,
};
let model = Model::new(config).expect("test");
let embedding_params = vocab_size * hidden_dim;
let layer_params = num_layers
* (hidden_dim * hidden_dim * 4 + hidden_dim * intermediate_dim * 2); let total_params = embedding_params + layer_params;
let model_size_bytes = total_params * 4;
let output = model.forward(&[1, 2, 3]).expect("test");
assert!(output.size() > 0, "QA-013: Model should produce output");
assert!(
model_size_bytes > 0,
"QA-013: Model has non-zero size: {} bytes",
model_size_bytes
);
}
#[test]
fn test_qa_014_compute_utilization() {
use std::time::Instant;
let layer_norm = LayerNorm::new(512, 1e-5).expect("test");
let input = Tensor::from_vec(vec![64, 512], vec![0.1; 64 * 512]).expect("test");
for _ in 0..10 {
let _ = layer_norm.forward(&input).expect("test");
}
let iterations = 50;
let start = Instant::now();
for _ in 0..iterations {
let _ = layer_norm.forward(&input).expect("test");
}
let elapsed = start.elapsed();
assert!(
elapsed.as_millis() < 5000,
"QA-014: Compute should be efficient, took {}ms for {} iterations",
elapsed.as_millis(),
iterations
);
}
#[test]
fn test_qa_016_cold_start_latency() {
use std::time::Instant;
let start = Instant::now();
let config = ModelConfig {
vocab_size: 5000,
hidden_dim: 256,
num_heads: 8,
num_layers: 6,
intermediate_dim: 1024,
eps: 1e-5,
};
let model = Model::new(config).expect("test");
let cold_start = start.elapsed();
assert!(
cold_start.as_secs() < 5,
"QA-016: Cold start took {}s, should be < 5s",
cold_start.as_secs_f64()
);
let output = model.forward(&[1]).expect("test");
assert!(output.size() > 0, "QA-016: Model should be functional");
}
#[test]
fn test_qa_018_batch_scaling() {
use std::time::Instant;
let layer_norm = LayerNorm::new(128, 1e-5).expect("test");
let single_input = Tensor::from_vec(vec![1, 128], vec![0.1; 128]).expect("test");
let iterations = 100;
let start = Instant::now();
for _ in 0..iterations {
let _ = layer_norm.forward(&single_input).expect("test");
}
let single_time = start.elapsed();
let batch_input = Tensor::from_vec(vec![8, 128], vec![0.1; 8 * 128]).expect("test");
let start = Instant::now();
for _ in 0..iterations {
let _ = layer_norm.forward(&batch_input).expect("test");
}
let batch_time = start.elapsed();
let ratio = batch_time.as_secs_f64() / single_time.as_secs_f64();
assert!(
ratio > 0.0 && ratio < 1000.0,
"QA-018: Batch=8 ratio ({:.2}x) should be in reasonable bounds",
ratio
);
}
#[test]
#[ignore = "Timing test unreliable - depends on system load"]
fn test_qa_020_context_scaling() {
use std::time::Instant;
let attention = Attention::new(32).expect("test");
let small_len = 16;
let small_q = Tensor::from_vec(vec![small_len, 32], vec![0.1; small_len * 32]).expect("test");
let small_k = small_q.clone();
let small_v = small_q.clone();
let start = Instant::now();
for _ in 0..50 {
let _ = attention
.forward(&small_q, &small_k, &small_v)
.expect("test");
}
let small_time = start.elapsed();
let large_len = 64;
let large_q = Tensor::from_vec(vec![large_len, 32], vec![0.1; large_len * 32]).expect("test");
let large_k = large_q.clone();
let large_v = large_q.clone();
let start = Instant::now();
for _ in 0..50 {
let _ = attention
.forward(&large_q, &large_k, &large_v)
.expect("test");
}
let large_time = start.elapsed();
let ratio = large_time.as_secs_f64() / small_time.as_secs_f64();
assert!(
ratio < 32.0,
"QA-020: 4x context took {:.2}x longer (should be < 32x for O(n^2))",
ratio
);
}
#[test]
fn test_qa_021_oom_handling() {
let result = Tensor::<f32>::from_vec(vec![10, 64], vec![0.0; 5]);
assert!(
result.is_err(),
"QA-021: Tensor with mismatched data/shape should fail gracefully"
);
let ln_result = LayerNorm::new(0, 1e-5);
assert!(
ln_result.is_err(),
"QA-021: LayerNorm with zero dim should fail gracefully"
);
let embed_result = Embedding::new(0, 64);
assert!(
embed_result.is_err(),
"QA-021: Embedding with zero vocab should fail gracefully"
);
}
#[test]
fn test_qa_022_timeout_recovery() {
use std::time::{Duration, Instant};
let layer_norm = LayerNorm::new(64, 1e-5).expect("test");
let input = Tensor::from_vec(vec![16, 64], vec![0.1; 16 * 64]).expect("test");
let timeout = Duration::from_secs(5);
let start = Instant::now();
for _ in 0..100 {
let result = layer_norm.forward(&input);
assert!(result.is_ok(), "QA-022: Operation should complete");
}
assert!(
start.elapsed() < timeout,
"QA-022: Operations should complete within timeout"
);
}
#[test]
fn test_qa_023_malformed_gguf() {
use crate::gguf::GGUFModel;
let empty_result = GGUFModel::from_bytes(&[]);
assert!(empty_result.is_err(), "QA-023: Empty GGUF should fail");
let garbage = vec![0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00];
let garbage_result = GGUFModel::from_bytes(&garbage);
assert!(garbage_result.is_err(), "QA-023: Garbage GGUF should fail");
let truncated = vec![0x47, 0x47, 0x55, 0x46]; let truncated_result = GGUFModel::from_bytes(&truncated);
assert!(
truncated_result.is_err(),
"QA-023: Truncated GGUF should fail"
);
}
#[test]
fn test_qa_024_truncated_files() {
use crate::safetensors::SafetensorsModel;
let empty_result = SafetensorsModel::from_bytes(&[]);
assert!(
empty_result.is_err(),
"QA-024: Empty safetensors should fail"
);
let truncated = vec![
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7B, 0x7D, ];
let truncated_result = SafetensorsModel::from_bytes(&truncated);
assert!(
truncated_result.is_err(),
"QA-024: Truncated safetensors should fail"
);
}
#[test]
fn test_qa_026_context_overflow() {
use crate::inference::KVCache;
let mut cache = KVCache::new(1, 32, 4);
for pos in 0..4 {
let k_data = vec![pos as f32; 32];
let v_data = vec![pos as f32; 32];
cache.store(0, &k_data, &v_data);
cache.advance();
}
let k_overflow = vec![99.0_f32; 32];
let v_overflow = vec![99.0_f32; 32];
cache.store(0, &k_overflow, &v_overflow);
let k = cache.get_k(0);
let v = cache.get_v(0);
assert!(!k.is_empty(), "QA-026: Cache should still be usable");
assert!(!v.is_empty(), "QA-026: Cache should still be usable");
}
#[test]
fn test_qa_028_thread_safety() {
use std::sync::Arc;
use std::thread;
let layer_norm = Arc::new(LayerNorm::new(64, 1e-5).expect("test"));
let handles: Vec<_> = (0..4)
.map(|i| {
let ln = Arc::clone(&layer_norm);
thread::spawn(move || {
let input =
Tensor::from_vec(vec![4, 64], vec![(i as f32) * 0.1; 4 * 64]).expect("test");
for _ in 0..10 {
let result = ln.forward(&input);
assert!(
result.is_ok(),
"QA-028: Thread {} inference should succeed",
i
);
}
})
})
.collect();
for handle in handles {
handle.join().expect("QA-028: Thread should not panic");
}
}