Skip to main content

shadow_integration_tests/
lib.rs

1//! # Shadow Network Integration Tests
2//!
3//! Cross-crate integration tests verifying the full system works end-to-end:
4//! - Crypto → Messaging pipeline
5//! - Steganography → Transport pipeline
6//! - DHT → Storage → Replication pipeline
7//! - Full E2E message flow
8//! - DPI evasion statistical tests
9//! - Monitoring integration
10
11pub mod crypto_messaging;
12pub mod stego_pipeline;
13pub mod dht_storage;
14pub mod e2e_flow;
15pub mod dpi_evasion;
16
17/// Run all integration tests programmatically
18pub fn run_all_integration_tests() -> IntegrationReport {
19    let mut report = IntegrationReport::new();
20
21    report.run("crypto_messaging_e2e", || crypto_messaging::test_full_messaging_pipeline());
22    report.run("stego_transport_roundtrip", || stego_pipeline::test_stego_transport_roundtrip());
23    report.run("stego_multi_packet", || stego_pipeline::test_multi_packet_pipeline());
24    report.run("dht_storage_integration", || dht_storage::test_dht_with_content_store());
25    report.run("dht_replication_recovery", || dht_storage::test_replication_peer_loss());
26    report.run("e2e_message_flow", || e2e_flow::test_full_e2e_flow());
27    report.run("e2e_group_messaging", || e2e_flow::test_group_messaging_e2e());
28    report.run("e2e_offline_delivery", || e2e_flow::test_offline_queue_delivery());
29    report.run("dpi_entropy_analysis", || dpi_evasion::test_stego_entropy());
30    report.run("dpi_cover_traffic_analysis", || dpi_evasion::test_cover_traffic_indistinguishability());
31    report.run("dpi_packet_size_distribution", || dpi_evasion::test_packet_size_distribution());
32
33    report
34}
35
36/// Integration test report
37#[derive(Debug)]
38pub struct IntegrationReport {
39    pub results: Vec<IntegrationTestResult>,
40}
41
42/// Single integration test result
43#[derive(Debug, Clone)]
44pub struct IntegrationTestResult {
45    pub name: String,
46    pub passed: bool,
47    pub error: Option<String>,
48}
49
50impl IntegrationReport {
51    pub fn new() -> Self {
52        Self {
53            results: Vec::new(),
54        }
55    }
56
57    pub fn run<F: FnOnce() -> Result<(), String>>(&mut self, name: &str, test: F) {
58        match test() {
59            Ok(()) => {
60                self.results.push(IntegrationTestResult {
61                    name: name.to_string(),
62                    passed: true,
63                    error: None,
64                });
65            }
66            Err(e) => {
67                self.results.push(IntegrationTestResult {
68                    name: name.to_string(),
69                    passed: false,
70                    error: Some(e),
71                });
72            }
73        }
74    }
75
76    pub fn all_passed(&self) -> bool {
77        self.results.iter().all(|r| r.passed)
78    }
79
80    pub fn passed_count(&self) -> usize {
81        self.results.iter().filter(|r| r.passed).count()
82    }
83
84    pub fn total_count(&self) -> usize {
85        self.results.len()
86    }
87
88    pub fn summary(&self) -> String {
89        let mut lines = vec![format!(
90            "Integration Tests: {}/{} passed",
91            self.passed_count(),
92            self.total_count()
93        )];
94        for r in &self.results {
95            let status = if r.passed { "pass" } else { "FAIL" };
96            let detail = r.error.as_deref().unwrap_or("OK");
97            lines.push(format!("  {} {} — {}", status, r.name, detail));
98        }
99        lines.join("\n")
100    }
101}
102
103impl Default for IntegrationReport {
104    fn default() -> Self {
105        Self::new()
106    }
107}
108
109#[cfg(test)]
110mod tests {
111    use super::*;
112
113    #[test]
114    fn test_all_integrations() {
115        let report = run_all_integration_tests();
116        println!("{}", report.summary());
117        assert!(
118            report.all_passed(),
119            "Some integration tests failed:\n{}",
120            report.summary()
121        );
122    }
123}