Files
nx9-wg/crates/nx9-wg-api/tests/test_reconciliation_subsystem.rs
T
2026-09-02 15:19:19 +05:30

80 lines
2.7 KiB
Rust

//! Integration test suite for Reconciliation Engine.
use nx9_wg_api::reconciliation::ReconciliationEngine;
use nx9_wg_api::state::AppState;
use nx9_wg_core::crypto::generate_keypair;
use nx9_wg_core::types::wireguard::{Interface, InterfaceRole};
use nx9_wg_core::validation::validate_cidr;
use nx9_wg_db::Store;
use nx9_wg_network::SimulatedNetworkEngine;
use nx9_wireguard::{SimulatedWireGuardEngine, WireGuardEngine};
use std::sync::Arc;
use tempfile::tempdir;
use uuid::Uuid;
#[tokio::test]
async fn test_reconciliation_engine_drift_detection_and_apply() {
let dir = tempdir().expect("create temp dir");
let db_path = dir.path().join("reconcile.db");
let store = Store::connect(&db_path.to_string_lossy())
.await
.expect("connect to db");
store.migrate().await.expect("run migrations");
let state = AppState::new(store.clone());
let wg_engine = Arc::new(SimulatedWireGuardEngine::new());
let net_engine = Arc::new(SimulatedNetworkEngine::new());
let reconciler = ReconciliationEngine::new(state, wg_engine.clone(), net_engine.clone());
// 1. Create desired interface in SQLite
let (priv_key, pub_key) = generate_keypair();
let iface = Interface {
id: Uuid::new_v4(),
name: "wg0".to_string(),
role: InterfaceRole::Overlay,
private_key: priv_key,
public_key: pub_key,
listen_port: Some(51820),
address_v4: validate_cidr("10.0.0.1/24").unwrap(),
address_v6: None,
mtu: Some(1420),
dns: None,
enabled: true,
pre_up: None,
post_up: None,
pre_down: None,
post_down: None,
created_at: chrono::Utc::now().naive_utc(),
updated_at: chrono::Utc::now().naive_utc(),
};
store
.create_interface(&iface)
.await
.expect("create interface");
// 2. Compute plan: should detect missing wg0 in kernel
let plan = reconciler.plan().await.expect("compute plan");
assert!(plan.has_drift);
assert_eq!(plan.interface_changes, 1);
assert!(!plan.actions.is_empty());
// 3. Apply reconciliation
let report = reconciler.apply().await.expect("apply plan");
assert!(report.success);
assert!(report.executed_actions > 0);
// 4. Verify live WireGuard interface state
let live_stats = wg_engine.get_interface_stats("wg0").await.unwrap();
assert!(live_stats.is_some());
let stats = live_stats.unwrap();
assert_eq!(stats.name, "wg0");
assert_eq!(stats.listen_port, 51820);
// 5. Verify audit event was logged
let audits = store
.list_audit_events(&nx9_wg_db::AuditFilter::default(), 10, 0)
.await
.expect("list audits");
assert!(!audits.is_empty());
}