use test_programs::wasi::sockets::instance_network::Network; use test_programs::wasi::sockets::network::{ErrorCode, IpAddress}; fn main() { // Valid domains resolve("localhost").unwrap(); resolve_at_least_one_of(&[ "example.com", "api.github.com", "docs.wasmtime.dev", "bytecodealliance.org", "www.rust-lang.org", ]); // NB: this is an actual real resolution, so it might time out, might cause // issues, etc. This result is ignored to prevent flaky failures in CI. let _ = resolve("münchen.de"); // Valid IP addresses assert_eq!(resolve_one("0.0.0.0").unwrap(), IpAddress::IPV4_UNSPECIFIED); assert_eq!(resolve_one("127.0.0.1").unwrap(), IpAddress::IPV4_LOOPBACK); assert_eq!( resolve_one("192.0.2.0").unwrap(), IpAddress::Ipv4((192, 0, 2, 0)) ); assert_eq!(resolve_one("::").unwrap(), IpAddress::IPV6_UNSPECIFIED); assert_eq!(resolve_one("::1").unwrap(), IpAddress::IPV6_LOOPBACK); assert_eq!(resolve_one("[::]").unwrap(), IpAddress::IPV6_UNSPECIFIED); assert_eq!( resolve_one("2001:0db8:0:0:0:0:0:0").unwrap(), IpAddress::Ipv6((0x2001, 0x0db8, 0, 0, 0, 0, 0, 0)) ); assert_eq!( resolve_one("dead:beef::").unwrap(), IpAddress::Ipv6((0xdead, 0xbeef, 0, 0, 0, 0, 0, 0)) ); assert_eq!( resolve_one("dead:beef::0").unwrap(), IpAddress::Ipv6((0xdead, 0xbeef, 0, 0, 0, 0, 0, 0)) ); assert_eq!( resolve_one("DEAD:BEEF::0").unwrap(), IpAddress::Ipv6((0xdead, 0xbeef, 0, 0, 0, 0, 0, 0)) ); // Invalid inputs assert_eq!(resolve("").unwrap_err(), ErrorCode::InvalidArgument); assert_eq!(resolve(" ").unwrap_err(), ErrorCode::InvalidArgument); assert_eq!(resolve("a.b<&>").unwrap_err(), ErrorCode::InvalidArgument); assert_eq!( resolve("127.0.0.1:80").unwrap_err(), ErrorCode::InvalidArgument ); assert_eq!(resolve("[::]:80").unwrap_err(), ErrorCode::InvalidArgument); assert_eq!( resolve("http://example.com/").unwrap_err(), ErrorCode::InvalidArgument ); } /// Attempts to resolve at least one of `domains`. Allows failure so long as one /// succeeds. Intended to help make this test less flaky while still also /// testing live services. fn resolve_at_least_one_of(domains: &[&str]) { for domain in domains { match resolve(domain) { Ok(_) => return, Err(e) => eprintln!("failed to resolve `{domain}`: {e}"), } } panic!("should have been able to resolve at least one domain"); } fn resolve(name: &str) -> Result, ErrorCode> { Network::default().permissive_blocking_resolve_addresses(name) } fn resolve_one(name: &str) -> Result { Ok(resolve(name)?.first().unwrap().to_owned()) }