Files
aitbc/tests/conftest_mesh_network.py
aitbc e31f00aaac
Some checks failed
Documentation Validation / validate-docs (push) Has been cancelled
Python Tests / test-python (push) Has been cancelled
feat: add complete mesh network implementation scripts and comprehensive test suite
- Add 5 implementation scripts for all mesh network phases
- Add comprehensive test suite with 95%+ coverage target
- Update MESH_NETWORK_TRANSITION_PLAN.md with implementation status
- Add performance benchmarks and security validation tests
- Ready for mesh network transition from single-producer to decentralized

Implementation Scripts:
- 01_consensus_setup.sh: Multi-validator PoA, PBFT, slashing, key management
- 02_network_infrastructure.sh: P2P discovery, health monitoring, topology optimization
- 03_economic_layer.sh: Staking, rewards, gas fees, attack prevention
- 04_agent_network_scaling.sh: Agent registration, reputation, communication, lifecycle
- 05_smart_contracts.sh: Escrow, disputes, upgrades, optimization

Test Suite:
- test_mesh_network_transition.py: Complete system tests (25+ test classes)
- test_phase_integration.py: Cross-phase integration tests (15+ test classes)
- test_performance_benchmarks.py: Performance and scalability tests
- test_security_validation.py: Security and attack prevention tests
- conftest_mesh_network.py: Test configuration and fixtures
- README.md: Complete test documentation

Status: Ready for immediate deployment and testing
2026-04-01 10:00:26 +02:00

622 lines
19 KiB
Python

"""
Pytest Configuration and Fixtures for AITBC Mesh Network Tests
Shared test configuration and utilities
"""
import pytest
import asyncio
import os
import sys
import json
import time
from unittest.mock import Mock, AsyncMock
from decimal import Decimal
# Add project paths
sys.path.insert(0, '/opt/aitbc/apps/blockchain-node/src')
sys.path.insert(0, '/opt/aitbc/apps/agent-services/agent-registry/src')
sys.path.insert(0, '/opt/aitbc/apps/agent-services/agent-coordinator/src')
sys.path.insert(0, '/opt/aitbc/apps/agent-services/agent-bridge/src')
sys.path.insert(0, '/opt/aitbc/apps/agent-services/agent-compliance/src')
# Test configuration
pytest_plugins = []
# Global test configuration
TEST_CONFIG = {
"network_timeout": 30.0,
"consensus_timeout": 10.0,
"transaction_timeout": 5.0,
"mock_mode": True, # Use mocks by default for faster tests
"integration_mode": False, # Set to True for integration tests
"performance_mode": False, # Set to True for performance tests
}
# Test data
TEST_ADDRESSES = {
"validator_1": "0x1111111111111111111111111111111111111111",
"validator_2": "0x2222222222222222222222222222222222222222",
"validator_3": "0x3333333333333333333333333333333333333333",
"validator_4": "0x4444444444444444444444444444444444444444",
"validator_5": "0x5555555555555555555555555555555555555555",
"client_1": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"client_2": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"agent_1": "0xcccccccccccccccccccccccccccccccccccccccccc",
"agent_2": "0xdddddddddddddddddddddddddddddddddddddddddd",
}
TEST_KEYS = {
"private_key_1": "0x1111111111111111111111111111111111111111111111111111111111111111",
"private_key_2": "0x2222222222222222222222222222222222222222222222222222222222222222",
"public_key_1": "0x031111111111111111111111111111111111111111111111111111111111111111",
"public_key_2": "0x032222222222222222222222222222222222222222222222222222222222222222",
}
# Test constants
MIN_STAKE_AMOUNT = 1000.0
DEFAULT_GAS_PRICE = 0.001
DEFAULT_BLOCK_TIME = 30
NETWORK_SIZE = 50
AGENT_COUNT = 100
@pytest.fixture(scope="session")
def event_loop():
"""Create an instance of the default event loop for the test session."""
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
@pytest.fixture(scope="session")
def test_config():
"""Provide test configuration"""
return TEST_CONFIG
@pytest.fixture
def mock_consensus():
"""Mock consensus layer components"""
class MockConsensus:
def __init__(self):
self.validators = {}
self.current_proposer = None
self.block_height = 100
self.round_robin_index = 0
def add_validator(self, address, stake):
self.validators[address] = Mock(address=address, stake=stake)
return True
def select_proposer(self, round_number=None):
if not self.validators:
return None
validator_list = list(self.validators.keys())
index = (round_number or self.round_robin_index) % len(validator_list)
self.round_robin_index = index + 1
self.current_proposer = validator_list[index]
return self.current_proposer
def validate_transaction(self, tx):
return True, "valid"
def process_block(self, block):
return True, "processed"
return MockConsensus()
@pytest.fixture
def mock_network():
"""Mock network layer components"""
class MockNetwork:
def __init__(self):
self.peers = {}
self.connected_peers = set()
self.message_handler = Mock()
def add_peer(self, peer_id, address, port):
self.peers[peer_id] = Mock(peer_id=peer_id, address=address, port=port)
self.connected_peers.add(peer_id)
return True
def remove_peer(self, peer_id):
self.connected_peers.discard(peer_id)
if peer_id in self.peers:
del self.peers[peer_id]
return True
def send_message(self, recipient, message_type, payload):
return True, "sent", f"msg_{int(time.time())}"
def broadcast_message(self, message_type, payload):
return True, "broadcasted"
def get_peer_count(self):
return len(self.connected_peers)
def get_peer_list(self):
return [self.peers[pid] for pid in self.connected_peers if pid in self.peers]
return MockNetwork()
@pytest.fixture
def mock_economics():
"""Mock economic layer components"""
class MockEconomics:
def __init__(self):
self.stakes = {}
self.rewards = {}
self.gas_prices = {}
def stake_tokens(self, address, amount):
self.stakes[address] = self.stakes.get(address, 0) + amount
return True, "staked"
def unstake_tokens(self, address, amount):
if address in self.stakes and self.stakes[address] >= amount:
self.stakes[address] -= amount
return True, "unstaked"
return False, "insufficient stake"
def calculate_reward(self, address, block_height):
return Decimal('10.0')
def get_gas_price(self):
return Decimal(DEFAULT_GAS_PRICE)
def update_gas_price(self, new_price):
self.gas_prices[int(time.time())] = new_price
return True
return MockEconomics()
@pytest.fixture
def mock_agents():
"""Mock agent network components"""
class MockAgents:
def __init__(self):
self.agents = {}
self.capabilities = {}
self.reputations = {}
def register_agent(self, agent_id, agent_type, capabilities):
self.agents[agent_id] = Mock(
agent_id=agent_id,
agent_type=agent_type,
capabilities=capabilities
)
self.capabilities[agent_id] = capabilities
self.reputations[agent_id] = 1.0
return True, "registered"
def find_agents(self, capability_type, limit=10):
matching_agents = []
for agent_id, caps in self.capabilities.items():
if capability_type in caps:
matching_agents.append(self.agents[agent_id])
if len(matching_agents) >= limit:
break
return matching_agents
def update_reputation(self, agent_id, delta):
if agent_id in self.reputations:
self.reputations[agent_id] = max(0.0, min(1.0, self.reputations[agent_id] + delta))
return True
return False
def get_reputation(self, agent_id):
return self.reputations.get(agent_id, 0.0)
return MockAgents()
@pytest.fixture
def mock_contracts():
"""Mock smart contract components"""
class MockContracts:
def __init__(self):
self.contracts = {}
self.disputes = {}
def create_escrow(self, job_id, client, agent, amount):
contract_id = f"contract_{int(time.time())}"
self.contracts[contract_id] = Mock(
contract_id=contract_id,
job_id=job_id,
client=client,
agent=agent,
amount=amount,
status="created"
)
return True, "created", contract_id
def fund_contract(self, contract_id):
if contract_id in self.contracts:
self.contracts[contract_id].status = "funded"
return True, "funded"
return False, "not found"
def create_dispute(self, contract_id, reason):
dispute_id = f"dispute_{int(time.time())}"
self.disputes[dispute_id] = Mock(
dispute_id=dispute_id,
contract_id=contract_id,
reason=reason,
status="open"
)
return True, "created", dispute_id
def resolve_dispute(self, dispute_id, resolution):
if dispute_id in self.disputes:
self.disputes[dispute_id].status = "resolved"
self.disputes[dispute_id].resolution = resolution
return True, "resolved"
return False, "not found"
return MockContracts()
@pytest.fixture
def sample_transactions():
"""Sample transaction data for testing"""
return [
{
"tx_id": "tx_001",
"type": "transfer",
"from": TEST_ADDRESSES["client_1"],
"to": TEST_ADDRESSES["agent_1"],
"amount": Decimal('100.0'),
"gas_limit": 21000,
"gas_price": DEFAULT_GAS_PRICE
},
{
"tx_id": "tx_002",
"type": "stake",
"from": TEST_ADDRESSES["validator_1"],
"amount": Decimal('1000.0'),
"gas_limit": 50000,
"gas_price": DEFAULT_GAS_PRICE
},
{
"tx_id": "tx_003",
"type": "job_create",
"from": TEST_ADDRESSES["client_2"],
"to": TEST_ADDRESSES["agent_2"],
"amount": Decimal('50.0'),
"gas_limit": 100000,
"gas_price": DEFAULT_GAS_PRICE
}
]
@pytest.fixture
def sample_agents():
"""Sample agent data for testing"""
return [
{
"agent_id": "agent_001",
"agent_type": "AI_MODEL",
"capabilities": ["text_generation", "summarization"],
"cost_per_use": Decimal('0.001'),
"reputation": 0.9
},
{
"agent_id": "agent_002",
"agent_type": "DATA_PROVIDER",
"capabilities": ["data_analysis", "prediction"],
"cost_per_use": Decimal('0.002'),
"reputation": 0.85
},
{
"agent_id": "agent_003",
"agent_type": "VALIDATOR",
"capabilities": ["validation", "verification"],
"cost_per_use": Decimal('0.0005'),
"reputation": 0.95
}
]
@pytest.fixture
def sample_jobs():
"""Sample job data for testing"""
return [
{
"job_id": "job_001",
"client_address": TEST_ADDRESSES["client_1"],
"capability_required": "text_generation",
"parameters": {"max_tokens": 1000, "temperature": 0.7},
"payment": Decimal('10.0')
},
{
"job_id": "job_002",
"client_address": TEST_ADDRESSES["client_2"],
"capability_required": "data_analysis",
"parameters": {"dataset_size": 1000, "algorithm": "linear_regression"},
"payment": Decimal('20.0')
}
]
@pytest.fixture
def test_network_config():
"""Test network configuration"""
return {
"bootstrap_nodes": [
"10.1.223.93:8000",
"10.1.223.40:8000"
],
"discovery_interval": 30,
"max_peers": 50,
"heartbeat_interval": 60
}
@pytest.fixture
def test_consensus_config():
"""Test consensus configuration"""
return {
"min_validators": 3,
"max_validators": 100,
"block_time": DEFAULT_BLOCK_TIME,
"consensus_timeout": 10,
"slashing_threshold": 0.1
}
@pytest.fixture
def test_economics_config():
"""Test economics configuration"""
return {
"min_stake": MIN_STAKE_AMOUNT,
"reward_rate": 0.05,
"gas_price": DEFAULT_GAS_PRICE,
"escrow_fee": 0.025,
"dispute_timeout": 604800
}
@pytest.fixture
def temp_config_files(tmp_path):
"""Create temporary configuration files for testing"""
config_dir = tmp_path / "config"
config_dir.mkdir()
configs = {
"consensus_test.json": test_consensus_config(),
"network_test.json": test_network_config(),
"economics_test.json": test_economics_config(),
"agent_network_test.json": {"max_agents": AGENT_COUNT},
"smart_contracts_test.json": {"escrow_fee": 0.025}
}
created_files = {}
for filename, config_data in configs.items():
config_path = config_dir / filename
with open(config_path, 'w') as f:
json.dump(config_data, f, indent=2)
created_files[filename] = config_path
return created_files
@pytest.fixture
def mock_blockchain_state():
"""Mock blockchain state for testing"""
return {
"block_height": 1000,
"total_supply": Decimal('1000000'),
"active_validators": 10,
"total_staked": Decimal('100000'),
"gas_price": DEFAULT_GAS_PRICE,
"network_hashrate": 1000000,
"difficulty": 1000
}
@pytest.fixture
def performance_metrics():
"""Performance metrics for testing"""
return {
"block_propagation_time": 2.5, # seconds
"transaction_throughput": 1000, # tx/s
"consensus_latency": 0.5, # seconds
"network_latency": 0.1, # seconds
"memory_usage": 512, # MB
"cpu_usage": 0.3, # 30%
"disk_io": 100, # MB/s
}
# Test markers
pytest.mark.unit = pytest.mark.unit
pytest.mark.integration = pytest.mark.integration
pytest.mark.performance = pytest.mark.performance
pytest.mark.security = pytest.mark.security
pytest.mark.slow = pytest.mark.slow
# Custom test helpers
def create_test_validator(address, stake=1000.0):
"""Create a test validator"""
return Mock(
address=address,
stake=stake,
public_key=f"0x03{address[2:]}",
last_seen=time.time(),
status="active"
)
def create_test_agent(agent_id, agent_type="AI_MODEL", reputation=1.0):
"""Create a test agent"""
return Mock(
agent_id=agent_id,
agent_type=agent_type,
reputation=reputation,
capabilities=["test_capability"],
endpoint=f"http://localhost:8000/{agent_id}",
created_at=time.time()
)
def create_test_transaction(tx_type="transfer", amount=100.0):
"""Create a test transaction"""
return Mock(
tx_id=f"tx_{int(time.time())}",
type=tx_type,
from_address=TEST_ADDRESSES["client_1"],
to_address=TEST_ADDRESSES["agent_1"],
amount=Decimal(str(amount)),
gas_limit=21000,
gas_price=DEFAULT_GAS_PRICE,
timestamp=time.time()
)
def assert_performance_metric(actual, expected, tolerance=0.1, metric_name="metric"):
"""Assert performance metric within tolerance"""
lower_bound = expected * (1 - tolerance)
upper_bound = expected * (1 + tolerance)
assert lower_bound <= actual <= upper_bound, (
f"{metric_name} {actual} not within tolerance of expected {expected} "
f"(range: {lower_bound} - {upper_bound})"
)
def wait_for_condition(condition, timeout=10.0, interval=0.1, description="condition"):
"""Wait for a condition to be true"""
start_time = time.time()
while time.time() - start_time < timeout:
if condition():
return True
time.sleep(interval)
raise AssertionError(f"Timeout waiting for {description}")
# Test data generators
def generate_test_transactions(count=100):
"""Generate test transactions"""
transactions = []
for i in range(count):
tx = create_test_transaction(
tx_type=["transfer", "stake", "unstake", "job_create"][i % 4],
amount=100.0 + (i % 10) * 10
)
transactions.append(tx)
return transactions
def generate_test_agents(count=50):
"""Generate test agents"""
agents = []
agent_types = ["AI_MODEL", "DATA_PROVIDER", "VALIDATOR", "ORACLE"]
for i in range(count):
agent = create_test_agent(
f"agent_{i:03d}",
agent_type=agent_types[i % len(agent_types)],
reputation=0.5 + (i % 50) / 100
)
agents.append(agent)
return agents
# Async test helpers
async def async_wait_for_condition(condition, timeout=10.0, interval=0.1, description="condition"):
"""Async version of wait_for_condition"""
start_time = time.time()
while time.time() - start_time < timeout:
if condition():
return True
await asyncio.sleep(interval)
raise AssertionError(f"Timeout waiting for {description}")
# Mock decorators
def mock_integration_test(func):
"""Decorator for integration tests that require mocking"""
return pytest.mark.integration(func)
def mock_performance_test(func):
"""Decorator for performance tests"""
return pytest.mark.performance(func)
def mock_security_test(func):
"""Decorator for security tests"""
return pytest.mark.security(func)
# Environment setup
def setup_test_environment():
"""Setup test environment"""
# Set environment variables
os.environ.setdefault('AITBC_TEST_MODE', 'true')
os.environ.setdefault('AITBC_MOCK_MODE', 'true')
os.environ.setdefault('AITBC_LOG_LEVEL', 'DEBUG')
# Create test directories if they don't exist
test_dirs = [
'/opt/aitbc/tests/tmp',
'/opt/aitbc/tests/logs',
'/opt/aitbc/tests/data'
]
for test_dir in test_dirs:
os.makedirs(test_dir, exist_ok=True)
def cleanup_test_environment():
"""Cleanup test environment"""
# Remove test environment variables
test_env_vars = ['AITBC_TEST_MODE', 'AITBC_MOCK_MODE', 'AITBC_LOG_LEVEL']
for var in test_env_vars:
os.environ.pop(var, None)
# Setup and cleanup hooks
def pytest_configure(config):
"""Pytest configuration hook"""
setup_test_environment()
# Add custom markers
config.addinivalue_line(
"markers", "unit: mark test as a unit test"
)
config.addinivalue_line(
"markers", "integration: mark test as an integration test"
)
config.addinivalue_line(
"markers", "performance: mark test as a performance test"
)
config.addinivalue_line(
"markers", "security: mark test as a security test"
)
config.addinivalue_line(
"markers", "slow: mark test as slow running"
)
def pytest_unconfigure(config):
"""Pytest cleanup hook"""
cleanup_test_environment()
# Test collection hooks
def pytest_collection_modifyitems(config, items):
"""Modify test collection"""
# Add markers based on test location
for item in items:
# Mark tests in performance directory
if "performance" in str(item.fspath):
item.add_marker(pytest.mark.performance)
# Mark tests in security directory
elif "security" in str(item.fspath):
item.add_marker(pytest.mark.security)
# Mark integration tests
elif "integration" in str(item.fspath):
item.add_marker(pytest.mark.integration)
# Default to unit tests
else:
item.add_marker(pytest.mark.unit)
# Test reporting
def pytest_html_report_title(report):
"""Custom HTML report title"""
report.title = "AITBC Mesh Network Test Report"
# Test discovery
def pytest_ignore_collect(path, config):
"""Ignore certain files during test collection"""
# Skip __pycache__ directories
if "__pycache__" in str(path):
return True
# Skip backup files
if path.name.endswith(".bak") or path.name.endswith("~"):
return True
return False