From 61bb4bb3155ee2e938d74fc19e5ad1669ccc214a Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 2 Feb 2024 15:09:45 +0100 Subject: [PATCH] test nameserver with dig --- src/lib.rs | 60 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 79e43bb7..80bc2a5a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ use core::fmt; -use std::process::{self, ExitStatus, Output}; +use std::process::{self, Child, Output}; use std::sync::atomic; use std::{ fs, @@ -48,7 +48,7 @@ fn nsd_conf(domain: &str) -> String { template.render(context! { domain => domain }).unwrap() } -enum Domain<'a> { +pub enum Domain<'a> { Root, Tld { domain: &'a str }, } @@ -63,11 +63,12 @@ impl Domain<'_> { } pub struct NsdContainer { - inner: Container, + child: Child, + container: Container, } impl NsdContainer { - pub fn new(domain: Domain) -> Result { + pub fn start(domain: Domain) -> Result { let container = Container::run(Image::Nsd)?; container.exec(&["mkdir", "-p", "/etc/nsd/zones"])?; @@ -86,11 +87,19 @@ impl NsdContainer { container.cp(zone_path, &zone_file_contents, CHMOD_RW_EVERYONE)?; - Ok(Self { inner: container }) + let child = container.spawn(&["nsd", "-d"])?; + + Ok(Self { child, container }) } - pub fn start(&self) -> Result { - self.inner.exec2(&["nsd", "-d"]) + pub fn ip_addr(&self) -> Result { + self.container.ip_addr() + } +} + +impl Drop for NsdContainer { + fn drop(&mut self) { + let _ = self.child.kill(); } } @@ -190,14 +199,13 @@ impl Container { Ok(output) } - // FIXME - pub fn exec2(&self, cmd: &[&str]) -> Result { + pub fn spawn(&self, cmd: &[&str]) -> Result { let mut command = Command::new("docker"); command.args(&["exec", "-t", &self.id]).args(cmd); - let status = command.status()?; + let child = command.spawn()?; - Ok(status) + Ok(child) } pub fn ip_addr(&self) -> Result { @@ -296,28 +304,34 @@ mod tests { Ok(()) } - // TODO create `nsd.conf` file at runtime #[test] fn tld_setup() -> Result<()> { - let tld_ns = NsdContainer::new(Domain::Tld { domain: "com." })?; - tld_ns.start()?; + let tld_ns = NsdContainer::start(Domain::Tld { domain: "com." })?; + let ip_addr = tld_ns.ip_addr()?; + + let client = Container::run(Image::Client)?; + let output = client.exec(&["dig", &format!("@{ip_addr}"), "SOA", "com."])?; + + assert!(output.status.success()); + let stdout = core::str::from_utf8(&output.stdout)?; + println!("{stdout}"); + assert!(stdout.contains("status: NOERROR")); Ok(()) } #[test] fn root_setup() -> Result<()> { - let root_ns = NsdContainer::new(Domain::Root)?; - root_ns.start()?; + let root_ns = NsdContainer::start(Domain::Root)?; + let ip_addr = root_ns.ip_addr()?; - // let root_ns = Container::run(Image::Nsd)?; + let client = Container::run(Image::Client)?; + let output = client.exec(&["dig", &format!("@{ip_addr}"), "SOA", "."])?; - // root_ns.exec(&["mkdir", "-p", "/etc/nsd/zones"])?; - // let zone_path = "/etc/nsd/zones/main.zone"; - // root_ns.cp("/etc/nsd/nsd.conf", &nsd_conf("."), CHMOD_RW_EVERYONE)?; - // root_ns.cp(zone_path, &root_zone(), CHMOD_RW_EVERYONE)?; - - // root_ns.exec2(&["nsd", "-d"])?; + assert!(output.status.success()); + let stdout = core::str::from_utf8(&output.stdout)?; + println!("{stdout}"); + assert!(stdout.contains("status: NOERROR")); Ok(()) }