rust-network-mgr 0.1.2

Linux based network management, packet routing and LAN peers IP monitoring service
Documentation
use rust_network_mgr::{config, network::NetworkMonitor, nftables::NftablesManager, socket::SocketHandler, types::{ControlCommand, NetworkEvent}};

use std::collections::HashMap;
use std::io::Write;
use std::net::IpAddr;
use tempfile::NamedTempFile;
use tokio::sync::mpsc;

// Helper to create a dummy config file
fn create_dummy_config_file() -> NamedTempFile {
    let yaml = r#"
interfaces:
  - name: lo
    dhcp: false
    address: 127.0.0.1/8
    nftables_zone: local
  - name: eth_test
    dhcp: true
    nftables_zone: wan
socket_path: /tmp/rust-net-test.sock
nftables_rules_path: /tmp/dummy_rules.nft
"#;
    let mut file = NamedTempFile::new().unwrap();
    writeln!(file, "{}", yaml).unwrap();
    file
}

#[tokio::test]
async fn test_config_loading_integration() {
    let config_file = create_dummy_config_file();
    let result = config::load_config(Some(config_file.path()));
    assert!(result.is_ok());
    let config = result.unwrap();
    assert_eq!(config.interfaces.len(), 2);
    assert_eq!(config.interfaces[0].name, "lo");
    assert_eq!(config.interfaces[1].nftables_zone, Some("wan".to_string()));
    assert!(config::validate_config(&config).is_ok());
}

#[tokio::test]
async fn test_component_instantiation() {
    // Create dummy channels
    let (network_tx, _network_rx) = mpsc::channel::<NetworkEvent>(1);
    let (control_tx, _control_rx) = mpsc::channel::<ControlCommand>(1);

    // Load a dummy config
    let config_file = create_dummy_config_file();
    let config = config::load_config(Some(config_file.path())).expect("Failed to load dummy config");

    // Test NetworkMonitor instantiation
    let _monitor = NetworkMonitor::new(network_tx);
    // Note: monitor.start() requires root/capabilities and network setup, cannot easily test here.

    // Test NftablesManager instantiation
    let _nft_manager = NftablesManager::new(config.clone());

    // Test SocketHandler instantiation
    // This might fail if socket path exists and cannot be removed, or due to permissions
    let socket_result = SocketHandler::new(config.socket_path.as_deref(), control_tx).await;
    // Clean up the socket file if created
    if let Some(path) = config.socket_path {
        let _ = std::fs::remove_file(path); // Ignore error if file doesn't exist
    }
    assert!(socket_result.is_ok(), "SocketHandler creation failed: {:?}", socket_result.err());

    println!("Basic component instantiation successful.");
}

// Add more tests as needed, potentially focusing on:
// - Specific parsing logic in config
// - State update logic in main (if extracted)
// - Command parsing in socket (if extracted)

// Integration tests requiring network namespaces or mocking are separate.