@@ -1591,6 +1591,7 @@ mod tests {
15911591 use std:: net:: { Ipv4Addr , Ipv6Addr } ;
15921592
15931593 use super :: * ;
1594+ use crate :: operations:: OpError ;
15941595
15951596 #[ tokio:: test]
15961597 async fn test_hostname_resolution ( ) {
@@ -1612,4 +1613,160 @@ mod tests {
16121613 let socket_addr = NodeConfig :: parse_socket_addr ( & addr) . await . unwrap ( ) ;
16131614 assert_eq ! ( socket_addr. port( ) , 8080 ) ;
16141615 }
1616+
1617+ #[ tokio:: test]
1618+ async fn test_hostname_resolution_with_trailing_dot ( ) {
1619+ // DNS names with trailing dot should be handled
1620+ let addr = Address :: Hostname ( "localhost." . to_string ( ) ) ;
1621+ let result = NodeConfig :: parse_socket_addr ( & addr) . await ;
1622+ // This should either succeed or fail gracefully
1623+ if let Ok ( socket_addr) = result {
1624+ assert ! (
1625+ socket_addr. ip( ) == IpAddr :: V4 ( Ipv4Addr :: LOCALHOST )
1626+ || socket_addr. ip( ) == IpAddr :: V6 ( Ipv6Addr :: LOCALHOST )
1627+ ) ;
1628+ }
1629+ }
1630+
1631+ #[ tokio:: test]
1632+ async fn test_hostname_resolution_direct_socket_addr ( ) {
1633+ let socket = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 1 , 1 ) ) , 8080 ) ;
1634+ let addr = Address :: HostAddress ( socket) ;
1635+ let resolved = NodeConfig :: parse_socket_addr ( & addr) . await . unwrap ( ) ;
1636+ assert_eq ! ( resolved, socket) ;
1637+ }
1638+
1639+ #[ tokio:: test]
1640+ async fn test_hostname_resolution_invalid_port ( ) {
1641+ let addr = Address :: Hostname ( "localhost:not_a_port" . to_string ( ) ) ;
1642+ let result = NodeConfig :: parse_socket_addr ( & addr) . await ;
1643+ assert ! ( result. is_err( ) ) ;
1644+ }
1645+
1646+ // PeerId tests
1647+ #[ test]
1648+ fn test_peer_id_equality_based_on_addr ( ) {
1649+ let keypair1 = TransportKeypair :: new ( ) ;
1650+ let keypair2 = TransportKeypair :: new ( ) ;
1651+ let addr = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , 8080 ) ;
1652+
1653+ let peer1 = PeerId :: new ( addr, keypair1. public ( ) . clone ( ) ) ;
1654+ let peer2 = PeerId :: new ( addr, keypair2. public ( ) . clone ( ) ) ;
1655+
1656+ // PeerId equality is based on address, not public key
1657+ assert_eq ! ( peer1, peer2) ;
1658+ }
1659+
1660+ #[ test]
1661+ fn test_peer_id_inequality_different_addr ( ) {
1662+ let keypair = TransportKeypair :: new ( ) ;
1663+ let addr1 = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , 8080 ) ;
1664+ let addr2 = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , 8081 ) ;
1665+
1666+ let peer1 = PeerId :: new ( addr1, keypair. public ( ) . clone ( ) ) ;
1667+ let peer2 = PeerId :: new ( addr2, keypair. public ( ) . clone ( ) ) ;
1668+
1669+ assert_ne ! ( peer1, peer2) ;
1670+ }
1671+
1672+ #[ test]
1673+ fn test_peer_id_ordering ( ) {
1674+ let keypair = TransportKeypair :: new ( ) ;
1675+ let addr1 = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , 8080 ) ;
1676+ let addr2 = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , 8081 ) ;
1677+
1678+ let peer1 = PeerId :: new ( addr1, keypair. public ( ) . clone ( ) ) ;
1679+ let peer2 = PeerId :: new ( addr2, keypair. public ( ) . clone ( ) ) ;
1680+
1681+ // Ordering should be consistent
1682+ assert ! ( peer1 < peer2) ;
1683+ assert ! ( peer2 > peer1) ;
1684+ }
1685+
1686+ #[ test]
1687+ fn test_peer_id_hash_consistency ( ) {
1688+ use std:: collections:: hash_map:: DefaultHasher ;
1689+ use std:: hash:: { Hash , Hasher } ;
1690+
1691+ let keypair1 = TransportKeypair :: new ( ) ;
1692+ let keypair2 = TransportKeypair :: new ( ) ;
1693+ let addr = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , 8080 ) ;
1694+
1695+ let peer1 = PeerId :: new ( addr, keypair1. public ( ) . clone ( ) ) ;
1696+ let peer2 = PeerId :: new ( addr, keypair2. public ( ) . clone ( ) ) ;
1697+
1698+ let mut hasher1 = DefaultHasher :: new ( ) ;
1699+ let mut hasher2 = DefaultHasher :: new ( ) ;
1700+ peer1. hash ( & mut hasher1) ;
1701+ peer2. hash ( & mut hasher2) ;
1702+
1703+ // Same address should produce same hash
1704+ assert_eq ! ( hasher1. finish( ) , hasher2. finish( ) ) ;
1705+ }
1706+
1707+ #[ test]
1708+ fn test_peer_id_random_produces_unique ( ) {
1709+ let peer1 = PeerId :: random ( ) ;
1710+ let peer2 = PeerId :: random ( ) ;
1711+
1712+ // Random peers should have different addresses (with high probability)
1713+ assert_ne ! ( peer1. addr, peer2. addr) ;
1714+ }
1715+
1716+ #[ test]
1717+ fn test_peer_id_serialization ( ) {
1718+ let peer = PeerId :: random ( ) ;
1719+ let bytes = peer. clone ( ) . to_bytes ( ) ;
1720+ assert ! ( !bytes. is_empty( ) ) ;
1721+
1722+ // Should be deserializable
1723+ let deserialized: PeerId = bincode:: deserialize ( & bytes) . unwrap ( ) ;
1724+ assert_eq ! ( peer. addr, deserialized. addr) ;
1725+ }
1726+
1727+ #[ test]
1728+ fn test_peer_id_display ( ) {
1729+ let peer = PeerId :: random ( ) ;
1730+ let display = format ! ( "{}" , peer) ;
1731+ let debug = format ! ( "{:?}" , peer) ;
1732+
1733+ // Display and Debug should produce the same output
1734+ assert_eq ! ( display, debug) ;
1735+ // Should not be empty
1736+ assert ! ( !display. is_empty( ) ) ;
1737+ }
1738+
1739+ // InitPeerNode tests
1740+ #[ test]
1741+ fn test_init_peer_node_construction ( ) {
1742+ let keypair = TransportKeypair :: new ( ) ;
1743+ let addr = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 1 , 1 ) ) , 8080 ) ;
1744+ let peer_key_location = PeerKeyLocation :: new ( keypair. public ( ) . clone ( ) , addr) ;
1745+ let location = Location :: new ( 0.5 ) ;
1746+
1747+ let init_peer = InitPeerNode :: new ( peer_key_location. clone ( ) , location) ;
1748+
1749+ assert_eq ! ( init_peer. peer_key_location, peer_key_location) ;
1750+ assert_eq ! ( init_peer. location, location) ;
1751+ }
1752+
1753+ // is_operation_completed tests
1754+ #[ test]
1755+ fn test_is_operation_completed_with_none ( ) {
1756+ let result: Result < Option < OpEnum > , OpError > = Ok ( None ) ;
1757+ assert ! ( !is_operation_completed( & result) ) ;
1758+ }
1759+
1760+ #[ test]
1761+ fn test_is_operation_completed_with_error ( ) {
1762+ let result: Result < Option < OpEnum > , OpError > =
1763+ Err ( OpError :: OpNotAvailable ( super :: OpNotAvailable :: Running ) ) ;
1764+ assert ! ( !is_operation_completed( & result) ) ;
1765+ }
1766+
1767+ #[ test]
1768+ fn test_is_operation_completed_with_state_pushed_error ( ) {
1769+ let result: Result < Option < OpEnum > , OpError > = Err ( OpError :: StatePushed ) ;
1770+ assert ! ( !is_operation_completed( & result) ) ;
1771+ }
16151772}
0 commit comments