use sal_process::{kill, process_get, process_list, which, ProcessError}; #[test] fn test_which_existing_command() { // Test with a command that should exist on all systems #[cfg(target_os = "windows")] let cmd = "cmd"; #[cfg(not(target_os = "windows"))] let cmd = "sh"; let result = which(cmd); assert!(result.is_some()); assert!(!result.unwrap().is_empty()); } #[test] fn test_which_nonexistent_command() { let result = which("nonexistent_command_12345"); assert!(result.is_none()); } #[test] fn test_which_common_commands() { // Test common commands that should exist let common_commands = if cfg!(target_os = "windows") { vec!["cmd", "powershell"] } else { vec!["sh", "ls", "echo"] }; for cmd in common_commands { let result = which(cmd); assert!(result.is_some(), "Command '{}' should be found", cmd); assert!(!result.unwrap().is_empty()); } } #[test] fn test_process_list_all() { let result = process_list("").unwrap(); assert!( !result.is_empty(), "Should find at least one running process" ); // Verify process info structure let first_process = &result[0]; assert!(first_process.pid > 0, "Process PID should be positive"); assert!( !first_process.name.is_empty(), "Process name should not be empty" ); } #[test] fn test_process_list_with_pattern() { // Try to find processes with common names let patterns = if cfg!(target_os = "windows") { vec!["explorer", "winlogon", "System"] } else { vec!["init", "kernel", "systemd"] }; let mut found_any = false; for pattern in patterns { if let Ok(processes) = process_list(pattern) { if !processes.is_empty() { found_any = true; for process in processes { assert!( process.name.contains(pattern) || process .name .to_lowercase() .contains(&pattern.to_lowercase()) ); assert!(process.pid > 0); } break; } } } // At least one pattern should match some processes assert!( found_any, "Should find at least one process with common patterns" ); } #[test] fn test_process_list_nonexistent_pattern() { let result = process_list("nonexistent_process_12345").unwrap(); assert!( result.is_empty(), "Should not find any processes with nonexistent pattern" ); } #[test] fn test_process_info_structure() { let processes = process_list("").unwrap(); assert!(!processes.is_empty()); let process = &processes[0]; // Test ProcessInfo fields assert!(process.pid > 0); assert!(!process.name.is_empty()); // memory and cpu are placeholders, so we just check they exist assert!(process.memory >= 0.0); assert!(process.cpu >= 0.0); } #[test] fn test_process_get_single_match() { // Find a process that should be unique let processes = process_list("").unwrap(); assert!(!processes.is_empty()); // Try to find a process with a unique enough name let mut unique_process = None; for process in &processes { let matches = process_list(&process.name).unwrap(); if matches.len() == 1 { unique_process = Some(process.clone()); break; } } if let Some(process) = unique_process { let result = process_get(&process.name).unwrap(); assert_eq!(result.pid, process.pid); assert_eq!(result.name, process.name); } } #[test] fn test_process_get_no_match() { let result = process_get("nonexistent_process_12345"); assert!(result.is_err()); match result.unwrap_err() { ProcessError::NoProcessFound(pattern) => { assert_eq!(pattern, "nonexistent_process_12345"); } _ => panic!("Expected NoProcessFound error"), } } #[test] fn test_process_get_multiple_matches() { // Find a pattern that matches multiple processes let all_processes = process_list("").unwrap(); assert!(!all_processes.is_empty()); // Try common patterns that might match multiple processes let patterns = if cfg!(target_os = "windows") { vec!["svchost", "conhost"] } else { vec!["kthread", "ksoftirqd"] }; let mut _found_multiple = false; for pattern in patterns { if let Ok(processes) = process_list(pattern) { if processes.len() > 1 { let result = process_get(pattern); assert!(result.is_err()); match result.unwrap_err() { ProcessError::MultipleProcessesFound(p, count) => { assert_eq!(p, pattern); assert_eq!(count, processes.len()); _found_multiple = true; break; } _ => panic!("Expected MultipleProcessesFound error"), } } } } // If we can't find multiple matches with common patterns, that's okay // The test validates the error handling works correctly } #[test] fn test_kill_nonexistent_process() { let result = kill("nonexistent_process_12345").unwrap(); assert!(result.contains("No matching processes") || result.contains("Successfully killed")); } #[test] fn test_process_list_performance() { use std::time::Instant; let start = Instant::now(); let _processes = process_list("").unwrap(); let duration = start.elapsed(); // Process listing should complete within reasonable time (5 seconds) assert!( duration.as_secs() < 5, "Process listing took too long: {:?}", duration ); } #[test] fn test_which_performance() { use std::time::Instant; let start = Instant::now(); let _result = which("echo"); let duration = start.elapsed(); // Which command should be very fast (1 second) assert!( duration.as_secs() < 1, "Which command took too long: {:?}", duration ); } #[test] fn test_process_list_filtering_accuracy() { // Test that filtering actually works correctly let all_processes = process_list("").unwrap(); assert!(!all_processes.is_empty()); // Pick a process name and filter by it let test_process = &all_processes[0]; let filtered_processes = process_list(&test_process.name).unwrap(); // All filtered processes should contain the pattern for process in filtered_processes { assert!(process.name.contains(&test_process.name)); } } #[test] fn test_process_error_display() { let error = ProcessError::NoProcessFound("test".to_string()); let error_string = format!("{}", error); assert!(error_string.contains("No processes found matching 'test'")); let error = ProcessError::MultipleProcessesFound("test".to_string(), 5); let error_string = format!("{}", error); assert!(error_string.contains("Multiple processes (5) found matching 'test'")); } #[test] fn test_cross_platform_process_operations() { // Test operations that should work on all platforms // Test which with platform-specific commands #[cfg(target_os = "windows")] { assert!(which("cmd").is_some()); assert!(which("notepad").is_some()); } #[cfg(target_os = "macos")] { assert!(which("sh").is_some()); assert!(which("ls").is_some()); } #[cfg(target_os = "linux")] { assert!(which("sh").is_some()); assert!(which("ls").is_some()); } // Test process listing works on all platforms let processes = process_list("").unwrap(); assert!(!processes.is_empty()); }