Files
aitbc/tests/fixtures/staking_fixtures.py
aitbc e4f1a96172
Some checks failed
Blockchain Synchronization Verification / sync-verification (push) Failing after 8s
CLI Tests / test-cli (push) Successful in 10s
Contract Performance Benchmarks / benchmark-gas-usage (push) Successful in 1m22s
Contract Performance Benchmarks / benchmark-execution-time (push) Successful in 1m11s
Contract Performance Benchmarks / benchmark-throughput (push) Successful in 1m13s
Cross-Chain Functionality Tests / test-cross-chain-sync (push) Failing after 5s
Cross-Chain Functionality Tests / test-cross-chain-transactions (push) Successful in 5s
Cross-Chain Functionality Tests / test-cross-chain-bridge (push) Has been skipped
Cross-Chain Functionality Tests / test-multi-chain-consensus (push) Failing after 3s
Cross-Chain Functionality Tests / aggregate-results (push) Has been skipped
Cross-Node Transaction Testing / transaction-test (push) Successful in 5s
Deploy to Testnet / deploy-testnet (push) Successful in 1m14s
Contract Performance Benchmarks / compare-benchmarks (push) Has been cancelled
Documentation Validation / validate-docs (push) Failing after 10s
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Node Failover Simulation / failover-test (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled
Smart Contract Tests / test-solidity (map[name:aitbc-contracts path:contracts]) (push) Has been cancelled
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Has been cancelled
Smart Contract Tests / test-foundry (push) Has been cancelled
Smart Contract Tests / lint-solidity (push) Has been cancelled
Smart Contract Tests / deploy-contracts (push) Has been cancelled
Documentation Validation / validate-policies-strict (push) Successful in 3s
Integration Tests / test-service-integration (push) Failing after 45s
Multi-Chain Island Architecture Tests / test-multi-chain-island (push) Failing after 2s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 5s
P2P Network Verification / p2p-verification (push) Successful in 3s
Production Tests / Production Integration Tests (push) Failing after 7s
Python Tests / test-python (push) Failing after 46s
Staking Tests / test-staking-service (push) Failing after 2s
Staking Tests / test-staking-integration (push) Has been skipped
Staking Tests / test-staking-contract (push) Has been skipped
Staking Tests / run-staking-test-runner (push) Has been skipped
Systemd Sync / sync-systemd (push) Successful in 21s
API Endpoint Tests / test-api-endpoints (push) Failing after 12m19s
ci: standardize pytest invocation and add security scanning
- Changed pytest calls to use `venv/bin/python -m pytest` with explicit config
- Added `--rootdir "$PWD"` and `--import-mode=importlib` for consistent imports
- Fixed PYTHONPATH to use absolute paths with $PWD prefix
- Added smart contract security scanning for Solidity files
- Added Circom circuit security checks for ZK proof circuits
- Added ZK proof implementation security validation
- Added contracts/** to security scanning workflow
2026-05-11 13:46:42 +02:00

336 lines
9.1 KiB
Python

"""
Shared fixtures for staking tests
Reusable fixtures for service and integration tests to avoid duplication
"""
import sys
from pathlib import Path
from datetime import UTC, datetime, timezone, timedelta
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session
from sqlmodel import SQLModel
# Add paths for imports
REPO_ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(REPO_ROOT / "apps" / "coordinator-api" / "src"))
from app.domain.bounty import (
AgentStake, AgentMetrics, StakingPool,
StakeStatus, PerformanceTier
)
from app.services.staking_service import StakingService
@pytest.fixture
def db_session():
"""Create in-memory SQLite database for testing"""
engine = create_engine("sqlite:///:memory:")
SQLModel.metadata.create_all(engine)
SessionLocal = sessionmaker(bind=engine)
session = SessionLocal()
try:
yield session
finally:
session.close()
engine.dispose()
@pytest.fixture
def staking_service(db_session):
"""Create StakingService instance with test session"""
return StakingService(db_session)
@pytest.fixture
def agent_wallet():
"""Default test agent wallet address"""
return "0x1234567890123456789012345678901234567890"
@pytest.fixture
def staker_address():
"""Default test staker address"""
return "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"
@pytest.fixture
def agent_metrics(agent_wallet):
"""Create test agent metrics with GOLD tier"""
return AgentMetrics(
agent_wallet=agent_wallet,
total_submissions=10,
successful_submissions=9,
average_accuracy=95.0,
current_tier=PerformanceTier.GOLD,
tier_score=85.0,
total_staked=0.0,
staker_count=0,
total_rewards_distributed=0.0,
last_update_time=datetime.now(UTC)
)
@pytest.fixture
def agent_metrics_bronze(agent_wallet):
"""Create test agent metrics with BRONZE tier"""
return AgentMetrics(
agent_wallet=agent_wallet,
total_submissions=5,
successful_submissions=4,
average_accuracy=80.0,
current_tier=PerformanceTier.BRONZE,
tier_score=60.0,
total_staked=0.0,
staker_count=0,
total_rewards_distributed=0.0,
last_update_time=datetime.now(UTC)
)
@pytest.fixture
def agent_metrics_diamond(agent_wallet):
"""Create test agent metrics with DIAMOND tier"""
return AgentMetrics(
agent_wallet=agent_wallet,
total_submissions=50,
successful_submissions=48,
average_accuracy=98.0,
current_tier=PerformanceTier.DIAMOND,
tier_score=95.0,
total_staked=0.0,
staker_count=0,
total_rewards_distributed=0.0,
last_update_time=datetime.now(UTC)
)
@pytest.fixture
def staking_pool(db_session, agent_metrics):
"""Create test staking pool"""
pool = StakingPool(
agent_wallet=agent_metrics.agent_wallet,
total_staked=0.0,
total_rewards=0.0,
pool_apy=5.0,
staker_count=0,
active_stakers=[],
last_distribution_time=datetime.now(UTC),
distribution_frequency=1
)
db_session.add(pool)
db_session.commit()
db_session.refresh(pool)
return pool
@pytest.fixture
def stake_data():
"""Default stake creation data"""
return {
"amount": 1000.0,
"lock_period": 30,
"auto_compound": False
}
@pytest.fixture
def large_stake_data():
"""Large stake creation data"""
return {
"amount": 50000.0,
"lock_period": 90,
"auto_compound": True
}
@pytest.fixture
def small_stake_data():
"""Small stake creation data"""
return {
"amount": 100.0,
"lock_period": 7,
"auto_compound": False
}
@pytest.fixture
def invalid_stake_data():
"""Invalid stake creation data (below minimum)"""
return {
"amount": 50.0,
"lock_period": 30,
"auto_compound": False
}
@pytest.fixture
def created_stake(staking_service, agent_metrics, staker_address, stake_data):
"""Create a stake for testing"""
return staking_service.create_stake(
staker_address=staker_address,
agent_wallet=agent_metrics.agent_wallet,
amount=stake_data["amount"],
lock_period=stake_data["lock_period"],
auto_compound=stake_data["auto_compound"]
)
@pytest.fixture
def active_stake(db_session, agent_wallet, staker_address):
"""Create an active stake directly in database"""
stake = AgentStake(
stake_id="stake_test_001",
staker_address=staker_address,
agent_wallet=agent_wallet,
amount=1000.0,
lock_period=30,
start_time=datetime.now(UTC),
end_time=datetime.now(UTC) + timedelta(days=30),
status=StakeStatus.ACTIVE,
accumulated_rewards=0.0,
last_reward_time=datetime.now(UTC),
current_apy=8.25,
agent_tier=PerformanceTier.GOLD,
performance_multiplier=1.5,
auto_compound=False
)
db_session.add(stake)
db_session.commit()
db_session.refresh(stake)
return stake
@pytest.fixture
def unbonding_stake(db_session, agent_wallet, staker_address):
"""Create an unbonding stake directly in database"""
stake = AgentStake(
stake_id="stake_test_002",
staker_address=staker_address,
agent_wallet=agent_wallet,
amount=1000.0,
lock_period=30,
start_time=datetime.now(UTC) - timedelta(days=35),
end_time=datetime.now(UTC) - timedelta(days=5),
status=StakeStatus.UNBONDING,
accumulated_rewards=50.0,
last_reward_time=datetime.now(UTC) - timedelta(days=5),
current_apy=8.25,
agent_tier=PerformanceTier.GOLD,
performance_multiplier=1.5,
auto_compound=False,
unbonding_time=datetime.now(UTC) - timedelta(days=5)
)
db_session.add(stake)
db_session.commit()
db_session.refresh(stake)
return stake
@pytest.fixture
def completed_stake(db_session, agent_wallet, staker_address):
"""Create a completed stake directly in database"""
stake = AgentStake(
stake_id="stake_test_003",
staker_address=staker_address,
agent_wallet=agent_wallet,
amount=1000.0,
lock_period=30,
start_time=datetime.now(UTC) - timedelta(days=70),
end_time=datetime.now(UTC) - timedelta(days=40),
status=StakeStatus.COMPLETED,
accumulated_rewards=100.0,
last_reward_time=datetime.now(UTC) - timedelta(days=40),
current_apy=8.25,
agent_tier=PerformanceTier.GOLD,
performance_multiplier=1.5,
auto_compound=False,
unbonding_time=datetime.now(UTC) - timedelta(days=40)
)
db_session.add(stake)
db_session.commit()
db_session.refresh(stake)
return stake
@pytest.fixture
def multiple_stakes(db_session, agent_wallet, staker_address):
"""Create multiple stakes for testing"""
stakes = []
# Stake 1: Active, 30-day lock
stake1 = AgentStake(
stake_id="stake_test_001",
staker_address=staker_address,
agent_wallet=agent_wallet,
amount=1000.0,
lock_period=30,
start_time=datetime.now(UTC),
end_time=datetime.now(UTC) + timedelta(days=30),
status=StakeStatus.ACTIVE,
accumulated_rewards=0.0,
last_reward_time=datetime.now(UTC),
current_apy=8.25,
agent_tier=PerformanceTier.GOLD,
performance_multiplier=1.5,
auto_compound=False
)
# Stake 2: Active, 90-day lock with auto-compound
stake2 = AgentStake(
stake_id="stake_test_002",
staker_address=staker_address,
agent_wallet=agent_wallet,
amount=2000.0,
lock_period=90,
start_time=datetime.now(UTC),
end_time=datetime.now(UTC) + timedelta(days=90),
status=StakeStatus.ACTIVE,
accumulated_rewards=0.0,
last_reward_time=datetime.now(UTC),
current_apy=10.0,
agent_tier=PerformanceTier.GOLD,
performance_multiplier=1.5,
auto_compound=True
)
db_session.add_all([stake1, stake2])
db_session.commit()
for stake in [stake1, stake2]:
db_session.refresh(stake)
stakes.append(stake)
return stakes
def calculate_expected_apy(base_apy=5.0, tier_multiplier=1.0, lock_multiplier=1.0):
"""Calculate expected APY based on parameters"""
apy = base_apy * tier_multiplier * lock_multiplier
return min(apy, 20.0) # Cap at 20%
def get_tier_multiplier(tier):
"""Get tier multiplier for APY calculation"""
multipliers = {
PerformanceTier.BRONZE: 1.0,
PerformanceTier.SILVER: 1.25,
PerformanceTier.GOLD: 1.5,
PerformanceTier.PLATINUM: 2.0,
PerformanceTier.DIAMOND: 3.0
}
return multipliers.get(tier, 1.0)
def get_lock_multiplier(lock_period_days):
"""Get lock period multiplier for APY calculation"""
if lock_period_days >= 365:
return 2.0
elif lock_period_days >= 90:
return 1.5
elif lock_period_days >= 30:
return 1.1
else:
return 1.0