Files
vmware-api-simulator/tests/unit/test_property_collector.py
T
inecs f8d3cbdd59 Initial commit: VMware vSphere API simulator scaffold.
Add the FastAPI app, PostgreSQL migrations, Docker/Helm packaging, API
contracts, docs, client examples, and the unit/integration/compatibility
test suite for local client and tooling labs without a real vCenter.
2026-07-18 04:42:11 +03:00

132 lines
4.4 KiB
Python

"""Unit tests for SOAP PropertyCollector helpers."""
from __future__ import annotations
import os
import pytest
from app.vsphere.inventory import ManagedObject
from app.vsphere.soap.property_collector import (
_descendants,
_one_level_traverse,
_type_matches,
_wants_parent_traversal,
build_prop_map,
clear_pc_state,
resolve_inventory_path,
store_page_token,
take_page_token,
take_page_token_full,
view_moids_from_object,
wait_updates_xml,
)
def _obj(
moid: str,
type_name: str,
name: str,
parent: str | None,
props: dict | None = None,
) -> ManagedObject:
return ManagedObject(
moid=moid,
type=type_name,
name=name,
parent_moid=parent,
props=props or {},
)
def test_type_matches_and_parent_traversal() -> None:
assert _type_matches("VirtualMachine", {"ManagedEntity"})
assert _wants_parent_traversal("<path>parent</path>")
def test_descendants() -> None:
objects = [
_obj("group-d1", "Folder", "Datacenters", None),
_obj("datacenter-21", "Datacenter", "DC", "group-d1"),
_obj("group-v23", "Folder", "vm", "datacenter-21"),
_obj("vm-101", "VirtualMachine", "web-01", "group-v23"),
]
expanded = _descendants([objects[0]], objects)
assert {o.moid for o in expanded} >= {"group-d1", "datacenter-21", "group-v23", "vm-101"}
def test_view_moids_from_object_props() -> None:
view = _obj("view-1", "ContainerView", "view-1", None, {"view_moids": ["vm-101", "vm-102"]})
assert view_moids_from_object(view) == ["vm-101", "vm-102"]
props = build_prop_map(
view,
children=[],
all_by_moid={
"vm-101": _obj("vm-101", "VirtualMachine", "a", "group-v23"),
"vm-102": _obj("vm-102", "VirtualMachine", "b", "group-v23"),
},
)
assert "view" in props
@pytest.mark.integration
@pytest.mark.asyncio
async def test_page_token_roundtrip_db() -> None:
database_url = os.getenv("TEST_DATABASE_URL") or os.getenv("DATABASE_URL")
if not database_url:
pytest.skip("TEST_DATABASE_URL / DATABASE_URL required")
from app.config import Settings
from app.db.pool import AsyncpgDatabase
database = AsyncpgDatabase(Settings(database_url=database_url)) # type: ignore[arg-type]
await database.connect()
try:
await clear_pc_state(database)
token = await store_page_token(database, ["vm-1", "vm-2"], path_sets=["name"])
assert await take_page_token_full(database, token) == (["vm-1", "vm-2"], ["name"])
token2 = await store_page_token(database, ["vm-3"])
assert await take_page_token(database, token2) == ["vm-3"]
assert await take_page_token(database, token2) is None
finally:
await database.close()
@pytest.mark.integration
@pytest.mark.asyncio
async def test_wait_updates_versions_db() -> None:
database_url = os.getenv("TEST_DATABASE_URL") or os.getenv("DATABASE_URL")
if not database_url:
pytest.skip("TEST_DATABASE_URL / DATABASE_URL required")
from app.config import Settings
from app.db.pool import AsyncpgDatabase
database = AsyncpgDatabase(Settings(database_url=database_url)) # type: ignore[arg-type]
await database.connect()
try:
await clear_pc_state(database)
objects = [_obj("vm-101", "VirtualMachine", "web-01", "group-v23")]
first = await wait_updates_xml(
database, session_key="sess-1", body="<version></version>", objects=objects
)
assert "<version>1</version>" in first
idle = await wait_updates_xml(
database, session_key="sess-1", body="<version>1</version>", objects=objects
)
assert "<version>1</version>" in idle
assert "objectSet" not in idle
finally:
await database.close()
def test_resolve_inventory_path_and_one_level() -> None:
objects = [
_obj("group-d1", "Folder", "Datacenters", None),
_obj("datacenter-21", "Datacenter", "DC1", "group-d1", {"vm_folder": "group-v23"}),
_obj("group-v23", "Folder", "vm", "datacenter-21"),
_obj("vm-101", "VirtualMachine", "web-01", "group-v23"),
]
hit = resolve_inventory_path("/DC1/vm/web-01", objects)
assert hit is not None and hit.moid == "vm-101"
kids = _one_level_traverse([objects[2]], objects, "<path>childEntity</path>")
assert any(o.moid == "vm-101" for o in kids)