use denet::config::{MonitorConfig, MonitorConfigBuilder, OutputConfigBuilder};
use denet::core::constants::delays;
use denet::core::monitoring_utils::{MonitoringConfig, MonitoringLoop};
use denet::error::{DenetError, Result};
use denet::ProcessMonitor;
use std::time::Duration;
#[test]
fn test_monitor_config_validation_errors() {
let result = MonitorConfigBuilder::default()
.base_interval_ms(1000)
.max_interval_ms(500)
.build();
assert!(result.is_err());
match result {
Err(DenetError::InvalidConfiguration(msg)) => {
assert!(msg.contains("Base interval cannot be greater than max interval"));
}
_ => panic!("Expected InvalidConfiguration error"),
}
let result = MonitorConfigBuilder::default().base_interval_ms(0).build();
assert!(result.is_err());
match result {
Err(DenetError::InvalidConfiguration(msg)) => {
assert!(msg.contains("Base interval cannot be zero"));
}
_ => panic!("Expected InvalidConfiguration error"),
}
}
#[test]
fn test_output_format_parsing_errors() {
use denet::config::OutputFormat;
use std::str::FromStr;
let invalid_formats = ["xml", "yaml", "txt", "binary", "", "json "];
for format in &invalid_formats {
let result = OutputFormat::from_str(format);
assert!(result.is_err());
match result {
Err(DenetError::InvalidConfiguration(msg)) => {
assert!(msg.contains("Unknown output format"));
assert!(msg.contains(format));
}
_ => panic!("Expected InvalidConfiguration error for format: {}", format),
}
}
}
#[test]
fn test_output_config_builder_format_str_error() {
let result = OutputConfigBuilder::default().format_str("invalid_format");
assert!(result.is_err());
match result {
Err(DenetError::InvalidConfiguration(_)) => {
}
_ => panic!("Expected InvalidConfiguration error"),
}
}
#[test]
fn test_process_monitor_creation_errors() {
let cmd = vec!["definitely_nonexistent_command_12345".to_string()];
let result = ProcessMonitor::new(cmd, Duration::from_millis(100), Duration::from_millis(1000));
assert!(result.is_err());
}
#[test]
fn test_process_monitor_invalid_pid() {
let result =
ProcessMonitor::from_pid(0, Duration::from_millis(100), Duration::from_millis(1000));
assert!(result.is_err());
}
#[test]
fn test_process_monitor_very_large_pid() {
let result = ProcessMonitor::from_pid(
u32::MAX as usize,
Duration::from_millis(100),
Duration::from_millis(1000),
);
assert!(result.is_err());
}
#[test]
fn test_monitoring_config_edge_cases() {
let config = MonitoringConfig::new().with_timeout(Duration::from_secs(0));
assert_eq!(config.timeout, Some(Duration::from_secs(0)));
let large_timeout = Duration::from_secs(u64::MAX);
let config = MonitoringConfig::new().with_timeout(large_timeout);
assert_eq!(config.timeout, Some(large_timeout));
let config = MonitoringConfig::new().with_final_samples(0, delays::STANDARD);
assert_eq!(config.final_sample_count, 0);
assert!(config.monitor_after_exit);
let config = MonitoringConfig::new().with_final_samples(u32::MAX, delays::MINIMAL);
assert_eq!(config.final_sample_count, u32::MAX);
}
#[test]
fn test_error_display_formatting() {
let config_error = DenetError::InvalidConfiguration("test message".to_string());
let display_string = format!("{}", config_error);
assert!(display_string.contains("test message"));
assert!(!display_string.is_empty());
}
#[test]
fn test_error_debug_formatting() {
let config_error = DenetError::InvalidConfiguration("debug test".to_string());
let debug_string = format!("{:?}", config_error);
assert!(debug_string.contains("InvalidConfiguration"));
assert!(debug_string.contains("debug test"));
}
#[test]
fn test_result_type_alias() {
fn test_function() -> Result<i32> {
Ok(42)
}
fn test_error_function() -> Result<i32> {
Err(DenetError::InvalidConfiguration("test".to_string()))
}
assert!(test_function().is_ok());
assert_eq!(test_function().unwrap(), 42);
assert!(test_error_function().is_err());
}
#[test]
fn test_config_builder_partial_specification() {
let config = MonitorConfigBuilder::default()
.base_interval_ms(200)
.build()
.unwrap();
assert_eq!(config.base_interval, Duration::from_millis(200));
assert_eq!(config.max_interval, Duration::from_millis(1000));
let config = MonitorConfigBuilder::default()
.max_interval_ms(2000)
.build()
.unwrap();
assert_eq!(config.base_interval, Duration::from_millis(100)); assert_eq!(config.max_interval, Duration::from_millis(2000));
}
#[test]
fn test_output_config_builder_partial_specification() {
let config = OutputConfigBuilder::default().quiet(true).build();
assert!(config.quiet);
assert!(config.store_in_memory);
let config = OutputConfigBuilder::default()
.store_in_memory(false)
.build();
assert!(!config.store_in_memory);
assert!(!config.quiet); }
#[test]
fn test_monitoring_loop_with_invalid_config() {
let config = MonitoringConfig::new()
.with_sample_interval(Duration::from_nanos(1)) .with_timeout(Duration::from_nanos(1));
let loop_monitor = MonitoringLoop::with_config(config);
let _ = loop_monitor;
}
#[test]
fn test_duration_edge_cases() {
let config = MonitorConfig {
base_interval: Duration::from_nanos(1),
max_interval: Duration::from_secs(1),
..MonitorConfig::default()
};
assert!(config.validate().is_ok());
let config = MonitorConfig {
base_interval: Duration::from_millis(100),
max_interval: Duration::from_secs(u64::MAX),
..MonitorConfig::default()
};
assert!(config.validate().is_ok());
}
#[test]
fn test_error_source_chain() {
let error = DenetError::InvalidConfiguration("root cause".to_string());
let result: Result<()> = Err(error);
assert!(result.is_err());
match result {
Err(DenetError::InvalidConfiguration(msg)) => {
assert_eq!(msg, "root cause");
}
_ => panic!("Unexpected error type"),
}
}
#[test]
fn test_concurrent_config_creation() {
use std::thread;
let handles: Vec<_> = (0..10)
.map(|i| {
thread::spawn(move || {
let config = MonitorConfigBuilder::default()
.base_interval_ms(100 + i * 10)
.max_interval_ms(1000 + i * 100)
.since_process_start(i % 2 == 0)
.build()
.unwrap();
assert_eq!(config.base_interval, Duration::from_millis(100 + i * 10));
assert_eq!(config.max_interval, Duration::from_millis(1000 + i * 100));
assert_eq!(config.since_process_start, i % 2 == 0);
})
})
.collect();
for handle in handles {
handle.join().unwrap();
}
}
#[test]
fn test_config_validation_boundary_conditions() {
let config = MonitorConfig {
base_interval: Duration::from_nanos(1),
max_interval: Duration::from_nanos(1),
..MonitorConfig::default()
};
assert!(config.validate().is_ok());
let config = MonitorConfig {
base_interval: Duration::from_millis(500),
max_interval: Duration::from_millis(500),
..MonitorConfig::default()
};
assert!(config.validate().is_ok());
let config = MonitorConfig {
base_interval: Duration::from_nanos(999),
max_interval: Duration::from_nanos(1000),
..MonitorConfig::default()
};
assert!(config.validate().is_ok());
let config = MonitorConfig {
base_interval: Duration::from_nanos(1001),
max_interval: Duration::from_nanos(1000),
..MonitorConfig::default()
};
assert!(config.validate().is_err());
}
#[test]
fn test_max_duration_secs_edge_cases() {
let config = MonitorConfigBuilder::default()
.max_duration_secs(0) .build()
.unwrap();
assert_eq!(config.max_duration, None);
let config = MonitorConfigBuilder::default()
.max_duration_secs(1) .build()
.unwrap();
assert_eq!(config.max_duration, Some(Duration::from_secs(1)));
let config = MonitorConfigBuilder::default()
.max_duration_secs(u64::MAX) .build()
.unwrap();
assert_eq!(config.max_duration, Some(Duration::from_secs(u64::MAX)));
}
#[test]
fn test_invalid_path_handling() {
use std::path::PathBuf;
let config = OutputConfigBuilder::default()
.output_file(PathBuf::from("/invalid\0path"))
.build();
assert!(config.output_file.is_some());
}
#[test]
fn test_error_conversions() {
let config_error = DenetError::InvalidConfiguration("test".to_string());
let _display = format!("{}", config_error);
let _debug = format!("{:?}", config_error);
let result: Result<()> = Err(config_error);
assert!(result.is_err());
}