Files
NetTest/tests/integration_examples.rs
2025-08-11 17:29:47 +02:00

357 lines
11 KiB
Rust

//! Integration test examples demonstrating `NetTest` library usage.
//!
//! These tests serve as comprehensive examples of how to use the `NetTest` library
//! for various network testing scenarios. They can be run with `cargo test --test integration_examples`.
use hickory_client::rr::RecordType;
use nettest::*;
use std::time::Duration;
use tokio;
#[tokio::test]
async fn example_basic_dns_query() {
// Example: Basic DNS A record query
let test = dns::DnsTest::new("google.com".to_string(), RecordType::A);
let result = test.run().await;
// DNS queries should generally succeed for major domains
assert!(
result.success,
"DNS query should succeed for google.com: {:?}",
result.error
);
assert!(result.details.contains("A records"));
assert!(result.duration < Duration::from_secs(10));
}
#[tokio::test]
async fn example_dns_with_custom_server() {
// Example: Query specific DNS server with timeout
use std::net::SocketAddr;
use std::str::FromStr;
let server = SocketAddr::from_str("8.8.8.8:53").unwrap();
let test = dns::DnsTest::new("cloudflare.com".to_string(), RecordType::A)
.with_server(server)
.with_timeout(Duration::from_secs(5))
.with_tcp(false);
let result = test.run().await;
assert!(
result.success,
"Custom DNS server query failed: {:?}",
result.error
);
assert!(result.test_name.contains("8.8.8.8"));
assert!(result.details.contains("via 8.8.8.8"));
}
#[tokio::test]
async fn example_comprehensive_dns_testing() {
// Example: Test against all DNS providers
let results = dns::test_common_dns_servers("example.com", RecordType::A).await;
// Should test at least 30 providers (23 traditional + 16 DoH)
assert!(
results.len() >= 30,
"Should test many DNS providers, got {}",
results.len()
);
// Count successful vs failed
let successful = results.iter().filter(|r| r.success).count();
let total = results.len();
println!(
"DNS provider test results: {}/{} successful",
successful, total
);
// At least 50% of providers should work for a major domain
assert!(
successful * 2 >= total,
"At least 50% of DNS providers should work"
);
// Should have both traditional and DoH tests
let has_traditional = results.iter().any(|r| r.test_name.contains("8.8.8.8"));
let has_doh = results.iter().any(|r| r.test_name.contains("DoH"));
assert!(has_traditional, "Should include traditional DNS tests");
assert!(has_doh, "Should include DoH tests");
}
#[tokio::test]
async fn example_doh_testing() {
// Example: DNS-over-HTTPS testing with multiple providers
let results = dns::doh::test_doh_providers("google.com", RecordType::A).await;
assert!(!results.is_empty(), "Should have DoH provider results");
let successful = results.iter().filter(|r| r.success).count();
println!(
"DoH provider test results: {}/{} successful",
successful,
results.len()
);
// Should have results from multiple providers
let provider_names: std::collections::HashSet<_> = results
.iter()
.map(|r| {
// Extract provider name from test name
if let Some(pos) = r.test_name.find(" via ") {
&r.test_name[pos + 5..]
} else {
"unknown"
}
})
.collect();
assert!(
provider_names.len() >= 10,
"Should test multiple DoH providers"
);
}
#[tokio::test]
async fn example_network_connectivity() {
// Example: Basic network connectivity testing
let tcp_test = network::NetworkTest::new(
"google.com".to_string(),
network::IpVersion::V4,
network::NetworkProtocol::Tcp,
)
.with_port(80);
let result = tcp_test.run().await;
assert!(
result.success,
"TCP connection to google.com:80 should succeed: {:?}",
result.error
);
assert!(result.test_name.contains("Tcp test to"));
assert!(result.test_name.contains("google.com"));
assert!(result.test_name.contains(":80"));
}
#[tokio::test]
async fn example_ping_testing() {
// Example: Multiple ping tests
let results = network::ping_test("8.8.8.8", network::IpVersion::V4, 3).await;
assert_eq!(results.len(), 3, "Should perform 3 ping tests");
for (i, result) in results.iter().enumerate() {
let expected_name = format!("ICMP ping #{} to 8.8.8.8 (V4)", i + 1);
assert_eq!(result.test_name, expected_name);
// Ping to 8.8.8.8 should generally work
if !result.success {
println!("Warning: Ping #{} failed: {:?}", i + 1, result.error);
}
}
}
#[tokio::test]
async fn example_mtu_discovery() {
// Example: MTU discovery with custom range
let discovery = mtu::MtuDiscovery::new("cloudflare.com".to_string(), network::IpVersion::V4)
.with_range(1200, 1600);
let result = discovery.discover().await;
// MTU discovery might fail due to network restrictions, but the structure should be correct
assert!(result.test_name.contains("MTU discovery"));
assert!(result.test_name.contains("cloudflare.com"));
if result.success {
assert!(result.details.contains("Discovered MTU"));
println!("MTU discovery result: {}", result.details);
} else {
println!(
"MTU discovery failed (expected in some environments): {:?}",
result.error
);
}
}
#[tokio::test]
async fn example_common_mtu_testing() {
// Example: Test common MTU sizes
let results = mtu::test_common_mtu_sizes("google.com", network::IpVersion::V4, false).await;
assert!(!results.is_empty(), "Should test multiple MTU sizes");
for result in &results {
assert!(result.test_name.contains("MTU test"));
assert!(result.test_name.contains("google.com"));
}
let successful = results.iter().filter(|r| r.success).count();
println!(
"MTU size tests: {}/{} successful",
successful,
results.len()
);
}
#[tokio::test]
async fn example_txt_record_handling() {
// Example: Large TXT record handling (tests EDNS0 support)
let test = dns::DnsTest::new("google.com".to_string(), RecordType::TXT);
let result = test.run().await;
// Google has large TXT records, this tests EDNS0 support
if result.success {
assert!(result.details.contains("TXT records"));
println!("TXT record result: {}", result.details);
// Should complete reasonably quickly with EDNS0
assert!(result.duration < Duration::from_secs(5));
} else {
println!("TXT query failed: {:?}", result.error);
}
}
#[tokio::test]
async fn example_security_testing() {
// Example: Security-focused DNS testing
let test = dns::DnsTest::new("example.com".to_string(), RecordType::A);
// Test security analysis
let security_result = test.run_security_test().await;
assert!(security_result.test_name.contains("DNS"));
// Security tests interpret results differently than normal tests
println!("Security test result: {}", security_result.test_name);
}
#[tokio::test]
async fn example_dns_filtering_analysis() {
// Example: Test DNS filtering capabilities
let results = dns::categories::test_dns_filtering_effectiveness().await;
assert!(!results.is_empty(), "Should have filtering test results");
for result in &results {
println!(
"Filtering test: {} - Success: {}",
result.test_name, result.success
);
}
}
#[tokio::test]
async fn example_comprehensive_dns_queries() {
// Example: Test multiple record types
let record_types = [
RecordType::A,
RecordType::AAAA,
RecordType::MX,
RecordType::NS,
RecordType::TXT,
];
for record_type in &record_types {
let test = dns::DnsTest::new("google.com".to_string(), *record_type);
let result = test.run().await;
println!(
"Record type {:?}: Success = {}",
record_type, result.success
);
if result.success {
assert!(result
.details
.contains(&format!("{:?} records", record_type)));
}
}
}
#[tokio::test]
async fn example_ipv6_support() {
// Example: IPv6 connectivity testing
let test = network::NetworkTest::new(
"google.com".to_string(),
network::IpVersion::V6,
network::NetworkProtocol::Tcp,
)
.with_port(80);
let result = test.run().await;
// IPv6 may not be available in all environments
if result.success {
assert!(result.test_name.contains("V6"));
println!("IPv6 test successful: {}", result.details);
} else {
println!("IPv6 test failed (may be expected): {:?}", result.error);
}
}
#[tokio::test]
async fn example_timeout_handling() {
// Example: Testing timeout behavior
let test = dns::DnsTest::new(
"nonexistent-domain-12345.invalid".to_string(),
RecordType::A,
)
.with_timeout(Duration::from_millis(100)); // Very short timeout
let result = test.run().await;
// Should either fail due to nonexistent domain or timeout
assert!(!result.success);
assert!(result.duration <= Duration::from_secs(1));
if let Some(error) = result.error {
match error {
NetworkError::Timeout => println!("Request timed out as expected"),
NetworkError::DnsResolution(_) => println!("DNS resolution failed as expected"),
_ => println!("Other error: {:?}", error),
}
}
}
#[tokio::test]
async fn example_concurrent_testing() {
// Example: Concurrent testing capabilities
use tokio::time::Instant;
let start = Instant::now();
// Run multiple tests concurrently
let futures = vec![
tokio::spawn(async {
let test = dns::DnsTest::new("google.com".to_string(), RecordType::A);
test.run().await
}),
tokio::spawn(async {
let test = dns::DnsTest::new("cloudflare.com".to_string(), RecordType::A);
test.run().await
}),
tokio::spawn(async {
let test = dns::DnsTest::new("github.com".to_string(), RecordType::A);
test.run().await
}),
];
let results = futures::future::join_all(futures).await;
let duration = start.elapsed();
// Concurrent execution should be faster than sequential
assert!(duration < Duration::from_secs(10));
for result in results {
let test_result = result.unwrap();
println!(
"Concurrent test: {} - Success: {}",
test_result.test_name, test_result.success
);
}
}