Files
aitbc/cli/tests/multichain/test_deployment.py
oib 15427c96c0 chore: update file permissions to executable across repository
- Change file mode from 644 to 755 for all project files
- Add chain_id parameter to get_balance RPC endpoint with default "ait-devnet"
- Rename Miner.extra_meta_data to extra_metadata for consistency
2026-03-06 22:17:54 +01:00

404 lines
13 KiB
Python
Executable File

"""
Test for production deployment and scaling system
"""
import asyncio
import pytest
from datetime import datetime, timedelta
from pathlib import Path
from aitbc_cli.core.deployment import (
ProductionDeployment, DeploymentConfig, DeploymentMetrics,
ScalingEvent, ScalingPolicy, DeploymentStatus
)
def test_deployment_creation():
"""Test deployment system creation"""
deployment = ProductionDeployment("/tmp/test_aitbc")
assert deployment.config_path == Path("/tmp/test_aitbc")
assert deployment.deployments == {}
assert deployment.metrics == {}
assert deployment.scaling_events == []
assert deployment.health_checks == {}
# Check directories were created
assert deployment.deployment_dir.exists()
assert deployment.config_dir.exists()
assert deployment.logs_dir.exists()
assert deployment.backups_dir.exists()
async def test_create_deployment_config():
"""Test deployment configuration creation"""
deployment = ProductionDeployment("/tmp/test_aitbc")
# Create deployment
deployment_id = await deployment.create_deployment(
name="test-deployment",
environment="production",
region="us-west-1",
instance_type="t3.medium",
min_instances=1,
max_instances=10,
desired_instances=2,
port=8080,
domain="test.aitbc.dev",
database_config={"host": "localhost", "port": 5432, "name": "aitbc"}
)
assert deployment_id is not None
assert deployment_id in deployment.deployments
config = deployment.deployments[deployment_id]
assert config.name == "test-deployment"
assert config.environment == "production"
assert config.min_instances == 1
assert config.max_instances == 10
assert config.desired_instances == 2
assert config.scaling_policy == ScalingPolicy.AUTO
assert config.port == 8080
assert config.domain == "test.aitbc.dev"
async def test_deployment_application():
"""Test application deployment"""
deployment = ProductionDeployment("/tmp/test_aitbc")
# Create deployment first
deployment_id = await deployment.create_deployment(
name="test-app",
environment="staging",
region="us-east-1",
instance_type="t3.small",
min_instances=1,
max_instances=5,
desired_instances=2,
port=3000,
domain="staging.aitbc.dev",
database_config={"host": "localhost", "port": 5432, "name": "aitbc_staging"}
)
# Mock the infrastructure deployment (skip actual system calls)
original_deploy_infra = deployment._deploy_infrastructure
async def mock_deploy_infra(dep_config):
print(f"Mock infrastructure deployment for {dep_config.name}")
return True
deployment._deploy_infrastructure = mock_deploy_infra
# Deploy application
success = await deployment.deploy_application(deployment_id)
assert success
assert deployment_id in deployment.health_checks
assert deployment.health_checks[deployment_id] == True
assert deployment_id in deployment.metrics
# Restore original method
deployment._deploy_infrastructure = original_deploy_infra
async def test_manual_scaling():
"""Test manual scaling"""
deployment = ProductionDeployment("/tmp/test_aitbc")
# Create deployment
deployment_id = await deployment.create_deployment(
name="scale-test",
environment="production",
region="us-west-2",
instance_type="t3.medium",
min_instances=1,
max_instances=10,
desired_instances=2,
port=8080,
domain="scale.aitbc.dev",
database_config={"host": "localhost", "port": 5432, "name": "aitbc"}
)
# Mock infrastructure deployment
original_deploy_infra = deployment._deploy_infrastructure
async def mock_deploy_infra(dep_config):
return True
deployment._deploy_infrastructure = mock_deploy_infra
# Deploy first
await deployment.deploy_application(deployment_id)
# Scale up
success = await deployment.scale_deployment(deployment_id, 5, "manual scaling test")
assert success
# Check deployment was updated
config = deployment.deployments[deployment_id]
assert config.desired_instances == 5
# Check scaling event was created
scaling_events = [e for e in deployment.scaling_events if e.deployment_id == deployment_id]
assert len(scaling_events) > 0
latest_event = scaling_events[-1]
assert latest_event.old_instances == 2
assert latest_event.new_instances == 5
assert latest_event.success == True
assert latest_event.trigger_reason == "manual scaling test"
# Restore original method
deployment._deploy_infrastructure = original_deploy_infra
async def test_auto_scaling():
"""Test automatic scaling"""
deployment = ProductionDeployment("/tmp/test_aitbc")
# Create deployment
deployment_id = await deployment.create_deployment(
name="auto-scale-test",
environment="production",
region="us-east-1",
instance_type="t3.medium",
min_instances=1,
max_instances=10,
desired_instances=2,
port=8080,
domain="autoscale.aitbc.dev",
database_config={"host": "localhost", "port": 5432, "name": "aitbc"}
)
# Mock infrastructure deployment
original_deploy_infra = deployment._deploy_infrastructure
async def mock_deploy_infra(dep_config):
return True
deployment._deploy_infrastructure = mock_deploy_infra
# Deploy first
await deployment.deploy_application(deployment_id)
# Set metrics to trigger scale up (high CPU)
metrics = deployment.metrics[deployment_id]
metrics.cpu_usage = 85.0 # Above threshold
metrics.memory_usage = 40.0
metrics.error_rate = 1.0
metrics.response_time = 500.0
# Trigger auto-scaling
success = await deployment.auto_scale_deployment(deployment_id)
assert success
# Check deployment was scaled up
config = deployment.deployments[deployment_id]
assert config.desired_instances == 3 # Should have scaled up by 1
# Set metrics to trigger scale down
metrics.cpu_usage = 15.0 # Below threshold
metrics.memory_usage = 25.0
# Trigger auto-scaling again
success = await deployment.auto_scale_deployment(deployment_id)
assert success
# Check deployment was scaled down
config = deployment.deployments[deployment_id]
assert config.desired_instances == 2 # Should have scaled down by 1
# Restore original method
deployment._deploy_infrastructure = original_deploy_infra
async def test_deployment_status():
"""Test deployment status retrieval"""
deployment = ProductionDeployment("/tmp/test_aitbc")
# Create and deploy
deployment_id = await deployment.create_deployment(
name="status-test",
environment="production",
region="us-west-1",
instance_type="t3.medium",
min_instances=1,
max_instances=5,
desired_instances=2,
port=8080,
domain="status.aitbc.dev",
database_config={"host": "localhost", "port": 5432, "name": "aitbc"}
)
# Mock infrastructure deployment
original_deploy_infra = deployment._deploy_infrastructure
async def mock_deploy_infra(dep_config):
return True
deployment._deploy_infrastructure = mock_deploy_infra
await deployment.deploy_application(deployment_id)
# Get status
status = await deployment.get_deployment_status(deployment_id)
assert status is not None
assert "deployment" in status
assert "metrics" in status
assert "health_status" in status
assert "recent_scaling_events" in status
assert "uptime_percentage" in status
# Check deployment info
deployment_info = status["deployment"]
assert deployment_info["name"] == "status-test"
assert deployment_info["environment"] == "production"
assert deployment_info["desired_instances"] == 2
# Check health status
assert status["health_status"] == True
# Check metrics
metrics = status["metrics"]
assert metrics["deployment_id"] == deployment_id
assert metrics["cpu_usage"] >= 0
assert metrics["memory_usage"] >= 0
# Restore original method
deployment._deploy_infrastructure = original_deploy_infra
async def test_cluster_overview():
"""Test cluster overview"""
deployment = ProductionDeployment("/tmp/test_aitbc")
# Mock infrastructure deployment
original_deploy_infra = deployment._deploy_infrastructure
async def mock_deploy_infra(dep_config):
return True
deployment._deploy_infrastructure = mock_deploy_infra
# Create multiple deployments
deployment_ids = []
for i in range(3):
deployment_id = await deployment.create_deployment(
name=f"cluster-test-{i+1}",
environment="production" if i % 2 == 0 else "staging",
region="us-west-1",
instance_type="t3.medium",
min_instances=1,
max_instances=5,
desired_instances=2,
port=8080 + i,
domain=f"test{i+1}.aitbc.dev",
database_config={"host": "localhost", "port": 5432, "name": f"aitbc_{i+1}"}
)
await deployment.deploy_application(deployment_id)
deployment_ids.append(deployment_id)
# Get cluster overview
overview = await deployment.get_cluster_overview()
assert overview is not None
assert "total_deployments" in overview
assert "running_deployments" in overview
assert "total_instances" in overview
assert "aggregate_metrics" in overview
assert "recent_scaling_events" in overview
assert "successful_scaling_rate" in overview
assert "health_check_coverage" in overview
# Check overview data
assert overview["total_deployments"] == 3
assert overview["running_deployments"] == 3
assert overview["total_instances"] == 6 # 2 instances per deployment
assert overview["health_check_coverage"] == 1.0 # 100% coverage
# Restore original method
deployment._deploy_infrastructure = original_deploy_infra
def test_scaling_thresholds():
"""Test scaling threshold configuration"""
deployment = ProductionDeployment("/tmp/test_aitbc")
# Check default thresholds
assert deployment.scaling_thresholds['cpu_high'] == 80.0
assert deployment.scaling_thresholds['cpu_low'] == 20.0
assert deployment.scaling_thresholds['memory_high'] == 85.0
assert deployment.scaling_thresholds['memory_low'] == 30.0
assert deployment.scaling_thresholds['error_rate_high'] == 5.0
assert deployment.scaling_thresholds['response_time_high'] == 2000.0
assert deployment.scaling_thresholds['min_uptime'] == 99.0
async def test_deployment_config_validation():
"""Test deployment configuration validation"""
deployment = ProductionDeployment("/tmp/test_aitbc")
# Test valid configuration
deployment_id = await deployment.create_deployment(
name="valid-config",
environment="production",
region="us-west-1",
instance_type="t3.medium",
min_instances=1,
max_instances=10,
desired_instances=5,
port=8080,
domain="valid.aitbc.dev",
database_config={"host": "localhost", "port": 5432, "name": "aitbc"}
)
assert deployment_id is not None
config = deployment.deployments[deployment_id]
assert config.min_instances <= config.desired_instances <= config.max_instances
async def test_metrics_initialization():
"""Test metrics initialization"""
deployment = ProductionDeployment("/tmp/test_aitbc")
# Create deployment
deployment_id = await deployment.create_deployment(
name="metrics-test",
environment="production",
region="us-west-1",
instance_type="t3.medium",
min_instances=1,
max_instances=5,
desired_instances=2,
port=8080,
domain="metrics.aitbc.dev",
database_config={"host": "localhost", "port": 5432, "name": "aitbc"}
)
# Mock infrastructure deployment
original_deploy_infra = deployment._deploy_infrastructure
async def mock_deploy_infra(dep_config):
return True
deployment._deploy_infrastructure = mock_deploy_infra
# Deploy to initialize metrics
await deployment.deploy_application(deployment_id)
# Check metrics were initialized
metrics = deployment.metrics[deployment_id]
assert metrics.deployment_id == deployment_id
assert metrics.cpu_usage >= 0
assert metrics.memory_usage >= 0
assert metrics.disk_usage >= 0
assert metrics.request_count >= 0
assert metrics.error_rate >= 0
assert metrics.response_time >= 0
assert metrics.uptime_percentage >= 0
assert metrics.active_instances >= 1
# Restore original method
deployment._deploy_infrastructure = original_deploy_infra
if __name__ == "__main__":
# Run basic tests
test_deployment_creation()
test_scaling_thresholds()
# Run async tests
asyncio.run(test_create_deployment_config())
asyncio.run(test_deployment_application())
asyncio.run(test_manual_scaling())
asyncio.run(test_auto_scaling())
asyncio.run(test_deployment_status())
asyncio.run(test_cluster_overview())
asyncio.run(test_deployment_config_validation())
asyncio.run(test_metrics_initialization())
print("✅ All deployment tests passed!")