use nlink::{Result, ValidationErrorInfo};
#[test]
fn validation_error_info_is_nameable_and_the_constructor_callable() {
let errs = vec![
ValidationErrorInfo::new("mtu", "must be at least 68"),
ValidationErrorInfo::new("name", "too long"),
];
let e = nlink::Error::validation(errs);
let shown = e.to_string();
assert!(shown.contains("mtu"), "got {shown}");
assert!(shown.contains("name"), "got {shown}");
}
#[test]
fn config_apply_and_diff_types_are_nameable() {
use nlink::netlink::config::{ApplyError, LinkChanges};
fn _report(_errs: &[ApplyError]) {}
fn _explain(_changes: &LinkChanges) {}
let changes = LinkChanges::default();
assert!(changes.is_empty());
}
#[cfg(feature = "tuntap")]
#[test]
fn tuntap_enumeration_is_reachable() {
fn _names(devs: &[nlink::tuntap::TunTapInfo]) -> Vec<&str> {
devs.iter().map(|d| d.name.as_str()).collect()
}
let _ = nlink::tuntap::list_devices();
}
#[tokio::test]
async fn dump_stream_works_in_dispatcher_mode() -> Result<()> {
use tokio_stream::StreamExt;
let conn = nlink::Connection::<nlink::Route>::new()?.with_dispatcher();
let mut stream = conn.stream_links().await?;
let mut seen = 0usize;
while let Some(link) = stream.next().await {
link?;
seen += 1;
}
assert!(
seen > 0,
"a link dump must yield at least `lo`; the docs claimed this \
path returns Error::NotSupported (#276)"
);
Ok(())
}
#[cfg(feature = "sockdiag")]
#[test]
fn an_inet_filter_can_be_built_without_a_struct_literal() {
use nlink::sockdiag::{FilterKind, InetFilterBuilder, Protocol, SocketFilter, TcpState};
let filter = SocketFilter::tcp().states(&[TcpState::TimeWait]).build_inet();
assert_eq!(filter.protocol, Protocol::Tcp);
assert_ne!(filter.states, 0, "the state mask should carry TimeWait");
fn _takes(_b: InetFilterBuilder) {}
let wrapped = SocketFilter::tcp().build();
assert!(matches!(wrapped.kind, FilterKind::Inet(_)));
}