postfix-log-parser 0.2.0

高性能模块化Postfix日志解析器,经3.2GB生产数据验证,SMTPD事件100%准确率
Documentation
//! Tests for postfix-script component parser

use postfix_log_parser::components::{ComponentParser, PostfixScriptParser};
use postfix_log_parser::events::postfix_script::{
    PostfixScriptEvent, PostfixScriptFatalError, PostfixScriptOperation, PostfixScriptWarningType,
};
use postfix_log_parser::events::ComponentEvent;

#[test]
fn test_starting_system() {
    let parser = PostfixScriptParser::new();

    let result = parser.parse("starting the Postfix mail system");

    assert!(result.is_ok());
    if let Ok(ComponentEvent::PostfixScript(PostfixScriptEvent::SystemOperation {
        operation,
        ..
    })) = result
    {
        assert_eq!(operation, PostfixScriptOperation::Starting);
    } else {
        panic!("Expected SystemOperation::Starting");
    }
}

#[test]
fn test_system_running() {
    let parser = PostfixScriptParser::new();

    let result = parser.parse("the Postfix mail system is running: PID: 1");

    assert!(result.is_ok());
    if let Ok(ComponentEvent::PostfixScript(PostfixScriptEvent::SystemOperation {
        operation,
        ..
    })) = result
    {
        assert_eq!(operation, PostfixScriptOperation::Running { pid: Some(1) });
    } else {
        panic!("Expected SystemOperation::Running");
    }
}

#[test]
fn test_refreshing_system() {
    let parser = PostfixScriptParser::new();

    let result = parser.parse("refreshing the Postfix mail system");

    assert!(result.is_ok());
    if let Ok(ComponentEvent::PostfixScript(PostfixScriptEvent::SystemOperation {
        operation,
        ..
    })) = result
    {
        assert_eq!(operation, PostfixScriptOperation::Refreshing);
    } else {
        panic!("Expected SystemOperation::Refreshing");
    }
}

#[test]
fn test_cannot_execute_postconf() {
    let parser = PostfixScriptParser::new();

    let result = parser.parse("cannot execute /usr/sbin/postconf!");

    assert!(result.is_ok());
    if let Ok(ComponentEvent::PostfixScript(PostfixScriptEvent::FatalError { error, .. })) = result
    {
        assert_eq!(error, PostfixScriptFatalError::CannotExecutePostconf);
    } else {
        panic!("Expected FatalError::CannotExecutePostconf");
    }
}

#[test]
fn test_not_owned_by_root() {
    let parser = PostfixScriptParser::new();

    let result = parser.parse("not owned by root: /usr/lib/postfix/./sbin/cleanup");

    assert!(result.is_ok());
    if let Ok(ComponentEvent::PostfixScript(PostfixScriptEvent::Warning { warning, .. })) = result {
        assert_eq!(
            warning,
            PostfixScriptWarningType::NotOwnedBy {
                path: "/usr/lib/postfix/./sbin/cleanup".to_string(),
                expected_owner: "root".to_string()
            }
        );
    } else {
        panic!("Expected Warning::NotOwnedBy");
    }
}

#[test]
fn test_not_owned_by_postfix() {
    let parser = PostfixScriptParser::new();

    let result = parser.parse("not owned by postfix: /var/spool/postfix/incoming");

    assert!(result.is_ok());
    if let Ok(ComponentEvent::PostfixScript(PostfixScriptEvent::Warning { warning, .. })) = result {
        assert_eq!(
            warning,
            PostfixScriptWarningType::NotOwnedBy {
                path: "/var/spool/postfix/incoming".to_string(),
                expected_owner: "postfix".to_string()
            }
        );
    } else {
        panic!("Expected Warning::NotOwnedBy");
    }
}

#[test]
fn test_group_writable() {
    let parser = PostfixScriptParser::new();

    let result = parser.parse("group or other writable: /usr/lib/postfix/./sbin/cleanup/cleanup");

    assert!(result.is_ok());
    if let Ok(ComponentEvent::PostfixScript(PostfixScriptEvent::Warning { warning, .. })) = result {
        assert_eq!(
            warning,
            PostfixScriptWarningType::GroupWritable {
                path: "/usr/lib/postfix/./sbin/cleanup/cleanup".to_string()
            }
        );
    } else {
        panic!("Expected Warning::GroupWritable");
    }
}

#[test]
fn test_component_parser_interface() {
    let parser = PostfixScriptParser::new();

    assert_eq!(parser.component_name(), "postfix-script");
    assert!(parser.can_parse("postfix-script"));
    assert!(!parser.can_parse("smtpd"));
    assert!(!parser.can_parse("qmgr"));
}

#[test]
fn test_unsupported_message() {
    let parser = PostfixScriptParser::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: "postfix-script".to_string(),
        process_id: 75,
        log_level: PostfixLogLevel::Info,
        raw_message: "test message".to_string(),
    };

    let starting_event = PostfixScriptEvent::SystemOperation {
        base: base.clone(),
        operation: PostfixScriptOperation::Starting,
    };
    assert_eq!(starting_event.event_type(), "system_starting");

    let running_event = PostfixScriptEvent::SystemOperation {
        base: base.clone(),
        operation: PostfixScriptOperation::Running { pid: Some(1) },
    };
    assert_eq!(running_event.event_type(), "system_running");

    let refreshing_event = PostfixScriptEvent::SystemOperation {
        base: base.clone(),
        operation: PostfixScriptOperation::Refreshing,
    };
    assert_eq!(refreshing_event.event_type(), "system_refreshing");

    let fatal_event = PostfixScriptEvent::FatalError {
        base: base.clone(),
        error: PostfixScriptFatalError::CannotExecutePostconf,
    };
    assert_eq!(fatal_event.event_type(), "fatal_error");

    let warning_event = PostfixScriptEvent::Warning {
        base: base.clone(),
        warning: PostfixScriptWarningType::NotOwnedBy {
            path: "/test".to_string(),
            expected_owner: "root".to_string(),
        },
    };
    assert_eq!(warning_event.event_type(), "warning");
}