Improve documentation and tests.
This commit is contained in:
@@ -0,0 +1,356 @@
|
||||
//! 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
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user