From 9adf9aa4994994bc525acd92e93309893dc323c1 Mon Sep 17 00:00:00 2001 From: "sumanjeet0012@gmail.com" Date: Mon, 23 Jun 2025 01:48:12 +0530 Subject: [PATCH] refactor: improve test structure in mDNS tests --- tests/discovery/mdns/test_broadcaster.py | 23 ++-- tests/discovery/mdns/test_integration.py | 128 -------------------- tests/discovery/mdns/test_listener.py | 27 +++-- tests/discovery/mdns/test_mdns.py | 141 +++++++++-------------- tests/discovery/mdns/test_utils.py | 14 +-- 5 files changed, 89 insertions(+), 244 deletions(-) delete mode 100644 tests/discovery/mdns/test_integration.py diff --git a/tests/discovery/mdns/test_broadcaster.py b/tests/discovery/mdns/test_broadcaster.py index d4722ba7..cdb2e8c4 100644 --- a/tests/discovery/mdns/test_broadcaster.py +++ b/tests/discovery/mdns/test_broadcaster.py @@ -1,23 +1,24 @@ """ Unit tests for mDNS broadcaster component. """ -import socket -import pytest -from zeroconf import ServiceInfo, Zeroconf + +from zeroconf import Zeroconf from libp2p.discovery.mdns.broadcaster import PeerBroadcaster from libp2p.peer.id import ID class TestPeerBroadcaster: - """Basic unit tests for PeerBroadcaster.""" + """Unit tests for PeerBroadcaster.""" def test_broadcaster_initialization(self): """Test that broadcaster initializes correctly.""" zeroconf = Zeroconf() service_type = "_p2p._udp.local." service_name = "test-peer._p2p._udp.local." - peer_id = "QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN" # String, not ID object + peer_id = ( + "QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN" # String, not ID object + ) port = 8000 broadcaster = PeerBroadcaster( @@ -25,7 +26,7 @@ class TestPeerBroadcaster: service_type=service_type, service_name=service_name, peer_id=peer_id, - port=port + port=port, ) assert broadcaster.zeroconf == zeroconf @@ -33,7 +34,7 @@ class TestPeerBroadcaster: assert broadcaster.service_name == service_name assert broadcaster.peer_id == peer_id assert broadcaster.port == port - + # Clean up zeroconf.close() @@ -51,7 +52,7 @@ class TestPeerBroadcaster: service_type=service_type, service_name=service_name, peer_id=peer_id, - port=port + port=port, ) # Verify service was created and registered @@ -62,7 +63,7 @@ class TestPeerBroadcaster: assert service_info.port == port assert b"id" in service_info.properties assert service_info.properties[b"id"] == peer_id.encode() - + # Clean up zeroconf.close() @@ -80,11 +81,11 @@ class TestPeerBroadcaster: service_type=service_type, service_name=service_name, peer_id=peer_id, - port=port + port=port, ) # Service should be registered assert broadcaster.service_info is not None - + # Clean up zeroconf.close() diff --git a/tests/discovery/mdns/test_integration.py b/tests/discovery/mdns/test_integration.py deleted file mode 100644 index c7291aa7..00000000 --- a/tests/discovery/mdns/test_integration.py +++ /dev/null @@ -1,128 +0,0 @@ -""" -Basic integration tests for mDNS components. -""" -import socket -import pytest -from zeroconf import ServiceInfo, Zeroconf - -from libp2p.discovery.mdns.broadcaster import PeerBroadcaster -from libp2p.discovery.mdns.listener import PeerListener -from libp2p.peer.id import ID -from libp2p.peer.peerstore import PeerStore - - -class TestMDNSIntegration: - """Basic integration tests for mDNS components.""" - - def test_broadcaster_listener_basic_integration(self): - """Test basic broadcaster and listener integration with actual service discovery.""" - import time - - # Create two separate Zeroconf instances - zeroconf1 = Zeroconf() - zeroconf2 = Zeroconf() - - try: - # Set up broadcaster - broadcaster_peer_id_obj = ID.from_base58("QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN") - broadcaster_peer_id = str(broadcaster_peer_id_obj) # Convert to string - broadcaster = PeerBroadcaster( - zeroconf=zeroconf1, - service_type="_p2p._udp.local.", - service_name="broadcaster-peer._p2p._udp.local.", - peer_id=broadcaster_peer_id, - port=8000 - ) - - # Set up listener - peerstore = PeerStore() - listener = PeerListener( - peerstore=peerstore, - zeroconf=zeroconf2, - service_type="_p2p._udp.local.", - service_name="listener-peer._p2p._udp.local.", - ) - - # Verify initial state - assert broadcaster.service_info is not None - assert listener.discovered_services == {} - assert len(peerstore.peer_ids()) == 0 - - # Broadcaster registers its service - broadcaster.register() - - # Simulate discovery - listener discovers the broadcaster's service - listener.add_service( - zeroconf1, # Use broadcaster's zeroconf to find the service - "_p2p._udp.local.", - "broadcaster-peer._p2p._udp.local." - ) - - # Verify that the listener discovered the broadcaster - assert len(listener.discovered_services) > 0 - assert "broadcaster-peer._p2p._udp.local." in listener.discovered_services - - # Verify the discovered peer ID matches what was broadcast - discovered_peer_id = listener.discovered_services["broadcaster-peer._p2p._udp.local."] - assert str(discovered_peer_id) == broadcaster_peer_id - - # Verify the peer was added to the peerstore - assert len(peerstore.peer_ids()) > 0 - assert discovered_peer_id in peerstore.peer_ids() - - # Verify the addresses were correctly stored - addrs = peerstore.addrs(discovered_peer_id) - assert len(addrs) > 0 - # Should be TCP since we always use TCP protocol - assert "/tcp/8000" in str(addrs[0]) - - print(f"✅ Integration test successful!") - print(f" Broadcaster peer ID: {broadcaster_peer_id}") - print(f" Discovered peer ID: {discovered_peer_id}") - print(f" Discovered addresses: {[str(addr) for addr in addrs]}") - - # Clean up - broadcaster.unregister() - - finally: - zeroconf1.close() - zeroconf2.close() - - def test_service_info_extraction(self): - """Test service info extraction functionality.""" - peerstore = PeerStore() - zeroconf = Zeroconf() - - try: - listener = PeerListener( - peerstore=peerstore, - zeroconf=zeroconf, - service_type="_p2p._udp.local.", - service_name="test-listener._p2p._udp.local.", - ) - - # Create a test service info - test_peer_id = ID.from_base58("QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N") - hostname = socket.gethostname() - - service_info = ServiceInfo( - type_="_p2p._udp.local.", - name="test-service._p2p._udp.local.", - port=8001, - properties={b"id": str(test_peer_id).encode()}, - server=f"{hostname}.local.", - addresses=[socket.inet_aton("192.168.1.100")], - ) - - # Test extraction - peer_info = listener._extract_peer_info(service_info) - - assert peer_info is not None - assert peer_info.peer_id == test_peer_id - assert len(peer_info.addrs) == 1 - assert "/tcp/8001" in str(peer_info.addrs[0]) - - # Clean up - - finally: - zeroconf.close() diff --git a/tests/discovery/mdns/test_listener.py b/tests/discovery/mdns/test_listener.py index aa4992c0..1995202e 100644 --- a/tests/discovery/mdns/test_listener.py +++ b/tests/discovery/mdns/test_listener.py @@ -1,18 +1,19 @@ """ Unit tests for mDNS listener component. """ + import socket -import pytest + from zeroconf import ServiceInfo, Zeroconf +from libp2p.abc import Multiaddr from libp2p.discovery.mdns.listener import PeerListener from libp2p.peer.id import ID from libp2p.peer.peerstore import PeerStore -from libp2p.abc import Multiaddr class TestPeerListener: - """Basic unit tests for PeerListener.""" + """Unit tests for PeerListener.""" def test_listener_initialization(self): """Test that listener initializes correctly.""" @@ -33,7 +34,7 @@ class TestPeerListener: assert listener.service_type == service_type assert listener.service_name == service_name assert listener.discovered_services == {} - + # Clean up listener.stop() zeroconf.close() @@ -42,7 +43,7 @@ class TestPeerListener: """Test successful PeerInfo extraction from ServiceInfo.""" peerstore = PeerStore() zeroconf = Zeroconf() - + listener = PeerListener( peerstore=peerstore, zeroconf=zeroconf, @@ -51,10 +52,12 @@ class TestPeerListener: ) # Create sample service info - sample_peer_id = ID.from_base58("QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN") + sample_peer_id = ID.from_base58( + "QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN" + ) hostname = socket.gethostname() local_ip = "192.168.1.100" - + sample_service_info = ServiceInfo( type_="_p2p._udp.local.", name="test-peer._p2p._udp.local.", @@ -70,10 +73,10 @@ class TestPeerListener: assert isinstance(peer_info.peer_id, ID) assert len(peer_info.addrs) > 0 assert all(isinstance(addr, Multiaddr) for addr in peer_info.addrs) - + # Check that protocol is TCP since we always use TCP assert "/tcp/" in str(peer_info.addrs[0]) - + # Clean up listener.stop() zeroconf.close() @@ -82,7 +85,7 @@ class TestPeerListener: """Test PeerInfo extraction fails with invalid peer ID.""" peerstore = PeerStore() zeroconf = Zeroconf() - + listener = PeerListener( peerstore=peerstore, zeroconf=zeroconf, @@ -93,7 +96,7 @@ class TestPeerListener: # Create service info with invalid peer ID hostname = socket.gethostname() local_ip = "192.168.1.100" - + service_info = ServiceInfo( type_="_p2p._udp.local.", name="invalid-peer._p2p._udp.local.", @@ -105,7 +108,7 @@ class TestPeerListener: peer_info = listener._extract_peer_info(service_info) assert peer_info is None - + # Clean up listener.stop() zeroconf.close() diff --git a/tests/discovery/mdns/test_mdns.py b/tests/discovery/mdns/test_mdns.py index 502f8011..83d734a7 100644 --- a/tests/discovery/mdns/test_mdns.py +++ b/tests/discovery/mdns/test_mdns.py @@ -1,9 +1,9 @@ """ -Integration test for mDNS discovery where one host finds another. +Comprehensive integration tests for mDNS discovery functionality. """ -import time + import socket -import pytest + from zeroconf import Zeroconf from libp2p.discovery.mdns.broadcaster import PeerBroadcaster @@ -13,26 +13,28 @@ from libp2p.peer.peerstore import PeerStore class TestMDNSDiscovery: - """Integration test for mDNS peer discovery.""" + """Comprehensive integration tests for mDNS peer discovery.""" def test_one_host_finds_another(self): """Test that one host can find another host using mDNS.""" # Create two separate Zeroconf instances to simulate different hosts host1_zeroconf = Zeroconf() host2_zeroconf = Zeroconf() - + try: # Host 1: Set up as broadcaster (the host to be discovered) - host1_peer_id_obj = ID.from_base58("QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN") + host1_peer_id_obj = ID.from_base58( + "QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN" + ) host1_peer_id = str(host1_peer_id_obj) # Convert to string host1_broadcaster = PeerBroadcaster( zeroconf=host1_zeroconf, service_type="_p2p._udp.local.", service_name="host1._p2p._udp.local.", peer_id=host1_peer_id, - port=8000 + port=8000, ) - + # Host 2: Set up as listener (the host that discovers others) host2_peerstore = PeerStore() host2_listener = PeerListener( @@ -41,27 +43,20 @@ class TestMDNSDiscovery: service_type="_p2p._udp.local.", service_name="host2._p2p._udp.local.", ) - + # Host 1 registers its service for discovery host1_broadcaster.register() - - - # Manually trigger discovery by calling add_service - # This simulates what happens when mDNS discovers a service - host2_listener.add_service( - host1_zeroconf, # Use host1's zeroconf so it can find the service - "_p2p._udp.local.", - "host1._p2p._udp.local." - ) - + # Verify that host2 discovered host1 assert len(host2_listener.discovered_services) > 0 assert "host1._p2p._udp.local." in host2_listener.discovered_services - + # Verify that host1's peer info was added to host2's peerstore - discovered_peer_id = host2_listener.discovered_services["host1._p2p._udp.local."] + discovered_peer_id = host2_listener.discovered_services[ + "host1._p2p._udp.local." + ] assert str(discovered_peer_id) == host1_peer_id - + # Verify addresses were added to peerstore try: addrs = host2_peerstore.addrs(discovered_peer_id) @@ -71,82 +66,56 @@ class TestMDNSDiscovery: except Exception: # If no addresses found, the discovery didn't work properly assert False, "Host1 addresses should be in Host2's peerstore" - - print(f"✅ Host2 successfully discovered Host1!") - print(f" Discovered peer ID: {discovered_peer_id}") - print(f" Discovered addresses: {[str(addr) for addr in addrs]}") - + # Clean up host1_broadcaster.unregister() host2_listener.stop() - + finally: host1_zeroconf.close() host2_zeroconf.close() - def test_peer_discovery_with_multiple_addresses(self): - """Test discovery works with peers having multiple IP addresses.""" - host1_zeroconf = Zeroconf() - host2_zeroconf = Zeroconf() - + def test_service_info_extraction(self): + """Test service info extraction functionality.""" + peerstore = PeerStore() + zeroconf = Zeroconf() + try: - # Create a peer with multiple addresses - host1_peer_id_obj = ID.from_base58("QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N") - host1_peer_id = str(host1_peer_id_obj) # Convert to string - - # Manually create service info with multiple addresses - from zeroconf import ServiceInfo + listener = PeerListener( + peerstore=peerstore, + zeroconf=zeroconf, + service_type="_p2p._udp.local.", + service_name="test-listener._p2p._udp.local.", + ) + + # Create a test service info + test_peer_id = ID.from_base58( + "QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N" + ) hostname = socket.gethostname() - + + from zeroconf import ServiceInfo + service_info = ServiceInfo( type_="_p2p._udp.local.", - name="multi-addr-host._p2p._udp.local.", + name="test-service._p2p._udp.local.", port=8001, - properties={b"id": host1_peer_id.encode()}, + properties={b"id": str(test_peer_id).encode()}, server=f"{hostname}.local.", - addresses=[ - socket.inet_aton("192.168.1.100"), - socket.inet_aton("10.0.0.50"), - ], + addresses=[socket.inet_aton("192.168.1.100")], ) - - # Register the service - host1_zeroconf.register_service(service_info) - - # Set up listener - host2_peerstore = PeerStore() - host2_listener = PeerListener( - peerstore=host2_peerstore, - zeroconf=host2_zeroconf, - service_type="_p2p._udp.local.", - service_name="host2._p2p._udp.local.", - ) - - # Trigger discovery - host2_listener.add_service( - host1_zeroconf, - "_p2p._udp.local.", - "multi-addr-host._p2p._udp.local." - ) - - # Verify discovery - assert "multi-addr-host._p2p._udp.local." in host2_listener.discovered_services - discovered_peer_id = host2_listener.discovered_services["multi-addr-host._p2p._udp.local."] - - # Check multiple addresses were discovered - addrs = host2_peerstore.addrs(discovered_peer_id) - assert len(addrs) == 2 - - addr_strings = [str(addr) for addr in addrs] - assert "/ip4/192.168.1.100/tcp/8001" in addr_strings - assert "/ip4/10.0.0.50/tcp/8001" in addr_strings - - print(f"✅ Successfully discovered peer with multiple addresses!") - print(f" Addresses: {addr_strings}") - - # Clean up - host2_listener.stop() - + + # Test extraction + peer_info = listener._extract_peer_info(service_info) + + assert peer_info is not None + assert peer_info.peer_id == test_peer_id + assert len(peer_info.addrs) == 1 + assert "/tcp/8001" in str(peer_info.addrs[0]) + + print("✅ Service info extraction test successful!") + print(f" Extracted peer ID: {peer_info.peer_id}") + print(f" Extracted addresses: {[str(addr) for addr in peer_info.addrs]}") + finally: - host1_zeroconf.close() - host2_zeroconf.close() + zeroconf.close() diff --git a/tests/discovery/mdns/test_utils.py b/tests/discovery/mdns/test_utils.py index b50fd44c..81c296bc 100644 --- a/tests/discovery/mdns/test_utils.py +++ b/tests/discovery/mdns/test_utils.py @@ -1,22 +1,22 @@ """ Basic unit tests for mDNS utils module. """ + import string -import pytest from libp2p.discovery.mdns.utils import stringGen class TestStringGen: - """Basic unit tests for stringGen function.""" + """Unit tests for stringGen function.""" def test_stringgen_default_length(self): """Test stringGen with default length (63).""" result = stringGen() - + assert isinstance(result, str) assert len(result) == 63 - + # Check that all characters are from the expected charset charset = string.ascii_lowercase + string.digits for char in result: @@ -26,13 +26,13 @@ class TestStringGen: """Test stringGen with custom lengths.""" # Test various lengths test_lengths = [1, 5, 10, 20, 50, 100] - + for length in test_lengths: result = stringGen(length) - + assert isinstance(result, str) assert len(result) == length - + # Check that all characters are from the expected charset charset = string.ascii_lowercase + string.digits for char in result: