little update

This commit is contained in:
2026-08-12 21:11:39 +03:00
parent e3d5de12fe
commit 3af436d48a
37 changed files with 2299 additions and 9 deletions

View File

@@ -0,0 +1,151 @@
from uuid import uuid4
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from cloud.models import AvailabilityZone, Subnet
from cloud.vm_manager import VMAPIError
from database.models import Base, NetworkPoolEntry
from networking import NetworkingManager, NetworkPoolExhaustedError
class Cloud:
def __init__(self) -> None:
self.subnets: dict[str, Subnet] = {}
self.created: list[str] = []
self.requests = []
self.zones: list[AvailabilityZone] = []
self.subnet_states: list[str] = []
def get_subnet(self, subnet_id: str) -> Subnet:
if subnet_id not in self.subnets:
raise VMAPIError(404, "not found")
subnet = self.subnets[subnet_id]
if self.subnet_states:
subnet.state = self.subnet_states.pop(0)
return subnet
def list_availability_zones(self) -> list[AvailabilityZone]:
return self.zones
def create_subnet(self, request):
self.requests.append(request)
subnet = Subnet(
id=f"subnet-{len(self.subnets) + 1}",
name=request.name,
subnet_address=request.subnet_address,
)
self.subnets[subnet.id] = subnet
self.created.append(subnet.subnet_address)
return subnet
@pytest.fixture
def session_factory():
engine = create_engine("sqlite://")
Base.metadata.create_all(engine)
return sessionmaker(engine, expire_on_commit=False)
def test_allocates_new_network_and_reuses_after_release(session_factory) -> None:
cloud = Cloud()
manager = NetworkingManager(session_factory, cloud, "project-id", availability_zone_id="zone-id")
first_game = uuid4()
first = manager.getNetworkFromPool(first_game)
assert first.cidr == "10.0.0.0/20"
assert first.game_id == first_game
assert cloud.created == ["10.0.0.0/20"]
manager.releaseNetworkToPool(first_game)
reused = manager.getNetworkFromPool(uuid4())
assert reused.cidr == first.cidr
assert len(cloud.created) == 1
def test_waits_for_new_subnet_to_be_ready(session_factory) -> None:
cloud = Cloud()
cloud.subnet_states = ["creating", "created"]
entry = NetworkingManager(
session_factory,
cloud,
"project-id",
availability_zone_id="zone-id",
poll_interval=0.001,
).getNetworkFromPool(uuid4())
assert entry.cidr == "10.0.0.0/20"
def test_discards_missing_cloud_network_and_creates_replacement(session_factory) -> None:
cloud = Cloud()
with session_factory.begin() as session:
session.add(NetworkPoolEntry(cidr="10.0.0.0/20", cloud_subnet_id="gone"))
entry = NetworkingManager(session_factory, cloud, "project-id", availability_zone_id="zone-id").getNetworkFromPool(uuid4())
assert entry.cidr == "10.0.0.0/20"
assert entry.cloud_subnet_id == "subnet-1"
def test_passes_vpc_and_availability_zone_to_subnet_create(session_factory) -> None:
cloud = Cloud()
NetworkingManager(
session_factory,
cloud,
"project-id",
vpc_id="vpc-id",
availability_zone_id="zone-id",
).getNetworkFromPool(uuid4())
request = cloud.requests[0]
assert request.subnet_address == "10.0.0.0/20"
assert request.vpc_id == "vpc-id"
assert request.availability_zone_id == "zone-id"
assert request.model_dump(exclude_none=True)["availability_zone_id"] == "zone-id"
def test_resolves_availability_zone_name_to_id(session_factory) -> None:
cloud = Cloud()
cloud.zones.append(AvailabilityZone(id="zone-uuid", name="ru.AZ-2"))
NetworkingManager(
session_factory,
cloud,
"project-id",
availability_zone_name="ru.AZ-2",
).getNetworkFromPool(uuid4())
assert cloud.requests[0].availability_zone_id == "zone-uuid"
def test_raises_for_unknown_availability_zone_name(session_factory) -> None:
cloud = Cloud()
cloud.zones.append(AvailabilityZone(id="zone-uuid", name="ru.AZ-2"))
with pytest.raises(LookupError, match="ru.AZ-9"):
NetworkingManager(
session_factory,
cloud,
"project-id",
availability_zone_name="ru.AZ-9",
).getNetworkFromPool(uuid4())
def test_raises_when_all_pool_cidrs_are_used(session_factory) -> None:
cloud = Cloud()
with session_factory.begin() as session:
for octet in range(0, 256, 16):
session.add(
NetworkPoolEntry(
cidr=f"10.{octet}.0.0/20",
cloud_subnet_id=str(octet),
game_id=uuid4(),
)
)
with pytest.raises(NetworkPoolExhaustedError, match="network pool exhausted"):
NetworkingManager(session_factory, cloud, "project-id", availability_zone_id="zone-id").getNetworkFromPool(uuid4())