Skip to content
This repository has been archived by the owner on Jun 7, 2024. It is now read-only.

Commit

Permalink
turn dns_test::{subject,peer} into immutable statics
Browse files Browse the repository at this point in the history
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
  • Loading branch information
japaric committed May 22, 2024
1 parent 2e46421 commit 5823902
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 35 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -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()?;

Expand Down Expand Up @@ -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()?;

Expand Down
2 changes: 1 addition & 1 deletion packages/conformance-tests/src/name_server/scenarios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
10 changes: 4 additions & 6 deletions packages/conformance-tests/src/resolver/dns/scenarios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)?;
Expand All @@ -47,17 +46,16 @@ 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,
root,
..
} = 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)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()?;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()?;

Expand All @@ -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)?;
Expand All @@ -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 {
Expand All @@ -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)?;
Expand Down
1 change: 1 addition & 0 deletions packages/dns-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
10 changes: 5 additions & 5 deletions packages/dns-test/examples/explore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand Down Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions packages/dns-test/src/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub enum Role {
Resolver,
}

#[derive(Clone)]
#[derive(Clone, Debug)]
pub enum Implementation {
Bind,
Hickory(Repository<'static>),
Expand Down Expand Up @@ -178,7 +178,7 @@ impl fmt::Display for Implementation {
}
}

#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct Repository<'a> {
inner: Cow<'a, str>,
}
Expand Down
65 changes: 59 additions & 6 deletions packages/dns-test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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;
}
Expand All @@ -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);
}
}

0 comments on commit 5823902

Please sign in to comment.