test: add net tet

This commit is contained in:
shiro.lee
2024-07-04 23:26:25 +08:00
parent 0cc9970184
commit c6aa724060
3 changed files with 184 additions and 21 deletions
+40 -18
View File
@@ -1,12 +1,19 @@
use crate::error::{Error, Result};
use lazy_static::lazy_static;
use std::{
collections::HashSet,
net::{IpAddr, SocketAddr, ToSocketAddrs},
};
use url::Host;
lazy_static! {
static ref LOCAL_IPS: Vec<IpAddr> = must_get_local_ips().unwrap();
}
/// helper for validating if the provided arg is an ip address.
pub fn is_socket_addr(host: &str) -> bool {
// TODO IPv6 zone information?
host.parse::<SocketAddr>().is_ok() || host.parse::<IpAddr>().is_ok()
}
@@ -30,7 +37,7 @@ pub fn check_local_server_addr(server_addr: &str) -> Result<SocketAddr> {
SocketAddr::V6(a) => Host::Ipv6(*a.ip()),
};
if is_local_host(host, 0, 0).is_ok() {
if is_local_host(host, 0, 0)? {
return Ok(a);
}
}
@@ -38,22 +45,10 @@ pub fn check_local_server_addr(server_addr: &str) -> Result<SocketAddr> {
Err(Error::from_string("host in server address should be this server"))
}
pub fn split_host_port(s: &str) -> Result<(String, u16)> {
let parts: Vec<&str> = s.split(':').collect();
if parts.len() == 2 {
if let Ok(port) = parts[1].parse::<u16>() {
return Ok((parts[0].to_string(), port));
}
}
Err(Error::from_string("Invalid address format or port number"))
}
/// checks if the given parameter correspond to one of
/// the local IP of the current machine
pub fn is_local_host(host: Host<&str>, port: u16, local_port: u16) -> Result<bool> {
let local_ips = must_get_local_ips();
let local_set: HashSet<IpAddr> = local_ips.into_iter().collect();
let local_set: HashSet<IpAddr> = LOCAL_IPS.iter().copied().collect();
let is_local_host = match host {
Host::Domain(domain) => {
let ips = match (domain, 0).to_socket_addrs().map(|v| v.map(|v| v.ip()).collect::<Vec<_>>()) {
@@ -75,10 +70,10 @@ pub fn is_local_host(host: Host<&str>, port: u16, local_port: u16) -> Result<boo
}
/// returns IPs of local interface
fn must_get_local_ips() -> Vec<IpAddr> {
fn must_get_local_ips() -> Result<Vec<IpAddr>> {
match netif::up() {
Ok(up) => up.map(|x| x.address().to_owned()).collect(),
Err(_) => vec![],
Ok(up) => Ok(up.map(|x| x.address().to_owned()).collect()),
Err(err) => Err(Error::from_string(format!("Unable to get IP addresses of this host: {}", err))),
}
}
@@ -106,9 +101,36 @@ mod test {
}
}
#[test]
fn test_check_local_server_addr() {
let test_cases = [
(":54321", Ok(())),
("localhost:54321", Ok(())),
("0.0.0.0:9000", Ok(())),
(":0", Ok(())),
("localhost", Err(Error::from_string("invalid socket address"))),
("", Err(Error::from_string("invalid socket address"))),
(
"example.org:54321",
Err(Error::from_string("host in server address should be this server")),
),
(":-10", Err(Error::from_string("invalid port value"))),
];
for test_case in test_cases {
let ret = check_local_server_addr(test_case.0);
if test_case.1.is_ok() && ret.is_err() {
panic!("{}: error: expected = <nil>, got = {:?}", test_case.0, ret);
}
if test_case.1.is_err() && ret.is_ok() {
panic!("{}: error: expected = {:?}, got = <nil>", test_case.0, test_case.1);
}
}
}
#[test]
fn test_must_get_local_ips() {
let local_ips = must_get_local_ips();
let local_ips = must_get_local_ips().unwrap();
let local_set: HashSet<IpAddr> = local_ips.into_iter().collect();
assert!(local_set.contains(&IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))));