use postfix_log_parser::components::{ComponentParser, MasterParser};
use postfix_log_parser::events::master::{
MasterConfigWarning, MasterEvent, MasterLifecycleEvent, MasterProcessWarning,
MasterServiceLimit,
};
use postfix_log_parser::events::ComponentEvent;
#[test]
fn test_daemon_started() {
let parser = MasterParser::new();
let result = parser.parse("daemon started -- version 3.8.0, configuration /etc/postfix");
assert!(result.is_ok());
if let Ok(ComponentEvent::Master(MasterEvent::DaemonLifecycle { lifecycle, .. })) = result {
assert_eq!(
lifecycle,
MasterLifecycleEvent::Started {
version: "3.8.0".to_string(),
configuration: "/etc/postfix".to_string()
}
);
} else {
panic!("Expected DaemonLifecycle::Started");
}
}
#[test]
fn test_daemon_reload() {
let parser = MasterParser::new();
let result = parser.parse("reload -- version 3.10.1, configuration /etc/postfix");
assert!(result.is_ok());
if let Ok(ComponentEvent::Master(MasterEvent::DaemonLifecycle { lifecycle, .. })) = result {
assert_eq!(
lifecycle,
MasterLifecycleEvent::Reload {
version: "3.10.1".to_string(),
configuration: "/etc/postfix".to_string()
}
);
} else {
panic!("Expected DaemonLifecycle::Reload");
}
}
#[test]
fn test_process_killed() {
let parser = MasterParser::new();
let result =
parser.parse("warning: process /usr/libexec/postfix/smtpd pid 866 killed by signal 9");
assert!(result.is_ok());
if let Ok(ComponentEvent::Master(MasterEvent::ProcessWarning { warning, .. })) = result {
assert_eq!(
warning,
MasterProcessWarning::ProcessKilled {
service: "smtpd".to_string(),
process_path: "/usr/libexec/postfix/smtpd".to_string(),
pid: 866,
signal: 9,
}
);
} else {
panic!("Expected ProcessWarning::ProcessKilled");
}
}
#[test]
fn test_bad_command_startup() {
let parser = MasterParser::new();
let result =
parser.parse("warning: /usr/libexec/postfix/smtpd: bad command startup -- throttling");
assert!(result.is_ok());
if let Ok(ComponentEvent::Master(MasterEvent::ProcessWarning { warning, .. })) = result {
assert_eq!(
warning,
MasterProcessWarning::BadCommandStartup {
service: "smtpd".to_string(),
}
);
} else {
panic!("Expected ProcessWarning::BadCommandStartup");
}
}
#[test]
fn test_service_limit_reached() {
let parser = MasterParser::new();
let result = parser.parse(r#"warning: service "0.0.0.0:10026" ([0.0.0.0]:10026) has reached its process limit "10": new clients may experience noticeable delays"#);
assert!(result.is_ok());
if let Ok(ComponentEvent::Master(MasterEvent::ServiceLimit { limit, .. })) = result {
assert_eq!(
limit,
MasterServiceLimit::ProcessLimitReached {
service: "0.0.0.0:10026".to_string(),
service_address: "[0.0.0.0]:10026".to_string(),
limit: 10,
}
);
} else {
panic!("Expected ServiceLimit::ProcessLimitReached");
}
}
#[test]
fn test_process_count_suggestion() {
let parser = MasterParser::new();
let result = parser.parse("warning: to avoid this condition, increase the process count in master.cf or reduce the service time per client");
assert!(result.is_ok());
if let Ok(ComponentEvent::Master(MasterEvent::ConfigurationWarning { warning, .. })) = result {
assert_eq!(warning, MasterConfigWarning::ProcessCountSuggestion);
} else {
panic!("Expected ConfigurationWarning::ProcessCountSuggestion");
}
}
#[test]
fn test_stress_config_reference() {
let parser = MasterParser::new();
let result = parser.parse("warning: see https://www.postfix.org/STRESS_README.html for examples of stress-adapting configuration settings");
assert!(result.is_ok());
if let Ok(ComponentEvent::Master(MasterEvent::ConfigurationWarning { warning, .. })) = result {
assert_eq!(
warning,
MasterConfigWarning::StressConfigReference {
url: "https://www.postfix.org/STRESS_README.html".to_string(),
}
);
} else {
panic!("Expected ConfigurationWarning::StressConfigReference");
}
}
#[test]
fn test_component_parser_interface() {
let parser = MasterParser::new();
assert_eq!(parser.component_name(), "master");
assert!(parser.can_parse("master"));
assert!(!parser.can_parse("smtpd"));
assert!(!parser.can_parse("qmgr"));
}
#[test]
fn test_unsupported_message() {
let parser = MasterParser::new();
let result = parser.parse("some unsupported message format");
assert!(result.is_err());
}
#[test]
fn test_event_type_methods() {
use chrono::{DateTime, Utc};
use postfix_log_parser::events::base::{BaseEvent, PostfixLogLevel};
let base = BaseEvent {
timestamp: DateTime::parse_from_rfc3339("2024-04-27T16:20:48Z")
.unwrap()
.with_timezone(&Utc),
hostname: "m01".to_string(),
component: "master".to_string(),
process_id: 1,
log_level: PostfixLogLevel::Info,
raw_message: "test message".to_string(),
};
let started_event = MasterEvent::DaemonLifecycle {
base: base.clone(),
lifecycle: MasterLifecycleEvent::Started {
version: "3.8.0".to_string(),
configuration: "/etc/postfix".to_string(),
},
};
assert_eq!(started_event.event_type(), "daemon_started");
let reload_event = MasterEvent::DaemonLifecycle {
base: base.clone(),
lifecycle: MasterLifecycleEvent::Reload {
version: "3.10.1".to_string(),
configuration: "/etc/postfix".to_string(),
},
};
assert_eq!(reload_event.event_type(), "daemon_reload");
let process_killed_event = MasterEvent::ProcessWarning {
base: base.clone(),
warning: MasterProcessWarning::ProcessKilled {
service: "smtpd".to_string(),
process_path: "/usr/libexec/postfix/smtpd".to_string(),
pid: 866,
signal: 9,
},
};
assert_eq!(process_killed_event.event_type(), "process_killed");
let service_limit_event = MasterEvent::ServiceLimit {
base: base.clone(),
limit: MasterServiceLimit::ProcessLimitReached {
service: "test".to_string(),
service_address: "test".to_string(),
limit: 10,
},
};
assert_eq!(service_limit_event.event_type(), "service_limit_reached");
}