Files
py-libp2p/tests/discovery/mdns/test_mdns.py
2025-06-24 14:25:46 +05:30

153 lines
5.9 KiB
Python

"""
Integration test for mDNS discovery where one host finds another.
"""
import time
import socket
import pytest
from zeroconf import 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 TestMDNSDiscovery:
"""Integration test 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 = 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
)
# Host 2: Set up as listener (the host that discovers others)
host2_peerstore = PeerStore()
host2_listener = PeerListener(
peerstore=host2_peerstore,
zeroconf=host2_zeroconf,
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."]
assert str(discovered_peer_id) == host1_peer_id
# Verify addresses were added to peerstore
try:
addrs = host2_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])
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()
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
hostname = socket.gethostname()
service_info = ServiceInfo(
type_="_p2p._udp.local.",
name="multi-addr-host._p2p._udp.local.",
port=8001,
properties={b"id": host1_peer_id.encode()},
server=f"{hostname}.local.",
addresses=[
socket.inet_aton("192.168.1.100"),
socket.inet_aton("10.0.0.50"),
],
)
# 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()
finally:
host1_zeroconf.close()
host2_zeroconf.close()