Skip to content

Commit

Permalink
add tests for cache in lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
bluejekyll committed Aug 29, 2017
1 parent 404ba18 commit d2e1a44
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 22 deletions.
3 changes: 3 additions & 0 deletions resolver/src/config.rs
Expand Up @@ -201,6 +201,8 @@ pub struct ResolverOpts {
pub validate: bool,
/// The ip_strategy for the Resolver to use when lookup Ipv4 or Ipv6 addresses
pub ip_strategy: LookupIpStrategy,
/// Cache size is in number of records (some records can be large)
pub cache_size: usize,
}

impl Default for ResolverOpts {
Expand All @@ -217,6 +219,7 @@ impl Default for ResolverOpts {
edns0: false,
validate: false,
ip_strategy: LookupIpStrategy::default(),
cache_size: 32,
}
}
}
91 changes: 73 additions & 18 deletions resolver/src/lookup_ip.rs
Expand Up @@ -74,18 +74,6 @@ impl ClientHandle for LookupIpEither {
}
}

// impl Future for LookupIpEither {
// type Item = LookupIp;
// type Error = io::Error;

// fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
// match self {
// LookupIpEither::Retry(f) => f.poll(),
// LookupIpEither::Secure(f) => f.poll(),
// }
// }
// }

/// The Future returned from ResolverFuture when performing an A or AAAA lookup.
pub type LookupIpFuture = InnerLookupIpFuture<LookupIpEither>;

Expand Down Expand Up @@ -253,9 +241,7 @@ impl Future for InsertCache {
let name = mem::replace(&mut self.name, Name::root());
let ips = mem::replace(&mut self.ips, vec![]);

return Ok(Async::Ready(
lru.insert(name, ips, Instant::now()),
));
return Ok(Async::Ready(lru.insert(name, ips, Instant::now())));
}
}
}
Expand Down Expand Up @@ -389,7 +375,6 @@ impl<C: ClientHandle + 'static> Future for LookupIpState<C> {
}
}

// TODO: rename this to query?
/// returns a new future for lookup
fn strategic_lookup<C: ClientHandle + 'static>(
name: Name,
Expand Down Expand Up @@ -567,7 +552,7 @@ mod tests {
message.insert_answers(vec![
Record::from_rdata(
Name::root(),
0,
86400,
RecordType::A,
RData::A(Ipv4Addr::new(127, 0, 0, 1))
),
Expand All @@ -580,7 +565,7 @@ mod tests {
message.insert_answers(vec![
Record::from_rdata(
Name::root(),
0,
86400,
RecordType::AAAA,
RData::AAAA(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))
),
Expand Down Expand Up @@ -747,4 +732,74 @@ mod tests {
vec![Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)]
);
}

#[test]
fn test_empty_cache() {
let cache = Arc::new(Mutex::new(DnsLru::new(1)));
let mut client = mock(vec![empty()]);

let ips =
LookupIpState::lookup(Name::root(), LookupIpStrategy::Ipv4Only, &mut client, cache)
.wait()
.unwrap();

assert!(ips.iter().next().is_none());
}

#[test]
fn test_from_cache() {
let cache = Arc::new(Mutex::new(DnsLru::new(1)));
cache.lock().unwrap().insert(
Name::root(),
vec![
(IpAddr::from(Ipv4Addr::new(127, 0, 0, 1)), u32::max_value()),
],
Instant::now(),
);

let mut client = mock(vec![empty()]);

let ips =
LookupIpState::lookup(Name::root(), LookupIpStrategy::Ipv4Only, &mut client, cache)
.wait()
.unwrap();

assert_eq!(
ips.iter().cloned().collect::<Vec<IpAddr>>(),
vec![Ipv4Addr::new(127, 0, 0, 1)]
);
}

#[test]
fn test_no_cache_insert() {
let cache = Arc::new(Mutex::new(DnsLru::new(1)));
// first should come from client...
let mut client = mock(vec![v4_message()]);

let ips = LookupIpState::lookup(
Name::root(),
LookupIpStrategy::Ipv4Only,
&mut client,
cache.clone(),
).wait()
.unwrap();

assert_eq!(
ips.iter().cloned().collect::<Vec<IpAddr>>(),
vec![Ipv4Addr::new(127, 0, 0, 1)]
);

// next should come from cache...
let mut client = mock(vec![empty()]);

let ips =
LookupIpState::lookup(Name::root(), LookupIpStrategy::Ipv4Only, &mut client, cache)
.wait()
.unwrap();

assert_eq!(
ips.iter().cloned().collect::<Vec<IpAddr>>(),
vec![Ipv4Addr::new(127, 0, 0, 1)]
);
}
}
11 changes: 7 additions & 4 deletions resolver/src/resolver_future.rs
Expand Up @@ -32,12 +32,11 @@ impl ResolverFuture {
/// Construct a new ResolverFuture with the associated Client.
pub fn new(config: ResolverConfig, options: ResolverOpts, reactor: &Handle) -> Self {
let pool = NameServerPool::from_config(&config, &options, reactor);
// FIXME: how to specify cache? optional? or just size?
ResolverFuture {
config,
options,
pool,
lru: Arc::new(Mutex::new(DnsLru::new(10)))
lru: Arc::new(Mutex::new(DnsLru::new(options.cache_size))),
}
}

Expand Down Expand Up @@ -71,7 +70,6 @@ impl ResolverFuture {
let names = if name.is_fqdn() {
vec![name]
} else {

// Otherwise we have to build the search list
// Note: the vec is built in reverse order of precedence, for stack semantics
let mut names =
Expand Down Expand Up @@ -105,7 +103,12 @@ impl ResolverFuture {
either = LookupIpEither::Retry(client);
}

LookupIpFuture::lookup(names, self.options.ip_strategy, &mut either, self.lru.clone())
LookupIpFuture::lookup(
names,
self.options.ip_strategy,
&mut either,
self.lru.clone(),
)
}

fn push_name(name: Name, names: &mut Vec<Name>) {
Expand Down

0 comments on commit d2e1a44

Please sign in to comment.