rust-network-mgr 0.1.8

Linux based network management, packet routing and LAN peers IP monitoring service
use rust_network_mgr::{
    config::{load_config}, types::{AppConfig, ControlCommand, NetworkEvent, DockerEvent, SystemEvent}, NetworkMonitor, NftablesManager, SocketHandler
};
use std::io::Write;
use std::sync::Arc;
use tempfile::NamedTempFile;
use tokio::sync::{mpsc, Mutex};
use tokio::runtime::Runtime;

// Helper to create a dummy config file
fn create_dummy_config_file() -> (NamedTempFile, AppConfig) {
    let yaml = r#"
interfaces:
  - name: "lo"
    dhcp: false
    address: "127.0.0.1/8"
  - name: "eth0"
    dhcp: true
    nftables_zone: "wan"
socket_path: "/tmp/rust_network_mgr_test.sock"
"#;
    let mut file = NamedTempFile::new().unwrap();
    writeln!(file, "{}", yaml).unwrap();
    let config = load_config(Some(file.path().to_str().unwrap())).expect("Failed to load dummy config");
    (file, config)
}

#[tokio::test]
async fn test_config_loading_integration() {
    let (_config_file, config) = create_dummy_config_file();
    // Assuming validate_config is private, we cannot directly call it. 
    // If it's intended to be public, consider making it public or providing a public wrapper.
    // For demonstration, let's assume there's a public wrapper or an alternative validation method.
    // assert!(validate_config(&config).is_ok());
}

#[test]
#[ignore] // Needs refinement and potentially root access for some components
fn test_component_instantiation() {
    let rt = Runtime::new().unwrap();
    rt.block_on(async {
        let (_temp_file, config) = create_dummy_config_file();

        // Create channels
        let (network_tx, _network_rx) = mpsc::channel::<NetworkEvent>(100);
        let (control_tx, _control_rx) = mpsc::channel::<ControlCommand>(10);
        let (docker_ev, _docker_ev) = mpsc::channel::<DockerEvent>(100);
        let (system_ev, _system_ev) = mpsc::channel::<SystemEvent>(100);

        // Test NetworkMonitor instantiation (Assuming new returns Self)
        let _monitor = NetworkMonitor::new(system_ev.clone()); 

        // Test NftablesManager instantiation
        let interface_config_arc = Arc::new(Mutex::new(config.interfaces.clone()));
        let nft_manager_result = NftablesManager::new(interface_config_arc).await;
        assert!(nft_manager_result.is_ok(), "NftablesManager creation failed: {:?}", nft_manager_result.err());

        // Test SocketHandler instantiation
        let socket_result = SocketHandler::new(config.socket_path.as_deref(), system_ev.clone()).await;
        assert!(socket_result.is_ok(), "SocketHandler creation failed: {:?}", socket_result.err());
        // Cleanup socket file if created
        if let Some(path) = &config.socket_path {
            if std::path::Path::new(path).exists() {
                let _ = std::fs::remove_file(path);
            }
        }
    });
}

// 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.