use lazy_static::lazy_static; use std::path::PathBuf; use suricata_ipc::prelude::*; #[derive(Clone, Default)] struct LogIntercept { saw_record: std::sync::Arc, saw_warning: std::sync::Arc, } lazy_static! { static ref PARSE_FAILURE: regex::Regex = regex::Regex::new(".*Failed to parse rule '#?'.*").unwrap(); } impl log::Log for LogIntercept { fn enabled(&self, _metadata: &log::Metadata) -> bool { true } fn log(&self, record: &log::Record) { self.saw_record .store(true, std::sync::atomic::Ordering::Relaxed); let s = record.args().to_string(); if PARSE_FAILURE.is_match(&s) { self.saw_warning .store(true, std::sync::atomic::Ordering::Relaxed); } } /// Flushes any buffered records. fn flush(&self) {} } #[test] fn parse_rules() { let logger = Box::new(LogIntercept::default()); log::set_boxed_logger(logger.clone()).unwrap(); log::set_max_level(log::LevelFilter::Debug); let rules_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) .join("resources") .join("test.rules"); log::info!("Checking logger"); let rules = Rules::from_path(rules_path).expect("Failed to get rules"); assert_eq!(rules.len(), 22); let cache: IntelCache = rules.into(); assert!(cache .inner .get(&IdsKey { gid: 1, sid: 3003002 }) .is_some()); assert!(cache .inner .get(&IdsKey { gid: 1, sid: 3016009 }) .is_some()); assert!(logger.saw_record.load(std::sync::atomic::Ordering::Relaxed)); assert!(!logger .saw_warning .load(std::sync::atomic::Ordering::Relaxed)); }