Skip to content

Commit

Permalink
add tests for hostname resolution and hostname checking
Browse files Browse the repository at this point in the history
  • Loading branch information
oysteintveit-nordicsemi committed Apr 15, 2024
1 parent fc240ad commit 2b7ae71
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 5 deletions.
30 changes: 28 additions & 2 deletions src/service_daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2641,8 +2641,9 @@ mod tests {
valid_instance_name, IntfSock, ServiceDaemon, ServiceEvent, ServiceInfo, GROUP_ADDR_V4,
MDNS_PORT,
};
use crate::dns_parser::{
DnsOutgoing, DnsPointer, CLASS_IN, FLAGS_AA, FLAGS_QR_RESPONSE, TYPE_PTR,
use crate::{
dns_parser::{DnsOutgoing, DnsPointer, CLASS_IN, FLAGS_AA, FLAGS_QR_RESPONSE, TYPE_PTR},
service_daemon::check_hostname,
};
use std::{net::SocketAddr, net::SocketAddrV4, time::Duration};

Expand All @@ -2669,6 +2670,31 @@ mod tests {
}
}

#[test]
fn test_check_hostname() {
// valid hostnames
for hostname in &[
"my_host.local.",
&("A".repeat(255 - ".local.".len()) + ".local."),
] {
let result = check_hostname(hostname);
assert!(result.is_ok());
}

// erroneous hostnames
for hostname in &[
"my_host.local",
".local.",
&("A".repeat(256 - ".local.".len()) + ".local."),
] {
let result = check_hostname(hostname);
assert!(result.is_err());
if let Err(e) = result {
println!("{}", e);
}
}
}

#[test]
fn service_with_temporarily_invalidated_ptr() {
// Create a daemon
Expand Down
82 changes: 79 additions & 3 deletions tests/mdns_test.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use if_addrs::{IfAddr, Interface};
use if_addrs::{get_if_addrs, IfAddr, Interface};
use mdns_sd::{
DaemonEvent, DaemonStatus, IfKind, IntoTxtProperties, ServiceDaemon, ServiceEvent, ServiceInfo,
UnregisterStatus,
DaemonEvent, DaemonStatus, HostnameResolutionEvent, IfKind, IntoTxtProperties, ServiceDaemon,
ServiceEvent, ServiceInfo, UnregisterStatus,
};
use std::collections::{HashMap, HashSet};
use std::convert::TryInto;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::sync::{Arc, Mutex};
use std::thread::sleep;
Expand Down Expand Up @@ -1053,3 +1054,78 @@ fn test_shutdown() {
let status = receiver.recv().unwrap();
assert!(matches!(status, DaemonStatus::Shutdown));
}

#[test]
fn test_hostname_resolution() {
let d = ServiceDaemon::new().expect("Failed to create daemon");
let hostname = "my_host._tcp.local.";
let service_ip_addr = my_ip_interfaces()
.iter()
.find(|iface| iface.ip().is_ipv4())
.map(|iface| iface.ip())
.unwrap();

let my_service = ServiceInfo::new(
"_test._tcp.local.",
"my_instance",
hostname,
&[service_ip_addr] as &[IpAddr],
1234,
None,
)
.expect("invalid service info");
d.register(my_service).unwrap();

let event_receiver = d.resolve_hostname(hostname, Some(2000)).unwrap();
let resolved = loop {
match event_receiver.recv() {
Ok(HostnameResolutionEvent::HostnameAddressesFound(found_hostname, addresses)) => {
assert!(found_hostname == hostname);
assert!(addresses.contains(&service_ip_addr));
break true;
}
Ok(HostnameResolutionEvent::SearchStopped(_)) => break false,
Ok(event) => println!("Received event {:?}", event),
Err(_) => break false,
}
};

assert!(resolved);
d.shutdown().unwrap();
}

#[test]
fn hostname_resolution_timeout() {
let d = ServiceDaemon::new().expect("Failed to create daemon");

let hostname = "nonexistent._tcp.local.";

let before = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("failed to get current UNIX time")
.as_millis() as u64;
let event_receiver = d.resolve_hostname(hostname, Some(2000)).unwrap();
let resolved = loop {
match event_receiver.recv() {
Ok(HostnameResolutionEvent::HostnameAddressesFound(found_hostname, _addresses)) => {
assert!(found_hostname == hostname);
break true;
}
Ok(HostnameResolutionEvent::SearchTimeout(_)) => break false,
Ok(event) => println!("Received event {:?}", event),
Err(_) => break false,
}
};
let after = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("failed to get current UNIX time")
.as_millis() as u64;

assert!(!resolved);

println!("Time spent resolving: {} ms", after - before);
assert!(after - before >= 2000 - 5);
assert!(after - before < 2000 + 1000);

d.shutdown().unwrap();
}

0 comments on commit 2b7ae71

Please sign in to comment.