#![allow(clippy::all)]
use proptest::prelude::*;
use std::collections::{HashMap, HashSet};
use trustformers::core::tensor::Tensor;
use trustformers::tokenizers::TokenizerWrapper;
use trustformers::*;
#[cfg(test)]
mod fuzz_tests {
use super::*;
#[test]
fn fuzz_tensor_operations() {
fn tensor_ops_test(
shape: Vec<usize>,
data: Vec<f32>,
) -> std::result::Result<(), TestCaseError> {
if shape.is_empty() || shape.contains(&0) {
return Ok(()); }
let total_elements: usize = shape.iter().product();
if total_elements > 1_000_000 || data.len() != total_elements {
return Ok(()); }
let tensor = Tensor::from_slice(&data, &shape);
match tensor {
Ok(t) => {
let _ = t.shape();
let _ = t.data();
if let Ok(zeros) = Tensor::zeros(&shape) {
let _ = t.add(&zeros);
let _ = t.mul(&zeros);
}
if total_elements > 1 {
let _ = t.reshape(&[total_elements]);
}
},
Err(_) => {
},
}
Ok(())
}
proptest!(|(
shape in prop::collection::vec(1usize..100, 1..4),
data_multiplier in 0.0f32..1000.0f32,
)| {
let total_elements: usize = shape.iter().product();
let data: Vec<f32> = (0..total_elements)
.map(|i| (i as f32) * data_multiplier / 1000.0)
.collect();
tensor_ops_test(shape, data)?;
});
}
#[test]
fn fuzz_tokenizer_random_text() {
fn tokenize_test(text: String) -> std::result::Result<(), TestCaseError> {
let vocab = HashMap::new();
let merges = Vec::new();
let bpe_tokenizer = trustformers::tokenizers::bpe::BPETokenizer::new(vocab, merges);
let tokenizer = TokenizerWrapper::BPE(bpe_tokenizer);
match tokenizer.encode(&text) {
Ok(tokens) => {
prop_assert!(tokens.input_ids.len() <= text.len() * 2 + 10);
if let Ok(decoded) = tokenizer.decode(&tokens.input_ids) {
prop_assert!(decoded.len() <= text.len() * 3);
}
},
Err(_) => {
},
}
Ok(())
}
proptest!(|(text in ".*{0,1000}")| {
tokenize_test(text)?;
});
}
#[test]
fn fuzz_pipeline_config() {
fn config_test(
_device: String,
batch_size: usize,
max_length: usize,
_temperature: f32,
) -> std::result::Result<(), TestCaseError> {
use trustformers::pipeline::PipelineOptions;
let config = PipelineOptions {
device: None, batch_size: Some(batch_size),
max_length: Some(max_length),
..Default::default()
};
prop_assert!(config.batch_size.unwrap_or(1) > 0);
prop_assert!(config.max_length.unwrap_or(1) > 0);
prop_assert!(config.truncation || !config.truncation);
Ok(())
}
proptest!(|(
device in prop::sample::select(vec!["cpu", "cuda", "mps", "auto"]),
batch_size in 1usize..=128,
max_length in 1usize..=8192,
temperature in 0.0f32..=2.0f32,
)| {
config_test(device.to_string(), batch_size, max_length, temperature)?;
});
}
#[test]
fn fuzz_model_metadata() {
fn metadata_test(
metadata: HashMap<String, String>,
) -> std::result::Result<(), TestCaseError> {
let metadata_json = serde_json::to_string(&metadata);
match metadata_json {
Ok(json_str) => {
if let Ok(parsed_metadata) =
serde_json::from_str::<HashMap<String, String>>(&json_str)
{
prop_assert_eq!(metadata.len(), parsed_metadata.len());
}
},
Err(_) => {
},
}
Ok(())
}
proptest!(|(
metadata in prop::collection::hash_map(
"[a-zA-Z0-9_-]{1,50}", // Keys
".*{0,200}", // Values
0..20 // Size
)
)| {
metadata_test(metadata)?;
});
}
#[test]
fn fuzz_error_handling() {
fn error_test(
error_message: String,
_error_code: u32,
) -> std::result::Result<(), TestCaseError> {
let error = trustformers::error::TrustformersError::Pipeline {
message: error_message.clone(),
pipeline_type: "test-pipeline".to_string(),
suggestion: Some("test suggestion".to_string()),
recovery_actions: vec![],
};
let error_string = format!("{}", error);
prop_assert!(!error_string.is_empty());
let debug_string = format!("{:?}", error);
prop_assert!(!debug_string.is_empty());
Ok(())
}
proptest!(|(
error_message in ".*{0,500}",
error_code in 0u32..=10000u32,
)| {
error_test(error_message, error_code)?;
});
}
#[test]
fn fuzz_memory_operations() {
fn memory_test(
allocation_size: usize,
alignment: usize,
) -> std::result::Result<(), TestCaseError> {
if allocation_size > 1_000_000 || alignment == 0 || !alignment.is_power_of_two() {
return Ok(());
}
use trustformers::memory_pool::{MemoryPool, MemoryPoolConfig};
let config = MemoryPoolConfig {
initial_size: allocation_size * 2,
max_size: allocation_size * 10,
alignment: 8,
..Default::default()
};
if let Ok(pool) = MemoryPool::new(config) {
if let Ok(memory) = pool.allocate(allocation_size) {
let _ = pool.deallocate(memory);
}
}
Ok(())
}
proptest!(|(
allocation_size in 1usize..=100_000,
alignment_exp in 0u8..=10,
)| {
let alignment = 1usize << alignment_exp;
memory_test(allocation_size, alignment)?;
});
}
#[test]
fn fuzz_hub_operations() {
fn hub_test(
model_id: String,
revision: Option<String>,
) -> std::result::Result<(), TestCaseError> {
use trustformers::hub::is_cached;
let _is_cached = is_cached(&model_id, revision.as_deref()).unwrap_or(false);
Ok(())
}
proptest!(|(
model_id in "[a-zA-Z0-9/_-]{1,100}",
revision in prop::option::of("[a-zA-Z0-9._-]{0,50}"),
)| {
hub_test(model_id, revision)?;
});
}
#[test]
fn fuzz_config_validation() {
fn config_validation_test(
learning_rate: f64,
batch_size: i32,
max_steps: i64,
) -> std::result::Result<(), TestCaseError> {
use trustformers::config_management::ConfigValidator;
let mut config = HashMap::new();
config.insert("learning_rate".to_string(), learning_rate.to_string());
config.insert("batch_size".to_string(), batch_size.to_string());
config.insert("max_steps".to_string(), max_steps.to_string());
let validator = ConfigValidator::new();
let config_value = serde_json::to_value(&config).expect("operation failed in test");
let schema = trustformers::config_management::ConfigSchema {
name: "test_schema".to_string(),
version: "1.0".to_string(),
description: "Test schema for fuzzing".to_string(),
fields: HashMap::new(),
required_fields: HashSet::new(),
conditional_requirements: Vec::new(),
};
let _result = validator.validate(&config_value, &schema);
Ok(())
}
proptest!(|(
learning_rate in -1.0f64..=1.0f64,
batch_size in -100i32..=1000i32,
max_steps in -1000i64..=100000i64,
)| {
config_validation_test(learning_rate, batch_size, max_steps)?;
});
}
#[test]
fn fuzz_streaming_operations() {
fn streaming_test(
chunk_size: usize,
buffer_size: usize,
timeout_ms: u64,
) -> std::result::Result<(), TestCaseError> {
use trustformers::pipeline::streaming::StreamConfig;
if chunk_size == 0 || buffer_size == 0 || timeout_ms > 60000 {
return Ok(());
}
let config = StreamConfig {
buffer_size,
max_concurrent: 4,
backpressure_threshold: 0.8,
timeout_ms,
enable_partial_results: true,
enable_transformations: true,
batch_size: Some(chunk_size),
flush_interval_ms: 100,
};
prop_assert!(config.buffer_size > 0);
prop_assert!(config.batch_size.unwrap_or(0) > 0);
prop_assert!(
config.backpressure_threshold >= 0.0 && config.backpressure_threshold <= 1.0
);
Ok(())
}
proptest!(|(
chunk_size in 1usize..=10000,
buffer_size in 1usize..=10000,
timeout_ms in 1u64..=5000,
)| {
streaming_test(chunk_size, buffer_size, timeout_ms)?;
});
}
}
#[cfg(test)]
mod regression_fuzz_tests {
use super::*;
#[test]
fn fuzz_empty_inputs() {
let empty_text = "";
let empty_vec: Vec<f32> = vec![];
let _empty_shape: Vec<usize> = vec![];
let vocab = HashMap::new();
let merges = Vec::new();
let bpe_tokenizer = trustformers::tokenizers::bpe::BPETokenizer::new(vocab, merges);
let tokenizer = TokenizerWrapper::BPE(bpe_tokenizer);
{
let _result = tokenizer.encode(empty_text);
}
let _tensor_result = Tensor::from_slice(&empty_vec, &[0]);
let empty_config: HashMap<String, String> = HashMap::new();
let _json_result = serde_json::to_string(&empty_config);
}
#[test]
fn fuzz_unicode_inputs() {
let long_text = "a".repeat(10000);
let unicode_texts = vec![
"Hello, 世界!",
"🦀 Rust is great! 🚀",
"Здравствуй мир",
"مرحبا بالعالم",
"नमस्ते दुनिया",
"こんにちは世界",
"",
"\n\t\r",
&long_text,
];
for text in unicode_texts {
let vocab = HashMap::new();
let merges = Vec::new();
let bpe_tokenizer = trustformers::tokenizers::bpe::BPETokenizer::new(vocab, merges);
let tokenizer = TokenizerWrapper::BPE(bpe_tokenizer);
let _result = tokenizer.encode(text);
let error = trustformers::error::TrustformersError::Pipeline {
message: text.to_string(),
pipeline_type: "test-pipeline".to_string(),
suggestion: Some("test suggestion".to_string()),
recovery_actions: vec![],
};
let _formatted = format!("{}", error);
}
}
#[test]
fn fuzz_numerical_edge_cases() {
let edge_values = vec![
f32::INFINITY,
f32::NEG_INFINITY,
f32::NAN,
f32::MIN,
f32::MAX,
0.0,
-0.0,
f32::EPSILON,
1.0,
-1.0,
];
for value in edge_values {
let data = vec![value; 10];
let _tensor_result = Tensor::from_slice(&data, &[2, 5]);
let mut config = HashMap::new();
config.insert("temperature".to_string(), value.to_string());
let _json_result = serde_json::to_string(&config);
}
}
}
#[cfg(test)]
mod performance_fuzz_tests {
use super::*;
use std::time::{Duration, Instant};
#[test]
fn fuzz_performance_bounds() {
proptest!(|(
size in 1usize..=1000,
iterations in 1usize..=100,
)| {
let start = Instant::now();
for _ in 0..iterations {
let data: Vec<f32> = (0..size).map(|i| i as f32).collect();
if let Ok(tensor) = Tensor::from_slice(&data, &[size]) {
let _ = tensor.data();
let _ = tensor.shape();
}
}
let elapsed = start.elapsed();
prop_assert!(elapsed < Duration::from_secs(10), "Operations took too long: {:?}", elapsed);
});
}
#[test]
fn fuzz_memory_bounds() {
use std::alloc::{GlobalAlloc, Layout, System};
proptest!(|(
allocation_count in 1usize..=100,
allocation_size in 1usize..=1000,
)| {
let mut allocations = Vec::new();
for _ in 0..allocation_count {
if let Ok(layout) = Layout::array::<u8>(allocation_size) {
let ptr = unsafe { System.alloc(layout) };
if !ptr.is_null() {
allocations.push((ptr, layout));
}
}
}
for (ptr, layout) in allocations {
unsafe { System.dealloc(ptr, layout) };
}
prop_assert!(true); });
}
}