video-processing-support/tests/stability_tracker_tests.rs
Benjamin Slingo a38143c28b Initial commit: Shared video processing crate
- Event-driven file stability tracking
- FFmpeg video conversion with hardware acceleration
- NFO file generation for Kodi compatibility
- Environment-based configuration
- Disk space monitoring and shutdown handling
- Comprehensive logging with tracing
2025-09-06 18:26:58 -04:00

188 lines
6.4 KiB
Rust

use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use std::time::{Duration, SystemTime};
use tempfile::TempDir;
use tokio::time::sleep;
use video_processing::{VideoProcessingConfig, StabilityTracker};
async fn create_test_file(path: &PathBuf, content: &str) -> std::io::Result<()> {
let mut file = File::create(path)?;
file.write_all(content.as_bytes())?;
file.flush()?;
Ok(())
}
#[tokio::test]
async fn test_new_file_tracking() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("test.mp4");
// Create initial file
create_test_file(&test_file, "initial content").await.unwrap();
let mut config = VideoProcessingConfig::from_env();
config.stability_check_interval_secs = 1;
config.stability_required_checks = 3;
let tracker = StabilityTracker::new(config);
// First event should start tracking but not be stable
let result = tracker.on_file_event(&test_file).unwrap();
assert!(!result, "New file should not be immediately stable");
// File should now be tracked
let tracked_files = tracker.get_tracked_files();
assert_eq!(tracked_files.len(), 1);
assert_eq!(tracked_files[0], test_file);
}
#[tokio::test]
async fn test_file_stability_detection() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("stable_test.mp4");
// Create initial file
create_test_file(&test_file, "stable content").await.unwrap();
let mut config = VideoProcessingConfig::from_env();
config.stability_check_interval_secs = 1;
config.stability_required_checks = 3;
let tracker = StabilityTracker::new(config);
// Start tracking
let result1 = tracker.on_file_event(&test_file).unwrap();
assert!(!result1, "First check should not be stable");
// Wait for interval and check again without changes
sleep(Duration::from_secs(1)).await;
let result2 = tracker.on_file_event(&test_file).unwrap();
assert!(!result2, "Second check should not be stable yet");
sleep(Duration::from_secs(1)).await;
let result3 = tracker.on_file_event(&test_file).unwrap();
assert!(!result3, "Third check should not be stable yet");
sleep(Duration::from_secs(1)).await;
let result4 = tracker.on_file_event(&test_file).unwrap();
assert!(result4, "Fourth check should be stable after 3 consecutive unchanged checks");
}
#[tokio::test]
async fn test_file_instability_resets_counter() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("unstable_test.mp4");
// Create initial file
create_test_file(&test_file, "initial").await.unwrap();
let mut config = VideoProcessingConfig::from_env();
config.stability_check_interval_secs = 1;
config.stability_required_checks = 3;
let tracker = StabilityTracker::new(config);
// Start tracking
tracker.on_file_event(&test_file).unwrap();
// Wait and check (should increment stability counter)
sleep(Duration::from_secs(1)).await;
let result1 = tracker.on_file_event(&test_file).unwrap();
assert!(!result1);
// Change file content (should reset counter)
create_test_file(&test_file, "changed content").await.unwrap();
sleep(Duration::from_secs(1)).await;
let result2 = tracker.on_file_event(&test_file).unwrap();
assert!(!result2, "File change should reset stability counter");
// Now check stability again
sleep(Duration::from_secs(1)).await;
tracker.on_file_event(&test_file).unwrap();
sleep(Duration::from_secs(1)).await;
tracker.on_file_event(&test_file).unwrap();
sleep(Duration::from_secs(1)).await;
let final_result = tracker.on_file_event(&test_file).unwrap();
assert!(final_result, "Should be stable after 3 consecutive unchanged checks");
}
#[tokio::test]
async fn test_remove_file_tracker() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("remove_test.mp4");
create_test_file(&test_file, "content").await.unwrap();
let config = VideoProcessingConfig::from_env();
let tracker = StabilityTracker::new(config);
// Start tracking
tracker.on_file_event(&test_file).unwrap();
assert_eq!(tracker.get_tracked_files().len(), 1);
// Remove tracker
tracker.remove_file_tracker(&test_file);
assert_eq!(tracker.get_tracked_files().len(), 0);
}
#[tokio::test]
async fn test_multiple_files_tracking() {
let temp_dir = TempDir::new().unwrap();
let file1 = temp_dir.path().join("file1.mp4");
let file2 = temp_dir.path().join("file2.mp4");
create_test_file(&file1, "content1").await.unwrap();
create_test_file(&file2, "content2").await.unwrap();
let config = VideoProcessingConfig::from_env();
let tracker = StabilityTracker::new(config);
// Track both files
tracker.on_file_event(&file1).unwrap();
tracker.on_file_event(&file2).unwrap();
let tracked_files = tracker.get_tracked_files();
assert_eq!(tracked_files.len(), 2);
assert!(tracked_files.contains(&file1));
assert!(tracked_files.contains(&file2));
// Remove one
tracker.remove_file_tracker(&file1);
let tracked_files = tracker.get_tracked_files();
assert_eq!(tracked_files.len(), 1);
assert!(tracked_files.contains(&file2));
}
#[tokio::test]
async fn test_rate_limiting() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("rate_limit_test.mp4");
create_test_file(&test_file, "content").await.unwrap();
let mut config = VideoProcessingConfig::from_env();
config.stability_check_interval_secs = 2; // 2 second interval
config.stability_required_checks = 2;
let tracker = StabilityTracker::new(config);
// Start tracking
tracker.on_file_event(&test_file).unwrap();
// Immediately check again (should be rate limited)
let result = tracker.on_file_event(&test_file).unwrap();
assert!(!result, "Should be rate limited and not advance stability counter");
// Wait for interval to pass
sleep(Duration::from_secs(2)).await;
let result = tracker.on_file_event(&test_file).unwrap();
assert!(!result, "After interval, should advance counter but not be stable yet");
sleep(Duration::from_secs(2)).await;
let result = tracker.on_file_event(&test_file).unwrap();
assert!(result, "Should be stable after required checks with proper intervals");
}