pub mod coredns;
pub mod nginx;
pub use reqwest;
pub use testcontainers;
pub use nginx::*;
use std::time::Duration;
use coredns::CoreDnsContainer;
use testcontainers::core::WaitFor;
pub struct DnsTestEnv {
#[allow(dead_code)]
backend_a: NginxContainer,
#[allow(dead_code)]
backend_b: NginxContainer,
coredns: CoreDnsContainer,
backend_b_ip: String,
network: String,
}
fn dns_backend_config(name: &str) -> String {
format!(
r#"events {{ worker_connections 64; }}
http {{
server {{
listen 80;
location / {{
return 200 '{name}';
}}
}}
}}
"#
)
}
impl DnsTestEnv {
pub async fn start(network_prefix: &str) -> Self {
let network = format!("{network_prefix}-{}", std::process::id());
let backend_a = NginxContainer::builder()
.network(&network)
.start(dns_backend_config("backend-a"))
.await;
let backend_b = NginxContainer::builder()
.network(&network)
.start(dns_backend_config("backend-b"))
.await;
let backend_a_ip = backend_a
.bridge_ip()
.expect("Failed to get backend-a IP")
.to_string();
let backend_b_ip = backend_b
.bridge_ip()
.expect("Failed to get backend-b IP")
.to_string();
eprintln!("backend-a IP: {backend_a_ip}");
eprintln!("backend-b IP: {backend_b_ip}");
let coredns = CoreDnsContainer::start(&network, &backend_a_ip).await;
Self {
backend_a,
backend_b,
coredns,
backend_b_ip,
network,
}
}
pub fn coredns_ip(&self) -> &str {
self.coredns.ip()
}
pub fn network(&self) -> &str {
&self.network
}
pub async fn start_nginx(&self, config: impl Into<Vec<u8>>) -> NginxContainer {
let startup_script = self.nginx_startup_script();
NginxContainer::builder()
.network(&self.network)
.entrypoint("sh")
.cmd(vec!["-c", &startup_script])
.wait_for(WaitFor::message_on_stderr("start worker process"))
.start(config)
.await
}
pub async fn switch_to_backend_b(&self) {
self.coredns.update_hosts(&self.backend_b_ip);
tokio::time::sleep(Duration::from_secs(5)).await;
}
pub fn nginx_startup_script(&self) -> String {
format!(
"echo 'nameserver {}' > /etc/resolv.conf && \
exec nginx -g 'daemon off; error_log /dev/stderr notice;'",
self.coredns_ip()
)
}
}