turn dns_test::{subject,peer} into immutable statics
using `std::env::set_var` to set or change the value of either DNS_TEST_SUBJECT or DNS_TEST_PEER is A Bad Idea, specially so when tests are running in parallel we can't forbid the use of `env::set_var` _but_ at least we can ensure that even in its presence the return value of `dns_test::{subject,peer}` will not change this is accomplished using a "lazy" static variable that gets initialized at most once during the lifetime of the process instead of reading the env var each time `{subject,peer}` is called to better convey the fact that the return value of `{subject,peer}` won't change, we present them as static variables instead
This commit is contained in:
parent
2e46421927
commit
58239028f4
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -155,6 +155,7 @@ name = "dns-test"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ctrlc",
|
||||
"lazy_static",
|
||||
"minijinja",
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
|
@ -295,6 +296,12 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
|
|
|
@ -8,7 +8,7 @@ use dns_test::{Network, Result, FQDN};
|
|||
fn rrsig_in_answer_section() -> Result<()> {
|
||||
let network = Network::new()?;
|
||||
|
||||
let ns = NameServer::new(&dns_test::subject(), FQDN::ROOT, &network)?
|
||||
let ns = NameServer::new(&dns_test::SUBJECT, FQDN::ROOT, &network)?
|
||||
.sign()?
|
||||
.start()?;
|
||||
|
||||
|
@ -37,7 +37,7 @@ fn rrsig_in_answer_section() -> Result<()> {
|
|||
fn rrsig_in_authority_section() -> Result<()> {
|
||||
let network = Network::new()?;
|
||||
|
||||
let ns = NameServer::new(&dns_test::subject(), FQDN::ROOT, &network)?
|
||||
let ns = NameServer::new(&dns_test::SUBJECT, FQDN::ROOT, &network)?
|
||||
.sign()?
|
||||
.start()?;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use dns_test::{Network, Result, FQDN};
|
|||
#[test]
|
||||
fn authoritative_answer() -> Result<()> {
|
||||
let network = &Network::new()?;
|
||||
let ns = NameServer::new(&dns_test::subject(), FQDN::ROOT, network)?.start()?;
|
||||
let ns = NameServer::new(&dns_test::SUBJECT, FQDN::ROOT, network)?.start()?;
|
||||
|
||||
let client = Client::new(network)?;
|
||||
let ans = client.dig(
|
||||
|
|
|
@ -11,9 +11,8 @@ fn can_resolve() -> Result<()> {
|
|||
let needle_fqdn = FQDN("example.nameservers.com.")?;
|
||||
|
||||
let network = Network::new()?;
|
||||
let peer = dns_test::peer();
|
||||
|
||||
let mut leaf_ns = NameServer::new(&peer, FQDN::NAMESERVERS, &network)?;
|
||||
let mut leaf_ns = NameServer::new(&dns_test::PEER, FQDN::NAMESERVERS, &network)?;
|
||||
leaf_ns.add(Record::a(needle_fqdn.clone(), expected_ipv4_addr));
|
||||
|
||||
let Graph {
|
||||
|
@ -22,7 +21,7 @@ fn can_resolve() -> Result<()> {
|
|||
..
|
||||
} = Graph::build(leaf_ns, Sign::No)?;
|
||||
|
||||
let resolver = Resolver::new(&network, root).start(&dns_test::subject())?;
|
||||
let resolver = Resolver::new(&network, root).start(&dns_test::SUBJECT)?;
|
||||
let resolver_ip_addr = resolver.ipv4_addr();
|
||||
|
||||
let client = Client::new(&network)?;
|
||||
|
@ -47,9 +46,8 @@ fn nxdomain() -> Result<()> {
|
|||
let needle_fqdn = FQDN("unicorn.nameservers.com.")?;
|
||||
|
||||
let network = Network::new()?;
|
||||
let peer = dns_test::peer();
|
||||
|
||||
let leaf_ns = NameServer::new(&peer, FQDN::NAMESERVERS, &network)?;
|
||||
let leaf_ns = NameServer::new(&dns_test::PEER, FQDN::NAMESERVERS, &network)?;
|
||||
|
||||
let Graph {
|
||||
nameservers: _nameservers,
|
||||
|
@ -57,7 +55,7 @@ fn nxdomain() -> Result<()> {
|
|||
..
|
||||
} = Graph::build(leaf_ns, Sign::No)?;
|
||||
|
||||
let resolver = Resolver::new(&network, root).start(&dns_test::subject())?;
|
||||
let resolver = Resolver::new(&network, root).start(&dns_test::SUBJECT)?;
|
||||
let resolver_ip_addr = resolver.ipv4_addr();
|
||||
|
||||
let client = Client::new(&network)?;
|
||||
|
|
|
@ -9,9 +9,9 @@ use dns_test::{Network, Resolver, Result, FQDN};
|
|||
#[ignore]
|
||||
fn edns_support() -> Result<()> {
|
||||
let network = &Network::new()?;
|
||||
let ns = NameServer::new(&dns_test::peer(), FQDN::ROOT, network)?.start()?;
|
||||
let ns = NameServer::new(&dns_test::PEER, FQDN::ROOT, network)?.start()?;
|
||||
let resolver = Resolver::new(network, Root::new(ns.fqdn().clone(), ns.ipv4_addr()))
|
||||
.start(&dns_test::subject())?;
|
||||
.start(&dns_test::SUBJECT)?;
|
||||
|
||||
let mut tshark = resolver.eavesdrop()?;
|
||||
|
||||
|
|
|
@ -13,9 +13,8 @@ fn bad_signature_in_leaf_nameserver() -> Result<()> {
|
|||
let needle_fqdn = FQDN("example.nameservers.com.")?;
|
||||
|
||||
let network = Network::new()?;
|
||||
let peer = dns_test::peer();
|
||||
|
||||
let mut leaf_ns = NameServer::new(&peer, FQDN::NAMESERVERS, &network)?;
|
||||
let mut leaf_ns = NameServer::new(&dns_test::PEER, FQDN::NAMESERVERS, &network)?;
|
||||
leaf_ns.add(Record::a(needle_fqdn.clone(), expected_ipv4_addr));
|
||||
|
||||
let Graph {
|
||||
|
@ -48,7 +47,7 @@ fn bad_signature_in_leaf_nameserver() -> Result<()> {
|
|||
let trust_anchor = &trust_anchor.unwrap();
|
||||
let resolver = Resolver::new(&network, root)
|
||||
.trust_anchor(trust_anchor)
|
||||
.start(&dns_test::subject())?;
|
||||
.start(&dns_test::SUBJECT)?;
|
||||
let resolver_addr = resolver.ipv4_addr();
|
||||
|
||||
let client = Client::new(&network)?;
|
||||
|
|
|
@ -125,14 +125,14 @@ fn fixture(
|
|||
expected: ExtendedDnsError,
|
||||
amend: fn(needle_fqdn: &FQDN, zone: &FQDN, records: &mut Vec<Record>),
|
||||
) -> Result<()> {
|
||||
let subject = dns_test::subject();
|
||||
let subject = &dns_test::SUBJECT;
|
||||
let supports_ede = subject.supports_ede();
|
||||
|
||||
let expected_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4);
|
||||
let needle_fqdn = FQDN("example.nameservers.com.")?;
|
||||
|
||||
let network = Network::new()?;
|
||||
let mut leaf_ns = NameServer::new(&dns_test::peer(), FQDN::NAMESERVERS, &network)?;
|
||||
let mut leaf_ns = NameServer::new(&dns_test::PEER, FQDN::NAMESERVERS, &network)?;
|
||||
leaf_ns.add(Record::a(needle_fqdn.clone(), expected_ipv4_addr));
|
||||
|
||||
let Graph {
|
||||
|
@ -153,7 +153,7 @@ fn fixture(
|
|||
}
|
||||
|
||||
let trust_anchor = &trust_anchor.unwrap();
|
||||
let resolver = resolver.trust_anchor(trust_anchor).start(&subject)?;
|
||||
let resolver = resolver.trust_anchor(trust_anchor).start(subject)?;
|
||||
let resolver_addr = resolver.ipv4_addr();
|
||||
|
||||
let client = Client::new(&network)?;
|
||||
|
|
|
@ -11,7 +11,7 @@ use dns_test::{Network, Resolver, Result, TrustAnchor, FQDN};
|
|||
#[test]
|
||||
fn can_validate_without_delegation() -> Result<()> {
|
||||
let network = Network::new()?;
|
||||
let mut ns = NameServer::new(&dns_test::peer(), FQDN::ROOT, &network)?;
|
||||
let mut ns = NameServer::new(&dns_test::PEER, FQDN::ROOT, &network)?;
|
||||
ns.add(Record::a(ns.fqdn().clone(), ns.ipv4_addr()));
|
||||
let ns = ns.sign()?;
|
||||
|
||||
|
@ -27,7 +27,7 @@ fn can_validate_without_delegation() -> Result<()> {
|
|||
let trust_anchor = &TrustAnchor::from_iter([root_ksk.clone(), root_zsk.clone()]);
|
||||
let resolver = Resolver::new(&network, Root::new(ns.fqdn().clone(), ns.ipv4_addr()))
|
||||
.trust_anchor(trust_anchor)
|
||||
.start(&dns_test::subject())?;
|
||||
.start(&dns_test::SUBJECT)?;
|
||||
let resolver_addr = resolver.ipv4_addr();
|
||||
|
||||
let client = Client::new(&network)?;
|
||||
|
@ -49,10 +49,9 @@ fn can_validate_with_delegation() -> Result<()> {
|
|||
let expected_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4);
|
||||
let needle_fqdn = FQDN("example.nameservers.com.")?;
|
||||
|
||||
let peer = dns_test::peer();
|
||||
let network = Network::new()?;
|
||||
|
||||
let mut leaf_ns = NameServer::new(&peer, FQDN::NAMESERVERS, &network)?;
|
||||
let mut leaf_ns = NameServer::new(&dns_test::PEER, FQDN::NAMESERVERS, &network)?;
|
||||
leaf_ns.add(Record::a(needle_fqdn.clone(), expected_ipv4_addr));
|
||||
|
||||
let Graph {
|
||||
|
@ -64,7 +63,7 @@ fn can_validate_with_delegation() -> Result<()> {
|
|||
let trust_anchor = &trust_anchor.unwrap();
|
||||
let resolver = Resolver::new(&network, root)
|
||||
.trust_anchor(trust_anchor)
|
||||
.start(&dns_test::subject())?;
|
||||
.start(&dns_test::SUBJECT)?;
|
||||
let resolver_addr = resolver.ipv4_addr();
|
||||
|
||||
let client = Client::new(&network)?;
|
||||
|
|
|
@ -6,6 +6,7 @@ publish = false
|
|||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
lazy_static = "1.4.0"
|
||||
minijinja = "1.0.12"
|
||||
serde = { version = "1.0.196", features = ["derive"] }
|
||||
serde_json = "1.0.113"
|
||||
|
|
|
@ -8,16 +8,16 @@ use dns_test::{Network, Resolver, Result, TrustAnchor, FQDN};
|
|||
|
||||
fn main() -> Result<()> {
|
||||
let network = Network::new()?;
|
||||
let peer = dns_test::peer();
|
||||
let peer = &dns_test::PEER;
|
||||
|
||||
println!("building docker image...");
|
||||
let mut root_ns = NameServer::new(&peer, FQDN::ROOT, &network)?;
|
||||
let mut root_ns = NameServer::new(peer, FQDN::ROOT, &network)?;
|
||||
println!("DONE");
|
||||
|
||||
println!("setting up name servers...");
|
||||
let mut com_ns = NameServer::new(&peer, FQDN::COM, &network)?;
|
||||
let mut com_ns = NameServer::new(peer, FQDN::COM, &network)?;
|
||||
|
||||
let mut nameservers_ns = NameServer::new(&peer, FQDN("nameservers.com.")?, &network)?;
|
||||
let mut nameservers_ns = NameServer::new(peer, FQDN("nameservers.com.")?, &network)?;
|
||||
nameservers_ns
|
||||
.add(Record::a(root_ns.fqdn().clone(), root_ns.ipv4_addr()))
|
||||
.add(Record::a(com_ns.fqdn().clone(), com_ns.ipv4_addr()));
|
||||
|
@ -53,7 +53,7 @@ fn main() -> Result<()> {
|
|||
Root::new(root_ns.fqdn().clone(), root_ns.ipv4_addr()),
|
||||
)
|
||||
.trust_anchor(&trust_anchor)
|
||||
.start(&dns_test::subject())?;
|
||||
.start(&dns_test::SUBJECT)?;
|
||||
println!("DONE\n\n");
|
||||
|
||||
let resolver_addr = resolver.ipv4_addr();
|
||||
|
|
|
@ -34,7 +34,7 @@ pub enum Role {
|
|||
Resolver,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Implementation {
|
||||
Bind,
|
||||
Hickory(Repository<'static>),
|
||||
|
@ -178,7 +178,7 @@ impl fmt::Display for Implementation {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Repository<'a> {
|
||||
inner: Cow<'a, str>,
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
//! A test framework for all things DNS
|
||||
|
||||
use std::env;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
pub use crate::container::Network;
|
||||
pub use crate::fqdn::FQDN;
|
||||
pub use crate::implementation::{Implementation, Repository};
|
||||
|
@ -23,8 +27,13 @@ pub type Result<T> = core::result::Result<T, Error>;
|
|||
// TODO maybe this should be a TLS variable that each unit test (thread) can override
|
||||
const DEFAULT_TTL: u32 = 24 * 60 * 60; // 1 day
|
||||
|
||||
pub fn subject() -> Implementation {
|
||||
if let Ok(subject) = std::env::var("DNS_TEST_SUBJECT") {
|
||||
lazy_static! {
|
||||
pub static ref SUBJECT: Implementation = parse_subject();
|
||||
pub static ref PEER: Implementation = parse_peer();
|
||||
}
|
||||
|
||||
fn parse_subject() -> Implementation {
|
||||
if let Ok(subject) = env::var("DNS_TEST_SUBJECT") {
|
||||
if subject == "unbound" {
|
||||
return Implementation::Unbound;
|
||||
}
|
||||
|
@ -47,14 +56,58 @@ pub fn subject() -> Implementation {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn peer() -> Implementation {
|
||||
if let Ok(subject) = std::env::var("DNS_TEST_PEER") {
|
||||
match subject.as_str() {
|
||||
fn parse_peer() -> Implementation {
|
||||
if let Ok(peer) = env::var("DNS_TEST_PEER") {
|
||||
match peer.as_str() {
|
||||
"unbound" => Implementation::Unbound,
|
||||
"bind" => Implementation::Bind,
|
||||
_ => panic!("`{subject}` is not supported as a test peer implementation"),
|
||||
_ => panic!("`{peer}` is not supported as a test peer implementation"),
|
||||
}
|
||||
} else {
|
||||
Implementation::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::env;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl PartialEq for Implementation {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(Self::Hickory(_), Self::Hickory(_)) => true,
|
||||
_ => core::mem::discriminant(self) == core::mem::discriminant(other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn immutable_subject() {
|
||||
let before = super::SUBJECT.clone();
|
||||
let newval = if before == Implementation::Unbound {
|
||||
"bind"
|
||||
} else {
|
||||
"unbound"
|
||||
};
|
||||
env::set_var("DNS_TEST_SUBJECT", newval);
|
||||
|
||||
let after = super::SUBJECT.clone();
|
||||
assert_eq!(before, after);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn immutable_peer() {
|
||||
let before = super::PEER.clone();
|
||||
let newval = if before == Implementation::Unbound {
|
||||
"bind"
|
||||
} else {
|
||||
"unbound"
|
||||
};
|
||||
env::set_var("DNS_TEST_PEER", newval);
|
||||
|
||||
let after = super::PEER.clone();
|
||||
assert_eq!(before, after);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user