refactor: ruff autofixes

This commit is contained in:
Mark Paronyan committed 2026-09-27 15:55:10 +03:00
1 parent 2ac637c662
commit a0450b6bce
455 files changed
+12322 -14762

No files matched your search

+44 -16
View File
@@ -30,28 +30,56 @@ pytestmark = pytest.mark.asyncio
class TestCapabilitiesRoutes:
async def test_get(self, app: FastAPI, compute_client: AsyncClient, windows_platform) -> None:
response = await compute_client.get(app.url_path_for("compute:get_capabilities"))
assert response.status_code == status.HTTP_200_OK
assert response.json() == {'node_types': ['cloud', 'ethernet_hub', 'ethernet_switch', 'nat', 'vpcs', 'virtualbox', 'dynamips', 'frame_relay_switch', 'atm_switch', 'qemu', 'vmware', 'docker', 'iou'],
'version': __version__,
'platform': sys.platform,
'cpus': psutil.cpu_count(logical=True),
'memory': psutil.virtual_memory().total,
'disk_size': psutil.disk_usage(get_default_project_directory()).total,
}
assert response.json() == {
"node_types": [
"cloud",
"ethernet_hub",
"ethernet_switch",
"nat",
"vpcs",
"virtualbox",
"dynamips",
"frame_relay_switch",
"atm_switch",
"qemu",
"vmware",
"docker",
"iou",
],
"version": __version__,
"platform": sys.platform,
"cpus": psutil.cpu_count(logical=True),
"memory": psutil.virtual_memory().total,
"disk_size": psutil.disk_usage(get_default_project_directory()).total,
}
async def test_get_on_gns3vm(self, app: FastAPI, compute_client: AsyncClient, on_gns3vm) -> None:
response = await compute_client.get(app.url_path_for("compute:get_capabilities"))
assert response.status_code == status.HTTP_200_OK
assert response.json() == {'node_types': ['cloud', 'ethernet_hub', 'ethernet_switch', 'nat', 'vpcs', 'virtualbox', 'dynamips', 'frame_relay_switch', 'atm_switch', 'qemu', 'vmware', 'docker', 'iou'],
'version': __version__,
'platform': sys.platform,
'cpus': psutil.cpu_count(logical=True),
'memory': psutil.virtual_memory().total,
'disk_size': psutil.disk_usage(get_default_project_directory()).total,
}
assert response.json() == {
"node_types": [
"cloud",
"ethernet_hub",
"ethernet_switch",
"nat",
"vpcs",
"virtualbox",
"dynamips",
"frame_relay_switch",
"atm_switch",
"qemu",
"vmware",
"docker",
"iou",
],
"version": __version__,
"platform": sys.platform,
"cpus": psutil.cpu_count(logical=True),
"memory": psutil.virtual_memory().total,
"disk_size": psutil.disk_usage(get_default_project_directory()).total,
}
+87 -137
View File
@@ -29,231 +29,181 @@ pytestmark = pytest.mark.asyncio
class TestCloudNodesRoutes:
@pytest_asyncio.fixture
async def vm(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, on_gns3vm) -> dict:
with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud._start_ubridge"):
response = await compute_client.post(app.url_path_for("compute:create_cloud", project_id=compute_project.id),
json={"name": "Cloud 1"})
response = await compute_client.post(
app.url_path_for("compute:create_cloud", project_id=compute_project.id), json={"name": "Cloud 1"}
)
assert response.status_code == status.HTTP_201_CREATED
return response.json()
async def test_cloud_create(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project
) -> None:
async def test_cloud_create(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud._start_ubridge"):
response = await compute_client.post(app.url_path_for("compute:create_cloud", project_id=compute_project.id),
json={"name": "Cloud 1"})
response = await compute_client.post(
app.url_path_for("compute:create_cloud", project_id=compute_project.id), json={"name": "Cloud 1"}
)
assert response.status_code == 201
assert response.json()["name"] == "Cloud 1"
assert response.json()["project_id"] == compute_project.id
async def test_get_cloud(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict
) -> None:
response = await compute_client.get(app.url_path_for("compute:get_cloud", project_id=vm["project_id"], node_id=vm["node_id"]))
response = await compute_client.get(
app.url_path_for("compute:get_cloud", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "Cloud 1"
assert response.json()["project_id"] == compute_project.id
assert response.json()["status"] == "started"
async def test_cloud_nio_create_udp(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict
) -> None:
params = {"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"}
url = app.url_path_for("compute:create_cloud_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
async def test_cloud_nio_update_udp(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1",
"filters": {"packet_loss": 10}
}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
url = app.url_path_for(
"compute:create_cloud_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
port_number="0",
)
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
async def test_cloud_nio_update_udp(
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict
) -> None:
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1", "filters": {"packet_loss": 10}}
url = app.url_path_for(
"compute:create_cloud_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["filters"] == {"packet_loss": 10}
params["filters"].clear()
url = app.url_path_for("compute:create_cloud_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:create_cloud_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
response = await compute_client.put(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
assert response.json()["filters"] == {}
async def test_cloud_delete_nio(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict
) -> None:
params = {"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
url = app.url_path_for("compute:create_cloud_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:create_cloud_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
await compute_client.post(url, json=params)
url = app.url_path_for("compute:delete_cloud_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:delete_cloud_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud._start_ubridge"):
response = await compute_client.delete(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_cloud_delete(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict
) -> None:
response = await compute_client.delete(
app.url_path_for(
"compute:delete_cloud",
project_id=vm["project_id"],
node_id=vm["node_id"]
)
app.url_path_for("compute:delete_cloud", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_cloud_stop(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict
) -> None:
response = await compute_client.post(
app.url_path_for(
"compute:stop_cloud",
project_id=vm["project_id"],
node_id=vm["node_id"]
)
app.url_path_for("compute:stop_cloud", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
async def test_cloud_suspend(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict
) -> None:
response = await compute_client.post(
app.url_path_for(
"compute:suspend_cloud",
project_id=vm["project_id"],
node_id=vm["node_id"]
)
app.url_path_for("compute:suspend_cloud", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
async def test_cloud_update(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
async def test_cloud_update(
self, app: FastAPI,
compute_client: AsyncClient,
vm: dict
) -> None:
response = await compute_client.put(app.url_path_for("compute:update_cloud", project_id=vm["project_id"], node_id=vm["node_id"]),
json={"name": "test"})
response = await compute_client.put(
app.url_path_for("compute:update_cloud", project_id=vm["project_id"], node_id=vm["node_id"]),
json={"name": "test"},
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "test"
async def test_cloud_start_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
async def test_cloud_start_capture(
self, app: FastAPI,
compute_client: AsyncClient,
vm: dict
) -> None:
params = {
"capture_file_name": "test.pcap",
"data_link_type": "DLT_EN10MB"
}
params = {"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"}
with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud.start_capture") as mock:
response = await compute_client.post(app.url_path_for("compute:start_cloud_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0"),
json=params)
response = await compute_client.post(
app.url_path_for(
"compute:start_cloud_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
),
json=params,
)
assert response.status_code == status.HTTP_200_OK
assert mock.called
assert "test.pcap" in response.json()["pcap_file_path"]
async def test_cloud_stop_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud.stop_capture") as mock:
response = await compute_client.post(app.url_path_for("compute:stop_cloud_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0"))
response = await compute_client.post(
app.url_path_for(
"compute:stop_cloud_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
)
assert response.status_code == status.HTTP_204_NO_CONTENT
assert mock.called
# @pytest.mark.asyncio
# async def test_cloud_pcap(self, compute_api, vm, compute_project):
#
+13 -20
View File
@@ -30,18 +30,13 @@ pytestmark = pytest.mark.asyncio
class TestComputeRoutes:
async def test_udp_allocation(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
async def test_udp_allocation(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project
) -> None:
response = await compute_client.post(app.url_path_for("compute:allocate_udp_port", project_id=compute_project.id), json={})
response = await compute_client.post(
app.url_path_for("compute:allocate_udp_port", project_id=compute_project.id), json={}
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()['udp_port'] is not None
assert response.json()["udp_port"] is not None
async def test_interfaces(self, app: FastAPI, compute_client: AsyncClient) -> None:
@@ -49,33 +44,30 @@ class TestComputeRoutes:
assert response.status_code == status.HTTP_200_OK
assert isinstance(response.json(), list)
async def test_version_output(self, app: FastAPI, compute_client: AsyncClient) -> None:
response = await compute_client.get(app.url_path_for("compute:compute_version"))
assert response.status_code == status.HTTP_200_OK
assert response.json() == {'version': __version__}
assert response.json() == {"version": __version__}
async def test_compute_authentication(self, app: FastAPI, compute_client: AsyncClient) -> None:
response = await compute_client.get(app.url_path_for("compute:compute_version"), auth=("admin", "invalid_password"))
response = await compute_client.get(
app.url_path_for("compute:compute_version"), auth=("admin", "invalid_password")
)
assert response.status_code == status.HTTP_401_UNAUTHORIZED
# @pytest.mark.asyncio
# async def test_debug_output(compute_api):
#
# response = await compute_api.get('/debug')
# assert response.status_code == 200
async def test_statistics_output(self, app: FastAPI, compute_client: AsyncClient) -> None:
response = await compute_client.get(app.url_path_for("compute:compute_statistics"))
assert response.status_code == status.HTTP_200_OK
async def test_compute_auth_disabled(self, app: FastAPI, compute_client: AsyncClient) -> None:
mock_settings = MagicMock()
@@ -85,9 +77,10 @@ class TestComputeRoutes:
mock_server_settings.compute_password.get_secret_value.return_value = "testpass"
mock_settings.settings.Server = mock_server_settings
with patch("gns3server.api.routes.compute.dependencies.authentication.Config.instance", return_value=mock_settings):
with patch(
"gns3server.api.routes.compute.dependencies.authentication.Config.instance", return_value=mock_settings
):
response = await compute_client.get(
app.url_path_for("compute:compute_version"),
auth=("wrong_user", "wrong_password")
app.url_path_for("compute:compute_version"), auth=("wrong_user", "wrong_password")
)
assert response.status_code == status.HTTP_200_OK
+95 -112
View File
@@ -31,7 +31,6 @@ pytestmark = pytest.mark.asyncio
class TestDockerNodesRoutes:
@pytest.fixture
def base_params(self) -> dict:
"""Return standard parameters"""
@@ -44,11 +43,10 @@ class TestDockerNodesRoutes:
"environment": "YES=1\nNO=0",
"console_type": "telnet",
"console_resolution": "1280x1024",
"extra_hosts": "test:127.0.0.1"
"extra_hosts": "test:127.0.0.1",
}
return params
# @pytest.yield_fixture(autouse=True)
# def mock_connection():
#
@@ -58,30 +56,20 @@ class TestDockerNodesRoutes:
# yield
# Docker._instance = None
@pytest_asyncio.fixture
async def vm(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict
) -> dict:
async def vm(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict) -> dict:
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "nginx"}]):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value={"Id": "8bd8153ea8f5"}):
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="exited"):
response = await compute_client.post(app.url_path_for("compute:create_docker_node", project_id=compute_project.id),
json=base_params)
response = await compute_client.post(
app.url_path_for("compute:create_docker_node", project_id=compute_project.id), json=base_params
)
assert response.status_code == status.HTTP_201_CREATED
return response.json()
async def test_docker_create(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict
) -> None:
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "nginx"}]):
@@ -99,12 +87,8 @@ class TestDockerNodesRoutes:
assert response.json()["console_resolution"] == "1280x1024"
assert response.json()["extra_hosts"] == "test:127.0.0.1"
async def test_docker_create_iol_startup_config(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict
) -> None:
"""
The controller materializes the GNS3_IOL_STARTUP_CONFIG knob into
@@ -157,13 +141,13 @@ class TestDockerNodesRoutes:
),
)
async def test_docker_create_with_invalid_name(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
name: str,
status_code: int
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
name: str,
status_code: int,
) -> None:
base_params["name"] = name
@@ -174,81 +158,71 @@ class TestDockerNodesRoutes:
)
assert response.status_code == status_code
async def test_docker_start(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.start", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:start_docker_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:start_docker_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_docker_stop(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.stop", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:stop_docker_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:stop_docker_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_docker_reload(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.restart", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:reload_docker_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:reload_docker_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_docker_delete(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.delete", return_value=True) as mock:
response = await compute_client.delete(app.url_path_for("compute:delete_docker_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.delete(
app.url_path_for("compute:delete_docker_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_docker_pause(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.pause", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:pause_docker_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:pause_docker_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_docker_unpause(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.unpause", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:unpause_docker_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:unpause_docker_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_docker_nio_create_udp(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
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")
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=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
@@ -281,7 +255,6 @@ class TestDockerNodesRoutes:
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["added"] == 2
async def test_docker_update_nio(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
@@ -290,25 +263,29 @@ class TestDockerNodesRoutes:
"rport": 4343,
"rhost": "127.0.0.1",
"filters": {"packet_loss": 10},
"suspend": False
"suspend": False,
}
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")
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=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["filters"] == {"packet_loss": 10}
params["filters"] = {}
params["suspend"] = True
url = app.url_path_for("compute:update_docker_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:update_docker_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.adapter_update_nio_binding"):
response = await compute_client.put(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
@@ -318,30 +295,34 @@ class TestDockerNodesRoutes:
async def test_docker_delete_nio(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
url = app.url_path_for("compute:delete_docker_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:delete_docker_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.adapter_remove_nio_binding"):
response = await compute_client.delete(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_docker_update(self, app: FastAPI, compute_client: AsyncClient, vm: dict, free_console_port: int) -> None:
async def test_docker_update(
self, app: FastAPI, compute_client: AsyncClient, vm: dict, free_console_port: int
) -> None:
params = {
"name": "test",
"console": free_console_port,
"start_command": "yes",
"environment": "GNS3=1\nGNS4=0",
"extra_hosts": "test:127.0.0.1"
"extra_hosts": "test:127.0.0.1",
}
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.update") as mock:
response = await compute_client.put(app.url_path_for("compute:update_docker_node",
project_id=vm["project_id"],
node_id=vm["node_id"]), json=params)
response = await compute_client.put(
app.url_path_for("compute:update_docker_node", project_id=vm["project_id"], node_id=vm["node_id"]),
json=params,
)
assert response.status_code == 200
assert mock.called
@@ -352,10 +333,7 @@ class TestDockerNodesRoutes:
assert response.json()["extra_hosts"] == "test:127.0.0.1"
async def test_docker_update_empty_strings_do_not_recreate_container(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project
) -> None:
"""
Web clients serialize empty form fields as "" while unset values are
@@ -390,14 +368,15 @@ class TestDockerNodesRoutes:
assert response.json()["start_command"] is None
assert response.json()["console_http_path"] == "/"
async def test_docker_start_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
url = app.url_path_for("compute:start_docker_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:start_docker_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with patch("gns3server.compute.docker.docker_vm.DockerVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.start_capture") as mock:
@@ -407,14 +386,15 @@ class TestDockerNodesRoutes:
assert mock.called
assert "test.pcap" in response.json()["pcap_file_path"]
async def test_docker_stop_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
url = app.url_path_for("compute:stop_docker_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:stop_docker_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with patch("gns3server.compute.docker.docker_vm.DockerVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.stop_capture") as mock:
@@ -422,18 +402,21 @@ class TestDockerNodesRoutes:
assert response.status_code == status.HTTP_204_NO_CONTENT
assert mock.called
async def test_docker_duplicate(self, app: FastAPI, compute_client: AsyncClient, vm: dict, base_params: dict) -> None:
async def test_docker_duplicate(
self, app: FastAPI, compute_client: AsyncClient, vm: dict, base_params: dict
) -> None:
# create destination node first
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "nginx"}]):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value={"Id": "8bd8153ea8f5"}):
response = await compute_client.post(app.url_path_for("compute:create_docker_node",
project_id=vm["project_id"]), json=base_params)
response = await compute_client.post(
app.url_path_for("compute:create_docker_node", project_id=vm["project_id"]), json=base_params
)
assert response.status_code == status.HTTP_201_CREATED
params = {"destination_node_id": response.json()["node_id"]}
response = await compute_client.post(app.url_path_for("compute:duplicate_docker_node",
project_id=vm["project_id"],
node_id=vm["node_id"]), json=params)
response = await compute_client.post(
app.url_path_for("compute:duplicate_docker_node", project_id=vm["project_id"], node_id=vm["node_id"]),
json=params,
)
assert response.status_code == status.HTTP_201_CREATED
+19 -29
View File
@@ -28,7 +28,6 @@ pytestmark = pytest.mark.asyncio
class TestDynamipsNodesRoutes:
# @pytest.yield_fixture(scope="module")
# async def vm(compute_api, compute_project, fake_image):
#
@@ -47,7 +46,6 @@ class TestDynamipsNodesRoutes:
# #with asyncio_patch("gns3server.compute.dynamips.Dynamips.find_dynamips", return_value=dynamips_path):
# # yield response.json
# async def test_dynamips_vm_create(compute_api, compute_project, fake_image):
#
# params = {
@@ -66,7 +64,6 @@ class TestDynamipsNodesRoutes:
# assert response.json["project_id"] == compute_project.id
# assert response.json["dynamips_id"]
# def test_dynamips_vm_get(compute_api, project, vm):
# response = compute_api.get("/projects/{project_id}/dynamips/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), example=True)
# assert response.status == 200
@@ -102,7 +99,6 @@ class TestDynamipsNodesRoutes:
# assert mock.called
# assert response.status == 204
# def test_vbox_nio_create_udp(compute_api, vm):
#
# with asyncio_patch('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_add_nio_binding') as mock:
@@ -142,48 +138,42 @@ class TestDynamipsNodesRoutes:
# assert response.json["name"] == "test"
# assert response.json["console"] == free_console_port
@pytest.fixture
def fake_image(self, tmpdir) -> str:
"""Create a fake Dynamips image on disk"""
path = str(tmpdir / "7200.bin")
with open(path, "wb+") as f:
f.write(b'\x7fELF\x01\x02\x01')
f.write(b"\x7fELF\x01\x02\x01")
os.chmod(path, stat.S_IREAD)
return path
@pytest.fixture
def fake_file(self, tmpdir) -> str:
"""Create a fake file disk"""
path = str(tmpdir / "7200.txt")
with open(path, "w+") as f:
f.write('1')
f.write("1")
os.chmod(path, stat.S_IREAD)
return path
async def test_images(
self, app: FastAPI,
compute_client: AsyncClient,
tmpdir, fake_image: str,
fake_file: str
self, app: FastAPI, compute_client: AsyncClient, tmpdir, fake_image: str, fake_file: str
) -> None:
with patch("gns3server.utils.images.default_images_directory", return_value=str(tmpdir)):
response = await compute_client.get(app.url_path_for("compute:get_dynamips_images"))
assert response.status_code == status.HTTP_200_OK
assert response.json() == [{"filename": "7200.bin",
"path": "7200.bin",
"filesize": 7,
"md5sum": "b0d5aa897d937aced5a6b1046e8f7e2e"}]
assert response.json() == [
{"filename": "7200.bin", "path": "7200.bin", "filesize": 7, "md5sum": "b0d5aa897d937aced5a6b1046e8f7e2e"}
]
async def test_upload_image(self, app: FastAPI, compute_client: AsyncClient, images_dir: str) -> None:
response = await compute_client.post(app.url_path_for("compute:upload_dynamips_image", filename="test2"), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_dynamips_image", filename="test2"), content=b"TEST"
)
assert response.status_code == status.HTTP_204_NO_CONTENT
with open(os.path.join(images_dir, "IOS", "test2")) as f:
@@ -193,35 +183,33 @@ class TestDynamipsNodesRoutes:
checksum = f.read()
assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
async def test_upload_image_forbidden_location(self, app: FastAPI, compute_client: AsyncClient) -> None:
file_path = "%2e%2e/hello"
response = await compute_client.post(app.url_path_for("compute:upload_dynamips_image", filename=file_path), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_dynamips_image", filename=file_path), content=b"TEST"
)
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_download_image(self, app: FastAPI, compute_client: AsyncClient, images_dir: str) -> None:
response = await compute_client.post(app.url_path_for("compute:upload_dynamips_image", filename="test3"), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_dynamips_image", filename="test3"), content=b"TEST"
)
assert response.status_code == status.HTTP_204_NO_CONTENT
response = await compute_client.get(app.url_path_for("compute:download_dynamips_image", filename="test3"))
assert response.status_code == status.HTTP_200_OK
async def test_download_image_forbidden(self, app: FastAPI, compute_client: AsyncClient, tmpdir) -> None:
file_path = "foo/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
response = await compute_client.get(app.url_path_for("compute:download_dynamips_image", filename=file_path))
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.skipif(os.getuid() == 0, reason="Root can delete any image")
async def test_upload_image_permission_denied(
self, app: FastAPI,
compute_client: AsyncClient,
images_dir: str
self, app: FastAPI, compute_client: AsyncClient, images_dir: str
) -> None:
os.makedirs(os.path.join(images_dir, "IOS"), exist_ok=True)
@@ -229,5 +217,7 @@ class TestDynamipsNodesRoutes:
f.write("")
os.chmod(os.path.join(images_dir, "IOS", "test2.tmp"), 0)
response = await compute_client.post(app.url_path_for("compute:upload_dynamips_image", filename="test2"), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_dynamips_image", filename="test2"), content=b"TEST"
)
assert response.status_code == status.HTTP_409_CONFLICT
@@ -34,12 +34,14 @@ pytestmark = pytest.mark.asyncio
class TestEthernetSwitchNodesRoutes:
@pytest_asyncio.fixture(autouse=True)
async def stub_ubridge(self):
"""Keep uBridge from really starting and capture every command."""
with asyncio_patch(f"{_NODE}._start_ubridge"), asyncio_patch(f"{_NODE}._stop_ubridge"), \
asyncio_patch(f"{_NODE}._ubridge_send"):
with (
asyncio_patch(f"{_NODE}._start_ubridge"),
asyncio_patch(f"{_NODE}._stop_ubridge"),
asyncio_patch(f"{_NODE}._ubridge_send"),
):
yield
@pytest_asyncio.fixture
@@ -47,8 +49,7 @@ class TestEthernetSwitchNodesRoutes:
params = {"name": "Ethernet Switch"}
response = await compute_client.post(
app.url_path_for("compute:create_ethernet_switch", project_id=compute_project.id),
json=params
app.url_path_for("compute:create_ethernet_switch", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
@@ -65,15 +66,12 @@ class TestEthernetSwitchNodesRoutes:
return {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
async def test_ethernet_switch_create(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project
) -> None:
params = {"name": "Ethernet Switch 1"}
response = await compute_client.post(
app.url_path_for("compute:create_ethernet_switch", project_id=compute_project.id),
json=params
app.url_path_for("compute:create_ethernet_switch", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "Ethernet Switch 1"
@@ -83,25 +81,24 @@ class TestEthernetSwitchNodesRoutes:
# creation stands up the kernel bridge with VLAN filtering
node = compute_project.get_node(response.json()["node_id"])
br = node._bridge_name
node._ubridge_send.assert_has_calls([
call(f'brctl delete "{br}"'),
call(f'brctl create "{br}"'),
call(f'link set "{br}" up'),
call(f'brctl vlanfiltering "{br}" on'),
])
node._ubridge_send.assert_has_calls(
[
call(f'brctl delete "{br}"'),
call(f'brctl create "{br}"'),
call(f'link set "{br}" up'),
call(f'brctl vlanfiltering "{br}" on'),
]
)
async def test_ethernet_switch_get(
self, app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict
) -> None:
response = await compute_client.get(
app.url_path_for(
"compute:get_ethernet_switch",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"]
node_id=ethernet_switch["node_id"],
)
)
assert response.status_code == status.HTTP_200_OK
@@ -110,18 +107,13 @@ class TestEthernetSwitchNodesRoutes:
assert response.json()["status"] == "started"
async def test_ethernet_switch_duplicate(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict
) -> None:
# create destination switch first
params = {"name": "Ethernet Switch 2"}
response = await compute_client.post(
app.url_path_for("compute:create_ethernet_switch", project_id=compute_project.id),
json=params
app.url_path_for("compute:create_ethernet_switch", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
@@ -130,16 +122,14 @@ class TestEthernetSwitchNodesRoutes:
app.url_path_for(
"compute:duplicate_ethernet_switch",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"]), json=params
node_id=ethernet_switch["node_id"],
),
json=params,
)
assert response.status_code == status.HTTP_201_CREATED
async def test_ethernet_switch_update(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict
) -> None:
params = {"name": "test", "console_type": "none"}
@@ -148,8 +138,9 @@ class TestEthernetSwitchNodesRoutes:
app.url_path_for(
"compute:update_ethernet_switch",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"]),
json=params
node_id=ethernet_switch["node_id"],
),
json=params,
)
assert response.status_code == status.HTTP_200_OK
@@ -160,11 +151,7 @@ class TestEthernetSwitchNodesRoutes:
node._ubridge_send.assert_not_called()
async def test_ethernet_switch_update_ports_qinq_proto(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict
) -> None:
# a QinQ port with the 802.1ad ethertype must switch the bridge protocol
@@ -179,8 +166,9 @@ class TestEthernetSwitchNodesRoutes:
app.url_path_for(
"compute:update_ethernet_switch",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"]),
json=port_params
node_id=ethernet_switch["node_id"],
),
json=port_params,
)
assert response.status_code == status.HTTP_200_OK
@@ -190,55 +178,60 @@ class TestEthernetSwitchNodesRoutes:
@pytest.mark.parametrize(
"ports_settings",
(
{"name": "Ethernet0", "port_number": 0, "type": "dot42q", "vlan": 1}, # bad type
{"name": "Ethernet0", "port_number": 0, "type": "access"}, # missing vlan
{"name": "Ethernet0", "port_number": 0, "type": "dot1q", "vlan": 1,
"ethertype": "0x88A8"}, # ethertype only for qinq
{"name": "Ethernet0", "port_number": 0, "type": "qinq", "vlan": 1,
"ethertype": "0x4242"}, # bad ethertype
{"name": "Ethernet0", "port_number": 0, "type": "access", "vlan": 0}, # vlan < 1
{"name": "Ethernet0", "port_number": 0, "type": "access", "vlan": 4242}, # vlan > 4094
)
{"name": "Ethernet0", "port_number": 0, "type": "dot42q", "vlan": 1}, # bad type
{"name": "Ethernet0", "port_number": 0, "type": "access"}, # missing vlan
{
"name": "Ethernet0",
"port_number": 0,
"type": "dot1q",
"vlan": 1,
"ethertype": "0x88A8",
}, # ethertype only for qinq
{"name": "Ethernet0", "port_number": 0, "type": "qinq", "vlan": 1, "ethertype": "0x4242"}, # bad ethertype
{"name": "Ethernet0", "port_number": 0, "type": "access", "vlan": 0}, # vlan < 1
{"name": "Ethernet0", "port_number": 0, "type": "access", "vlan": 4242}, # vlan > 4094
),
)
async def test_ethernet_switch_update_ports_invalid(
self,
app: FastAPI,
compute_client: AsyncClient,
ethernet_switch: dict,
ports_settings: dict,
self,
app: FastAPI,
compute_client: AsyncClient,
ethernet_switch: dict,
ports_settings: dict,
) -> None:
response = await compute_client.put(
app.url_path_for(
"compute:update_ethernet_switch",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"]),
json={"ports_mapping": [ports_settings]}
node_id=ethernet_switch["node_id"],
),
json={"ports_mapping": [ports_settings]},
)
assert response.status_code == status.HTTP_422_UNPROCESSABLE_CONTENT
async def test_ethernet_switch_delete(
self, app: FastAPI,
compute_client: AsyncClient,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, ethernet_switch: dict
) -> None:
response = await compute_client.delete(
app.url_path_for(
"compute:delete_ethernet_switch",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"]
node_id=ethernet_switch["node_id"],
)
)
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_ethernet_switch_start(self, app: FastAPI, compute_client: AsyncClient, ethernet_switch: dict) -> None:
async def test_ethernet_switch_start(
self, app: FastAPI, compute_client: AsyncClient, ethernet_switch: dict
) -> None:
response = await compute_client.post(
app.url_path_for(
"compute:start_ethernet_switch",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"]
node_id=ethernet_switch["node_id"],
)
)
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
@@ -249,39 +242,39 @@ class TestEthernetSwitchNodesRoutes:
app.url_path_for(
"compute:stop_ethernet_switch",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"]
node_id=ethernet_switch["node_id"],
)
)
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
async def test_ethernet_switch_suspend(self, app: FastAPI, compute_client: AsyncClient, ethernet_switch: dict) -> None:
async def test_ethernet_switch_suspend(
self, app: FastAPI, compute_client: AsyncClient, ethernet_switch: dict
) -> None:
response = await compute_client.post(
app.url_path_for(
"compute:suspend_ethernet_switch",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"]
node_id=ethernet_switch["node_id"],
)
)
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
async def test_ethernet_switch_reload(self, app: FastAPI, compute_client: AsyncClient, ethernet_switch: dict) -> None:
async def test_ethernet_switch_reload(
self, app: FastAPI, compute_client: AsyncClient, ethernet_switch: dict
) -> None:
response = await compute_client.post(
app.url_path_for(
"compute:reload_ethernet_switch",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"]
node_id=ethernet_switch["node_id"],
)
)
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
async def test_ethernet_switch_create_udp_access(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict
) -> None:
url = app.url_path_for(
@@ -289,7 +282,7 @@ class TestEthernetSwitchNodesRoutes:
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0"
port_number="0",
)
response = await compute_client.post(url, json=self._udp_params())
assert response.status_code == status.HTTP_201_CREATED
@@ -301,23 +294,21 @@ class TestEthernetSwitchNodesRoutes:
tap = f"{br}-0"
relay = f"{node.id}-0"
# access VLAN 1 (default): drop default PVID 1, re-add 1 as PVID/untagged
node._ubridge_send.assert_has_calls([
call(f"bridge create {relay}"),
call(f'bridge add_nio_tap {relay} "{tap}"'),
call(f'brctl addif "{br}" "{tap}"'),
call(f'brctl vlan_del "{br}" "{tap}" 1'),
call(f'brctl vlan_add "{br}" "{tap}" 1 pvid untagged'),
call(f"bridge add_nio_udp {relay} {nio.lport} {nio.rhost} {nio.rport}"),
call(f"bridge reset_packet_filters {relay}"),
call(f"bridge start {relay}"),
])
node._ubridge_send.assert_has_calls(
[
call(f"bridge create {relay}"),
call(f'bridge add_nio_tap {relay} "{tap}"'),
call(f'brctl addif "{br}" "{tap}"'),
call(f'brctl vlan_del "{br}" "{tap}" 1'),
call(f'brctl vlan_add "{br}" "{tap}" 1 pvid untagged'),
call(f"bridge add_nio_udp {relay} {nio.lport} {nio.rhost} {nio.rport}"),
call(f"bridge reset_packet_filters {relay}"),
call(f"bridge start {relay}"),
]
)
async def test_ethernet_switch_create_udp_dot1q(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict
) -> None:
# make port 0 a dot1q trunk with native VLAN 10
@@ -325,10 +316,13 @@ class TestEthernetSwitchNodesRoutes:
app.url_path_for(
"compute:update_ethernet_switch",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"]),
json={"ports_mapping": [
{"name": "Ethernet0", "port_number": 0, "type": "dot1q", "vlan": 10},
]}
node_id=ethernet_switch["node_id"],
),
json={
"ports_mapping": [
{"name": "Ethernet0", "port_number": 0, "type": "dot1q", "vlan": 10},
]
},
)
node = compute_project.get_node(ethernet_switch["node_id"])
node._ubridge_send.reset_mock()
@@ -338,7 +332,7 @@ class TestEthernetSwitchNodesRoutes:
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0"
port_number="0",
)
response = await compute_client.post(url, json=self._udp_params())
assert response.status_code == status.HTTP_201_CREATED
@@ -346,18 +340,16 @@ class TestEthernetSwitchNodesRoutes:
br = node._bridge_name
tap = f"{br}-0"
# trunk: drop default 1, admit all VIDs tagged, mark native 10 PVID/untagged
node._ubridge_send.assert_has_calls([
call(f'brctl vlan_del "{br}" "{tap}" 1'),
call(f'brctl vlan_add "{br}" "{tap}" 1 vid 4094'),
call(f'brctl vlan_add "{br}" "{tap}" 10 pvid untagged'),
])
node._ubridge_send.assert_has_calls(
[
call(f'brctl vlan_del "{br}" "{tap}" 1'),
call(f'brctl vlan_add "{br}" "{tap}" 1 vid 4094'),
call(f'brctl vlan_add "{br}" "{tap}" 10 pvid untagged'),
]
)
async def test_ethernet_switch_delete_nio(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict
) -> None:
url = app.url_path_for(
@@ -365,7 +357,7 @@ class TestEthernetSwitchNodesRoutes:
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0"
port_number="0",
)
await compute_client.post(url, json=self._udp_params())
@@ -377,7 +369,7 @@ class TestEthernetSwitchNodesRoutes:
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0"
port_number="0",
)
response = await compute_client.delete(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
@@ -386,17 +378,15 @@ class TestEthernetSwitchNodesRoutes:
br = node._bridge_name
tap = f"{br}-0"
relay = f"{node.id}-0"
node._ubridge_send.assert_has_calls([
call(f'brctl delif "{br}" "{tap}"'),
call(f"bridge delete {relay}"),
])
node._ubridge_send.assert_has_calls(
[
call(f'brctl delif "{br}" "{tap}"'),
call(f"bridge delete {relay}"),
]
)
async def test_ethernet_switch_update_nio(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict
) -> None:
url = app.url_path_for(
@@ -404,7 +394,7 @@ class TestEthernetSwitchNodesRoutes:
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0"
port_number="0",
)
params = self._udp_params()
params["filters"] = {"delay": [10, 0]}
@@ -421,7 +411,7 @@ class TestEthernetSwitchNodesRoutes:
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0"
port_number="0",
)
response = await compute_client.put(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
@@ -432,11 +422,7 @@ class TestEthernetSwitchNodesRoutes:
node._ubridge_send.assert_any_call(f"bridge reset_packet_filters {relay}")
async def test_ethernet_switch_toggle_marker(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict
) -> None:
# a marker installed via the NIO registers in the node's filter-bridge map
@@ -445,7 +431,7 @@ class TestEthernetSwitchNodesRoutes:
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0"
port_number="0",
)
params = self._udp_params()
params["markers"] = {"icmp": {"bpf": "icmp", "link_id": "link-1", "enabled": True}}
@@ -459,7 +445,7 @@ class TestEthernetSwitchNodesRoutes:
"compute:toggle_ethernet_switch_marker",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
marker_name="icmp"
marker_name="icmp",
)
response = await compute_client.put(url, json={"enabled": False})
assert response.status_code == status.HTTP_200_OK
@@ -472,17 +458,13 @@ class TestEthernetSwitchNodesRoutes:
"compute:toggle_ethernet_switch_marker",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
marker_name="nope"
marker_name="nope",
)
response = await compute_client.put(url, json={"enabled": True})
assert response.status_code == status.HTTP_404_NOT_FOUND
async def test_ethernet_switch_start_capture(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict
) -> None:
# capture needs a wired port
@@ -491,7 +473,7 @@ class TestEthernetSwitchNodesRoutes:
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0"
port_number="0",
)
await compute_client.post(url, json=self._udp_params())
@@ -499,11 +481,13 @@ class TestEthernetSwitchNodesRoutes:
node._ubridge_send.reset_mock()
params = {"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"}
url = app.url_path_for("compute:start_ethernet_switch_capture",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:start_ethernet_switch_capture",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0",
)
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_200_OK
@@ -512,11 +496,7 @@ class TestEthernetSwitchNodesRoutes:
node._ubridge_send.assert_any_call(f'bridge start_capture {relay} "{node.get_nio(0).pcap_output_file}"')
async def test_ethernet_switch_stop_capture(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ethernet_switch: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict
) -> None:
# start a capture first
@@ -526,17 +506,19 @@ class TestEthernetSwitchNodesRoutes:
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0"
port_number="0",
),
json=self._udp_params()
json=self._udp_params(),
)
await compute_client.post(
app.url_path_for("compute:start_ethernet_switch_capture",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0"),
json={"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"}
app.url_path_for(
"compute:start_ethernet_switch_capture",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0",
),
json={"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"},
)
node = compute_project.get_node(ethernet_switch["node_id"])
@@ -544,11 +526,13 @@ class TestEthernetSwitchNodesRoutes:
relay = f"{node.id}-0"
response = await compute_client.post(
app.url_path_for("compute:stop_ethernet_switch_capture",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0")
app.url_path_for(
"compute:stop_ethernet_switch_capture",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
port_number="0",
)
)
assert response.status_code == status.HTTP_204_NO_CONTENT
node._ubridge_send.assert_any_call(f"bridge stop_capture {relay}")
+4 -10
View File
@@ -24,27 +24,22 @@ pytestmark = pytest.mark.asyncio
class TestImagesRoutes:
async def test_pull_docker_image(self, app: FastAPI, compute_client: AsyncClient) -> None:
with asyncio_patch("gns3server.compute.docker.Docker.pull_image") as mock:
response = await compute_client.post(
app.url_path_for("compute:pull_docker_image"),
json={"image": "nginx:latest"}
app.url_path_for("compute:pull_docker_image"), json={"image": "nginx:latest"}
)
mock.assert_called_once_with("nginx:latest", force=True)
assert response.status_code == status.HTTP_204_NO_CONTENT
@pytest.mark.parametrize("image", ["", " ", "nginx latest"])
async def test_pull_docker_image_rejects_invalid_name(
self, app: FastAPI, compute_client: AsyncClient, image: str
self, app: FastAPI, compute_client: AsyncClient, image: str
) -> None:
with asyncio_patch("gns3server.compute.docker.Docker.pull_image") as mock:
response = await compute_client.post(
app.url_path_for("compute:pull_docker_image"),
json={"image": image}
)
response = await compute_client.post(app.url_path_for("compute:pull_docker_image"), json={"image": image})
mock.assert_not_called()
assert response.status_code == status.HTTP_422_UNPROCESSABLE_CONTENT
@@ -52,8 +47,7 @@ class TestImagesRoutes:
with asyncio_patch("gns3server.compute.docker.Docker.load_image") as mock:
response = await compute_client.post(
app.url_path_for("compute:load_docker_image"),
content=b"docker-save-tar-bytes"
app.url_path_for("compute:load_docker_image"), content=b"docker-save-tar-bytes"
)
mock.assert_called_once()
# the tar is streamed to the Docker daemon as an async iterable
+152 -212
View File
@@ -32,55 +32,44 @@ pytestmark = pytest.mark.asyncio
class TestIOUNodesRoutes:
@pytest.fixture
def fake_iou_bin(self, images_dir) -> str:
"""Create a fake IOU image on disk"""
path = os.path.join(images_dir, "IOU", "iou.bin")
with open(path, "w+") as f:
f.write('\x7fELF\x01\x01\x01')
f.write("\x7fELF\x01\x01\x01")
os.chmod(path, stat.S_IREAD | stat.S_IEXEC)
return path
@pytest.fixture
def base_params(self, tmpdir, fake_iou_bin) -> dict:
"""Return standard parameters"""
return {"application_id": 42, "name": "IOU-TEST-1", "path": "iou.bin"}
@pytest_asyncio.fixture
async def vm(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict
) -> dict:
async def vm(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict) -> dict:
response = await compute_client.post(app.url_path_for("compute:create_iou_node", project_id=compute_project.id), json=base_params)
response = await compute_client.post(
app.url_path_for("compute:create_iou_node", project_id=compute_project.id), json=base_params
)
assert response.status_code == status.HTTP_201_CREATED
return response.json()
def startup_config_file(self, compute_project: Project, vm: dict) -> str:
directory = os.path.join(compute_project.path, "project-files", "iou", vm["node_id"])
os.makedirs(directory, exist_ok=True)
return os.path.join(directory, "startup-config.cfg")
async def test_iou_create(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict
) -> None:
response = await compute_client.post(app.url_path_for("compute:create_iou_node", project_id=compute_project.id), json=base_params)
response = await compute_client.post(
app.url_path_for("compute:create_iou_node", project_id=compute_project.id), json=base_params
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "IOU-TEST-1"
assert response.json()["project_id"] == compute_project.id
@@ -90,13 +79,8 @@ class TestIOUNodesRoutes:
assert response.json()["nvram"] == 256
assert response.json()["l1_keepalives"] is False
async def test_iou_create_with_params(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict
) -> None:
params = base_params
@@ -108,7 +92,9 @@ class TestIOUNodesRoutes:
params["startup_config_content"] = "hostname test"
params["use_default_iou_values"] = False
response = await compute_client.post(app.url_path_for("compute:create_iou_node", project_id=compute_project.id), json=params)
response = await compute_client.post(
app.url_path_for("compute:create_iou_node", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "IOU-TEST-1"
assert response.json()["project_id"] == compute_project.id
@@ -122,7 +108,6 @@ class TestIOUNodesRoutes:
with open(self.startup_config_file(compute_project, response.json())) as f:
assert f.read() == "hostname test"
@pytest.mark.parametrize(
"name, status_code",
(
@@ -136,13 +121,13 @@ class TestIOUNodesRoutes:
),
)
async def test_iou_create_with_invalid_name(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
name: str,
status_code: int
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
name: str,
status_code: int,
) -> None:
base_params["name"] = name
@@ -151,40 +136,33 @@ class TestIOUNodesRoutes:
)
assert response.status_code == status_code
async def test_iou_create_startup_config_already_exist(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict) -> None:
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict
) -> None:
"""We don't erase a startup-config if already exist at project creation"""
node_id = str(uuid.uuid4())
startup_config_file_path = self.startup_config_file(compute_project, {'node_id': node_id})
with open(startup_config_file_path, 'w+') as f:
startup_config_file_path = self.startup_config_file(compute_project, {"node_id": node_id})
with open(startup_config_file_path, "w+") as f:
f.write("echo hello")
params = base_params
params["node_id"] = node_id
params["startup_config_content"] = "hostname test"
response = await compute_client.post(app.url_path_for("compute:create_iou_node", project_id=compute_project.id), json=params)
response = await compute_client.post(
app.url_path_for("compute:create_iou_node", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
with open(self.startup_config_file(compute_project, response.json())) as f:
assert f.read() == "echo hello"
async def test_iou_get(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict) -> None:
async def test_iou_get(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
) -> None:
response = await compute_client.get(app.url_path_for("compute:get_iou_node", project_id=vm["project_id"], node_id=vm["node_id"]))
response = await compute_client.get(
app.url_path_for("compute:get_iou_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "IOU-TEST-1"
assert response.json()["project_id"] == compute_project.id
@@ -194,73 +172,62 @@ class TestIOUNodesRoutes:
assert response.json()["nvram"] == 256
assert response.json()["l1_keepalives"] is False
async def test_iou_start(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.start", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:start_iou_node",
project_id=vm["project_id"],
node_id=vm["node_id"]), json={})
response = await compute_client.post(
app.url_path_for("compute:start_iou_node", project_id=vm["project_id"], node_id=vm["node_id"]), json={}
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_iou_start_with_iourc(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {"iourc_content": "test"}
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.start", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:start_iou_node",
project_id=vm["project_id"],
node_id=vm["node_id"]), json=params)
response = await compute_client.post(
app.url_path_for("compute:start_iou_node", project_id=vm["project_id"], node_id=vm["node_id"]),
json=params,
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_iou_stop(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.stop", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:stop_iou_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:stop_iou_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_iou_reload(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.reload", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:reload_iou_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:reload_iou_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_iou_delete(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.iou.IOU.delete_node", return_value=True) as mock:
response = await compute_client.delete(app.url_path_for("compute:delete_iou_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.delete(
app.url_path_for("compute:delete_iou_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_iou_suspend(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
response = await compute_client.delete(
app.url_path_for(
"compute:suspend_iou_node",
project_id=vm["project_id"],
node_id=vm["node_id"])
app.url_path_for("compute:suspend_iou_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
async def test_iou_update(
self, app: FastAPI,
compute_client: AsyncClient,
vm: dict,
free_console_port: int
self, app: FastAPI, compute_client: AsyncClient, vm: dict, free_console_port: int
) -> None:
params = {
@@ -274,9 +241,9 @@ class TestIOUNodesRoutes:
"use_default_iou_values": True,
}
response = await compute_client.put(app.url_path_for("compute:update_iou_node",
project_id=vm["project_id"],
node_id=vm["node_id"]), json=params)
response = await compute_client.put(
app.url_path_for("compute:update_iou_node", project_id=vm["project_id"], node_id=vm["node_id"]), json=params
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "test"
assert response.json()["console"] == free_console_port
@@ -287,173 +254,141 @@ class TestIOUNodesRoutes:
assert response.json()["l1_keepalives"] is True
assert response.json()["use_default_iou_values"] is True
async def test_iou_nio_create_udp(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
url = app.url_path_for("compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0")
url = app.url_path_for(
"compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0",
)
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
async def test_iou_nio_update_udp(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1",
"filters": {"packet_loss": 10}
}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1", "filters": {"packet_loss": 10}}
url = app.url_path_for("compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0")
url = app.url_path_for(
"compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0",
)
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["filters"] == {"packet_loss": 10}
params["filters"].clear()
url = app.url_path_for("compute:update_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0")
url = app.url_path_for(
"compute:update_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0",
)
response = await compute_client.put(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
assert response.json()["filters"] == {}
async def test_iou_nio_create_ethernet(
self,
app: FastAPI,
compute_client: AsyncClient,
vm: dict,
ethernet_device: str
self, app: FastAPI, compute_client: AsyncClient, vm: dict, ethernet_device: str
) -> None:
params = {
"type": "nio_ethernet",
"ethernet_device": ethernet_device
}
params = {"type": "nio_ethernet", "ethernet_device": ethernet_device}
url = app.url_path_for("compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0")
url = app.url_path_for(
"compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0",
)
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_ethernet"
assert response.json()["ethernet_device"] == ethernet_device
async def test_iou_nio_create_ethernet_different_port(
self,
app: FastAPI,
compute_client: AsyncClient,
vm: dict,
ethernet_device: str
self, app: FastAPI, compute_client: AsyncClient, vm: dict, ethernet_device: str
) -> None:
params = {
"type": "nio_ethernet",
"ethernet_device": ethernet_device
}
params = {"type": "nio_ethernet", "ethernet_device": ethernet_device}
url = app.url_path_for("compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="3")
url = app.url_path_for(
"compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="3",
)
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_ethernet"
assert response.json()["ethernet_device"] == ethernet_device
async def test_iou_nio_create_tap(
self,
app: FastAPI,
compute_client: AsyncClient,
vm: dict,
ethernet_device: str
self, app: FastAPI, compute_client: AsyncClient, vm: dict, ethernet_device: str
) -> None:
params = {
"type": "nio_tap",
"tap_device": ethernet_device
}
params = {"type": "nio_tap", "tap_device": ethernet_device}
url = app.url_path_for("compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0")
url = app.url_path_for(
"compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0",
)
with patch("gns3server.compute.base_manager.BaseManager.has_privileged_access", return_value=True):
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_tap"
async def test_iou_delete_nio(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
async def test_iou_delete_nio(
self,
app: FastAPI,
compute_client: AsyncClient,
vm: dict
) -> None:
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
url = app.url_path_for("compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0")
url = app.url_path_for(
"compute:create_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0",
)
await compute_client.post(url, json=params)
url = app.url_path_for("compute:delete_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0")
url = app.url_path_for(
"compute:delete_iou_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="1",
port_number="0",
)
response = await compute_client.delete(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_iou_start_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"capture_file_name": "test.pcap",
"data_link_type": "DLT_EN10MB"
}
params = {"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"}
url = app.url_path_for("compute:start_iou_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:start_iou_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with patch("gns3server.compute.iou.iou_vm.IOUVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.start_capture") as mock:
@@ -462,14 +397,15 @@ class TestIOUNodesRoutes:
assert mock.called
assert "test.pcap" in response.json()["pcap_file_path"]
async def test_iou_stop_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
url = app.url_path_for("compute:stop_iou_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:stop_iou_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with patch("gns3server.compute.iou.iou_vm.IOUVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.stop_capture") as mock:
@@ -477,7 +413,6 @@ class TestIOUNodesRoutes:
assert response.status_code == status.HTTP_204_NO_CONTENT
assert mock.called
# @pytest.mark.asyncio
# async def test_iou_pcap(compute_api, vm, compute_project):
#
@@ -486,18 +421,20 @@ class TestIOUNodesRoutes:
# response = await compute_client.get("/projects/{project_id}/iou/nodes/{node_id}/adapters/0/ports/0/pcap".format(project_id=compute_project.id, node_id=vm["node_id"]), raw=True)
# assert response.status_code == status.HTTP_200_OK
async def test_images(self, app: FastAPI, compute_client: AsyncClient, fake_iou_bin: str) -> None:
response = await compute_client.get(app.url_path_for("compute:get_iou_images"))
assert response.status_code == status.HTTP_200_OK
assert response.json() == [{"filename": "iou.bin", "path": "iou.bin", "filesize": 7, "md5sum": "e573e8f5c93c6c00783f20c7a170aa6c"}]
assert response.json() == [
{"filename": "iou.bin", "path": "iou.bin", "filesize": 7, "md5sum": "e573e8f5c93c6c00783f20c7a170aa6c"}
]
async def test_upload_image(self, app: FastAPI, compute_client: AsyncClient, tmpdir) -> None:
with patch("gns3server.compute.IOU.get_images_directory", return_value=str(tmpdir)):
response = await compute_client.post(app.url_path_for("compute:upload_iou_image", filename="test2"), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_iou_image", filename="test2"), content=b"TEST"
)
assert response.status_code == status.HTTP_204_NO_CONTENT
with open(str(tmpdir / "test2")) as f:
@@ -507,39 +444,42 @@ class TestIOUNodesRoutes:
checksum = f.read()
assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
async def test_upload_image_forbidden_location(self, app: FastAPI, compute_client: AsyncClient) -> None:
file_path = "%2e%2e/hello"
response = await compute_client.post(app.url_path_for("compute:upload_dynamips_image", filename=file_path), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_dynamips_image", filename=file_path), content=b"TEST"
)
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_download_image(self, app: FastAPI, compute_client: AsyncClient, images_dir: str) -> None:
response = await compute_client.post(app.url_path_for("compute:upload_dynamips_image", filename="test3"), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_dynamips_image", filename="test3"), content=b"TEST"
)
assert response.status_code == status.HTTP_204_NO_CONTENT
response = await compute_client.get(app.url_path_for("compute:download_dynamips_image", filename="test3"))
assert response.status_code == status.HTTP_200_OK
async def test_download_image_forbidden(self, app: FastAPI, compute_client: AsyncClient, tmpdir) -> None:
file_path = "foo/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
response = await compute_client.get(app.url_path_for("compute:download_iou_image", filename=file_path))
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_iou_duplicate(self, app: FastAPI, compute_client: AsyncClient, vm: dict, base_params: dict) -> None:
# create destination node first
response = await compute_client.post(app.url_path_for("compute:create_iou_node", project_id=vm["project_id"]), json=base_params)
response = await compute_client.post(
app.url_path_for("compute:create_iou_node", project_id=vm["project_id"]), json=base_params
)
assert response.status_code == status.HTTP_201_CREATED
params = {"destination_node_id": response.json()["node_id"]}
response = await compute_client.post(app.url_path_for("compute:duplicate_iou_node",
project_id=vm["project_id"],
node_id=vm["node_id"]), json=params)
response = await compute_client.post(
app.url_path_for("compute:duplicate_iou_node", project_id=vm["project_id"], node_id=vm["node_id"]),
json=params,
)
assert response.status_code == status.HTTP_201_CREATED
+72 -97
View File
@@ -28,102 +28,81 @@ pytestmark = pytest.mark.asyncio
class TestNATNodesRoutes:
@pytest_asyncio.fixture
async def vm(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
ubridge_path: str,
on_gns3vm
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, ubridge_path: str, on_gns3vm
) -> dict:
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat._start_ubridge"):
response = await compute_client.post(app.url_path_for("compute:create_nat_node", project_id=compute_project.id),
json={"name": "Nat 1"})
response = await compute_client.post(
app.url_path_for("compute:create_nat_node", project_id=compute_project.id), json={"name": "Nat 1"}
)
assert response.status_code == status.HTTP_201_CREATED
return response.json()
async def test_nat_create(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
on_gns3vm
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, on_gns3vm
) -> None:
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat._start_ubridge"):
response = await compute_client.post(app.url_path_for("compute:create_nat_node", project_id=compute_project.id),
json={"name": "Nat 1"})
response = await compute_client.post(
app.url_path_for("compute:create_nat_node", project_id=compute_project.id), json={"name": "Nat 1"}
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "Nat 1"
assert response.json()["project_id"] == compute_project.id
async def test_nat_get(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict) -> None:
async def test_nat_get(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
) -> None:
response = await compute_client.get(app.url_path_for("compute:get_nat_node", project_id=vm["project_id"], node_id=vm["node_id"]))
response = await compute_client.get(
app.url_path_for("compute:get_nat_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "Nat 1"
assert response.json()["project_id"] == compute_project.id
assert response.json()["status"] == "started"
async def test_nat_nio_create_udp(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
url = app.url_path_for("compute:create_nat_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:create_nat_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.add_nio"):
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
async def test_nat_nio_update_udp(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1",
"filters": {"packet_loss": 10}
}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1", "filters": {"packet_loss": 10}}
url = app.url_path_for("compute:create_nat_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:create_nat_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=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["filters"] == {"packet_loss": 10}
params["filters"].clear()
url = app.url_path_for("compute:update_nat_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:update_nat_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
response = await compute_client.put(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
@@ -131,83 +110,79 @@ class TestNATNodesRoutes:
async def test_nat_delete_nio(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
url = app.url_path_for("compute:create_nat_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:create_nat_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.add_nio"):
await compute_client.post(url, json=params)
url = app.url_path_for("compute:delete_nat_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:delete_nat_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.remove_nio") as mock:
response = await compute_client.delete(url)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_nat_delete(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
response = await compute_client.delete(app.url_path_for("compute:delete_nat_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.delete(
app.url_path_for("compute:delete_nat_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_nat_update(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
response = await compute_client.put(app.url_path_for("compute:update_nat_node",
project_id=vm["project_id"],
node_id=vm["node_id"]), json={"name": "test"})
response = await compute_client.put(
app.url_path_for("compute:update_nat_node", project_id=vm["project_id"], node_id=vm["node_id"]),
json={"name": "test"},
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "test"
async def test_nat_start_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"capture_file_name": "test.pcap",
"data_link_type": "DLT_EN10MB"
}
params = {"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"}
url = app.url_path_for("compute:start_nat_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:start_nat_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.start_capture") as mock:
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_200_OK
assert mock.called
assert "test.pcap" in response.json()["pcap_file_path"]
async def test_nat_stop_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
url = app.url_path_for("compute:stop_nat_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:stop_nat_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.stop_capture") as mock:
response = await compute_client.post(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
assert mock.called
# @pytest.mark.asyncio
# async def test_nat_pcap(self, compute_api, vm, compute_project):
#
+12 -12
View File
@@ -27,16 +27,16 @@ from gns3server.compute.notification_manager import NotificationManager
# # FIXME: how to test websockets
# pass
#with compute_api.ws("/notifications/ws") as ws:
# with compute_api.ws("/notifications/ws") as ws:
# answer = await ws.receive_text()
# print(answer)
# answer = json.loads(answer)
#
# assert answer["action"] == "ping"
#
# NotificationManager.instance().emit("test", {})
#
# answer = await ws.receive_text()
# answer = json.loads(answer)
# assert answer["action"] == "test"
# answer = await ws.receive_text()
# print(answer)
# answer = json.loads(answer)
#
# assert answer["action"] == "ping"
#
# NotificationManager.instance().emit("test", {})
#
# answer = await ws.receive_text()
# answer = json.loads(answer)
# assert answer["action"] == "test"
+50 -73
View File
@@ -31,23 +31,15 @@ pytestmark = pytest.mark.asyncio
class TestComputeProjectRoutes:
@pytest.fixture
def base_params(self, tmpdir) -> dict:
"""Return standard parameters"""
params = {
"name": "test",
"project_id": str(uuid.uuid4())
}
params = {"name": "test", "project_id": str(uuid.uuid4())}
return params
async def test_create_project_without_dir(
self,
app: FastAPI,
compute_client: AsyncClient,
base_params: dict
self, app: FastAPI, compute_client: AsyncClient, base_params: dict
) -> None:
response = await compute_client.post(app.url_path_for("compute:create_compute_project"), json=base_params)
@@ -55,32 +47,27 @@ class TestComputeProjectRoutes:
assert response.json()["project_id"] == base_params["project_id"]
assert response.json()["name"] == base_params["name"]
async def test_show_project(
self,
app: FastAPI,
compute_client: AsyncClient,
base_params: dict
) -> None:
async def test_show_project(self, app: FastAPI, compute_client: AsyncClient, base_params: dict) -> None:
response = await compute_client.post(app.url_path_for("compute:create_compute_project"), json=base_params)
assert response.status_code == status.HTTP_201_CREATED
response = await compute_client.get(app.url_path_for("compute:get_compute_project", project_id=base_params["project_id"]))
response = await compute_client.get(
app.url_path_for("compute:get_compute_project", project_id=base_params["project_id"])
)
#print(response.json().keys())
#assert len(response.json().keys()) == 3
# print(response.json().keys())
# assert len(response.json().keys()) == 3
assert response.json()["project_id"] == base_params["project_id"]
assert response.json()["name"] == base_params["name"]
assert response.json()["variables"] is None
async def test_show_project_invalid_uuid(self, app: FastAPI, compute_client: AsyncClient) -> None:
response = await compute_client.get(app.url_path_for("compute:get_compute_project",
project_id="50010203-0405-0607-0809-0a0b0c0d0e42"))
response = await compute_client.get(
app.url_path_for("compute:get_compute_project", project_id="50010203-0405-0607-0809-0a0b0c0d0e42")
)
assert response.status_code == status.HTTP_404_NOT_FOUND
async def test_list_projects(self, app: FastAPI, compute_client: AsyncClient) -> dict:
ProjectManager.instance()._projects = {}
@@ -97,41 +84,43 @@ class TestComputeProjectRoutes:
assert len(response.json()) == 2
assert "51010203-0405-0607-0809-0a0b0c0d0e0f" in [p["project_id"] for p in response.json()]
async def test_delete_project(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
with asyncio_patch("gns3server.compute.project.Project.delete", return_value=True) as mock:
response = await compute_client.delete(app.url_path_for("compute:delete_compute_project", project_id=compute_project.id))
response = await compute_client.delete(
app.url_path_for("compute:delete_compute_project", project_id=compute_project.id)
)
assert response.status_code == status.HTTP_204_NO_CONTENT
assert mock.called
async def test_update_project(self, app: FastAPI, compute_client: AsyncClient, base_params: dict) -> None:
response = await compute_client.post(app.url_path_for("compute:create_compute_project"), json=base_params)
assert response.status_code == status.HTTP_201_CREATED
params = {"variables": [{"name": "TEST1", "value": "VAL1"}]}
response = await compute_client.put(app.url_path_for("compute:update_compute_project", project_id=base_params["project_id"]),
json=params)
response = await compute_client.put(
app.url_path_for("compute:update_compute_project", project_id=base_params["project_id"]), json=params
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["variables"] == [{"name": "TEST1", "value": "VAL1"}]
async def test_delete_project_invalid_uuid(self, app: FastAPI, compute_client: AsyncClient) -> None:
response = await compute_client.delete(app.url_path_for("compute:delete_compute_project", project_id=str(uuid.uuid4())))
response = await compute_client.delete(
app.url_path_for("compute:delete_compute_project", project_id=str(uuid.uuid4()))
)
assert response.status_code == status.HTTP_404_NOT_FOUND
async def test_close_project(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
with asyncio_patch("gns3server.compute.project.Project.close", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:close_compute_project", project_id=compute_project.id))
response = await compute_client.post(
app.url_path_for("compute:close_compute_project", project_id=compute_project.id)
)
assert response.status_code == status.HTTP_204_NO_CONTENT
assert mock.called
# @pytest.mark.asyncio
# async def test_close_project_two_client_connected(compute_api, compute_project):
#
@@ -141,13 +130,13 @@ class TestComputeProjectRoutes:
# assert response.status_code == status.HTTP_204_NO_CONTENT
# assert not mock.called
async def test_close_project_invalid_uuid(self, app: FastAPI, compute_client: AsyncClient) -> None:
response = await compute_client.post(app.url_path_for("compute:close_compute_project", project_id=str(uuid.uuid4())))
response = await compute_client.post(
app.url_path_for("compute:close_compute_project", project_id=str(uuid.uuid4()))
)
assert response.status_code == status.HTTP_404_NOT_FOUND
async def test_get_file(self, app: FastAPI, compute_client: AsyncClient) -> None:
project = ProjectManager.instance().create_project(project_id="01010203-0405-0607-0809-0a0b0c0d0e0b")
@@ -155,79 +144,67 @@ class TestComputeProjectRoutes:
with open(os.path.join(project.path, "hello"), "w+") as f:
f.write("world")
response = await compute_client.get(app.url_path_for("compute:get_compute_project_file", project_id=project.id, file_path="hello"))
response = await compute_client.get(
app.url_path_for("compute:get_compute_project_file", project_id=project.id, file_path="hello")
)
assert response.status_code == status.HTTP_200_OK
assert response.content == b"world"
response = await compute_client.get(app.url_path_for("compute:get_compute_project_file", project_id=project.id, file_path="false"))
response = await compute_client.get(
app.url_path_for("compute:get_compute_project_file", project_id=project.id, file_path="false")
)
assert response.status_code == status.HTTP_404_NOT_FOUND
response = await compute_client.get(app.url_path_for("compute:get_compute_project_file",
project_id=project.id,
file_path="../hello"))
response = await compute_client.get(
app.url_path_for("compute:get_compute_project_file", project_id=project.id, file_path="../hello")
)
assert response.status_code == status.HTTP_404_NOT_FOUND
async def test_get_file_forbidden_location(
self,
app: FastAPI,
compute_client: AsyncClient,
config,
tmpdir
) -> None:
async def test_get_file_forbidden_location(self, app: FastAPI, compute_client: AsyncClient, config, tmpdir) -> None:
config.settings.Server.projects_path = str(tmpdir)
project = ProjectManager.instance().create_project(project_id="01010203-0405-0607-0809-0a0b0c0d0e0b")
file_path = "foo/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
response = await compute_client.get(
app.url_path_for(
"compute:get_compute_project_file",
project_id=project.id,
file_path=file_path
)
app.url_path_for("compute:get_compute_project_file", project_id=project.id, file_path=file_path)
)
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_write_file(self, app: FastAPI, compute_client: AsyncClient, config, tmpdir) -> None:
config.settings.Server.projects_path = str(tmpdir)
project = ProjectManager.instance().create_project(project_id="01010203-0405-0607-0809-0a0b0c0d0e0b")
response = await compute_client.post(app.url_path_for("compute:write_compute_project_file",
project_id=project.id,
file_path="hello"), content=b"world")
response = await compute_client.post(
app.url_path_for("compute:write_compute_project_file", project_id=project.id, file_path="hello"),
content=b"world",
)
assert response.status_code == status.HTTP_204_NO_CONTENT
with open(os.path.join(project.path, "hello")) as f:
assert f.read() == "world"
response = await compute_client.post(app.url_path_for("compute:write_compute_project_file",
project_id=project.id,
file_path="../hello"))
response = await compute_client.post(
app.url_path_for("compute:write_compute_project_file", project_id=project.id, file_path="../hello")
)
assert response.status_code == status.HTTP_404_NOT_FOUND
async def test_write_file_forbidden_location(
self,
app: FastAPI,
compute_client: AsyncClient,
config,
tmpdir
self, app: FastAPI, compute_client: AsyncClient, config, tmpdir
) -> None:
config.settings.Server.projects_path = str(tmpdir)
project = ProjectManager.instance().create_project(project_id="01010203-0405-0607-0809-0a0b0c0d0e0b")
file_path = "%2e%2e/hello"
response = await compute_client.post(app.url_path_for("compute:write_compute_project_file",
project_id=project.id,
file_path=file_path), content=b"world")
response = await compute_client.post(
app.url_path_for("compute:write_compute_project_file", project_id=project.id, file_path=file_path),
content=b"world",
)
assert response.status_code == status.HTTP_403_FORBIDDEN
class TestBatchNIOEdgeCases:
@pytest.mark.asyncio
async def test_dynamips_router_dispatch_to_slot_add_nio_binding(self):
"""_add_nio_binding dispatches Dynamips router to slot_add_nio_binding."""
@@ -276,7 +253,7 @@ class TestBatchNIOEdgeCases:
dyn = _FakeDynamips()
base = _FakeBase()
assert len(inspect.signature(dyn.create_nio).parameters) == 2 # Dynamips
assert len(inspect.signature(dyn.create_nio).parameters) == 2 # Dynamips
assert len(inspect.signature(base.create_nio).parameters) == 1 # standard
assert inspect.iscoroutinefunction(dyn.create_nio)
assert not inspect.iscoroutinefunction(base.create_nio)
+239 -333
View File
@@ -33,113 +33,91 @@ pytestmark = pytest.mark.asyncio
class TestQemuNodesRoutes:
@pytest.fixture
def fake_qemu_bin(self, monkeypatch, tmpdir) -> str:
monkeypatch.setenv("PATH", str(tmpdir))
bin_path = os.path.join(os.environ["PATH"], "qemu-system-x86_64")
with open(bin_path, "w+") as f:
f.write("1")
os.chmod(bin_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
return bin_path
@pytest.fixture
def fake_qemu_vm(self, images_dir) -> str:
img_dir = os.path.join(images_dir, "QEMU")
bin_path = os.path.join(img_dir, "linux载.img")
with open(bin_path, "w+") as f:
f.write("1234567")
os.chmod(bin_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
return bin_path
@pytest.fixture
def fake_qemu_img_binary(self, tmpdir):
bin_path = str(tmpdir / "qemu-img")
with open(bin_path, "w+") as f:
f.write("1")
os.chmod(bin_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
return bin_path
@pytest.fixture
def base_params(self, tmpdir, fake_qemu_bin) -> dict:
"""Return standard parameters"""
return {"name": "QEMU-TEST-1", "qemu_path": fake_qemu_bin}
@pytest_asyncio.fixture
async def qemu_vm(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict
) -> None:
response = await compute_client.post(
app.url_path_for("compute:create_qemu_node", project_id=compute_project.id),
json=base_params
app.url_path_for("compute:create_qemu_node", project_id=compute_project.id), json=base_params
)
assert response.status_code == status.HTTP_201_CREATED
return response.json()
async def test_qemu_create(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
fake_qemu_bin: str
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict, fake_qemu_bin: str
) -> None:
response = await compute_client.post(app.url_path_for("compute:create_qemu_node", project_id=compute_project.id), json=base_params)
response = await compute_client.post(
app.url_path_for("compute:create_qemu_node", project_id=compute_project.id), json=base_params
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "QEMU-TEST-1"
assert response.json()["project_id"] == compute_project.id
assert response.json()["qemu_path"] == fake_qemu_bin
assert response.json()["platform"] == "x86_64"
async def test_qemu_create_platform(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
fake_qemu_bin: str
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict, fake_qemu_bin: str
):
base_params["qemu_path"] = None
base_params["platform"] = "x86_64"
response = await compute_client.post(app.url_path_for("compute:create_qemu_node", project_id=compute_project.id), json=base_params)
response = await compute_client.post(
app.url_path_for("compute:create_qemu_node", project_id=compute_project.id), json=base_params
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "QEMU-TEST-1"
assert response.json()["project_id"] == compute_project.id
assert response.json()["qemu_path"] == fake_qemu_bin
assert response.json()["platform"] == "x86_64"
@pytest.mark.asyncio
async def test_qemu_create_with_params(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
fake_qemu_vm: str
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict, fake_qemu_vm: str
):
params = base_params
params["ram"] = 1024
params["hda_disk_image"] = "linux载.img"
response = await compute_client.post(app.url_path_for("compute:create_qemu_node", project_id=compute_project.id), json=params)
response = await compute_client.post(
app.url_path_for("compute:create_qemu_node", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "QEMU-TEST-1"
assert response.json()["project_id"] == compute_project.id
@@ -147,12 +125,7 @@ class TestQemuNodesRoutes:
assert response.json()["hda_disk_image"] == "linux载.img"
async def test_qemu_create_discards_stale_overlay_for_replacement(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
fake_qemu_vm: str
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict, fake_qemu_vm: str
):
node_id = str(uuid.uuid4())
@@ -182,12 +155,7 @@ class TestQemuNodesRoutes:
assert not os.path.exists(stale_checksum)
async def test_qemu_create_preserves_existing_overlay_without_reset_marker(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
fake_qemu_vm: str
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict, fake_qemu_vm: str
):
node_id = str(uuid.uuid4())
@@ -210,12 +178,7 @@ class TestQemuNodesRoutes:
assert os.path.exists(overlay)
async def test_qemu_create_preserves_overlay_when_replacement_is_missing(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
fake_qemu_vm: str
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict, fake_qemu_vm: str
):
node_id = str(uuid.uuid4())
@@ -239,12 +202,7 @@ class TestQemuNodesRoutes:
assert os.path.exists(overlay)
async def test_qemu_create_resets_valid_replacement_when_another_disk_is_missing(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
fake_qemu_vm: str
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict, fake_qemu_vm: str
):
node_id = str(uuid.uuid4())
@@ -267,8 +225,7 @@ class TestQemuNodesRoutes:
assert response.status_code == status.HTTP_409_CONFLICT
assert not os.path.exists(stale_overlay)
@pytest.mark.parametrize(
"name, status_code",
(
@@ -286,21 +243,21 @@ class TestQemuNodesRoutes:
),
)
async def test_qemu_create_with_invalid_name(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
name: str,
status_code: int
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
base_params: dict,
name: str,
status_code: int,
) -> None:
base_params["name"] = name
response = await compute_client.post(
app.url_path_for("compute:create_qemu_node", project_id=compute_project.id), json=base_params
)
assert response.status_code == status_code
# async def test_qemu_create_with_project_file(self, app: FastAPI,
# compute_client: AsyncClient,
# compute_project: Project,
@@ -321,16 +278,9 @@ class TestQemuNodesRoutes:
# assert response.status_code == status.HTTP_201_CREATED
# assert response.json()["hda_disk_image"] == "hello.img"
# assert response.json()["hda_disk_image_md5sum"] == "7d793037a0760186574b0282f2f435e7"
async def test_qemu_get(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
qemu_vm: dict
):
async def test_qemu_get(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, qemu_vm: dict):
response = await compute_client.get(
app.url_path_for("compute:get_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"])
)
@@ -338,151 +288,130 @@ class TestQemuNodesRoutes:
assert response.json()["name"] == "QEMU-TEST-1"
assert response.json()["project_id"] == compute_project.id
assert response.json()["node_directory"] == os.path.join(
compute_project.path,
"project-files",
"qemu",
qemu_vm["node_id"]
compute_project.path, "project-files", "qemu", qemu_vm["node_id"]
)
async def test_qemu_start(self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.start", return_value=True) as mock:
response = await compute_client.post(
app.url_path_for("compute:start_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"])
app.url_path_for(
"compute:start_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]
)
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_qemu_stop(self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.stop", return_value=True) as mock:
response = await compute_client.post(
app.url_path_for("compute:stop_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_qemu_reload(self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.reload", return_value=True) as mock:
response = await compute_client.post(
app.url_path_for("compute:reload_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"])
app.url_path_for(
"compute:reload_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]
)
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_qemu_suspend(self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.suspend", return_value=True) as mock:
response = await compute_client.post(
app.url_path_for("compute:suspend_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"])
app.url_path_for(
"compute:suspend_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]
)
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_qemu_resume(self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.resume", return_value=True) as mock:
response = await compute_client.post(
app.url_path_for("compute:resume_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"])
app.url_path_for(
"compute:resume_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]
)
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_qemu_delete(self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
with asyncio_patch("gns3server.compute.qemu.Qemu.delete_node", return_value=True) as mock:
response = await compute_client.delete(
app.url_path_for("compute:delete_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"])
app.url_path_for(
"compute:delete_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]
)
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_qemu_update(
self,
app: FastAPI,
compute_client: AsyncClient,
qemu_vm: dict,
free_console_port: int,
fake_qemu_vm: str
self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict, free_console_port: int, fake_qemu_vm: str
) -> None:
params = {
"name": "test",
"console": free_console_port,
"ram": 1024,
"hdb_disk_image": "linux载.img"
}
params = {"name": "test", "console": free_console_port, "ram": 1024, "hdb_disk_image": "linux载.img"}
response = await compute_client.put(
app.url_path_for("compute:update_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]),
json=params
json=params,
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "test"
assert response.json()["console"] == free_console_port
assert response.json()["hdb_disk_image"] == "linux载.img"
assert response.json()["ram"] == 1024
async def test_qemu_nio_create_udp(self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.add_ubridge_udp_connection"):
await compute_client.put(
app.url_path_for("compute:update_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]),
json={"adapters": 2}
app.url_path_for(
"compute:update_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]
),
json={"adapters": 2},
)
url = app.url_path_for(
"compute:create_qemu_node_nio",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
adapter_number="1",
port_number="0"
port_number="0",
)
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
async def test_qemu_nio_update_udp(self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1",
"filters": {"packet_loss": 10}
}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1", "filters": {"packet_loss": 10}}
await compute_client.put(
app.url_path_for("compute:update_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]),
json={"adapters": 2}
json={"adapters": 2},
)
url = app.url_path_for(
"compute:create_qemu_node_nio",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
adapter_number="1",
port_number="0"
port_number="0",
)
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["filters"] == {"packet_loss": 10}
@@ -493,127 +422,125 @@ class TestQemuNodesRoutes:
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
adapter_number="1",
port_number="0"
port_number="0",
)
response = await compute_client.put(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
assert response.json()["filters"] == {}
async def test_qemu_delete_nio(self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM._ubridge_send"):
await compute_client.put(
app.url_path_for("compute:update_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]),
json={"adapters": 2}
app.url_path_for(
"compute:update_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]
),
json={"adapters": 2},
)
url = app.url_path_for(
"compute:create_qemu_node_nio",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
adapter_number="1",
port_number="0"
port_number="0",
)
await compute_client.post(url, json=params)
url = app.url_path_for(
"compute:delete_qemu_node_nio",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
adapter_number="1",
port_number="0"
port_number="0",
)
response = await compute_client.delete(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_images(self, app: FastAPI, compute_client: AsyncClient, fake_qemu_vm) -> None:
response = await compute_client.get(app.url_path_for("compute:get_qemu_images"))
assert response.status_code == status.HTTP_200_OK
print(response.json())
assert {"filename": "linux载.img", "path": "linux载.img", "md5sum": "fcea920f7412b5da7be0cf42b8c93759", "filesize": 7} in response.json()
assert {
"filename": "linux载.img",
"path": "linux载.img",
"md5sum": "fcea920f7412b5da7be0cf42b8c93759",
"filesize": 7,
} in response.json()
async def test_upload_image(self, app: FastAPI, compute_client: AsyncClient, tmpdir: str) -> None:
with patch("gns3server.compute.Qemu.get_images_directory", return_value=str(tmpdir)):
response = await compute_client.post(app.url_path_for("compute:upload_qemu_image",
filename="test2使"), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_qemu_image", filename="test2使"), content=b"TEST"
)
assert response.status_code == status.HTTP_204_NO_CONTENT
with open(str(tmpdir / "test2使")) as f:
assert f.read() == "TEST"
with open(str(tmpdir / "test2使.md5sum")) as f:
checksum = f.read()
assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
async def test_upload_image_ova(self, app: FastAPI, compute_client: AsyncClient, tmpdir:str) -> None:
async def test_upload_image_ova(self, app: FastAPI, compute_client: AsyncClient, tmpdir: str) -> None:
with patch("gns3server.compute.Qemu.get_images_directory", return_value=str(tmpdir)):
response = await compute_client.post(app.url_path_for("compute:upload_qemu_image",
filename="test2.ova/test2.vmdk"), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_qemu_image", filename="test2.ova/test2.vmdk"), content=b"TEST"
)
assert response.status_code == status.HTTP_204_NO_CONTENT
with open(str(tmpdir / "test2.ova" / "test2.vmdk")) as f:
assert f.read() == "TEST"
with open(str(tmpdir / "test2.ova" / "test2.vmdk.md5sum")) as f:
checksum = f.read()
assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
async def test_upload_image_forbidden_location(
self, app: FastAPI,
compute_client: AsyncClient,
tmpdir: str
self, app: FastAPI, compute_client: AsyncClient, tmpdir: str
) -> None:
response = await compute_client.post(app.url_path_for("compute:upload_qemu_image",
filename="/qemu/images/../../test2"), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_qemu_image", filename="/qemu/images/../../test2"), content=b"TEST"
)
assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_download_image(self, app: FastAPI, compute_client: AsyncClient, images_dir: str) -> None:
response = await compute_client.post(app.url_path_for("compute:upload_qemu_image", filename="test3"), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_qemu_image", filename="test3"), content=b"TEST"
)
assert response.status_code == status.HTTP_204_NO_CONTENT
response = await compute_client.get(app.url_path_for("compute:download_qemu_image", filename="test3"))
assert response.status_code == status.HTTP_200_OK
async def test_download_image_forbidden_location(self, app: FastAPI, compute_client: AsyncClient, tmpdir) -> None:
file_path = "foo/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
response = await compute_client.get(app.url_path_for("compute:download_qemu_image", filename=file_path))
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.skipif(os.getuid() == 0, reason="Root can delete any image")
async def test_upload_image_permission_denied(self, app: FastAPI, compute_client: AsyncClient, images_dir: str) -> None:
async def test_upload_image_permission_denied(
self, app: FastAPI, compute_client: AsyncClient, images_dir: str
) -> None:
with open(os.path.join(images_dir, "QEMU", "test2.tmp"), "w+") as f:
f.write("")
os.chmod(os.path.join(images_dir, "QEMU", "test2.tmp"), 0)
response = await compute_client.post(app.url_path_for("compute:upload_qemu_image", filename="test2"), content=b"TEST")
response = await compute_client.post(
app.url_path_for("compute:upload_qemu_image", filename="test2"), content=b"TEST"
)
assert response.status_code == status.HTTP_409_CONFLICT
# @pytest.mark.asyncio
# async def test_create_img_relative(self, app: FastAPI, compute_client: AsyncClient):
#
@@ -665,69 +592,62 @@ class TestQemuNodesRoutes:
# with asyncio_patch("gns3server.compute.Qemu.create_disk"):
# response = await compute_client.post(app.url_path_for("compute:create_qemu_image"), json=params)
# assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_capabilities(self, app: FastAPI, compute_client: AsyncClient) -> None:
with asyncio_patch("gns3server.compute.Qemu.get_kvm_archs", return_value=["x86_64"]):
response = await compute_client.get(app.url_path_for("compute:get_qemu_capabilities"))
assert response.json()["kvm"] == ["x86_64"]
async def test_qemu_duplicate(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
qemu_vm: dict,
base_params: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, qemu_vm: dict, base_params: dict
) -> None:
# create destination node first
response = await compute_client.post(
app.url_path_for("compute:create_qemu_node", project_id=qemu_vm["project_id"]),
json=base_params
app.url_path_for("compute:create_qemu_node", project_id=qemu_vm["project_id"]), json=base_params
)
assert response.status_code == status.HTTP_201_CREATED
params = {"destination_node_id": response.json()["node_id"]}
response = await compute_client.post(
app.url_path_for("compute:duplicate_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]),
json=params
app.url_path_for(
"compute:duplicate_qemu_node", project_id=qemu_vm["project_id"], node_id=qemu_vm["node_id"]
),
json=params,
)
assert response.status_code == status.HTTP_201_CREATED
async def test_qemu_create_disk_image(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
fake_qemu_img_binary: str,
qemu_vm: dict,
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
fake_qemu_img_binary: str,
qemu_vm: dict,
):
options = {
"format": "qcow2",
"preallocation": "metadata",
"cluster_size": 64,
"refcount_bits": 12,
"lazy_refcounts": "off",
"size": 30
"size": 30,
}
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()) as qemu_img:
response = await compute_client.post(
app.url_path_for(
"compute:create_qemu_disk_image",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
disk_name="disk.qcow2"
disk_name="disk.qcow2",
),
json=options
json=options,
)
assert response.status_code == status.HTTP_204_NO_CONTENT
args, kwargs = qemu_img.call_args
assert args == (
fake_qemu_img_binary,
@@ -743,39 +663,34 @@ class TestQemuNodesRoutes:
"-o",
"refcount_bits=12",
os.path.join(qemu_vm["node_directory"], "disk.qcow2"),
"30M"
"30M",
)
async def test_qemu_create_disk_image_already_exists(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
fake_qemu_img_binary: str,
qemu_vm: dict,
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
fake_qemu_img_binary: str,
qemu_vm: dict,
):
node = compute_project.get_node(qemu_vm["node_id"])
shutil.copy("tests/resources/empty8G.qcow2", os.path.join(node.working_dir, "disk.qcow2"))
options = {
"format": "qcow2",
"size": 100
}
options = {"format": "qcow2", "size": 100}
response = await compute_client.post(
app.url_path_for(
"compute:create_qemu_disk_image",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
disk_name="disk.qcow2"
disk_name="disk.qcow2",
),
json=options
json=options,
)
assert response.status_code == status.HTTP_409_CONFLICT
# async def test_qemu_create_disk_image_with_not_supported_characters_by_filesystem(
# app: FastAPI,
# compute_client: AsyncClient,
@@ -803,125 +718,116 @@ class TestQemuNodesRoutes:
# json=options
# )
# assert response.status_code == status.HTTP_409_CONFLICT
async def test_qemu_update_disk_image(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
fake_qemu_img_binary: str,
qemu_vm: dict,
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
fake_qemu_img_binary: str,
qemu_vm: dict,
) -> None:
node = compute_project.get_node(qemu_vm["node_id"])
shutil.copy("tests/resources/empty8G.qcow2", os.path.join(node.working_dir, "disk.qcow2"))
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()) as qemu_img:
response = await compute_client.put(
app.url_path_for(
"compute:update_qemu_disk_image",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
disk_name="disk.qcow2"
disk_name="disk.qcow2",
),
json={"extend": 10}
json={"extend": 10},
)
assert response.status_code == status.HTTP_204_NO_CONTENT
assert qemu_img.called
args, kwargs = qemu_img.call_args
assert args == (
fake_qemu_img_binary,
"resize",
os.path.join(qemu_vm["node_directory"], "disk.qcow2"),
"+10M"
"+10M",
)
async def test_qemu_delete_disk_image(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
qemu_vm: dict,
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
qemu_vm: dict,
) -> None:
node = compute_project.get_node(qemu_vm["node_id"])
shutil.copy("tests/resources/empty8G.qcow2", os.path.join(node.working_dir, "disk.qcow2"))
response = await compute_client.delete(
app.url_path_for(
"compute:delete_qemu_disk_image",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
disk_name="disk.qcow2"
disk_name="disk.qcow2",
)
)
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_qemu_delete_disk_image_missing_image(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
qemu_vm: dict,
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
qemu_vm: dict,
) -> None:
response = await compute_client.delete(
app.url_path_for(
"compute:delete_qemu_disk_image",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
disk_name="unknown_image.qcow2"
disk_name="unknown_image.qcow2",
)
)
assert response.status_code == status.HTTP_409_CONFLICT
@pytest.mark.asyncio
async def test_qemu_start_capture(self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict):
params = {
"capture_file_name": "test.pcap",
"data_link_type": "DLT_EN10MB"
}
params = {"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"}
url = app.url_path_for(
"compute:start_qemu_node_capture",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
adapter_number="0",
port_number="0"
port_number="0",
)
with patch("gns3server.compute.qemu.qemu_vm.QemuVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.start_capture") as mock:
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_200_OK
assert mock.called
assert "test.pcap" in response.json()["pcap_file_path"]
@pytest.mark.asyncio
async def test_qemu_stop_capture(self, app: FastAPI, compute_client: AsyncClient, qemu_vm: dict):
url = app.url_path_for(
"compute:stop_qemu_node_capture",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
adapter_number="0",
port_number="0"
port_number="0",
)
with patch("gns3server.compute.qemu.qemu_vm.QemuVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.stop_capture") as mock:
response = await compute_client.post(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
assert mock.called
# @pytest.mark.asyncio
# async def test_qemu_pcap(self, app: FastAPI, compute_client: AsyncClient, vm, compute_project):
#
+118 -130
View File
@@ -29,129 +29,119 @@ pytestmark = pytest.mark.asyncio
class TestVirtualBoxNodesRoutes:
@pytest_asyncio.fixture
async def vm(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
vboxmanage_path = "/fake/VboxManage"
params = {
"name": "VMTEST",
"vmname": "VMTEST",
"linked_clone": False
}
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.create", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:create_virtualbox_node", project_id=compute_project.id),
json=params)
params = {"name": "VMTEST", "vmname": "VMTEST", "linked_clone": False}
with asyncio_patch(
"gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.create", return_value=True
) as mock:
response = await compute_client.post(
app.url_path_for("compute:create_virtualbox_node", project_id=compute_project.id), json=params
)
assert mock.called
assert response.status_code == status.HTTP_201_CREATED
with patch("gns3server.compute.virtualbox.VirtualBox.find_vboxmanage", return_value=vboxmanage_path):
return response.json()
async def test_vbox_create(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
params = {
"name": "VM1",
"vmname": "VM1",
"linked_clone": False
}
params = {"name": "VM1", "vmname": "VM1", "linked_clone": False}
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.create", return_value=True):
response = await compute_client.post(app.url_path_for("compute:create_virtualbox_node", project_id=compute_project.id),
json=params)
response = await compute_client.post(
app.url_path_for("compute:create_virtualbox_node", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "VM1"
assert response.json()["project_id"] == compute_project.id
async def test_vbox_get(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict) -> None:
response = await compute_client.get(app.url_path_for("compute:get_virtualbox_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
async def test_vbox_get(
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict
) -> None:
response = await compute_client.get(
app.url_path_for("compute:get_virtualbox_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "VMTEST"
assert response.json()["project_id"] == compute_project.id
async def test_vbox_start(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.start", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:start_virtualbox_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:start_virtualbox_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vbox_stop(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.stop", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:stop_virtualbox_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:stop_virtualbox_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vbox_suspend(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.suspend", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:suspend_virtualbox_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
with asyncio_patch(
"gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.suspend", return_value=True
) as mock:
response = await compute_client.post(
app.url_path_for("compute:suspend_virtualbox_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vbox_resume(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.resume", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:resume_virtualbox_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
with asyncio_patch(
"gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.resume", return_value=True
) as mock:
response = await compute_client.post(
app.url_path_for("compute:resume_virtualbox_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vbox_reload(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.reload", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:reload_virtualbox_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
with asyncio_patch(
"gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.reload", return_value=True
) as mock:
response = await compute_client.post(
app.url_path_for("compute:reload_virtualbox_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vbox_nio_create_udp(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
url = app.url_path_for("compute:create_virtualbox_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
with asyncio_patch('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_add_nio_binding') as mock:
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
url = app.url_path_for(
"compute:create_virtualbox_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_add_nio_binding") as mock:
response = await compute_client.post(url, json=params)
assert mock.called
args, kwgars = mock.call_args
assert args[0] == 0
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
# @pytest.mark.asyncio
# async def test_vbox_nio_update_udp(self, app: FastAPI, compute_client: AsyncClient, vm):
#
@@ -169,78 +159,76 @@ class TestVirtualBoxNodesRoutes:
#
# assert response.status_code == status.HTTP_201_CREATED
# assert response.json()["type"] == "nio_udp"
async def test_vbox_delete_nio(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
url = app.url_path_for("compute:delete_virtualbox_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
with asyncio_patch('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_remove_nio_binding') as mock:
url = app.url_path_for(
"compute:delete_virtualbox_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch(
"gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_remove_nio_binding"
) as mock:
response = await compute_client.delete(url)
assert mock.called
args, kwgars = mock.call_args
assert args[0] == 0
assert response.status_code == status.HTTP_204_NO_CONTENT
@pytest.mark.asyncio
async def test_vbox_update(self, app: FastAPI, compute_client: AsyncClient, vm, free_console_port):
params = {
"name": "test",
"console": free_console_port
}
response = await compute_client.put(app.url_path_for("compute:update_virtualbox_node",
project_id=vm["project_id"],
node_id=vm["node_id"]), json=params)
params = {"name": "test", "console": free_console_port}
response = await compute_client.put(
app.url_path_for("compute:update_virtualbox_node", project_id=vm["project_id"], node_id=vm["node_id"]),
json=params,
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "test"
assert response.json()["console"] == free_console_port
@pytest.mark.asyncio
async def test_virtualbox_start_capture(self, app: FastAPI, compute_client: AsyncClient, vm):
params = {
"capture_file_name": "test.pcap",
"data_link_type": "DLT_EN10MB"
}
url = app.url_path_for("compute:start_virtualbox_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
params = {"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"}
url = app.url_path_for(
"compute:start_virtualbox_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.start_capture") as mock:
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_200_OK
assert mock.called
assert "test.pcap" in response.json()["pcap_file_path"]
@pytest.mark.asyncio
async def test_virtualbox_stop_capture(self, app: FastAPI, compute_client: AsyncClient, vm):
url = app.url_path_for("compute:stop_virtualbox_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:stop_virtualbox_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.stop_capture") as mock:
response = await compute_client.post(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
assert mock.called
# @pytest.mark.asyncio
# async def test_virtualbox_pcap(self, app: FastAPI, compute_client: AsyncClient, vm, compute_project):
#
+106 -141
View File
@@ -29,147 +29,121 @@ pytestmark = pytest.mark.asyncio
class TestVMwareNodesRoutes:
@pytest_asyncio.fixture
async def vm(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vmx_path: str) -> dict:
params = {
"name": "VMTEST",
"vmx_path": vmx_path,
"linked_clone": False
}
params = {"name": "VMTEST", "vmx_path": vmx_path, "linked_clone": False}
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.create", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:create_vmware_node", project_id=compute_project.id),
json=params)
response = await compute_client.post(
app.url_path_for("compute:create_vmware_node", project_id=compute_project.id), json=params
)
assert mock.called
assert response.status_code == status.HTTP_201_CREATED
return response.json()
@pytest.fixture
def vmx_path(self, tmpdir: str) -> str:
"""
Return a fake VMX file
"""
path = str(tmpdir / "test.vmx")
with open(path, 'w+') as f:
with open(path, "w+") as f:
f.write("1")
return path
async def test_vmware_create(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vmx_path: str
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vmx_path: str
) -> None:
params = {
"name": "VM1",
"vmx_path": vmx_path,
"linked_clone": False
}
params = {"name": "VM1", "vmx_path": vmx_path, "linked_clone": False}
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.create", return_value=True):
response = await compute_client.post(app.url_path_for("compute:create_vmware_node", project_id=compute_project.id),
json=params)
response = await compute_client.post(
app.url_path_for("compute:create_vmware_node", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "VM1"
assert response.json()["project_id"] == compute_project.id
async def test_vmware_get(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict
) -> None:
response = await compute_client.get(app.url_path_for("compute:get_vmware_node", project_id=vm["project_id"], node_id=vm["node_id"]))
response = await compute_client.get(
app.url_path_for("compute:get_vmware_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "VMTEST"
assert response.json()["project_id"] == compute_project.id
async def test_vmware_start(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.start", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:start_vmware_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:start_vmware_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vmware_stop(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.stop", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:stop_vmware_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:stop_vmware_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vmware_suspend(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.suspend", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:suspend_vmware_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:suspend_vmware_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vmware_resume(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.resume", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:resume_vmware_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:resume_vmware_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vmware_reload(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.reload", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:reload_vmware_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:reload_vmware_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vmware_nio_create_udp(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
url = app.url_path_for("compute:create_vmware_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
with asyncio_patch('gns3server.compute.vmware.vmware_vm.VMwareVM.adapter_add_nio_binding') as mock:
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
url = app.url_path_for(
"compute:create_vmware_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.adapter_add_nio_binding") as mock:
response = await compute_client.post(url, json=params)
assert mock.called
args, kwgars = mock.call_args
assert args[0] == 0
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
# @pytest.mark.asyncio
# async def test_vmware_nio_update_udp(self, app: FastAPI, compute_client: AsyncClient, vm):
#
@@ -187,83 +161,74 @@ class TestVMwareNodesRoutes:
# response = await compute_client.put("/projects/{project_id}/vmware/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
# assert response.status_code == status.HTTP_201_CREATED
# assert response.json()["type"] == "nio_udp"
async def test_vmware_delete_nio(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
url = app.url_path_for("compute:delete_vmware_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
with asyncio_patch('gns3server.compute.vmware.vmware_vm.VMwareVM.adapter_remove_nio_binding') as mock:
url = app.url_path_for(
"compute:delete_vmware_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.adapter_remove_nio_binding") as mock:
response = await compute_client.delete(url)
assert mock.called
args, kwgars = mock.call_args
assert args[0] == 0
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vmware_update(
self,
app: FastAPI,
compute_client: AsyncClient,
vm: dict,
free_console_port: int
self, app: FastAPI, compute_client: AsyncClient, vm: dict, free_console_port: int
) -> None:
params = {
"name": "test",
"console": free_console_port
}
response = await compute_client.put(app.url_path_for("compute:update_vmware_node",
project_id=vm["project_id"],
node_id=vm["node_id"]), json=params)
params = {"name": "test", "console": free_console_port}
response = await compute_client.put(
app.url_path_for("compute:update_vmware_node", project_id=vm["project_id"], node_id=vm["node_id"]),
json=params,
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "test"
assert response.json()["console"] == free_console_port
async def test_vmware_start_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"capture_file_name": "test.pcap",
"data_link_type": "DLT_EN10MB"
}
url = app.url_path_for("compute:start_vmware_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
params = {"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"}
url = app.url_path_for(
"compute:start_vmware_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with patch("gns3server.compute.vmware.vmware_vm.VMwareVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.start_capture") as mock:
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_200_OK
assert mock.called
assert "test.pcap" in response.json()["pcap_file_path"]
async def test_vmware_stop_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
url = app.url_path_for("compute:stop_vmware_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:stop_vmware_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with patch("gns3server.compute.vmware.vmware_vm.VMwareVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.stop_capture") as mock:
response = await compute_client.post(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
assert mock.called
# @pytest.mark.asyncio
# async def test_vmware_pcap(self, app: FastAPI, compute_client: AsyncClient, vm, compute_project):
#
+155 -196
View File
@@ -29,288 +29,247 @@ pytestmark = pytest.mark.asyncio
class TestVPCSNodesRoutes:
@pytest_asyncio.fixture
async def vm(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
params = {"name": "PC TEST 1"}
response = await compute_client.post(app.url_path_for("compute:create_vpcs_node", project_id=compute_project.id), json=params)
response = await compute_client.post(
app.url_path_for("compute:create_vpcs_node", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
return response.json()
async def test_vpcs_create(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
params = {"name": "PC TEST 1"}
response = await compute_client.post(app.url_path_for("compute:create_vpcs_node", project_id=compute_project.id), json=params)
response = await compute_client.post(
app.url_path_for("compute:create_vpcs_node", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "PC TEST 1"
assert response.json()["project_id"] == compute_project.id
async def test_vpcs_get(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict
) -> None:
response = await compute_client.get(app.url_path_for("compute:get_vpcs_node", project_id=vm["project_id"], node_id=vm["node_id"]))
response = await compute_client.get(
app.url_path_for("compute:get_vpcs_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "PC TEST 1"
assert response.json()["project_id"] == compute_project.id
assert response.json()["status"] == "stopped"
async def test_vpcs_create_startup_script(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project
) -> None:
params = {
"name": "PC TEST 1",
"startup_script": "ip 192.168.1.2\necho TEST"
}
response = await compute_client.post(app.url_path_for("compute:create_vpcs_node", project_id=compute_project.id), json=params)
params = {"name": "PC TEST 1", "startup_script": "ip 192.168.1.2\necho TEST"}
response = await compute_client.post(
app.url_path_for("compute:create_vpcs_node", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "PC TEST 1"
assert response.json()["project_id"] == compute_project.id
async def test_vpcs_create_port(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
free_console_port: int
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, free_console_port: int
) -> None:
params = {
"name": "PC TEST 1",
"console": free_console_port
}
response = await compute_client.post(app.url_path_for("compute:create_vpcs_node", project_id=compute_project.id), json=params)
params = {"name": "PC TEST 1", "console": free_console_port}
response = await compute_client.post(
app.url_path_for("compute:create_vpcs_node", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["name"] == "PC TEST 1"
assert response.json()["project_id"] == compute_project.id
assert response.json()["console"] == free_console_port
async def test_vpcs_nio_create_udp(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
url = app.url_path_for("compute:create_vpcs_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
url = app.url_path_for(
"compute:create_vpcs_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.add_ubridge_udp_connection"):
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
async def test_vpcs_nio_update_udp(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1",
"filters": {"packet_loss": 10}
}
url = app.url_path_for("compute:create_vpcs_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1", "filters": {"packet_loss": 10}}
url = app.url_path_for(
"compute:create_vpcs_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.add_ubridge_udp_connection"):
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["filters"] == {"packet_loss": 10}
params["filters"].clear()
url = app.url_path_for("compute:update_vpcs_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:update_vpcs_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
response = await compute_client.put(url, json=params)
assert response.status_code == status.HTTP_201_CREATED
assert response.json()["type"] == "nio_udp"
assert response.json()["filters"] == {}
async def test_vpcs_delete_nio(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
params = {"type": "nio_udp", "lport": 4242, "rport": 4343, "rhost": "127.0.0.1"}
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM._ubridge_send"):
url = app.url_path_for("compute:create_vpcs_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:create_vpcs_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
await compute_client.post(url, json=params)
url = app.url_path_for("compute:delete_vpcs_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:delete_vpcs_node_nio",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
response = await compute_client.delete(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vpcs_start(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.start", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:start_vpcs_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vpcs_stop(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.stop", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:stop_vpcs_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vpcs_reload(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.reload", return_value=True) as mock:
response = await compute_client.post(app.url_path_for("compute:reload_vpcs_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vpcs_delete(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vpcs.VPCS.delete_node", return_value=True) as mock:
response = await compute_client.delete(app.url_path_for("compute:delete_vpcs_node",
project_id=vm["project_id"],
node_id=vm["node_id"]))
response = await compute_client.post(
app.url_path_for("compute:start_vpcs_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vpcs_stop(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.stop", return_value=True) as mock:
response = await compute_client.post(
app.url_path_for("compute:stop_vpcs_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vpcs_reload(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.reload", return_value=True) as mock:
response = await compute_client.post(
app.url_path_for("compute:reload_vpcs_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vpcs_delete(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
with asyncio_patch("gns3server.compute.vpcs.VPCS.delete_node", return_value=True) as mock:
response = await compute_client.delete(
app.url_path_for("compute:delete_vpcs_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_vpcs_suspend(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
response = await compute_client.post(
app.url_path_for(
"compute:suspend_vpcs_node",
project_id=vm["project_id"],
node_id=vm["node_id"]
)
app.url_path_for("compute:suspend_vpcs_node", project_id=vm["project_id"], node_id=vm["node_id"])
)
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
async def test_vpcs_duplicate(
self,
app: FastAPI,
compute_client: AsyncClient,
compute_project: Project,
vm: dict
self, app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict
) -> None:
# create destination node first
params = {"name": "PC TEST 1"}
response = await compute_client.post(app.url_path_for("compute:create_vpcs_node", project_id=compute_project.id), json=params)
response = await compute_client.post(
app.url_path_for("compute:create_vpcs_node", project_id=compute_project.id), json=params
)
assert response.status_code == status.HTTP_201_CREATED
params = {"destination_node_id": response.json()["node_id"]}
response = await compute_client.post(app.url_path_for("compute:duplicate_vpcs_node",
project_id=vm["project_id"],
node_id=vm["node_id"]), json=params)
response = await compute_client.post(
app.url_path_for("compute:duplicate_vpcs_node", project_id=vm["project_id"], node_id=vm["node_id"]),
json=params,
)
assert response.status_code == status.HTTP_201_CREATED
async def test_vpcs_update(
self,
app: FastAPI,
compute_client: AsyncClient,
vm: dict,
free_console_port: int
self, app: FastAPI, compute_client: AsyncClient, vm: dict, free_console_port: int
) -> None:
console_port = free_console_port
params = {
"name": "test",
"console": console_port
}
response = await compute_client.put(app.url_path_for("compute:update_vpcs_node",
project_id=vm["project_id"],
node_id=vm["node_id"]), json=params)
params = {"name": "test", "console": console_port}
response = await compute_client.put(
app.url_path_for("compute:update_vpcs_node", project_id=vm["project_id"], node_id=vm["node_id"]),
json=params,
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["name"] == "test"
assert response.json()["console"] == console_port
async def test_vpcs_start_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
params = {
"capture_file_name": "test.pcap",
"data_link_type": "DLT_EN10MB"
}
url = app.url_path_for("compute:start_vpcs_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
params = {"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"}
url = app.url_path_for(
"compute:start_vpcs_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.start_capture") as mock:
response = await compute_client.post(url, json=params)
assert response.status_code == status.HTTP_200_OK
assert mock.called
assert "test.pcap" in response.json()["pcap_file_path"]
async def test_vpcs_stop_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
url = app.url_path_for("compute:stop_vpcs_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0")
url = app.url_path_for(
"compute:stop_vpcs_node_capture",
project_id=vm["project_id"],
node_id=vm["node_id"],
adapter_number="0",
port_number="0",
)
with patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.stop_capture") as mock:
response = await compute_client.post(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
assert mock.called
# @pytest.mark.asyncio
# async def test_vpcs_pcap(self, app: FastAPI, compute_client: AsyncClient, vm, compute_project: Project):
#