feat: release proxmoxer-compatible 0.1.0 slice
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""External client compatibility tests."""
|
||||
@@ -0,0 +1,39 @@
|
||||
"""Unmodified proxmoxer HTTPS smoke flow."""
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from proxmoxer import ProxmoxAPI # type: ignore[import-untyped]
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.compatibility,
|
||||
pytest.mark.skipif(not os.getenv("PROXMOXER_HOST"), reason="running TLS simulator required"),
|
||||
]
|
||||
|
||||
|
||||
def test_proxmoxer_read_and_qemu_task_flow() -> None:
|
||||
proxmox = ProxmoxAPI(
|
||||
os.environ["PROXMOXER_HOST"],
|
||||
port=int(os.getenv("PROXMOXER_PORT", "8007")),
|
||||
user="root@pam",
|
||||
password=os.getenv("PROXMOXER_PASSWORD", "secret"),
|
||||
verify_ssl=False,
|
||||
)
|
||||
|
||||
assert proxmox.version.get()["version"] == "9.2.3"
|
||||
assert any(node["node"] == "pve1" for node in proxmox.nodes.get())
|
||||
assert any(vm["vmid"] == 101 for vm in proxmox.nodes("pve1").qemu.get())
|
||||
|
||||
if os.getenv("PROXMOXER_MUTATION_TEST") == "1":
|
||||
status = proxmox.nodes("pve1").qemu("101").status.current.get()
|
||||
operation = "start" if status["status"] == "stopped" else "stop"
|
||||
endpoint = proxmox.nodes("pve1").qemu("101").status(operation)
|
||||
upid = endpoint.post()
|
||||
for _attempt in range(100):
|
||||
task = proxmox.nodes("pve1").tasks(upid).status.get()
|
||||
if task["status"] == "stopped":
|
||||
break
|
||||
time.sleep(0.05)
|
||||
assert task["status"] == "stopped"
|
||||
assert task["exitstatus"] == "OK"
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Bounded task worker outcome tests."""
|
||||
|
||||
import asyncio
|
||||
import uuid
|
||||
from typing import cast
|
||||
|
||||
@@ -72,3 +73,28 @@ async def test_worker_honors_persisted_cancellation() -> None:
|
||||
|
||||
assert not called
|
||||
assert repository.finishes == [("cancelled", None)]
|
||||
|
||||
|
||||
async def test_worker_retries_after_claim_failure() -> None:
|
||||
class RecoveringRepository:
|
||||
attempts = 0
|
||||
|
||||
async def claim(self, _worker_id: str, _lease_seconds: float) -> None:
|
||||
self.attempts += 1
|
||||
if self.attempts == 1:
|
||||
raise RuntimeError("database schema is not ready")
|
||||
return None
|
||||
|
||||
repository = RecoveringRepository()
|
||||
worker = TaskWorker(
|
||||
cast(TaskRepository, repository),
|
||||
"worker",
|
||||
{},
|
||||
poll_seconds=0.001,
|
||||
)
|
||||
running = asyncio.create_task(worker.run())
|
||||
await asyncio.sleep(0.01)
|
||||
worker.stop()
|
||||
await running
|
||||
|
||||
assert repository.attempts > 1
|
||||
|
||||
Reference in New Issue
Block a user