mod initialization_tests {
use super::super::initialization::is_manifest_url_ssrf_blocked;
#[test]
fn ssrf_blocks_localhost_by_name() {
assert!(is_manifest_url_ssrf_blocked("http://localhost/manifest.json"));
}
#[test]
fn ssrf_blocks_localhost_uppercase() {
assert!(is_manifest_url_ssrf_blocked("http://LOCALHOST/manifest.json"));
}
#[test]
fn ssrf_blocks_ipv4_loopback() {
assert!(is_manifest_url_ssrf_blocked("http://127.0.0.1/manifest.json"));
}
#[test]
fn ssrf_blocks_ipv4_private_192_168() {
assert!(is_manifest_url_ssrf_blocked("http://192.168.1.100/manifest.json"));
}
#[test]
fn ssrf_blocks_ipv4_private_10_x() {
assert!(is_manifest_url_ssrf_blocked("http://10.0.0.1/manifest.json"));
}
#[test]
fn ssrf_blocks_ipv4_private_172_16() {
assert!(is_manifest_url_ssrf_blocked("http://172.16.0.1/manifest.json"));
}
#[test]
fn ssrf_blocks_ipv4_link_local() {
assert!(is_manifest_url_ssrf_blocked("http://169.254.1.1/manifest.json"));
}
#[test]
fn ssrf_blocks_ipv6_loopback() {
assert!(is_manifest_url_ssrf_blocked("http://[::1]/manifest.json"));
}
#[test]
fn ssrf_blocks_ipv6_unspecified() {
assert!(is_manifest_url_ssrf_blocked("http://[::]/manifest.json"));
}
#[test]
fn ssrf_blocks_ipv6_ula() {
assert!(is_manifest_url_ssrf_blocked("http://[fd00::1]/manifest.json"));
}
#[test]
fn ssrf_blocks_unparseable_url() {
assert!(is_manifest_url_ssrf_blocked("not a url at all"));
}
#[test]
fn ssrf_allows_public_https() {
assert!(!is_manifest_url_ssrf_blocked("https://cdn.example.com/manifest.json"));
}
#[test]
fn ssrf_allows_public_ipv4() {
assert!(!is_manifest_url_ssrf_blocked("http://93.184.216.34/manifest.json"));
}
#[test]
fn ssrf_allows_public_ipv6_global() {
assert!(!is_manifest_url_ssrf_blocked("http://[2001:db8::1]/manifest.json"));
}
}
#[cfg(test)]
mod lifecycle_tests {
use std::time::Duration;
use super::super::lifecycle::drain_lifecycle_tasks;
#[tokio::test]
async fn drain_lifecycle_tasks_aborts_infinite_loops() {
let mut tasks: tokio::task::JoinSet<()> = tokio::task::JoinSet::new();
for _ in 0..3 {
tasks.spawn(async {
let mut ticker = tokio::time::interval(Duration::from_secs(60));
loop {
ticker.tick().await;
}
});
}
let drain =
tokio::time::timeout(Duration::from_secs(5), drain_lifecycle_tasks(tasks, 5)).await;
assert!(
drain.is_ok(),
"drain_lifecycle_tasks must abort infinite-loop tasks within the timeout"
);
}
#[tokio::test]
async fn drain_lifecycle_tasks_returns_quickly_for_empty_set() {
let tasks: tokio::task::JoinSet<()> = tokio::task::JoinSet::new();
let drain =
tokio::time::timeout(Duration::from_secs(1), drain_lifecycle_tasks(tasks, 5)).await;
assert!(drain.is_ok(), "drain on an empty JoinSet must be a no-op");
}
}