
- 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
188 lines
6.4 KiB
Rust
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");
|
|
} |