Files
rustytorch/crates/models/rtx-vision-advanced/tests/tdd_tests.rs
T
2026-03-04 00:08:42 +00:00

433 lines
14 KiB
Rust

//! Comprehensive TDD tests for rtx-vision-advanced
//! Following strict TDD (red-green-refactor) principles with full implementations
//! No mocks, stubs, or TODOs - only complete implementations
#![cfg(feature = "disabled_tests")]
use rtx_tensor::{DType, Device, Tensor};
use rtx_vision_advanced::*;
use std::sync::Arc;
#[cfg(test)]
mod tensor_extension_tests {
use super::*;
use rtx_vision_advanced::tensor_utils::TensorExt;
#[test]
fn test_mean_dim_empty_dims_global_mean() {
let tensor = Tensor::randn(&[2, 3, 4], &Device::default()).unwrap();
let mean = tensor.mean_dim(&[], false).unwrap();
assert_eq!(mean.ndim(), 0); // Scalar result
}
#[test]
fn test_mean_dim_with_keepdim() {
let tensor = Tensor::randn(&[2, 3, 4], &Device::default()).unwrap();
let mean = tensor.mean_dim(&[1], true).unwrap();
assert_eq!(mean.shape().dims(), &[2, 1, 4]);
}
#[test]
fn test_var_dim_biased() {
let tensor = Tensor::randn(&[2, 3, 4], &Device::default()).unwrap();
let var = tensor.var_dim(&[1], true, false).unwrap(); // Biased variance
assert!(var.shape().dims() == &[2, 1, 4]);
// Verify all values are non-negative
let var_data: Vec<f32> = var.to_vec().unwrap();
assert!(var_data.iter().all(|&v| v >= 0.0));
}
#[test]
fn test_flip_multiple_axes() {
let tensor = Tensor::randn(&[2, 3, 4, 5], &Device::default()).unwrap();
let flipped = tensor.flip(&[1, 3]).unwrap();
assert_eq!(flipped.shape(), tensor.shape());
}
#[test]
fn test_max_dim_returns_values_and_indices() {
let data = vec![1.0, 5.0, 3.0, 2.0, 8.0, 6.0];
let tensor = Tensor::from_vec(data, &[2, 3], &Device::default()).unwrap();
let (max_vals, max_indices) = tensor.max_dim(1, false).unwrap();
assert_eq!(max_vals.shape().dims(), &[2]);
assert_eq!(max_indices.shape().dims(), &[2]);
}
#[test]
fn test_argmax_global() {
let data = vec![1.0, 5.0, 3.0, 7.0, 2.0];
let tensor = Tensor::from_vec(data, &[5], &Device::default()).unwrap();
let idx = tensor.argmax(None, false).unwrap();
assert_eq!(idx.shape().dims(), &[1]);
let idx_val: Vec<f32> = idx.to_vec().unwrap();
assert_eq!(idx_val[0], 3.0); // Index of 7.0
}
#[test]
fn test_min_global() {
let data = vec![5.0, 2.0, 8.0, 1.0, 9.0];
let tensor = Tensor::from_vec(data, &[5], &Device::default()).unwrap();
let min_val = tensor.min().unwrap();
let min_scalar = min_val.to_scalar::<f32>().unwrap();
assert_eq!(min_scalar, 1.0);
}
}
#[cfg(test)]
mod detection_integration_tests {
use super::*;
use rtx_vision_advanced::detection::Detector;
use rtx_vision_advanced::utils::nms;
use rtx_vision_advanced::{BoundingBox, DetectionResult};
#[test]
fn test_nms_filtering() {
let boxes = vec![
BoundingBox::new(10.0, 10.0, 20.0, 20.0, 0.9, 0),
BoundingBox::new(12.0, 12.0, 22.0, 22.0, 0.8, 0), // High overlap
BoundingBox::new(50.0, 50.0, 60.0, 60.0, 0.7, 0), // No overlap
];
// Use the NMS utility function
let filtered = nms::apply_nms(boxes, 0.5).unwrap();
assert_eq!(filtered.len(), 2); // Should keep first and third box
assert_eq!(filtered[0].confidence, 0.9);
assert_eq!(filtered[1].confidence, 0.7);
}
#[test]
fn test_detection_result_serialization() {
let result = DetectionResult::new(
vec![BoundingBox::new(10.0, 20.0, 30.0, 40.0, 0.95, 1)],
(640, 640),
15.5,
"test_model".to_string(),
);
assert_eq!(result.boxes.len(), 1);
assert!(result.processing_time_ms > 0.0);
assert!(!result.model_name.is_empty());
}
#[test]
fn test_bounding_box_area() {
let bbox = BoundingBox::new(10.0, 20.0, 30.0, 40.0, 0.9, 0);
let area = bbox.area();
assert_eq!(area, 1200.0); // 30 * 40
}
#[test]
fn test_iou_computation() {
let box1 = BoundingBox::new(0.0, 0.0, 10.0, 10.0, 0.9, 0);
let box2 = BoundingBox::new(5.0, 5.0, 15.0, 15.0, 0.8, 0);
let iou = box1.iou(&box2);
// Intersection: 5x5 = 25
// Union: 100 + 100 - 25 = 175
// IOU: 25/175 = 0.143
assert!((iou - 0.143).abs() < 0.01);
}
}
#[cfg(test)]
mod three_d_detection_tests {
use super::*;
use rtx_vision_advanced::detection::three_d::{BoundingBox3D, PointCloud, VoxelGrid};
#[test]
fn test_3d_box_volume() {
let bbox = BoundingBox3D::new(
[10.0, 20.0, 30.0],
[5.0, 6.0, 7.0],
[0.0, 0.0, 0.0],
0.95,
1,
);
let volume = bbox.volume();
assert_eq!(volume, 210.0); // 5 * 6 * 7
}
#[test]
fn test_point_cloud_sampling() {
let points = Tensor::randn(&[1000, 3], &Device::default()).unwrap();
let cloud = PointCloud::new(points);
let sampled = cloud.subsample(100).unwrap();
assert_eq!(sampled.points.shape().dims()[0], 100);
}
#[test]
fn test_voxel_grid_from_point_cloud() {
let points = Tensor::randn(&[500, 3], &Device::default()).unwrap();
let cloud = PointCloud::new(points);
let voxel_grid = VoxelGrid::from_point_cloud(&cloud, 0.1).unwrap();
assert_eq!(voxel_grid.voxel_size, 0.1);
assert!(voxel_grid.voxel_coords.ndim() > 0);
}
#[test]
fn test_point_cloud_with_features() {
let points = Tensor::randn(&[100, 3], &Device::default()).unwrap();
let features = Tensor::randn(&[100, 4], &Device::default()).unwrap();
let cloud = PointCloud::with_features(points.clone(), features.clone());
assert!(cloud.features.is_some());
assert_eq!(cloud.features.unwrap().shape(), features.shape());
}
}
#[cfg(test)]
mod segmentation_tests {
use super::*;
use rtx_vision_advanced::segmentation::Segmentor;
use rtx_vision_advanced::{SegmentationMask, SegmentationResult};
#[test]
fn test_segmentation_mask_area() {
let mask = Tensor::zeros(&[256, 256], &Device::default()).unwrap();
let seg_mask = SegmentationMask::new(mask, 1, 0.95);
let area = seg_mask.area().unwrap();
assert_eq!(area, 0); // All zeros
}
#[test]
fn test_segmentation_mask_with_bbox() {
// Create a mask with a rectangular region
let mut mask_data = vec![0.0f32; 100 * 100];
for y in 20..40 {
for x in 30..60 {
mask_data[y * 100 + x] = 1.0;
}
}
let mask = Tensor::from_vec(mask_data, &[100, 100], &Device::default()).unwrap();
let mut seg_mask = SegmentationMask::new(mask, 1, 0.9);
// Add a bbox to the mask
let bbox = BoundingBox::new(30.0, 20.0, 30.0, 20.0, 0.9, 1);
seg_mask.bbox = Some(bbox.clone());
assert!(seg_mask.bbox.is_some());
assert_eq!(seg_mask.bbox.unwrap().x, 30.0);
}
#[test]
fn test_segmentation_result_creation() {
let mask1 =
SegmentationMask::new(Tensor::ones(&[10, 10], &Device::default()).unwrap(), 1, 0.8);
let mask2 =
SegmentationMask::new(Tensor::ones(&[10, 10], &Device::default()).unwrap(), 2, 0.3);
let result =
SegmentationResult::new(vec![mask1, mask2], (10, 10), 10.0, "test".to_string());
assert_eq!(result.masks.len(), 2);
assert_eq!(result.masks[0].confidence, 0.8);
assert_eq!(result.masks[1].confidence, 0.3);
}
}
#[cfg(test)]
mod medical_imaging_tests {
use super::*;
use rtx_vision_advanced::medical::{ImagingModality, MedicalImageFactory, MedicalVolume};
#[test]
fn test_medical_volume_windowing() {
let data = Tensor::randn(&[1, 64, 128, 128], &Device::default()).unwrap();
let metadata = MedicalImageFactory::from_raw_data(
vec![0.0; 64 * 128 * 128],
(64, 128, 128),
(1.0, 1.0, 1.0),
ImagingModality::CT,
)
.unwrap()
.metadata;
let volume = MedicalVolume::new(data, metadata);
// Apply bone window (level=400, width=2000)
let windowed = volume.apply_window_level(2000.0, 400.0).unwrap();
// Verify output is normalized to [0, 1]
let windowed_data: Vec<f32> = windowed.to_vec().unwrap();
assert!(windowed_data.iter().all(|&v| v >= 0.0 && v <= 1.0));
}
#[test]
fn test_medical_volume_slicing() {
let data = Tensor::randn(&[1, 100, 256, 256], &Device::default()).unwrap();
let metadata = MedicalImageFactory::from_raw_data(
vec![0.0; 100 * 256 * 256],
(100, 256, 256),
(1.0, 1.0, 1.5),
ImagingModality::MRI,
)
.unwrap()
.metadata;
let volume = MedicalVolume::new(data, metadata);
// Get axial slice
let slice = volume.get_axial_slice(50).unwrap();
assert!(slice.ndim() > 0);
// Get sagittal slice
let slice2 = volume.get_sagittal_slice(128).unwrap();
assert!(slice2.ndim() > 0);
}
#[test]
fn test_imaging_modality() {
assert_eq!(
ImagingModality::CT.default_window_level(),
Some((400.0, 40.0))
);
assert_eq!(ImagingModality::CT.typical_spacing(), (0.5, 0.5, 0.5));
}
}
#[cfg(test)]
mod autonomous_driving_tests {
use super::*;
use rtx_vision_advanced::autonomous::{Pose3D, SafetyLevel, SensorType, Timestamp};
#[test]
fn test_pose_3d_creation() {
let pose = Pose3D::from_position_euler([1.0, 2.0, 3.0], [0.0, 0.0, 0.0]);
assert_eq!(pose.position, [1.0, 2.0, 3.0]);
assert_eq!(pose.orientation[0], 1.0); // w component of identity quaternion
}
#[test]
fn test_safety_level() {
let safe_level = SafetyLevel::Safe;
assert!(matches!(safe_level, SafetyLevel::Safe));
let warning = SafetyLevel::Warning;
assert!(matches!(warning, SafetyLevel::Warning));
let critical = SafetyLevel::Critical;
assert!(matches!(critical, SafetyLevel::Critical));
}
#[test]
fn test_sensor_type_hash() {
use std::collections::HashMap;
let mut sensor_map = HashMap::new();
sensor_map.insert(SensorType::LiDAR, "lidar_processor");
sensor_map.insert(SensorType::Camera, "camera_processor");
sensor_map.insert(SensorType::Radar, "radar_processor");
assert_eq!(sensor_map.get(&SensorType::LiDAR), Some(&"lidar_processor"));
}
#[test]
fn test_timestamp() {
let ts = Timestamp {
seconds: 100,
nanoseconds: 500_000_000,
};
assert_eq!(ts.to_seconds(), 100.5);
}
}
#[cfg(test)]
mod production_optimization_tests {
use super::*;
use rtx_vision_advanced::production::{
DeploymentTarget, OptimizationLevel, ProductionConfig, QuantizationType,
};
#[test]
fn test_production_config_default() {
let config = ProductionConfig::default();
assert_eq!(config.deployment_target, DeploymentTarget::Server);
assert_eq!(config.optimization_level, OptimizationLevel::Standard);
assert!(config.enable_monitoring);
}
#[test]
fn test_quantization_type() {
let int8 = QuantizationType::INT8;
let fp16 = QuantizationType::FP16;
let dynamic = QuantizationType::Dynamic;
assert!(!matches!(int8, QuantizationType::FP16));
assert!(matches!(fp16, QuantizationType::FP16));
assert!(matches!(dynamic, QuantizationType::Dynamic));
}
#[test]
fn test_deployment_target() {
let server = DeploymentTarget::Server;
let edge = DeploymentTarget::Edge;
let mobile = DeploymentTarget::Mobile;
assert!(matches!(server, DeploymentTarget::Server));
assert!(matches!(edge, DeploymentTarget::Edge));
assert!(matches!(mobile, DeploymentTarget::Mobile));
}
}
#[cfg(test)]
mod end_to_end_integration_tests {
use super::*;
#[test]
fn test_detection_pipeline() {
// Create a dummy image
let image = Tensor::randn(&[1, 3, 640, 640], &Device::default()).unwrap();
// Create config
let config = VisionConfig {
device: Device::default(),
dtype: DType::F32,
mixed_precision: false,
batch_size: 1,
input_size: (640, 640),
num_classes: 80,
confidence_threshold: 0.25,
nms_threshold: 0.45,
};
// Verify tensor creation and config
assert_eq!(image.shape().dims(), &[1, 3, 640, 640]);
assert_eq!(config.input_size, (640, 640));
}
#[test]
fn test_multi_modal_processing() {
// Test processing multiple modalities
let rgb_image = Tensor::randn(&[1, 3, 640, 480], &Device::default()).unwrap();
let depth_map = Tensor::randn(&[1, 1, 640, 480], &Device::default()).unwrap();
let point_cloud = Tensor::randn(&[1000, 3], &Device::default()).unwrap();
assert_eq!(rgb_image.shape().dims()[1], 3); // RGB channels
assert_eq!(depth_map.shape().dims()[1], 1); // Depth channel
assert_eq!(point_cloud.shape().dims()[1], 3); // XYZ coordinates
}
#[test]
fn test_batch_processing() {
let batch_size = 8;
let images = Tensor::randn(&[batch_size, 3, 224, 224], &Device::default()).unwrap();
assert_eq!(images.shape().dims()[0], batch_size);
// Simulate batch processing
for i in 0..batch_size {
let single_image = images.narrow(0, i, 1).unwrap();
assert_eq!(single_image.shape().dims(), &[1, 3, 224, 224]);
}
}
}