mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-26 03:42:22 +02:00
test: cover the namespace-failure veth cleanup and BridgeNIO field validation
Both fixes from the code-review pass were carried by other tests' side effects: the move_to_ns failure path (the branch that used to skip the delete_veth) and the required-but-nullable bridge field on the NIO create routes.
This commit is contained in:
parent
2d8ddb5ed7
commit
96be37baa1
@ -226,6 +226,31 @@ class TestDockerNodesRoutes:
|
|||||||
assert response.status_code == status.HTTP_201_CREATED
|
assert response.status_code == status.HTTP_201_CREATED
|
||||||
assert response.json()["type"] == "nio_udp"
|
assert response.json()["type"] == "nio_udp"
|
||||||
|
|
||||||
|
async def test_docker_nio_create_bridge_requires_the_field_but_takes_null(
|
||||||
|
self, app: FastAPI, compute_client: AsyncClient, vm: dict
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
BridgeNIO.bridge is required-but-nullable: an omitted key is a 422
|
||||||
|
(the NIO factories read it, and the routes drop unset fields — an
|
||||||
|
omitted key used to pass validation and die as a KeyError during
|
||||||
|
binding), while an explicit null is the absorbed-link shape.
|
||||||
|
"""
|
||||||
|
|
||||||
|
url = app.url_path_for(
|
||||||
|
"compute:create_docker_node_nio",
|
||||||
|
project_id=vm["project_id"],
|
||||||
|
node_id=vm["node_id"],
|
||||||
|
adapter_number="0",
|
||||||
|
port_number="0",
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await compute_client.post(url, json={"type": "nio_bridge"})
|
||||||
|
assert response.status_code == status.HTTP_422_UNPROCESSABLE_CONTENT
|
||||||
|
|
||||||
|
response = await compute_client.post(url, json={"type": "nio_bridge", "bridge": None})
|
||||||
|
assert response.status_code == status.HTTP_201_CREATED
|
||||||
|
assert response.json()["bridge"] is None
|
||||||
|
|
||||||
async def test_docker_nio_batch_create(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
|
async def test_docker_nio_batch_create(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
|
||||||
"""
|
"""
|
||||||
Exercise the project-wide batch NIO endpoint: bind two NIOs on the same
|
Exercise the project-wide batch NIO endpoint: bind two NIOs on the same
|
||||||
|
|||||||
@ -33,7 +33,7 @@ from gns3server.compute.docker import Docker
|
|||||||
from gns3server.compute.docker.docker_error import DockerError, DockerHttp404Error
|
from gns3server.compute.docker.docker_error import DockerError, DockerHttp404Error
|
||||||
from gns3server.compute.docker.docker_vm import DockerVM
|
from gns3server.compute.docker.docker_vm import DockerVM
|
||||||
from gns3server.compute.nios.nio_bridge import NIOBridge
|
from gns3server.compute.nios.nio_bridge import NIOBridge
|
||||||
from gns3server.compute.ubridge.ubridge_error import UbridgeError
|
from gns3server.compute.ubridge.ubridge_error import UbridgeError, UbridgeNamespaceError
|
||||||
from tests.utils import AsyncioMagicMock
|
from tests.utils import AsyncioMagicMock
|
||||||
|
|
||||||
BRIDGE = "gns3a1b2c3d4e5f"
|
BRIDGE = "gns3a1b2c3d4e5f"
|
||||||
@ -261,6 +261,32 @@ async def test_add_ubridge_kernel_connection_cleans_up_on_failure(vm):
|
|||||||
assert (0, 0) not in vm._kernel_veths
|
assert (0, 0) not in vm._kernel_veths
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_create_veth_cleans_up_when_the_namespace_move_fails(vm):
|
||||||
|
"""
|
||||||
|
``move_to_ns`` failing (the container died between create and move)
|
||||||
|
raises UbridgeNamespaceError — and must take the same cleanup path as
|
||||||
|
any other failure: the old branch re-raised before the delete_veth,
|
||||||
|
leaving the half-created pair behind until the next start's sweep.
|
||||||
|
"""
|
||||||
|
|
||||||
|
vm._ubridge_hypervisor = MagicMock()
|
||||||
|
vm._namespace = 42
|
||||||
|
|
||||||
|
async def failing_send(command):
|
||||||
|
if command.startswith("docker move_to_ns"):
|
||||||
|
raise UbridgeError("Could not move interface: No such process")
|
||||||
|
|
||||||
|
vm._ubridge_send = AsyncioMagicMock(side_effect=failing_send)
|
||||||
|
|
||||||
|
with pytest.raises(UbridgeNamespaceError):
|
||||||
|
await vm._create_veth(0)
|
||||||
|
|
||||||
|
host_ifc, _ = vm._veth_names(0, 0)
|
||||||
|
vm._ubridge_send.assert_any_call(f'docker delete_veth "{host_ifc}"')
|
||||||
|
assert vm._kernel_veths == {}
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Link attach / detach
|
# Link attach / detach
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user