import os
import sys
from http import HTTPStatus
import json
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SRC_ROOT = os.path.join(PROJECT_ROOT, 'src')
if SRC_ROOT not in sys.path:
sys.path.insert(0, SRC_ROOT)
import pytest
from unittest.mock import patch, MagicMock
from virtcca_deploy.services.db_service import db, ComputeNode, VmInstance
import virtcca_deploy.common.constants as constants
class TestVmUndeployEndpoint:
def test_undeploy_cvm_with_list_format(self, authenticated_client, app):
"""测试使用直接列表格式卸载虚拟机"""
with app.app_context():
node1 = ComputeNode(
nodename="compute01",
ip="192.168.1.100",
physical_cpu=8,
memory=16384,
memory_free=8192,
secure_memory=4096,
secure_memory_free=4096,
secure_numa_topology="{}"
)
db.session.add(node1)
vm1 = VmInstance(
vm_id="compute01-1",
host_ip=node1.ip,
host_name=node1.nodename,
vm_spec_uuid="spec-123",
iface_list=json.dumps({
"mac_address": "00:11:22:33:44:55",
"vlan_id": 100,
"ip_address": "192.168.1.10",
"subnet_mask": "255.255.255.0",
"gateway": "192.168.1.1"})
)
db.session.add(vm1)
db.session.commit()
with patch('virtcca_deploy.services.vm_service.get_vm_service') as mock_get_vm_service:
mock_vm_service = MagicMock()
mock_vm_service.execute_undeployment.return_value = {
"compute01-1": {
"task_id": "task-123",
"host_ip": "192.168.1.100"
}
}
mock_get_vm_service.return_value = mock_vm_service
response = authenticated_client.post(
constants.ROUTE_VM_UNDEPLOY,
json=["compute01-1"]
)
assert response.status_code == HTTPStatus.ACCEPTED
assert "compute01-1" in response.json.get("data", {})
mock_vm_service.execute_undeployment.assert_called_once()
args, kwargs = mock_vm_service.execute_undeployment.call_args
assert args[0] == []
assert args[1] == ["compute01-1"]
def test_undeploy_cvm_with_object_list_format(self, authenticated_client, app):
"""测试使用对象包含列表格式卸载虚拟机:{["compute01-1"]}"""
with app.app_context():
node1 = ComputeNode(
nodename="compute01",
ip="192.168.1.100",
physical_cpu=8,
memory=16384,
memory_free=8192,
secure_memory=4096,
secure_memory_free=4096,
secure_numa_topology="{}"
)
db.session.add(node1)
vm1 = VmInstance(
vm_id="compute01-1",
host_ip=node1.ip,
host_name=node1.nodename,
vm_spec_uuid="spec-123",
iface_list=json.dumps({
"mac_address": "00:11:22:33:44:55",
"vlan_id": 100,
"ip_address": "192.168.1.10",
"subnet_mask": "255.255.255.0",
"gateway": "192.168.1.1"})
)
db.session.add(vm1)
db.session.commit()
with patch('virtcca_deploy.services.vm_service.get_vm_service') as mock_get_vm_service:
mock_vm_service = MagicMock()
mock_vm_service.execute_undeployment.return_value = {
"compute01-1": {
"task_id": "task-123",
"host_ip": "192.168.1.100"
}
}
mock_get_vm_service.return_value = mock_vm_service
response = authenticated_client.post(
constants.ROUTE_VM_UNDEPLOY,
json={"vm_ids": ["compute01-1"]}
)
assert response.status_code == HTTPStatus.ACCEPTED
assert "compute01-1" in response.json.get("data", {})
mock_vm_service.execute_undeployment.assert_called_once()
args, kwargs = mock_vm_service.execute_undeployment.call_args
assert args[0] == []
assert args[1] == ["compute01-1"]
def test_undeploy_cvm_with_old_format(self, authenticated_client, app):
"""测试使用旧格式卸载虚拟机:{"vm_id": ["compute01-1"]}"""
with app.app_context():
node1 = ComputeNode(
nodename="compute01",
ip="192.168.1.100",
physical_cpu=8,
memory=16384,
memory_free=8192,
secure_memory=4096,
secure_memory_free=4096,
secure_numa_topology="{}"
)
db.session.add(node1)
vm1 = VmInstance(
vm_id="compute01-1",
host_ip=node1.ip,
host_name=node1.nodename,
vm_spec_uuid="spec-123",
iface_list=json.dumps({
"mac_address": "00:11:22:33:44:55",
"vlan_id": 100,
"ip_address": "192.168.1.10",
"subnet_mask": "255.255.255.0",
"gateway": "192.168.1.1"})
)
db.session.add(vm1)
db.session.commit()
with patch('virtcca_deploy.services.vm_service.get_vm_service') as mock_get_vm_service:
mock_vm_service = MagicMock()
mock_vm_service.execute_undeployment.return_value = {
"compute01-1": {
"task_id": "task-123",
"host_ip": "192.168.1.100"
}
}
mock_get_vm_service.return_value = mock_vm_service
response = authenticated_client.post(
constants.ROUTE_VM_UNDEPLOY,
json={"vm_ids": ["compute01-1"]}
)
assert response.status_code == HTTPStatus.ACCEPTED
assert "compute01-1" in response.json.get("data", {})
mock_vm_service.execute_undeployment.assert_called_once()
args, kwargs = mock_vm_service.execute_undeployment.call_args
assert args[0] == []
assert args[1] == ["compute01-1"]
def test_undeploy_cvm_invalid_format(self, authenticated_client):
"""测试无效的输入格式"""
response = authenticated_client.post(
constants.ROUTE_VM_UNDEPLOY,
json={"invalid_key": ["compute01-1"]}
)
assert response.status_code == HTTPStatus.BAD_REQUEST
def test_undeploy_cvm_empty_list(self, authenticated_client):
"""测试空列表输入"""
response = authenticated_client.post(
constants.ROUTE_VM_UNDEPLOY,
json=[]
)
assert response.status_code == HTTPStatus.BAD_REQUEST
print(response.json)
assert "Invalid request format, expected a list of VM IDs" in response.json.get("message", "")
def test_undeploy_cvm_non_list_format(self, authenticated_client):
"""测试非列表格式输入"""
response = authenticated_client.post(
constants.ROUTE_VM_UNDEPLOY,
json={"vm_id": "compute01-1"}
)
assert response.status_code == HTTPStatus.BAD_REQUEST
assert "Invalid request format" in response.json.get("message", "")