#[cfg(feature = "pnet-backend")]
use netui::backend::PnetBackendFactory;
#[cfg(feature = "pnet-backend")]
use netui::backend::{BackendConfig, BackendFactory};
#[cfg(feature = "ebpf-backend")]
use netui::backend::EbpfBackendFactory;
fn get_test_interface() -> String {
use pnet_datalink::interfaces;
for interface in interfaces() {
if !interface.is_loopback() && !interface.ips.is_empty() {
return interface.name;
}
}
"lo".to_string()
}
#[test]
#[cfg(feature = "pnet-backend")]
fn test_backend_factory_names() {
let pnet_factory = PnetBackendFactory;
assert_eq!(pnet_factory.name(), "pnet");
assert!(!pnet_factory.name().is_empty());
}
#[test]
fn test_backend_config_creation() {
let config = BackendConfig::new("test0".to_string());
assert_eq!(config.interface_name, "test0");
assert_eq!(config.read_timeout_ms, Some(500));
}
#[test]
#[cfg(feature = "pnet-backend")]
fn test_pnet_backend_fails_with_invalid_interface() {
let factory = PnetBackendFactory;
let config = BackendConfig::new("nonexistent_interface_12345".to_string());
let result = factory.create(config);
assert!(result.is_err(), "Should fail with invalid interface name");
if let Err(e) = result {
let error_msg = e.to_string().to_lowercase();
assert!(
error_msg.contains("interface") || error_msg.contains("not found"),
"Error should mention interface issue: {}",
e
);
}
}
#[test]
#[cfg(feature = "pnet-backend")]
#[ignore]
fn test_pnet_backend_creates_with_valid_interface() {
let factory = PnetBackendFactory;
let interface_name = get_test_interface();
let config = BackendConfig::new(interface_name.clone());
let result = factory.create(config);
match result {
Ok((mut source, _sink)) => {
let packet = source.next_packet();
let _ = packet;
}
Err(e) => {
eprintln!(
"Warning: Could not create pnet backend on {}: {}",
interface_name, e
);
}
}
}
#[test]
#[cfg(all(feature = "pnet-backend", feature = "ebpf-backend"))]
fn test_both_backends_implement_factory() {
let _pnet_factory = PnetBackendFactory;
let _ebpf_factory = EbpfBackendFactory;
fn assert_factory<T: BackendFactory>(_factory: T) {}
assert_factory(PnetBackendFactory);
assert_factory(EbpfBackendFactory);
}
#[test]
#[cfg(feature = "ebpf-backend")]
fn test_ebpf_backend_factory_name() {
let factory = EbpfBackendFactory;
assert_eq!(factory.name(), "ebpf");
}
#[test]
#[cfg(feature = "ebpf-backend")]
fn test_ebpf_backend_fails_with_invalid_interface() {
let factory = EbpfBackendFactory;
let config = BackendConfig::new("nonexistent_interface_12345".to_string());
let result = factory.create(config);
assert!(result.is_err(), "Should fail with invalid interface name");
}
#[test]
#[cfg(feature = "pnet-backend")]
fn test_packet_sink_handles_invalid_data() {
use netui::backend::PnetBackendFactory;
let factory = PnetBackendFactory;
let interface_name = get_test_interface();
let config = BackendConfig::new(interface_name.clone());
let result = factory.create(config);
match result {
Ok((mut _source, mut sink)) => {
let invalid_packet = vec![0u8; 5];
let send_result = sink.send_packet(&invalid_packet);
let _ = send_result;
}
Err(e) => {
eprintln!(
"Warning: Could not create pnet backend on {}: {}",
interface_name, e
);
}
}
}
#[test]
#[cfg(feature = "pnet-backend")]
fn test_packet_with_context_creation() {
use netui::backend::PacketWithContext;
let packet = PacketWithContext {
data: vec![0u8; 100],
hook_source: None,
original_len: None,
direct_event: None,
timestamp_ns: None,
};
assert_eq!(packet.data.len(), 100);
assert!(packet.hook_source.is_none());
assert!(packet.original_len.is_none());
let packet = PacketWithContext {
data: vec![0u8; 100],
hook_source: Some(0), original_len: Some(1500),
direct_event: None,
timestamp_ns: Some(123456789),
};
assert_eq!(packet.data.len(), 100);
assert_eq!(packet.hook_source, Some(0));
assert_eq!(packet.original_len, Some(1500));
}