use anyhow::{anyhow, Error, Result};
use scxtop::bpf_skel::types::bpf_event;
use scxtop::edm::{ActionHandler, BpfEventActionPublisher, BpfEventHandler, EventDispatchManager};
use scxtop::Action;
use tokio::sync::mpsc;
struct MockActionHandler {
pub actions_received: Vec<Action>,
pub should_fail: bool,
}
impl ActionHandler for MockActionHandler {
fn on_action(&mut self, action: &Action) -> Result<()> {
if self.should_fail {
Err(anyhow!("Mock action handler error"))
} else {
self.actions_received.push(action.clone());
Ok(())
}
}
}
struct MockBpfEventHandler {
pub events_received: Vec<bpf_event>,
pub should_fail: bool,
}
impl BpfEventHandler for MockBpfEventHandler {
fn on_event(&mut self, event: &bpf_event) -> Result<()> {
if self.should_fail {
Err(anyhow!("Mock BPF event handler error"))
} else {
self.events_received.push(*event);
Ok(())
}
}
}
fn create_mock_bpf_event() -> bpf_event {
bpf_event::default()
}
#[test]
fn test_edm_new() {
let edm = EventDispatchManager::new(None, None);
drop(edm); }
#[test]
fn test_register_action_handler() {
let mut edm = EventDispatchManager::new(None, None);
let handler = Box::new(MockActionHandler {
actions_received: Vec::new(),
should_fail: false,
});
edm.register_action_handler(handler);
}
#[test]
fn test_register_bpf_handler() {
let mut edm = EventDispatchManager::new(None, None);
let handler = Box::new(MockBpfEventHandler {
events_received: Vec::new(),
should_fail: false,
});
edm.register_bpf_handler(handler);
}
#[test]
fn test_edm_on_action() {
let mut edm = EventDispatchManager::new(None, None);
let handler1 = Box::new(MockActionHandler {
actions_received: Vec::new(),
should_fail: false,
});
let handler2 = Box::new(MockActionHandler {
actions_received: Vec::new(),
should_fail: false,
});
edm.register_action_handler(handler1);
edm.register_action_handler(handler2);
let action = Action::Quit;
let result = edm.on_action(&action);
assert!(result.is_ok());
}
#[test]
fn test_edm_on_action_with_error() {
let error_callback = Box::new(|_: Error| {
Ok(())
}) as Box<dyn Fn(Error) -> Result<()>>;
let mut edm = EventDispatchManager::new(Some(error_callback), None);
let handler = Box::new(MockActionHandler {
actions_received: Vec::new(),
should_fail: true,
});
edm.register_action_handler(handler);
let action = Action::Quit;
let result = edm.on_action(&action);
assert!(result.is_ok());
}
#[test]
fn test_edm_on_event() {
let mut edm = EventDispatchManager::new(None, None);
let handler1 = Box::new(MockBpfEventHandler {
events_received: Vec::new(),
should_fail: false,
});
let handler2 = Box::new(MockBpfEventHandler {
events_received: Vec::new(),
should_fail: false,
});
edm.register_bpf_handler(handler1);
edm.register_bpf_handler(handler2);
let event = create_mock_bpf_event();
let result = edm.on_event(&event);
assert!(result.is_ok());
}
#[test]
fn test_bpf_event_action_publisher() {
let (tx, _rx) = mpsc::unbounded_channel();
let mut publisher = BpfEventActionPublisher::new(tx);
let event = create_mock_bpf_event();
let result = publisher.on_event(&event);
assert!(result.is_ok());
}
#[test]
fn test_bpf_event_action_publisher_handles_conversion_error() {
let (tx, mut rx) = mpsc::unbounded_channel();
let mut publisher = BpfEventActionPublisher::new(tx);
let mut event = create_mock_bpf_event();
event.r#type = i32::MAX;
let result = publisher.on_event(&event);
assert!(result.is_ok());
assert!(rx.try_recv().is_err());
}