Fix CI/pulumi blockers and document test suites with latest PASS results.

Stabilize node status, cluster-wide Ceph OSD ids, and QEMU cpu utilization so
status/list no longer 500 on model strings; align pulumi defaults to pve1;
add bilingual testing docs with the 2026-07-18 ci-all + pulumi-tests pass.
This commit is contained in:
Sergey Antropoff
2026-07-18 09:38:28 +03:00
parent 6f42d4c318
commit baa1f58ad0
31 changed files with 230 additions and 58 deletions
+5 -5
View File
@@ -33,7 +33,7 @@ def test_proxmoxer_read_and_qemu_task_flow() -> None:
assert proxmox.version.get()["version"] == "9.2.3"
assert any(node["node"] == "pve1" for node in proxmox.nodes.get())
assert any(vm["vmid"] == 100 for vm in proxmox.nodes("pve1").qemu.get())
assert any(vm["vmid"] == 103 for vm in proxmox.nodes("pve1").qemu.get())
token_api = ProxmoxAPI(
os.environ["PROXMOXER_HOST"],
@@ -55,9 +55,9 @@ def test_proxmoxer_read_and_qemu_task_flow() -> None:
)
assert readonly_api.nodes.get()
assert readonly_api.nodes("pve1").status.get()["status"] == "online"
assert readonly_api.nodes("pve1").qemu("100").config.get()["vmid"] == 100
assert readonly_api.nodes("pve1").qemu("103").config.get()["vmid"] == 103
with pytest.raises(ResourceException) as denied:
readonly_api.nodes("pve1").qemu("100").status.start.post()
readonly_api.nodes("pve1").qemu("103").status.start.post()
assert denied.value.status_code == 403
token_endpoint = proxmox.access.users("root@pam").token("ephemeral")
@@ -88,7 +88,7 @@ def test_proxmoxer_read_and_qemu_task_flow() -> None:
token_value=os.getenv("PROXMOXER_STORAGE_TOKEN_SECRET", "storage-secret"),
verify_ssl=False,
)
for vmid in ("100", "999999"):
for vmid in ("103", "999999"):
with pytest.raises(ResourceException) as hidden:
storage_api.nodes("pve1").qemu(vmid).config.get()
assert hidden.value.status_code == 403
@@ -176,7 +176,7 @@ def test_proxmoxer_read_and_qemu_task_flow() -> None:
token_value=os.getenv("PROXMOXER_OPERATOR_TOKEN_SECRET", "operator-secret"),
verify_ssl=False,
)
status_resource = operator_api.nodes("pve1").qemu("100").status
status_resource = operator_api.nodes("pve1").qemu("103").status
def run(operation: str, expected: str) -> None:
upid = status_resource(operation).post()
+20 -12
View File
@@ -86,11 +86,24 @@ async def test_backup_jobs_crud_and_shapes() -> None:
pool = BackupPool()
http = _request(pool)
listed = await registry.get("/cluster/backup", "GET")(http, {"values": {}})
list_jobs = registry.get("/cluster/backup", "GET")
create_job = registry.get("/cluster/backup", "POST")
backup_info = registry.get("/cluster/backup-info", "GET")
not_backed_up = registry.get("/cluster/backup-info/not-backed-up", "GET")
included_volumes = registry.get("/cluster/backup/{id}/included_volumes", "GET")
delete_job = registry.get("/cluster/backup/{id}", "DELETE")
assert list_jobs is not None
assert create_job is not None
assert backup_info is not None
assert not_backed_up is not None
assert included_volumes is not None
assert delete_job is not None
listed = await list_jobs(http, {"values": {}})
assert listed[0]["id"] == "backup-daily"
assert listed[0]["schedule"] == "0 2 * * *"
await registry.get("/cluster/backup", "POST")(
await create_job(
http,
{
"values": {
@@ -103,24 +116,19 @@ async def test_backup_jobs_crud_and_shapes() -> None:
)
assert "backup-weekly" in pool.metadata["backup_jobs"]
info = await registry.get("/cluster/backup-info", "GET")(http, {"values": {}})
info = await backup_info(http, {"values": {}})
assert info == [{"subdir": "not-backed-up"}]
missing = await registry.get("/cluster/backup-info/not-backed-up", "GET")(http, {"values": {}})
assert missing == [] # 100 covered by daily; after weekly both covered? weekly adds 200
missing = await not_backed_up(http, {"values": {}})
# daily covers 100, weekly covers 200 → none missing
assert missing == []
included = await registry.get("/cluster/backup/{id}/included_volumes", "GET")(
http, {"values": {"id": "backup-daily"}}
)
included = await included_volumes(http, {"values": {"id": "backup-daily"}})
assert included["children"][0]["id"] == 100
assert included["children"][0]["children"][0]["id"] == "scsi0"
await registry.get("/cluster/backup/{id}", "DELETE")(http, {"values": {"id": "backup-weekly"}})
await delete_job(http, {"values": {"id": "backup-weekly"}})
assert "backup-weekly" not in pool.metadata["backup_jobs"]
missing_after = await registry.get("/cluster/backup-info/not-backed-up", "GET")(
http, {"values": {}}
)
missing_after = await not_backed_up(http, {"values": {}})
assert missing_after[0]["vmid"] == 200
assert missing_after[0]["type"] == "lxc"
+4 -1
View File
@@ -93,7 +93,10 @@ async def test_worker_retries_after_claim_failure() -> None:
poll_seconds=0.001,
)
running = asyncio.create_task(worker.run())
await asyncio.sleep(0.01)
for _ in range(200):
if repository.attempts > 1:
break
await asyncio.sleep(0.01)
worker.stop()
await running