network: add hub registration, Redis persistence, and federated mesh join protocol
Some checks failed
CLI Tests / test-cli (push) Has been cancelled
Integration Tests / test-service-integration (push) Has been cancelled
Python Tests / test-python (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled
Documentation Validation / validate-docs (push) Has been cancelled
API Endpoint Tests / test-api-endpoints (push) Has been cancelled
Systemd Sync / sync-systemd (push) Has been cancelled
Some checks failed
CLI Tests / test-cli (push) Has been cancelled
Integration Tests / test-service-integration (push) Has been cancelled
Python Tests / test-python (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled
Documentation Validation / validate-docs (push) Has been cancelled
API Endpoint Tests / test-api-endpoints (push) Has been cancelled
Systemd Sync / sync-systemd (push) Has been cancelled
- Change default P2P port from 7070 to 8001 in config and .env.example - Add redis_url configuration option for hub persistence (default: redis://localhost:6379) - Implement DNS-based hub registration/unregistration via HTTPS API endpoints - Add Redis persistence for hub registrations with 1-hour TTL - Add island join request/response protocol with member list and blockchain credentials - Add GPU marketplace tracking (offers, bids, providers) in hub manager - Add
This commit is contained in:
@@ -21,17 +21,18 @@ class TestP2PDiscovery:
|
||||
|
||||
def test_generate_node_id(self):
|
||||
"""Test node ID generation"""
|
||||
hostname = "node1.example.com"
|
||||
address = "127.0.0.1"
|
||||
port = 8000
|
||||
public_key = "test_public_key"
|
||||
|
||||
node_id = self.discovery.generate_node_id(address, port, public_key)
|
||||
|
||||
|
||||
node_id = self.discovery.generate_node_id(hostname, address, port, public_key)
|
||||
|
||||
assert isinstance(node_id, str)
|
||||
assert len(node_id) == 64 # SHA256 hex length
|
||||
|
||||
|
||||
# Test consistency
|
||||
node_id2 = self.discovery.generate_node_id(address, port, public_key)
|
||||
node_id2 = self.discovery.generate_node_id(hostname, address, port, public_key)
|
||||
assert node_id == node_id2
|
||||
|
||||
def test_add_bootstrap_node(self):
|
||||
@@ -45,17 +46,18 @@ class TestP2PDiscovery:
|
||||
|
||||
def test_generate_node_id_consistency(self):
|
||||
"""Test node ID generation consistency"""
|
||||
hostname = "node2.example.com"
|
||||
address = "192.168.1.1"
|
||||
port = 9000
|
||||
public_key = "test_key"
|
||||
|
||||
node_id1 = self.discovery.generate_node_id(address, port, public_key)
|
||||
node_id2 = self.discovery.generate_node_id(address, port, public_key)
|
||||
|
||||
|
||||
node_id1 = self.discovery.generate_node_id(hostname, address, port, public_key)
|
||||
node_id2 = self.discovery.generate_node_id(hostname, address, port, public_key)
|
||||
|
||||
assert node_id1 == node_id2
|
||||
|
||||
|
||||
# Different inputs should produce different IDs
|
||||
node_id3 = self.discovery.generate_node_id("192.168.1.2", port, public_key)
|
||||
node_id3 = self.discovery.generate_node_id(hostname, "192.168.1.2", port, public_key)
|
||||
assert node_id1 != node_id3
|
||||
|
||||
def test_get_peer_count_empty(self):
|
||||
|
||||
324
apps/blockchain-node/tests/network/test_hub_manager.py
Normal file
324
apps/blockchain-node/tests/network/test_hub_manager.py
Normal file
@@ -0,0 +1,324 @@
|
||||
"""
|
||||
Tests for Hub Manager with Redis persistence
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import asyncio
|
||||
from unittest.mock import Mock, AsyncMock, patch
|
||||
from aitbc_chain.network.hub_manager import HubManager, HubInfo, HubStatus, PeerInfo
|
||||
|
||||
|
||||
class TestHubManager:
|
||||
"""Test cases for Hub Manager with Redis persistence"""
|
||||
|
||||
@pytest.fixture
|
||||
def hub_manager(self):
|
||||
"""Create a HubManager instance for testing"""
|
||||
return HubManager(
|
||||
local_node_id="test-node-id",
|
||||
local_address="127.0.0.1",
|
||||
local_port=7070,
|
||||
island_id="test-island-id",
|
||||
island_name="test-island",
|
||||
redis_url="redis://localhost:6379"
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_connect_redis_success(self, hub_manager):
|
||||
"""Test successful Redis connection"""
|
||||
with patch('aitbc_chain.network.hub_manager.redis.asyncio') as mock_redis:
|
||||
mock_client = AsyncMock()
|
||||
mock_client.ping = AsyncMock(return_value=True)
|
||||
mock_redis.from_url.return_value = mock_client
|
||||
|
||||
result = await hub_manager._connect_redis()
|
||||
|
||||
assert result is True
|
||||
assert hub_manager._redis is not None
|
||||
mock_redis.from_url.assert_called_once_with("redis://localhost:6379")
|
||||
mock_client.ping.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_connect_redis_failure(self, hub_manager):
|
||||
"""Test Redis connection failure"""
|
||||
with patch('aitbc_chain.network.hub_manager.redis.asyncio') as mock_redis:
|
||||
mock_redis.from_url.side_effect = Exception("Connection failed")
|
||||
|
||||
result = await hub_manager._connect_redis()
|
||||
|
||||
assert result is False
|
||||
assert hub_manager._redis is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_persist_hub_registration_success(self, hub_manager):
|
||||
"""Test successful hub registration persistence to Redis"""
|
||||
hub_info = HubInfo(
|
||||
node_id="test-node-id",
|
||||
address="127.0.0.1",
|
||||
port=7070,
|
||||
island_id="test-island-id",
|
||||
island_name="test-island",
|
||||
public_address="1.2.3.4",
|
||||
public_port=7070,
|
||||
registered_at=1234567890.0,
|
||||
last_seen=1234567890.0
|
||||
)
|
||||
|
||||
with patch('aitbc_chain.network.hub_manager.redis.asyncio') as mock_redis:
|
||||
mock_client = AsyncMock()
|
||||
mock_client.setex = AsyncMock(return_value=True)
|
||||
mock_redis.from_url.return_value = mock_client
|
||||
|
||||
result = await hub_manager._persist_hub_registration(hub_info)
|
||||
|
||||
assert result is True
|
||||
mock_client.setex.assert_called_once()
|
||||
key = mock_client.setex.call_args[0][0]
|
||||
assert key == "hub:test-node-id"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_persist_hub_registration_no_redis(self, hub_manager):
|
||||
"""Test hub registration persistence when Redis is unavailable"""
|
||||
hub_info = HubInfo(
|
||||
node_id="test-node-id",
|
||||
address="127.0.0.1",
|
||||
port=7070,
|
||||
island_id="test-island-id",
|
||||
island_name="test-island"
|
||||
)
|
||||
|
||||
with patch.object(hub_manager, '_connect_redis', return_value=False):
|
||||
result = await hub_manager._persist_hub_registration(hub_info)
|
||||
|
||||
assert result is False
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_remove_hub_registration_success(self, hub_manager):
|
||||
"""Test successful hub registration removal from Redis"""
|
||||
with patch('aitbc_chain.network.hub_manager.redis.asyncio') as mock_redis:
|
||||
mock_client = AsyncMock()
|
||||
mock_client.delete = AsyncMock(return_value=True)
|
||||
mock_redis.from_url.return_value = mock_client
|
||||
|
||||
result = await hub_manager._remove_hub_registration("test-node-id")
|
||||
|
||||
assert result is True
|
||||
mock_client.delete.assert_called_once_with("hub:test-node-id")
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_load_hub_registration_success(self, hub_manager):
|
||||
"""Test successful hub registration loading from Redis"""
|
||||
with patch('aitbc_chain.network.hub_manager.redis.asyncio') as mock_redis:
|
||||
mock_client = AsyncMock()
|
||||
hub_data = {
|
||||
"node_id": "test-node-id",
|
||||
"address": "127.0.0.1",
|
||||
"port": 7070,
|
||||
"island_id": "test-island-id",
|
||||
"island_name": "test-island"
|
||||
}
|
||||
mock_client.get = AsyncMock(return_value='{"node_id": "test-node-id", "address": "127.0.0.1", "port": 7070, "island_id": "test-island-id", "island_name": "test-island"}')
|
||||
mock_redis.from_url.return_value = mock_client
|
||||
|
||||
result = await hub_manager._load_hub_registration()
|
||||
|
||||
assert result is not None
|
||||
assert result.node_id == "test-node-id"
|
||||
mock_client.get.assert_called_once_with("hub:test-node-id")
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_load_hub_registration_not_found(self, hub_manager):
|
||||
"""Test hub registration loading when not found in Redis"""
|
||||
with patch('aitbc_chain.network.hub_manager.redis.asyncio') as mock_redis:
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get = AsyncMock(return_value=None)
|
||||
mock_redis.from_url.return_value = mock_client
|
||||
|
||||
result = await hub_manager._load_hub_registration()
|
||||
|
||||
assert result is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_register_as_hub_success(self, hub_manager):
|
||||
"""Test successful hub registration"""
|
||||
with patch.object(hub_manager, '_persist_hub_registration', return_value=True):
|
||||
result = await hub_manager.register_as_hub(public_address="1.2.3.4", public_port=7070)
|
||||
|
||||
assert result is True
|
||||
assert hub_manager.is_hub is True
|
||||
assert hub_manager.hub_status == HubStatus.REGISTERED
|
||||
assert hub_manager.registered_at is not None
|
||||
assert hub_manager.local_node_id in hub_manager.known_hubs
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_register_as_hub_already_registered(self, hub_manager):
|
||||
"""Test hub registration when already registered"""
|
||||
hub_manager.is_hub = True
|
||||
hub_manager.hub_status = HubStatus.REGISTERED
|
||||
|
||||
result = await hub_manager.register_as_hub()
|
||||
|
||||
assert result is False
|
||||
assert hub_manager.is_hub is True
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_unregister_as_hub_success(self, hub_manager):
|
||||
"""Test successful hub unregistration"""
|
||||
hub_manager.is_hub = True
|
||||
hub_manager.hub_status = HubStatus.REGISTERED
|
||||
hub_manager.known_hubs["test-node-id"] = HubInfo(
|
||||
node_id="test-node-id",
|
||||
address="127.0.0.1",
|
||||
port=7070,
|
||||
island_id="test-island-id",
|
||||
island_name="test-island"
|
||||
)
|
||||
|
||||
with patch.object(hub_manager, '_remove_hub_registration', return_value=True):
|
||||
result = await hub_manager.unregister_as_hub()
|
||||
|
||||
assert result is True
|
||||
assert hub_manager.is_hub is False
|
||||
assert hub_manager.hub_status == HubStatus.UNREGISTERED
|
||||
assert hub_manager.registered_at is None
|
||||
assert hub_manager.local_node_id not in hub_manager.known_hubs
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_unregister_as_hub_not_registered(self, hub_manager):
|
||||
"""Test hub unregistration when not registered"""
|
||||
result = await hub_manager.unregister_as_hub()
|
||||
|
||||
assert result is False
|
||||
assert hub_manager.is_hub is False
|
||||
|
||||
def test_register_peer(self, hub_manager):
|
||||
"""Test peer registration"""
|
||||
peer_info = PeerInfo(
|
||||
node_id="peer-1",
|
||||
address="192.168.1.1",
|
||||
port=7071,
|
||||
island_id="test-island-id",
|
||||
is_hub=False
|
||||
)
|
||||
|
||||
result = hub_manager.register_peer(peer_info)
|
||||
|
||||
assert result is True
|
||||
assert "peer-1" in hub_manager.peer_registry
|
||||
assert "peer-1" in hub_manager.island_peers["test-island-id"]
|
||||
|
||||
def test_unregister_peer(self, hub_manager):
|
||||
"""Test peer unregistration"""
|
||||
peer_info = PeerInfo(
|
||||
node_id="peer-1",
|
||||
address="192.168.1.1",
|
||||
port=7071,
|
||||
island_id="test-island-id",
|
||||
is_hub=False
|
||||
)
|
||||
hub_manager.register_peer(peer_info)
|
||||
|
||||
result = hub_manager.unregister_peer("peer-1")
|
||||
|
||||
assert result is True
|
||||
assert "peer-1" not in hub_manager.peer_registry
|
||||
assert "peer-1" not in hub_manager.island_peers["test-island-id"]
|
||||
|
||||
def test_add_known_hub(self, hub_manager):
|
||||
"""Test adding a known hub"""
|
||||
hub_info = HubInfo(
|
||||
node_id="hub-1",
|
||||
address="10.1.1.1",
|
||||
port=7070,
|
||||
island_id="test-island-id",
|
||||
island_name="test-island"
|
||||
)
|
||||
|
||||
hub_manager.add_known_hub(hub_info)
|
||||
|
||||
assert "hub-1" in hub_manager.known_hubs
|
||||
assert hub_manager.known_hubs["hub-1"] == hub_info
|
||||
|
||||
def test_remove_known_hub(self, hub_manager):
|
||||
"""Test removing a known hub"""
|
||||
hub_info = HubInfo(
|
||||
node_id="hub-1",
|
||||
address="10.1.1.1",
|
||||
port=7070,
|
||||
island_id="test-island-id",
|
||||
island_name="test-island"
|
||||
)
|
||||
hub_manager.add_known_hub(hub_info)
|
||||
|
||||
result = hub_manager.remove_known_hub("hub-1")
|
||||
|
||||
assert result is True
|
||||
assert "hub-1" not in hub_manager.known_hubs
|
||||
|
||||
def test_get_peer_list(self, hub_manager):
|
||||
"""Test getting peer list for an island"""
|
||||
peer_info1 = PeerInfo(
|
||||
node_id="peer-1",
|
||||
address="192.168.1.1",
|
||||
port=7071,
|
||||
island_id="test-island-id",
|
||||
is_hub=False
|
||||
)
|
||||
peer_info2 = PeerInfo(
|
||||
node_id="peer-2",
|
||||
address="192.168.1.2",
|
||||
port=7072,
|
||||
island_id="other-island-id",
|
||||
is_hub=False
|
||||
)
|
||||
hub_manager.register_peer(peer_info1)
|
||||
hub_manager.register_peer(peer_info2)
|
||||
|
||||
peers = hub_manager.get_peer_list("test-island-id")
|
||||
|
||||
assert len(peers) == 1
|
||||
assert peers[0].node_id == "peer-1"
|
||||
|
||||
def test_get_hub_list(self, hub_manager):
|
||||
"""Test getting hub list"""
|
||||
hub_info1 = HubInfo(
|
||||
node_id="hub-1",
|
||||
address="10.1.1.1",
|
||||
port=7070,
|
||||
island_id="test-island-id",
|
||||
island_name="test-island"
|
||||
)
|
||||
hub_info2 = HubInfo(
|
||||
node_id="hub-2",
|
||||
address="10.1.1.2",
|
||||
port=7070,
|
||||
island_id="other-island-id",
|
||||
island_name="other-island"
|
||||
)
|
||||
hub_manager.add_known_hub(hub_info1)
|
||||
hub_manager.add_known_hub(hub_info2)
|
||||
|
||||
hubs = hub_manager.get_hub_list("test-island-id")
|
||||
|
||||
assert len(hubs) == 1
|
||||
assert hubs[0].node_id == "hub-1"
|
||||
|
||||
def test_update_peer_last_seen(self, hub_manager):
|
||||
"""Test updating peer last seen time"""
|
||||
peer_info = PeerInfo(
|
||||
node_id="peer-1",
|
||||
address="192.168.1.1",
|
||||
port=7071,
|
||||
island_id="test-island-id",
|
||||
is_hub=False,
|
||||
last_seen=100.0
|
||||
)
|
||||
hub_manager.register_peer(peer_info)
|
||||
|
||||
hub_manager.update_peer_last_seen("peer-1")
|
||||
|
||||
assert hub_manager.peer_registry["peer-1"].last_seen > 100.0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__])
|
||||
244
apps/blockchain-node/tests/network/test_island_join.py
Normal file
244
apps/blockchain-node/tests/network/test_island_join.py
Normal file
@@ -0,0 +1,244 @@
|
||||
"""
|
||||
Tests for Island Join functionality
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import asyncio
|
||||
from unittest.mock import Mock, AsyncMock, patch, MagicMock
|
||||
from aitbc_chain.network.hub_manager import HubManager, HubInfo, PeerInfo
|
||||
from aitbc_chain.p2p_network import P2PNetworkService
|
||||
|
||||
|
||||
class TestHubManagerJoin:
|
||||
"""Test cases for HubManager join request handling"""
|
||||
|
||||
@pytest.fixture
|
||||
def hub_manager(self):
|
||||
"""Create a HubManager instance for testing"""
|
||||
return HubManager(
|
||||
local_node_id="test-hub-node",
|
||||
local_address="127.0.0.1",
|
||||
local_port=7070,
|
||||
island_id="test-island-id",
|
||||
island_name="test-island",
|
||||
redis_url="redis://localhost:6379"
|
||||
)
|
||||
|
||||
def test_get_blockchain_credentials(self, hub_manager):
|
||||
"""Test blockchain credentials retrieval"""
|
||||
with patch('aitbc_chain.network.hub_manager.os.path.exists', return_value=True):
|
||||
with patch('aitbc_chain.network.hub_manager.open', create=True) as mock_open:
|
||||
# Mock genesis.json
|
||||
genesis_data = {
|
||||
'blocks': [{'hash': 'test-genesis-hash'}]
|
||||
}
|
||||
mock_file = MagicMock()
|
||||
mock_file.read.return_value = '{"blocks": [{"hash": "test-genesis-hash"}]}'
|
||||
mock_open.return_value.__enter__.return_value = mock_file
|
||||
|
||||
# Mock keystore
|
||||
with patch('aitbc_chain.network.hub_manager.json.load') as mock_json_load:
|
||||
mock_json_load.return_value = {'0x123': {'public_key_pem': 'test-key'}}
|
||||
|
||||
credentials = hub_manager._get_blockchain_credentials()
|
||||
|
||||
assert credentials is not None
|
||||
assert 'chain_id' in credentials
|
||||
assert 'island_id' in credentials
|
||||
assert credentials['island_id'] == 'test-island-id'
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_join_request_success(self, hub_manager):
|
||||
"""Test successful join request handling"""
|
||||
# Add some peers to the registry
|
||||
peer_info = PeerInfo(
|
||||
node_id="peer-1",
|
||||
address="192.168.1.1",
|
||||
port=7071,
|
||||
island_id="test-island-id",
|
||||
is_hub=False
|
||||
)
|
||||
hub_manager.register_peer(peer_info)
|
||||
|
||||
join_request = {
|
||||
'type': 'join_request',
|
||||
'node_id': 'new-node',
|
||||
'island_id': 'test-island-id',
|
||||
'island_name': 'test-island',
|
||||
'public_key_pem': 'test-pem'
|
||||
}
|
||||
|
||||
with patch.object(hub_manager, '_get_blockchain_credentials', return_value={'chain_id': 'test-chain'}):
|
||||
response = await hub_manager.handle_join_request(join_request)
|
||||
|
||||
assert response is not None
|
||||
assert response['type'] == 'join_response'
|
||||
assert response['island_id'] == 'test-island-id'
|
||||
assert len(response['members']) >= 1 # At least the hub itself
|
||||
assert 'credentials' in response
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_join_request_wrong_island(self, hub_manager):
|
||||
"""Test join request for wrong island"""
|
||||
join_request = {
|
||||
'type': 'join_request',
|
||||
'node_id': 'new-node',
|
||||
'island_id': 'wrong-island-id',
|
||||
'island_name': 'wrong-island',
|
||||
'public_key_pem': 'test-pem'
|
||||
}
|
||||
|
||||
response = await hub_manager.handle_join_request(join_request)
|
||||
|
||||
assert response is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_join_request_with_members(self, hub_manager):
|
||||
"""Test join request returns all island members"""
|
||||
# Add multiple peers
|
||||
for i in range(3):
|
||||
peer_info = PeerInfo(
|
||||
node_id=f"peer-{i}",
|
||||
address=f"192.168.1.{i}",
|
||||
port=7070 + i,
|
||||
island_id="test-island-id",
|
||||
is_hub=False
|
||||
)
|
||||
hub_manager.register_peer(peer_info)
|
||||
|
||||
join_request = {
|
||||
'type': 'join_request',
|
||||
'node_id': 'new-node',
|
||||
'island_id': 'test-island-id',
|
||||
'island_name': 'test-island',
|
||||
'public_key_pem': 'test-pem'
|
||||
}
|
||||
|
||||
with patch.object(hub_manager, '_get_blockchain_credentials', return_value={'chain_id': 'test-chain'}):
|
||||
response = await hub_manager.handle_join_request(join_request)
|
||||
|
||||
assert response is not None
|
||||
# Should include all peers + hub itself
|
||||
assert len(response['members']) >= 4
|
||||
|
||||
|
||||
class TestP2PNetworkJoin:
|
||||
"""Test cases for P2P network join request functionality"""
|
||||
|
||||
@pytest.fixture
|
||||
def p2p_service(self):
|
||||
"""Create a P2P service instance for testing"""
|
||||
return P2PNetworkService(
|
||||
host="127.0.0.1",
|
||||
port=7070,
|
||||
node_id="test-node",
|
||||
peers=[]
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_join_request_success(self, p2p_service):
|
||||
"""Test successful join request to hub"""
|
||||
join_response = {
|
||||
'type': 'join_response',
|
||||
'island_id': 'test-island-id',
|
||||
'island_name': 'test-island',
|
||||
'island_chain_id': 'test-chain',
|
||||
'members': [],
|
||||
'credentials': {}
|
||||
}
|
||||
|
||||
with patch('aitbc_chain.p2p_network.asyncio.open_connection') as mock_open:
|
||||
# Mock reader and writer
|
||||
mock_reader = AsyncMock()
|
||||
mock_reader.readline = AsyncMock(return_value=b'{"type": "join_response"}')
|
||||
mock_writer = AsyncMock()
|
||||
mock_writer.close = AsyncMock()
|
||||
mock_writer.wait_closed = AsyncMock()
|
||||
mock_open.return_value = (mock_reader, mock_writer)
|
||||
|
||||
response = await p2p_service.send_join_request(
|
||||
hub_address="127.0.0.1",
|
||||
hub_port=7070,
|
||||
island_id="test-island-id",
|
||||
island_name="test-island",
|
||||
node_id="test-node",
|
||||
public_key_pem="test-pem"
|
||||
)
|
||||
|
||||
assert response is not None
|
||||
mock_open.assert_called_once_with("127.0.0.1", 7070)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_join_request_connection_refused(self, p2p_service):
|
||||
"""Test join request when hub refuses connection"""
|
||||
with patch('aitbc_chain.p2p_network.asyncio.open_connection') as mock_open:
|
||||
mock_open.side_effect = ConnectionRefusedError()
|
||||
|
||||
response = await p2p_service.send_join_request(
|
||||
hub_address="127.0.0.1",
|
||||
hub_port=7070,
|
||||
island_id="test-island-id",
|
||||
island_name="test-island",
|
||||
node_id="test-node",
|
||||
public_key_pem="test-pem"
|
||||
)
|
||||
|
||||
assert response is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_join_request_timeout(self, p2p_service):
|
||||
"""Test join request timeout"""
|
||||
with patch('aitbc_chain.p2p_network.asyncio.open_connection') as mock_open:
|
||||
# Mock reader that times out
|
||||
mock_reader = AsyncMock()
|
||||
mock_reader.readline = AsyncMock(side_effect=asyncio.TimeoutError())
|
||||
mock_writer = AsyncMock()
|
||||
mock_writer.close = AsyncMock()
|
||||
mock_writer.wait_closed = AsyncMock()
|
||||
mock_open.return_value = (mock_reader, mock_writer)
|
||||
|
||||
response = await p2p_service.send_join_request(
|
||||
hub_address="127.0.0.1",
|
||||
hub_port=7070,
|
||||
island_id="test-island-id",
|
||||
island_name="test-island",
|
||||
node_id="test-node",
|
||||
public_key_pem="test-pem"
|
||||
)
|
||||
|
||||
assert response is None
|
||||
|
||||
|
||||
class TestJoinMessageHandling:
|
||||
"""Test cases for join message handling in P2P network"""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_join_request_message_handling(self):
|
||||
"""Test that join_request messages are handled correctly"""
|
||||
service = P2PNetworkService(
|
||||
host="127.0.0.1",
|
||||
port=7070,
|
||||
node_id="test-node",
|
||||
peers=[]
|
||||
)
|
||||
|
||||
# Mock hub manager
|
||||
service.hub_manager = Mock()
|
||||
service.hub_manager.handle_join_request = AsyncMock(return_value={'type': 'join_response'})
|
||||
|
||||
join_request = {
|
||||
'type': 'join_request',
|
||||
'node_id': 'new-node',
|
||||
'island_id': 'test-island-id'
|
||||
}
|
||||
|
||||
# The actual message handling happens in _listen_to_stream
|
||||
# This test verifies the hub_manager.handle_join_request would be called
|
||||
response = await service.hub_manager.handle_join_request(join_request)
|
||||
|
||||
assert response is not None
|
||||
assert response['type'] == 'join_response'
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__])
|
||||
Reference in New Issue
Block a user