#![deny(unsafe_code)]
#![deny(missing_docs)]
#![deny(clippy::unwrap_used)]
#![deny(clippy::panic)]
use crate::prelude::error::{LatticeArcError, Result};
pub struct UtilityMemorySafetyTester;
impl Default for UtilityMemorySafetyTester {
fn default() -> Self {
Self::new()
}
}
impl UtilityMemorySafetyTester {
#[must_use]
pub fn new() -> Self {
Self {}
}
pub fn test_memory_safety_succeeds(&self) -> Result<()> {
tracing::info!("Testing utility memory safety");
let invalid_hex = ["g", "gg", "invalid", "z", "G", "xyz", "123", "abcdefg"];
for &hex_str in &invalid_hex {
let result = hex::decode(hex_str);
if result.is_ok() {
return Err(LatticeArcError::ValidationError {
message: format!("Hex string '{}' should be invalid", hex_str),
});
}
}
if hex::decode("").is_err() {
return Err(LatticeArcError::ValidationError {
message: "Empty hex string should be valid".to_string(),
});
}
for _ in 0..100 {
let uuid = uuid::Uuid::new_v4();
if uuid.is_nil() {
return Err(LatticeArcError::ValidationError {
message: "UUID should not be nil".to_string(),
});
}
let uuid_str = uuid.to_string();
if uuid_str.len() != 36 {
return Err(LatticeArcError::ValidationError {
message: format!("UUID string should be 36 chars, got {}", uuid_str.len()),
});
}
}
let test_errors = vec![
LatticeArcError::InvalidInput("test".to_string()),
LatticeArcError::IoError(
std::io::Error::new(std::io::ErrorKind::NotFound, "test").to_string(),
),
];
for error in test_errors {
let _display = format!("{}", error);
let _debug = format!("{:?}", error);
}
tracing::info!("Utility memory safety tests passed");
Ok(())
}
pub fn test_hex_memory_safety_succeeds(&self) -> Result<()> {
let invalid_hex = ["g", "gg", "invalid", "z", "G", "xyz", "123", "abcdefg"];
for &hex_str in &invalid_hex {
let result = hex::decode(hex_str);
if result.is_ok() {
return Err(LatticeArcError::ValidationError {
message: format!("Hex string '{}' should be invalid", hex_str),
});
}
}
if hex::decode("").is_err() {
return Err(LatticeArcError::ValidationError {
message: "Empty hex string should be valid".to_string(),
});
}
Ok(())
}
pub fn test_uuid_memory_safety_succeeds(&self) -> Result<()> {
for _ in 0..100 {
let uuid = uuid::Uuid::new_v4();
if uuid.is_nil() {
return Err(LatticeArcError::ValidationError {
message: "UUID should not be nil".to_string(),
});
}
if uuid.get_version_num() != 4 {
return Err(LatticeArcError::ValidationError {
message: format!("UUID version should be 4, got {}", uuid.get_version_num()),
});
}
let uuid_str = uuid.to_string();
if uuid_str.len() != 36 {
return Err(LatticeArcError::ValidationError {
message: format!("UUID string should be 36 chars, got {}", uuid_str.len()),
});
}
let parsed = uuid::Uuid::parse_str(&uuid_str)?;
if parsed != uuid {
return Err(LatticeArcError::ValidationError {
message: "Parsed UUID should match original".to_string(),
});
}
}
Ok(())
}
pub fn test_error_memory_safety_fails(&self) -> Result<()> {
let errors = vec![
LatticeArcError::InvalidInput("test".to_string()),
LatticeArcError::NetworkError("connection failed".to_string()),
LatticeArcError::IoError("file not found".to_string()),
LatticeArcError::EncryptionError("cipher failed".to_string()),
];
for error in errors {
let json = serde_json::to_string(&error)?;
let deserialized: LatticeArcError = serde_json::from_str(&json)?;
if error != deserialized {
return Err(LatticeArcError::ValidationError {
message: "Deserialized error should match original".to_string(),
});
}
}
Ok(())
}
pub fn test_concurrent_safety_succeeds(&self) -> Result<()> {
use std::thread;
let mut handles = vec![];
for i in 0..4 {
let handle: thread::JoinHandle<Result<()>> = thread::spawn(move || {
for j in 0..100 {
let data = format!("thread_{}_{}", i, j).into_bytes();
let encoded = hex::encode(&data);
let _decoded = hex::decode(&encoded)?;
let _uuid = uuid::Uuid::new_v4();
let _error = LatticeArcError::InvalidInput(format!("test_{}_{}", i, j));
}
Ok::<(), LatticeArcError>(())
});
handles.push(handle);
}
for handle in handles {
handle
.join()
.map_err(|e| {
let msg = e
.downcast_ref::<&str>()
.map(ToString::to_string)
.or_else(|| e.downcast_ref::<String>().cloned())
.unwrap_or_else(|| "Unknown panic payload".to_string());
LatticeArcError::ConcurrencyError(format!("Thread panic: {}", msg))
})??;
}
Ok(())
}
}
pub struct UtilityLeakDetector;
impl Default for UtilityLeakDetector {
fn default() -> Self {
Self::new()
}
}
impl UtilityLeakDetector {
#[must_use]
pub fn new() -> Self {
Self
}
pub fn monitor_leaks<F>(&self, operation: F) -> Result<()>
where
F: Fn() -> Result<()>,
{
let mut success_count = 0;
let mut error_count = 0;
for i in 0..1000 {
match operation() {
#[allow(clippy::arithmetic_side_effects)]
Ok(_) => success_count += 1,
#[allow(clippy::arithmetic_side_effects)]
Err(e) => {
error_count += 1;
tracing::warn!("Operation {} failed: {}", i, e);
}
}
}
tracing::info!(
"Leak detection completed: {} successes, {} errors out of 1000 operations",
success_count,
error_count
);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_memory_safety_passes_for_utility_tester_succeeds() {
let tester = UtilityMemorySafetyTester::new();
assert!(tester.test_memory_safety_succeeds().is_ok());
}
#[test]
fn test_concurrent_safety_passes_for_utility_tester_succeeds() {
let tester = UtilityMemorySafetyTester::new();
assert!(tester.test_concurrent_safety_succeeds().is_ok());
}
#[test]
fn test_hex_memory_safety_passes_for_utility_tester_succeeds() {
let tester = UtilityMemorySafetyTester::new();
assert!(tester.test_hex_memory_safety_succeeds().is_ok());
}
#[test]
fn test_uuid_memory_safety_passes_for_utility_tester_succeeds() {
let tester = UtilityMemorySafetyTester::new();
assert!(tester.test_uuid_memory_safety_succeeds().is_ok());
}
#[test]
fn test_error_memory_safety_passes_for_utility_tester_fails() {
let tester = UtilityMemorySafetyTester::new();
assert!(tester.test_error_memory_safety_fails().is_ok());
}
#[test]
fn test_leak_detector_monitor_leaks_succeeds() {
let detector = UtilityLeakDetector::new();
let result = detector.monitor_leaks(|| {
let _data = vec![0u8; 100];
let _encoded = hex::encode(&_data);
Ok(())
});
assert!(result.is_ok());
}
#[test]
fn test_memory_safety_tester_default_passes_memory_safety_succeeds() {
let tester = UtilityMemorySafetyTester;
assert!(tester.test_memory_safety_succeeds().is_ok());
}
#[test]
fn test_leak_detector_default_monitor_leaks_succeeds() {
let detector = UtilityLeakDetector;
let result = detector.monitor_leaks(|| Ok(()));
assert!(result.is_ok());
}
#[test]
fn test_leak_detector_with_failing_operation_fails() {
let detector = UtilityLeakDetector::new();
let result = detector.monitor_leaks(|| {
Err(LatticeArcError::InvalidInput("intentional failure".to_string()))
});
assert!(result.is_ok());
}
#[test]
fn test_leak_detector_with_intermittent_failures_fails() {
let detector = UtilityLeakDetector::new();
let counter = std::sync::atomic::AtomicUsize::new(0);
let result = detector.monitor_leaks(|| {
let val = counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
if val.is_multiple_of(3) {
Err(LatticeArcError::InvalidInput("every third fails".to_string()))
} else {
Ok(())
}
});
assert!(result.is_ok());
}
#[test]
fn test_memory_safety_tester_new_and_default_are_equivalent_succeeds() {
let t1 = UtilityMemorySafetyTester::new();
let t2 = UtilityMemorySafetyTester;
assert!(t1.test_hex_memory_safety_succeeds().is_ok());
assert!(t2.test_hex_memory_safety_succeeds().is_ok());
}
#[test]
fn test_leak_detector_new_and_default_are_equivalent_succeeds() {
let d1 = UtilityLeakDetector::new();
let d2 = UtilityLeakDetector;
assert!(d1.monitor_leaks(|| Ok(())).is_ok());
assert!(d2.monitor_leaks(|| Ok(())).is_ok());
}
#[test]
fn test_uuid_memory_safety_standalone_succeeds() {
let tester = UtilityMemorySafetyTester::new();
assert!(tester.test_uuid_memory_safety_succeeds().is_ok());
}
#[test]
fn test_error_memory_safety_standalone_succeeds() {
let tester = UtilityMemorySafetyTester::new();
assert!(tester.test_error_memory_safety_fails().is_ok());
}
#[test]
fn test_hex_roundtrip_large_data_roundtrip() {
let tester = UtilityMemorySafetyTester::new();
let data = vec![0xABu8; 4096];
let encoded = hex::encode(&data);
let decoded = hex::decode(&encoded);
assert!(decoded.is_ok());
if let Ok(ref bytes) = decoded {
assert_eq!(bytes, &data);
}
assert!(tester.test_hex_memory_safety_succeeds().is_ok());
}
#[test]
fn test_concurrent_safety_produces_no_errors_fails() {
let tester = UtilityMemorySafetyTester::new();
for _ in 0..3 {
assert!(tester.test_concurrent_safety_succeeds().is_ok());
}
}
#[test]
fn test_leak_detector_monitor_many_successes_runs_1000_iterations_succeeds() {
let detector = UtilityLeakDetector::new();
let counter = std::sync::atomic::AtomicUsize::new(0);
let result = detector.monitor_leaks(|| {
counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
Ok(())
});
assert!(result.is_ok());
assert_eq!(counter.load(std::sync::atomic::Ordering::SeqCst), 1000);
}
#[test]
fn test_monitor_leaks_with_allocating_operation_succeeds() {
let detector = UtilityLeakDetector::new();
let result = detector.monitor_leaks(|| {
let data = vec![0xABu8; 256];
let encoded = hex::encode(&data);
let _decoded = hex::decode(&encoded);
Ok(())
});
assert!(result.is_ok());
}
#[test]
fn test_monitor_leaks_sequential_runs_all_succeed_succeeds() {
let detector = UtilityLeakDetector::new();
for _ in 0..3 {
let result = detector.monitor_leaks(|| Ok(()));
assert!(result.is_ok());
}
}
#[test]
fn test_utility_memory_safety_tester_default_passes_memory_safety_succeeds() {
let tester = UtilityMemorySafetyTester::new();
assert!(tester.test_memory_safety_succeeds().is_ok());
}
#[test]
fn test_hex_roundtrip_empty_and_single_byte_roundtrip() {
let empty: Vec<u8> = vec![];
let encoded = hex::encode(&empty);
assert_eq!(encoded, "");
let decoded = hex::decode(&encoded);
assert!(decoded.is_ok());
if let Ok(ref bytes) = decoded {
assert!(bytes.is_empty());
}
let single = vec![0xFFu8];
let encoded = hex::encode(&single);
assert_eq!(encoded, "ff");
let decoded = hex::decode(&encoded);
assert!(decoded.is_ok());
if let Ok(ref bytes) = decoded {
assert_eq!(bytes, &single);
}
}
}