Some checks failed
API Endpoint Tests / test-api-endpoints (push) Successful in 56s
Blockchain Synchronization Verification / sync-verification (push) Failing after 3s
CLI Tests / test-cli (push) Failing after 5s
Coverage Phase 1 (70% Target) / test-coverage-70 (push) Failing after 19s
Coverage Phase 2 (85% Target) / test-coverage-85 (push) Failing after 18s
Cross-Chain Functionality Tests / test-cross-chain-sync (push) Successful in 3s
Cross-Chain Functionality Tests / test-cross-chain-transactions (push) Successful in 4s
Cross-Chain Functionality Tests / test-multi-chain-consensus (push) Successful in 5s
Deploy to Testnet / deploy-testnet (push) Failing after 21s
Documentation Validation / validate-docs (push) Failing after 13s
Documentation Validation / validate-policies-strict (push) Successful in 4s
Integration Tests / test-service-integration (push) Failing after 2s
Multi-Chain Island Architecture Tests / test-multi-chain-island (push) Successful in 4s
Multi-Node Blockchain Health Monitoring / health-check (push) Failing after 14s
Node Failover Simulation / failover-test (push) Successful in 9s
P2P Network Verification / p2p-verification (push) Successful in 5s
Package Tests / Python package - aitbc-agent-sdk (push) Successful in 51s
Package Tests / Python package - aitbc-core (push) Failing after 3s
Package Tests / Python package - aitbc-crypto (push) Successful in 22s
Package Tests / Python package - aitbc-sdk (push) Successful in 16s
Package Tests / JavaScript package - aitbc-sdk-js (push) Successful in 21s
Package Tests / JavaScript package - aitbc-token (push) Failing after 18s
Production Tests / Production Integration Tests (push) Failing after 1m9s
Python Tests / test-python (push) Failing after 3s
Security Scanning / security-scan (push) Failing after 41s
Smart Contract Tests / test-solidity (map[name:aitbc-contracts path:contracts]) (push) Failing after 6s
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Failing after 7s
Smart Contract Tests / test-foundry (push) Failing after 20s
Smart Contract Tests / lint-solidity (push) Failing after 4s
Smart Contract Tests / deploy-contracts (push) Failing after 5s
Cross-Chain Functionality Tests / aggregate-results (push) Successful in 2s
Multi-Node Stress Testing / stress-test (push) Successful in 2s
Cross-Node Transaction Testing / transaction-test (push) Successful in 3s
Phase 1: Security fixes - Added CORSMiddleware to marketplace-service with specific origins - Fixed blockchain-node auth to fail closed on JWT errors - Added security regression tests (test_cors_configuration.py, test_dispute_auth.py) Phase 2: Repository cleanup - Removed 51 fix/backup/legacy files - Deleted marketplace-service-debug directory Phase 3.1: Python version constraints - Updated aitbc-crypto and aitbc-sdk with requires-python >=3.13 - Added explicit [tool.poetry].packages declarations Phase 3.2: Agent service DI architecture - Created aitbc-agent-core package with protocols and shared service - Implemented adapters for agent-management and coordinator-api - Created factory functions for gradual migration - Added migration comments to existing integration files Phase 4.1: Auth/utils extraction - Created auth.py module with JWT validation and security utilities - Created utils.py module with common helpers Phase 4.2: Router decomposition - Decomposed router.py into 10 domain modules (58 endpoints) - Created route table snapshot for verification - Preserved router_old.py as reference Phase 5: App shell classification - Documented app shell patterns across services Phase 6: Quality gates - Verified mypy type checking (75% error reduction) - Analyzed logging inconsistencies with structlog migration plan - Removed unused orjson dependency Documentation: - Created comprehensive remediation report - Added architecture documentation for DI pattern - Added quality analysis documents
192 lines
5.4 KiB
Python
192 lines
5.4 KiB
Python
"""Unit tests for agent marketplace service"""
|
|
|
|
import pytest
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Add app src to path
|
|
project_root = Path(__file__).parent.parent.parent.parent
|
|
sys.path.insert(0, str(project_root / "apps" / "marketplace"))
|
|
|
|
from agent_marketplace import app, GPUOffering, DealRequest, DealConfirmation, MinerRegistration, DEFAULT_CORS_ORIGINS, get_cors_origins
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_app_initialization():
|
|
"""Test that the FastAPI app initializes correctly"""
|
|
assert app is not None
|
|
assert app.title == "AITBC Agent-First GPU Marketplace"
|
|
assert app.version == "1.0.0"
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_gpu_offering_model():
|
|
"""Test GPUOffering model"""
|
|
offering = GPUOffering(
|
|
miner_id="miner_123",
|
|
gpu_model="RTX 4090",
|
|
gpu_memory=24576,
|
|
cuda_cores=16384,
|
|
price_per_hour=0.50,
|
|
available_hours=24,
|
|
chains=["ait-devnet", "ait-testnet"],
|
|
capabilities=["inference", "training"]
|
|
)
|
|
assert offering.miner_id == "miner_123"
|
|
assert offering.gpu_model == "RTX 4090"
|
|
assert offering.gpu_memory == 24576
|
|
assert offering.price_per_hour == 0.50
|
|
assert offering.chains == ["ait-devnet", "ait-testnet"]
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_gpu_offering_defaults():
|
|
"""Test GPUOffering with default values"""
|
|
offering = GPUOffering(
|
|
miner_id="miner_123",
|
|
gpu_model="RTX 4090",
|
|
gpu_memory=24576,
|
|
cuda_cores=16384,
|
|
price_per_hour=0.50,
|
|
available_hours=24,
|
|
chains=["ait-devnet"],
|
|
capabilities=["inference"]
|
|
)
|
|
assert offering.min_rental_hours == 1
|
|
assert offering.max_concurrent_jobs == 1
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_deal_request_model():
|
|
"""Test DealRequest model"""
|
|
request = DealRequest(
|
|
offering_id="offering_123",
|
|
buyer_id="buyer_123",
|
|
rental_hours=10,
|
|
chain="ait-devnet",
|
|
special_requirements="Need for high performance"
|
|
)
|
|
assert request.offering_id == "offering_123"
|
|
assert request.buyer_id == "buyer_123"
|
|
assert request.rental_hours == 10
|
|
assert request.chain == "ait-devnet"
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_deal_request_without_special_requirements():
|
|
"""Test DealRequest without special requirements"""
|
|
request = DealRequest(
|
|
offering_id="offering_123",
|
|
buyer_id="buyer_123",
|
|
rental_hours=10,
|
|
chain="ait-devnet"
|
|
)
|
|
assert request.special_requirements is None
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_deal_confirmation_model():
|
|
"""Test DealConfirmation model"""
|
|
confirmation = DealConfirmation(
|
|
deal_id="deal_123",
|
|
miner_confirmation=True,
|
|
chain="ait-devnet"
|
|
)
|
|
assert confirmation.deal_id == "deal_123"
|
|
assert confirmation.miner_confirmation is True
|
|
assert confirmation.chain == "ait-devnet"
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_deal_confirmation_rejection():
|
|
"""Test DealConfirmation with rejection"""
|
|
confirmation = DealConfirmation(
|
|
deal_id="deal_123",
|
|
miner_confirmation=False,
|
|
chain="ait-devnet"
|
|
)
|
|
assert confirmation.miner_confirmation is False
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_miner_registration_model():
|
|
"""Test MinerRegistration model"""
|
|
registration = MinerRegistration(
|
|
miner_id="miner_123",
|
|
wallet_address="0x1234567890abcdef",
|
|
preferred_chains=["ait-devnet", "ait-testnet"],
|
|
gpu_specs={"model": "RTX 4090", "memory": 24576}
|
|
)
|
|
assert registration.miner_id == "miner_123"
|
|
assert registration.wallet_address == "0x1234567890abcdef"
|
|
assert registration.preferred_chains == ["ait-devnet", "ait-testnet"]
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_miner_registration_defaults():
|
|
"""Test MinerRegistration with default pricing model"""
|
|
registration = MinerRegistration(
|
|
miner_id="miner_123",
|
|
wallet_address="0x1234567890abcdef",
|
|
preferred_chains=["ait-devnet"],
|
|
gpu_specs={"model": "RTX 4090"}
|
|
)
|
|
assert registration.pricing_model == "hourly"
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_gpu_offering_negative_price():
|
|
"""Test GPUOffering with negative price"""
|
|
offering = GPUOffering(
|
|
miner_id="miner_123",
|
|
gpu_model="RTX 4090",
|
|
gpu_memory=24576,
|
|
cuda_cores=16384,
|
|
price_per_hour=-0.50,
|
|
available_hours=24,
|
|
chains=["ait-devnet"],
|
|
capabilities=["inference"]
|
|
)
|
|
assert offering.price_per_hour == -0.50
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_gpu_offering_zero_hours():
|
|
"""Test GPUOffering with zero available hours"""
|
|
offering = GPUOffering(
|
|
miner_id="miner_123",
|
|
gpu_model="RTX 4090",
|
|
gpu_memory=24576,
|
|
cuda_cores=16384,
|
|
price_per_hour=0.50,
|
|
available_hours=0,
|
|
chains=["ait-devnet"],
|
|
capabilities=["inference"]
|
|
)
|
|
assert offering.available_hours == 0
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_deal_request_negative_hours():
|
|
"""Test DealRequest with negative rental hours"""
|
|
request = DealRequest(
|
|
offering_id="offering_123",
|
|
buyer_id="buyer_123",
|
|
rental_hours=-10,
|
|
chain="ait-devnet"
|
|
)
|
|
assert request.rental_hours == -10
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_default_cors_origins_do_not_allow_wildcard():
|
|
assert "*" not in DEFAULT_CORS_ORIGINS
|
|
assert "*" not in get_cors_origins()
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_wildcard_cors_origin_rejected(monkeypatch):
|
|
monkeypatch.setenv("AITBC_MARKETPLACE_CORS_ORIGINS", "*")
|
|
with pytest.raises(ValueError):
|
|
get_cors_origins()
|