Initial commit: add Gitea PyPI publish workflow
This commit is contained in:
242
tests/test_compute.py
Normal file
242
tests/test_compute.py
Normal file
@@ -0,0 +1,242 @@
|
||||
"""Tests for the Proxmox compute client."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
import respx
|
||||
from httpx import Response
|
||||
|
||||
from conduit_client import AsyncConduitClient, ConduitClient
|
||||
from conduit_client.models.compute import (
|
||||
CloneVmRequest,
|
||||
ComputeTicketRequest,
|
||||
CreateContainerRequest,
|
||||
CreateSnapshotRequest,
|
||||
CreateVmRequest,
|
||||
MigrateVmRequest,
|
||||
NodeTasksQuery,
|
||||
StorageQuery,
|
||||
UploadStorageRequest,
|
||||
)
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_auth_ticket(api_key: str) -> None:
|
||||
route = respx.post("https://api.example.com/compute/auth/ticket").mock(
|
||||
return_value=Response(
|
||||
200,
|
||||
json={
|
||||
"ticket": "tck",
|
||||
"CSRFPreventionToken": "csrf",
|
||||
"username": "root",
|
||||
},
|
||||
)
|
||||
)
|
||||
with ConduitClient(api_key, base_url="https://api.example.com") as client:
|
||||
result = client.compute.auth_ticket(
|
||||
ComputeTicketRequest(username="root", password="pw")
|
||||
)
|
||||
assert result.ticket == "tck"
|
||||
assert result.csrfpreventiontoken == "csrf"
|
||||
assert json.loads(route.calls[0].request.content) == {
|
||||
"username": "root",
|
||||
"password": "pw",
|
||||
}
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_list_resources_and_nodes(api_key: str) -> None:
|
||||
respx.get("https://api.example.com/compute/resources").mock(
|
||||
return_value=Response(200, json=[{"id": "qemu/100"}])
|
||||
)
|
||||
respx.get("https://api.example.com/compute/resources").mock(
|
||||
return_value=Response(200, json=[{"id": "qemu/100"}])
|
||||
)
|
||||
respx.get("https://api.example.com/compute/cluster/status").mock(
|
||||
return_value=Response(200, json={"quorate": True})
|
||||
)
|
||||
respx.get("https://api.example.com/compute/nodes").mock(
|
||||
return_value=Response(200, json=[{"node": "pve"}])
|
||||
)
|
||||
with ConduitClient(api_key, base_url="https://api.example.com") as client:
|
||||
assert client.compute.list_resources() == [{"id": "qemu/100"}]
|
||||
assert client.compute.list_resources(type_="vm") == [{"id": "qemu/100"}]
|
||||
assert client.compute.cluster_status() == {"quorate": True}
|
||||
assert client.compute.list_nodes() == [{"node": "pve"}]
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_node_status_and_tasks(api_key: str) -> None:
|
||||
respx.get("https://api.example.com/compute/nodes/pve/status").mock(
|
||||
return_value=Response(200, json={"cpu": 0.1})
|
||||
)
|
||||
route = respx.get("https://api.example.com/compute/nodes/pve/tasks").mock(
|
||||
return_value=Response(200, json=[])
|
||||
)
|
||||
with ConduitClient(api_key, base_url="https://api.example.com") as client:
|
||||
assert client.compute.get_node_status("pve") == {"cpu": 0.1}
|
||||
assert client.compute.list_node_tasks("pve", NodeTasksQuery(limit=10)) == []
|
||||
assert route.calls[0].request.url.params["limit"] == "10"
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_vm_lifecycle(api_key: str) -> None:
|
||||
respx.get("https://api.example.com/compute/vms").mock(
|
||||
return_value=Response(200, json=[{"vmid": 100}])
|
||||
)
|
||||
create_route = respx.post("https://api.example.com/compute/vms").mock(
|
||||
return_value=Response(200, json={"task": "UPID:abc"})
|
||||
)
|
||||
respx.get("https://api.example.com/compute/vms/100").mock(
|
||||
return_value=Response(200, json={"vmid": 100, "name": "vm1"})
|
||||
)
|
||||
patch_route = respx.patch("https://api.example.com/compute/vms/100").mock(
|
||||
return_value=Response(200, json={"task": "UPID:patch"})
|
||||
)
|
||||
respx.delete("https://api.example.com/compute/vms/100").mock(
|
||||
return_value=Response(204)
|
||||
)
|
||||
respx.post("https://api.example.com/compute/vms/100/start").mock(
|
||||
return_value=Response(200, json={"task": "UPID:start"})
|
||||
)
|
||||
respx.post("https://api.example.com/compute/vms/100/stop").mock(
|
||||
return_value=Response(200, json={"task": "UPID:stop"})
|
||||
)
|
||||
respx.post("https://api.example.com/compute/vms/100/shutdown").mock(
|
||||
return_value=Response(200, json={"task": "UPID:shutdown"})
|
||||
)
|
||||
respx.post("https://api.example.com/compute/vms/100/reboot").mock(
|
||||
return_value=Response(200, json={"task": "UPID:reboot"})
|
||||
)
|
||||
with ConduitClient(api_key, base_url="https://api.example.com") as client:
|
||||
assert client.compute.list_vms() == [{"vmid": 100}]
|
||||
result = client.compute.create_vm(
|
||||
CreateVmRequest(node="pve", vmid=100, cores=2, memory=1024)
|
||||
)
|
||||
assert result.task == "UPID:abc"
|
||||
assert client.compute.get_vm(100)["name"] == "vm1"
|
||||
assert client.compute.patch_vm(100, {"memory": 2048}).task == "UPID:patch"
|
||||
client.compute.delete_vm(100, confirm=100)
|
||||
assert client.compute.start_vm(100).task == "UPID:start"
|
||||
assert client.compute.stop_vm(100).task == "UPID:stop"
|
||||
assert client.compute.shutdown_vm(100).task == "UPID:shutdown"
|
||||
assert client.compute.reboot_vm(100).task == "UPID:reboot"
|
||||
body = json.loads(create_route.calls[0].request.content)
|
||||
assert body["node"] == "pve"
|
||||
assert body["cores"] == 2
|
||||
assert json.loads(patch_route.calls[0].request.content) == {"memory": 2048}
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_vm_clone_migrate_snapshots_agent(api_key: str) -> None:
|
||||
respx.post("https://api.example.com/compute/vms/100/clone").mock(
|
||||
return_value=Response(200, json={"task": "UPID:clone"})
|
||||
)
|
||||
respx.post("https://api.example.com/compute/vms/100/migrate").mock(
|
||||
return_value=Response(200, json={"task": "UPID:migrate"})
|
||||
)
|
||||
respx.get("https://api.example.com/compute/vms/100/snapshots").mock(
|
||||
return_value=Response(200, json=[{"name": "snap1"}])
|
||||
)
|
||||
respx.post("https://api.example.com/compute/vms/100/snapshots").mock(
|
||||
return_value=Response(200, json={"task": "UPID:snap"})
|
||||
)
|
||||
respx.post("https://api.example.com/compute/vms/100/agent/exec").mock(
|
||||
return_value=Response(200, json={"out-data": "ok"})
|
||||
)
|
||||
with ConduitClient(api_key, base_url="https://api.example.com") as client:
|
||||
assert client.compute.clone_vm(100, CloneVmRequest(newid=200)).task == "UPID:clone"
|
||||
assert client.compute.migrate_vm(
|
||||
100, MigrateVmRequest(target="pve2", online=True)
|
||||
).task == "UPID:migrate"
|
||||
assert client.compute.list_snapshots(100) == [{"name": "snap1"}]
|
||||
assert client.compute.create_snapshot(
|
||||
100, CreateSnapshotRequest(snapname="snap2")
|
||||
).task == "UPID:snap"
|
||||
assert client.compute.agent_action(100, "exec", {"command": "ls"}) == {"out-data": "ok"}
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_containers(api_key: str) -> None:
|
||||
create_route = respx.post("https://api.example.com/compute/containers").mock(
|
||||
return_value=Response(200, json={"task": "UPID:ct"})
|
||||
)
|
||||
respx.post("https://api.example.com/compute/containers/200/start").mock(
|
||||
return_value=Response(200, json={"task": "UPID:start"})
|
||||
)
|
||||
respx.post("https://api.example.com/compute/containers/200/stop").mock(
|
||||
return_value=Response(200, json={"task": "UPID:stop"})
|
||||
)
|
||||
with ConduitClient(api_key, base_url="https://api.example.com") as client:
|
||||
result = client.compute.create_container(
|
||||
CreateContainerRequest(node="pve", ostemplate="local:vztmpl/debian.tar.gz", vmid=200)
|
||||
)
|
||||
assert result.task == "UPID:ct"
|
||||
assert client.compute.start_container(200).task == "UPID:start"
|
||||
assert client.compute.stop_container(200).task == "UPID:stop"
|
||||
body = json.loads(create_route.calls[0].request.content)
|
||||
assert body["node"] == "pve"
|
||||
assert body["ostemplate"] == "local:vztmpl/debian.tar.gz"
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_storage(api_key: str) -> None:
|
||||
respx.get("https://api.example.com/compute/storage").mock(
|
||||
return_value=Response(200, json=[{"storage": "local"}])
|
||||
)
|
||||
respx.get("https://api.example.com/compute/storage/local/content").mock(
|
||||
return_value=Response(200, json=[{"volid": "local:iso/img.iso"}])
|
||||
)
|
||||
upload_route = respx.post("https://api.example.com/compute/storage/local/upload").mock(
|
||||
return_value=Response(200, json={"task": "UPID:upload"})
|
||||
)
|
||||
with ConduitClient(api_key, base_url="https://api.example.com") as client:
|
||||
assert client.compute.list_storage(StorageQuery(node="pve")) == [{"storage": "local"}]
|
||||
assert client.compute.list_storage_content("local", StorageQuery(node="pve")) == [
|
||||
{"volid": "local:iso/img.iso"}
|
||||
]
|
||||
result = client.compute.upload_to_storage(
|
||||
"local",
|
||||
UploadStorageRequest(content="abc", filename="img.iso"),
|
||||
node="pve",
|
||||
)
|
||||
assert result.task == "UPID:upload"
|
||||
assert upload_route.calls[0].request.url.params["node"] == "pve"
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_backup_jobs_and_misc(api_key: str) -> None:
|
||||
respx.get("https://api.example.com/compute/backups/jobs").mock(
|
||||
return_value=Response(200, json=[])
|
||||
)
|
||||
respx.post("https://api.example.com/compute/backups/jobs").mock(
|
||||
return_value=Response(200, json={"task": "UPID:backup"})
|
||||
)
|
||||
respx.get("https://api.example.com/compute/ha/resources").mock(
|
||||
return_value=Response(200, json=[])
|
||||
)
|
||||
respx.get("https://api.example.com/compute/access/users").mock(
|
||||
return_value=Response(200, json=[])
|
||||
)
|
||||
respx.get("https://api.example.com/compute/access/acl").mock(
|
||||
return_value=Response(200, json=[])
|
||||
)
|
||||
with ConduitClient(api_key, base_url="https://api.example.com") as client:
|
||||
assert client.compute.list_backup_jobs() == []
|
||||
assert client.compute.create_backup_job({"id": "job1"}).task == "UPID:backup"
|
||||
assert client.compute.list_ha_resources() == []
|
||||
assert client.compute.list_access_users() == []
|
||||
assert client.compute.list_access_acl() == []
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@respx.mock
|
||||
async def test_async_start_vm(api_key: str) -> None:
|
||||
respx.post("https://api.example.com/compute/vms/100/start").mock(
|
||||
return_value=Response(200, json={"task": "UPID:start"})
|
||||
)
|
||||
async with AsyncConduitClient(api_key, base_url="https://api.example.com") as client:
|
||||
result = await client.compute.start_vm(100)
|
||||
assert result.task == "UPID:start"
|
||||
Reference in New Issue
Block a user