diff --git a/dev-requirements.txt b/dev-requirements.txt
index 3aa82cdd..04ca562b 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,7 +1,7 @@
-pytest==8.3.3
+pytest==8.3.4
flake8==7.1.1
pytest-timeout==2.3.1
-pytest-asyncio==0.21.2
+pytest-asyncio==0.25.2
requests==2.32.3
-httpx==0.27.2 # version 0.24.1 is required by httpx_ws
-httpx_ws==0.6.2
+httpx==0.28.1
+httpx_ws==0.7.1
diff --git a/tests/api/routes/compute/test_capabilities.py b/tests/api/routes/compute/test_capabilities.py
index e6ad64b3..071c629f 100644
--- a/tests/api/routes/compute/test_capabilities.py
+++ b/tests/api/routes/compute/test_capabilities.py
@@ -29,27 +29,29 @@ from gns3server.utils.path import get_default_project_directory
pytestmark = pytest.mark.asyncio
-async def test_get(app: FastAPI, compute_client: AsyncClient, windows_platform) -> None:
+class TestCapabilitiesRoutes:
- 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,
- }
+ 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,
+ }
-async def test_get_on_gns3vm(app: FastAPI, compute_client: AsyncClient, on_gns3vm) -> None:
+ 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,
- }
+ 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,
+ }
diff --git a/tests/api/routes/compute/test_cloud_nodes.py b/tests/api/routes/compute/test_cloud_nodes.py
index b29f8a2b..18014eb9 100644
--- a/tests/api/routes/compute/test_cloud_nodes.py
+++ b/tests/api/routes/compute/test_cloud_nodes.py
@@ -28,154 +28,193 @@ from gns3server.compute.project import Project
pytestmark = pytest.mark.asyncio
-@pytest_asyncio.fixture(scope="function")
-async def vm(app: FastAPI, compute_client: AsyncClient, compute_project: Project, on_gns3vm) -> dict:
+class TestCloudNodesRoutes:
- 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"})
- assert response.status_code == status.HTTP_201_CREATED
- return response.json()
+ @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"})
+ assert response.status_code == status.HTTP_201_CREATED
+ return response.json()
-async def test_cloud_create(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"})
- assert response.status_code == 201
- assert response.json()["name"] == "Cloud 1"
- assert response.json()["project_id"] == compute_project.id
+ 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"})
+ assert response.status_code == 201
+ assert response.json()["name"] == "Cloud 1"
+ assert response.json()["project_id"] == compute_project.id
-async def test_get_cloud(app: FastAPI, compute_client: AsyncClient, compute_project: Project, vm: dict) -> None:
+ async def test_get_cloud(
+ 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"]))
- 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(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(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")
- await compute_client.post(url, json=params)
-
- params["filters"] = {}
- 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"
-
-
-async def test_cloud_delete_nio(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")
- 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")
- 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(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"]))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_cloud_update(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"})
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["name"] == "test"
-
-
-async def test_cloud_start_capture(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
-
- 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.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 mock.called
- assert "test.pcap" in response.json()["pcap_file_path"]
+ assert response.json()["name"] == "Cloud 1"
+ assert response.json()["project_id"] == compute_project.id
+ assert response.json()["status"] == "started"
-async def test_cloud_stop_capture(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ async def test_cloud_nio_create_udp(
+ self, app: FastAPI,
+ compute_client: AsyncClient,
+ compute_project: Project,
+ 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"))
+ 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"}
+
+ 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)
+
+ params["filters"] = {}
+ 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"
+
+
+ async def test_cloud_delete_nio(
+ 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")
+ 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")
+ 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
- assert mock.called
-# @pytest.mark.asyncio
-# async def test_cloud_pcap(compute_api, vm, compute_project):
-#
-# from itertools import repeat
-# stream = repeat(42, times=10)
-#
-# with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud.get_nio"):
-# with asyncio_patch("gns3server.compute.builtin.Builtin.stream_pcap_file", return_value=stream):
-# response = await compute_api.get("/projects/{project_id}/cloud/nodes/{node_id}/adapters/0/ports/0/pcap".format(project_id=compute_project.id, node_id=vm["node_id"]))
-# assert response.status_code == 200
-#
+ async def test_cloud_delete(
+ 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"]))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ 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"})
+ 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:
+
+ 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)
+ 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"))
+ 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):
+ #
+ # from itertools import repeat
+ # stream = repeat(42, times=10)
+ #
+ # with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud.get_nio"):
+ # with asyncio_patch("gns3server.compute.builtin.Builtin.stream_pcap_file", return_value=stream):
+ # response = await compute_api.get("/projects/{project_id}/cloud/nodes/{node_id}/adapters/0/ports/0/pcap".format(project_id=compute_project.id, node_id=vm["node_id"]))
+ # assert response.status_code == 200
+ #
diff --git a/tests/api/routes/compute/test_compute.py b/tests/api/routes/compute/test_compute.py
index 45325aad..aa70ff6b 100644
--- a/tests/api/routes/compute/test_compute.py
+++ b/tests/api/routes/compute/test_compute.py
@@ -26,41 +26,48 @@ from gns3server.compute.project import Project
pytestmark = pytest.mark.asyncio
-async def test_udp_allocation(app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
+class TestComputeRoutes:
- 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
+ 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={})
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()['udp_port'] is not None
-async def test_interfaces(app: FastAPI, compute_client: AsyncClient) -> None:
+ async def test_interfaces(self, app: FastAPI, compute_client: AsyncClient) -> None:
- response = await compute_client.get(app.url_path_for("compute:network_interfaces"))
- assert response.status_code == status.HTTP_200_OK
- assert isinstance(response.json(), list)
+ response = await compute_client.get(app.url_path_for("compute:network_interfaces"))
+ assert response.status_code == status.HTTP_200_OK
+ assert isinstance(response.json(), list)
-async def test_version_output(app: FastAPI, compute_client: AsyncClient) -> None:
+ 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__}
+ 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__}
-async def test_compute_authentication(app: FastAPI, compute_client: AsyncClient) -> None:
+ 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"))
- assert response.status_code == status.HTTP_401_UNAUTHORIZED
+ 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
+ # @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(app: FastAPI, compute_client: AsyncClient) -> None:
+ 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
+ response = await compute_client.get(app.url_path_for("compute:compute_statistics"))
+ assert response.status_code == status.HTTP_200_OK
diff --git a/tests/api/routes/compute/test_docker_nodes.py b/tests/api/routes/compute/test_docker_nodes.py
index f8c7935e..b36c2965 100644
--- a/tests/api/routes/compute/test_docker_nodes.py
+++ b/tests/api/routes/compute/test_docker_nodes.py
@@ -25,285 +25,299 @@ from unittest.mock import patch
from gns3server.compute.project import Project
-pytestmark = [pytest.mark.asyncio]
+pytestmark = pytest.mark.asyncio
-@pytest.fixture
-def base_params() -> dict:
- """Return standard parameters"""
+class TestDockerNodesRoutes:
- params = {
- "name": "DOCKER-TEST-1",
- "image": "nginx",
- "start_command": "nginx-daemon",
- "adapters": 2,
- "environment": "YES=1\nNO=0",
- "console_type": "telnet",
- "console_resolution": "1280x1024",
- "extra_hosts": "test:127.0.0.1"
- }
- return params
+ @pytest.fixture
+ def base_params(self) -> dict:
+ """Return standard parameters"""
+
+ params = {
+ "name": "DOCKER-TEST-1",
+ "image": "nginx",
+ "start_command": "nginx-daemon",
+ "adapters": 2,
+ "environment": "YES=1\nNO=0",
+ "console_type": "telnet",
+ "console_resolution": "1280x1024",
+ "extra_hosts": "test:127.0.0.1"
+ }
+ return params
-# @pytest.yield_fixture(autouse=True)
-# def mock_connection():
-#
-# docker = Docker.instance()
-# docker._connected = True
-# docker._connector = MagicMock()
-# yield
-# Docker._instance = None
+ # @pytest.yield_fixture(autouse=True)
+ # def mock_connection():
+ #
+ # docker = Docker.instance()
+ # docker._connected = True
+ # docker._connector = MagicMock()
+ # yield
+ # Docker._instance = None
-@pytest_asyncio.fixture
-async def vm(app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict) -> dict:
+ @pytest_asyncio.fixture
+ 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)
- assert response.status_code == status.HTTP_201_CREATED
- return response.json()
+ 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)
+ assert response.status_code == status.HTTP_201_CREATED
+ return response.json()
-async def test_docker_create(app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict) -> None:
+ async def test_docker_create(
+ 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"}]):
- 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=compute_project.id), json=base_params
- )
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["name"] == "DOCKER-TEST-1"
- assert response.json()["project_id"] == compute_project.id
- assert response.json()["container_id"] == "8bd8153ea8f5"
- assert response.json()["image"] == "nginx:latest"
- assert response.json()["adapters"] == 2
- assert response.json()["environment"] == "YES=1\nNO=0"
- assert response.json()["console_resolution"] == "1280x1024"
- assert response.json()["extra_hosts"] == "test:127.0.0.1"
+ 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=compute_project.id), json=base_params
+ )
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["name"] == "DOCKER-TEST-1"
+ assert response.json()["project_id"] == compute_project.id
+ assert response.json()["container_id"] == "8bd8153ea8f5"
+ assert response.json()["image"] == "nginx:latest"
+ assert response.json()["adapters"] == 2
+ assert response.json()["environment"] == "YES=1\nNO=0"
+ assert response.json()["console_resolution"] == "1280x1024"
+ assert response.json()["extra_hosts"] == "test:127.0.0.1"
-@pytest.mark.parametrize(
- "name, status_code",
- (
- ("valid-name.com", status.HTTP_201_CREATED),
- ("42name", status.HTTP_201_CREATED),
- ("424242", status.HTTP_409_CONFLICT),
- ("name42", status.HTTP_201_CREATED),
- ("name.424242", status.HTTP_409_CONFLICT),
- ("-name", status.HTTP_409_CONFLICT),
- ("name%-test", status.HTTP_409_CONFLICT),
- ("x" * 63, status.HTTP_201_CREATED),
- ("x" * 64, status.HTTP_409_CONFLICT),
- (("x" * 62 + ".") * 4, status.HTTP_201_CREATED),
- ("xx" + ("x" * 62 + ".") * 4, status.HTTP_409_CONFLICT),
- ),
-)
-async def test_docker_create_with_invalid_name(
- app: FastAPI,
- compute_client: AsyncClient,
- compute_project: Project,
- base_params: dict,
- name: str,
- status_code: int
-) -> None:
+ @pytest.mark.parametrize(
+ "name, status_code",
+ (
+ ("valid-name.com", status.HTTP_201_CREATED),
+ ("42name", status.HTTP_201_CREATED),
+ ("424242", status.HTTP_409_CONFLICT),
+ ("name42", status.HTTP_201_CREATED),
+ ("name.424242", status.HTTP_409_CONFLICT),
+ ("-name", status.HTTP_409_CONFLICT),
+ ("name%-test", status.HTTP_409_CONFLICT),
+ ("x" * 63, status.HTTP_201_CREATED),
+ ("x" * 64, status.HTTP_409_CONFLICT),
+ (("x" * 62 + ".") * 4, status.HTTP_201_CREATED),
+ ("xx" + ("x" * 62 + ".") * 4, status.HTTP_409_CONFLICT),
+ ),
+ )
+ 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
+ ) -> None:
- base_params["name"] = name
- 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=compute_project.id), json=base_params
- )
- assert response.status_code == status_code
+ base_params["name"] = name
+ 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=compute_project.id), json=base_params
+ )
+ assert response.status_code == status_code
-async def test_docker_start(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ 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:
+ 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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_docker_stop(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_docker_reload(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_docker_delete(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_docker_pause(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_docker_unpause(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_docker_nio_create_udp(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_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"
-
-
-async def test_docker_update_nio(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_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
-
- 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
-
-
-async def test_docker_delete_nio(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")
- 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(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"
- }
-
- 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)
-
- assert response.status_code == 200
- assert mock.called
- assert response.json()["name"] == "test"
- assert response.json()["console"] == free_console_port
- assert response.json()["start_command"] == "yes"
- assert response.json()["environment"] == "GNS3=1\nGNS4=0"
- assert response.json()["extra_hosts"] == "test:127.0.0.1"
-
-
-async def test_docker_start_capture(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")
-
- 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:
- params = {"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"}
- response = await compute_client.post(url, json=params)
- assert response.status_code == status.HTTP_200_OK
+ 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 "test.pcap" in response.json()["pcap_file_path"]
-
-
-async def test_docker_stop_capture(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")
-
- 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:
- response = await compute_client.post(url)
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"]))
assert mock.called
+ assert response.status_code == status.HTTP_204_NO_CONTENT
-async def test_docker_duplicate(app: FastAPI, compute_client: AsyncClient, vm: dict, base_params: dict) -> None:
+ async def test_docker_reload(self, app: FastAPI, compute_client: AsyncClient, vm: 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)
- assert response.status_code == status.HTTP_201_CREATED
+ 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"]))
+ assert mock.called
+ assert response.status_code == status.HTTP_204_NO_CONTENT
- 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)
- assert response.status_code == status.HTTP_201_CREATED
+
+ 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"]))
+ 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"]))
+ 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"]))
+ 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"}
+
+ 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"
+
+
+ async def test_docker_update_nio(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_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
+
+ 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
+
+
+ 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")
+ 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:
+
+ params = {
+ "name": "test",
+ "console": free_console_port,
+ "start_command": "yes",
+ "environment": "GNS3=1\nGNS4=0",
+ "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)
+
+ assert response.status_code == 200
+ assert mock.called
+ assert response.json()["name"] == "test"
+ assert response.json()["console"] == free_console_port
+ assert response.json()["start_command"] == "yes"
+ assert response.json()["environment"] == "GNS3=1\nGNS4=0"
+ assert response.json()["extra_hosts"] == "test:127.0.0.1"
+
+
+ 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")
+
+ 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:
+ params = {"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"}
+ 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_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")
+
+ 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:
+ response = await compute_client.post(url)
+ 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:
+
+ # 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)
+ 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)
+ assert response.status_code == status.HTTP_201_CREATED
diff --git a/tests/api/routes/compute/test_dynamips_nodes.py b/tests/api/routes/compute/test_dynamips_nodes.py
index 19bc691c..840d2b3d 100644
--- a/tests/api/routes/compute/test_dynamips_nodes.py
+++ b/tests/api/routes/compute/test_dynamips_nodes.py
@@ -26,196 +26,208 @@ from httpx import AsyncClient
pytestmark = pytest.mark.asyncio
-# @pytest.yield_fixture(scope="module")
-# async def vm(compute_api, compute_project, fake_image):
-#
-# dynamips_path = "/fake/dynamips"
-# params = {
-# "name": "My router",
-# "platform": "c3745",
-# "image": fake_image,
-# "ram": 128
-# }
-# with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.create", return_value=True) as mock:
-# response = await compute_api.post("/projects/{project_id}/dynamips/nodes".format(project_id=compute_project.id), params)
-# assert mock.called
-# assert response.status == 201
-#
-# #with asyncio_patch("gns3server.compute.dynamips.Dynamips.find_dynamips", return_value=dynamips_path):
-# # yield response.json
+
+class TestDynamipsNodesRoutes:
+
+ # @pytest.yield_fixture(scope="module")
+ # async def vm(compute_api, compute_project, fake_image):
+ #
+ # dynamips_path = "/fake/dynamips"
+ # params = {
+ # "name": "My router",
+ # "platform": "c3745",
+ # "image": fake_image,
+ # "ram": 128
+ # }
+ # with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.create", return_value=True) as mock:
+ # response = await compute_api.post("/projects/{project_id}/dynamips/nodes".format(project_id=compute_project.id), params)
+ # assert mock.called
+ # assert response.status == 201
+ #
+ # #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 = {
-# "name": "My router",
-# "platform": "c3745",
-# "image": os.path.basename(fake_image),
-# "ram": 128
-# }
-#
-# print(fake_image)
-#
-# with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.create", return_value=True):
-# response = await compute_api.post("/projects/{project_id}/dynamips/nodes".format(project_id=compute_project.id), params)
-# assert response.status == 201
-# assert response.json["name"] == "My router"
-# assert response.json["project_id"] == compute_project.id
-# assert response.json["dynamips_id"]
+ # async def test_dynamips_vm_create(compute_api, compute_project, fake_image):
+ #
+ # params = {
+ # "name": "My router",
+ # "platform": "c3745",
+ # "image": os.path.basename(fake_image),
+ # "ram": 128
+ # }
+ #
+ # print(fake_image)
+ #
+ # with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.create", return_value=True):
+ # response = await compute_api.post("/projects/{project_id}/dynamips/nodes".format(project_id=compute_project.id), params)
+ # assert response.status == 201
+ # assert response.json["name"] == "My router"
+ # 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
-# assert response.route == "/projects/{project_id}/dynamips/nodes/{node_id}"
-# assert response.json["name"] == "My router"
-# assert response.json["project_id"] == project.id
-#
-#
-# def test_dynamips_vm_start(compute_api, vm):
-# with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.start", return_value=True) as mock:
-# response = compute_api.post("/projects/{project_id}/dynamips/nodes/{node_id}/start".format(project_id=vm["project_id"], node_id=vm["node_id"]))
-# assert mock.called
-# assert response.status == 204
-#
-#
-# def test_dynamips_vm_stop(compute_api, vm):
-# with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.stop", return_value=True) as mock:
-# response = compute_api.post("/projects/{project_id}/dynamips/nodes/{node_id}/stop".format(project_id=vm["project_id"], node_id=vm["node_id"]))
-# assert mock.called
-# assert response.status == 204
-#
-#
-# def test_dynamips_vm_suspend(compute_api, vm):
-# with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.suspend", return_value=True) as mock:
-# response = compute_api.post("/projects/{project_id}/dynamips/nodes/{node_id}/suspend".format(project_id=vm["project_id"], node_id=vm["node_id"]))
-# assert mock.called
-# assert response.status == 204
-#
-#
-# def test_dynamips_vm_resume(compute_api, vm):
-# with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.resume", return_value=True) as mock:
-# response = compute_api.post("/projects/{project_id}/dynamips/nodes/{node_id}/resume".format(project_id=vm["project_id"], node_id=vm["node_id"]))
-# assert mock.called
-# assert response.status == 204
+ # 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
+ # assert response.route == "/projects/{project_id}/dynamips/nodes/{node_id}"
+ # assert response.json["name"] == "My router"
+ # assert response.json["project_id"] == project.id
+ #
+ #
+ # def test_dynamips_vm_start(compute_api, vm):
+ # with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.start", return_value=True) as mock:
+ # response = compute_api.post("/projects/{project_id}/dynamips/nodes/{node_id}/start".format(project_id=vm["project_id"], node_id=vm["node_id"]))
+ # assert mock.called
+ # assert response.status == 204
+ #
+ #
+ # def test_dynamips_vm_stop(compute_api, vm):
+ # with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.stop", return_value=True) as mock:
+ # response = compute_api.post("/projects/{project_id}/dynamips/nodes/{node_id}/stop".format(project_id=vm["project_id"], node_id=vm["node_id"]))
+ # assert mock.called
+ # assert response.status == 204
+ #
+ #
+ # def test_dynamips_vm_suspend(compute_api, vm):
+ # with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.suspend", return_value=True) as mock:
+ # response = compute_api.post("/projects/{project_id}/dynamips/nodes/{node_id}/suspend".format(project_id=vm["project_id"], node_id=vm["node_id"]))
+ # assert mock.called
+ # assert response.status == 204
+ #
+ #
+ # def test_dynamips_vm_resume(compute_api, vm):
+ # with asyncio_patch("gns3server.compute.dynamips.nodes.router.Router.resume", return_value=True) as mock:
+ # response = compute_api.post("/projects/{project_id}/dynamips/nodes/{node_id}/resume".format(project_id=vm["project_id"], node_id=vm["node_id"]))
+ # 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:
-# response = compute_api.post("/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/0/nio".format(project_id=vm["project_id"],
-# node_id=vm["node_id"]), {"type": "nio_udp",
-# "lport": 4242,
-# "rport": 4343,
-# "rhost": "127.0.0.1"},
-# example=True)
-#
-# assert mock.called
-# args, kwgars = mock.call_args
-# assert args[0] == 0
-#
-# assert response.status == 201
-# assert response.route == "/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/{adapter_id:\d+}/nio"
-# assert response.json["type"] == "nio_udp"
-#
-#
-# def test_vbox_delete_nio(compute_api, vm):
-#
-# with asyncio_patch('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_remove_nio_binding') as mock:
-# response = compute_api.delete("/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), example=True)
-#
-# assert mock.called
-# args, kwgars = mock.call_args
-# assert args[0] == 0
-#
-# assert response.status == 204
-# assert response.route == "/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/{adapter_id:\d+}/nio"
-#
-#
-# def test_vbox_update(compute_api, vm, free_console_port):
-# response = compute_api.put("/projects/{project_id}/virtualbox/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), {"name": "test",
-# "console": free_console_port})
-# assert response.status == 200
-# assert response.json["name"] == "test"
-# assert response.json["console"] == free_console_port
+ # def test_vbox_nio_create_udp(compute_api, vm):
+ #
+ # with asyncio_patch('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_add_nio_binding') as mock:
+ # response = compute_api.post("/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/0/nio".format(project_id=vm["project_id"],
+ # node_id=vm["node_id"]), {"type": "nio_udp",
+ # "lport": 4242,
+ # "rport": 4343,
+ # "rhost": "127.0.0.1"},
+ # example=True)
+ #
+ # assert mock.called
+ # args, kwgars = mock.call_args
+ # assert args[0] == 0
+ #
+ # assert response.status == 201
+ # assert response.route == "/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/{adapter_id:\d+}/nio"
+ # assert response.json["type"] == "nio_udp"
+ #
+ #
+ # def test_vbox_delete_nio(compute_api, vm):
+ #
+ # with asyncio_patch('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_remove_nio_binding') as mock:
+ # response = compute_api.delete("/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), example=True)
+ #
+ # assert mock.called
+ # args, kwgars = mock.call_args
+ # assert args[0] == 0
+ #
+ # assert response.status == 204
+ # assert response.route == "/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/{adapter_id:\d+}/nio"
+ #
+ #
+ # def test_vbox_update(compute_api, vm, free_console_port):
+ # response = compute_api.put("/projects/{project_id}/virtualbox/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), {"name": "test",
+ # "console": free_console_port})
+ # assert response.status == 200
+ # assert response.json["name"] == "test"
+ # assert response.json["console"] == free_console_port
-@pytest.fixture
-def fake_image(tmpdir) -> str:
- """Create a fake Dynamips image on disk"""
+ @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')
- os.chmod(path, stat.S_IREAD)
- return path
+ path = str(tmpdir / "7200.bin")
+ with open(path, "wb+") as f:
+ f.write(b'\x7fELF\x01\x02\x01')
+ os.chmod(path, stat.S_IREAD)
+ return path
-@pytest.fixture
-def fake_file(tmpdir) -> str:
- """Create a fake file disk"""
+ @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')
- os.chmod(path, stat.S_IREAD)
- return path
+ path = str(tmpdir / "7200.txt")
+ with open(path, "w+") as f:
+ f.write('1')
+ os.chmod(path, stat.S_IREAD)
+ return path
-async def test_images(app: FastAPI, compute_client: AsyncClient, tmpdir, fake_image: str, fake_file: str) -> None:
+ async def test_images(
+ 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"}]
+ 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"}]
-async def test_upload_image(app: FastAPI, compute_client: AsyncClient, images_dir: str) -> None:
+ 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")
- assert response.status_code == status.HTTP_204_NO_CONTENT
+ 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:
- assert f.read() == "TEST"
+ with open(os.path.join(images_dir, "IOS", "test2")) as f:
+ assert f.read() == "TEST"
- with open(os.path.join(images_dir, "IOS", "test2.md5sum")) as f:
- checksum = f.read()
- assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
+ with open(os.path.join(images_dir, "IOS", "test2.md5sum")) as f:
+ checksum = f.read()
+ assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
-async def test_upload_image_forbidden_location(app: FastAPI, compute_client: AsyncClient) -> None:
+ 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")
- assert response.status_code == status.HTTP_403_FORBIDDEN
+ file_path = "%2e%2e/hello"
+ 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(app: FastAPI, compute_client: AsyncClient, images_dir: str) -> None:
+ 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")
- assert response.status_code == status.HTTP_204_NO_CONTENT
+ 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
+ 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(app: FastAPI, compute_client: AsyncClient, tmpdir) -> None:
+ 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
+ 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(app: FastAPI, compute_client: AsyncClient, images_dir: str) -> None:
+ @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:
- os.makedirs(os.path.join(images_dir, "IOS"), exist_ok=True)
- with open(os.path.join(images_dir, "IOS", "test2.tmp"), "w+") as f:
- f.write("")
- os.chmod(os.path.join(images_dir, "IOS", "test2.tmp"), 0)
+ os.makedirs(os.path.join(images_dir, "IOS"), exist_ok=True)
+ with open(os.path.join(images_dir, "IOS", "test2.tmp"), "w+") as f:
+ 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")
- assert response.status_code == status.HTTP_409_CONFLICT
+ 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
diff --git a/tests/api/routes/compute/test_ethernet_switch_nodes.py b/tests/api/routes/compute/test_ethernet_switch_nodes.py
index 67390685..f0dc400b 100644
--- a/tests/api/routes/compute/test_ethernet_switch_nodes.py
+++ b/tests/api/routes/compute/test_ethernet_switch_nodes.py
@@ -28,427 +28,474 @@ from gns3server.compute.project import Project
pytestmark = pytest.mark.asyncio
-@pytest_asyncio.fixture
-async def ethernet_switch(app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> dict:
+class TestEthernetSwitchNodesRoutes:
- params = {"name": "Ethernet Switch"}
- with asyncio_patch("gns3server.compute.dynamips.nodes.ethernet_switch.EthernetSwitch.create") as mock:
- response = await compute_client.post(
- app.url_path_for("compute:create_ethernet_switch", project_id=compute_project.id),
- json=params
+ @pytest_asyncio.fixture
+ async def ethernet_switch(self, app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> dict:
+
+ params = {"name": "Ethernet Switch"}
+ with asyncio_patch("gns3server.compute.dynamips.nodes.ethernet_switch.EthernetSwitch.create") as mock:
+ response = await compute_client.post(
+ app.url_path_for("compute:create_ethernet_switch", project_id=compute_project.id),
+ json=params
+ )
+ assert mock.called
+ assert response.status_code == status.HTTP_201_CREATED
+
+ json_response = response.json()
+ node = compute_project.get_node(json_response["node_id"])
+ node._hypervisor = AsyncioMagicMock()
+ node._hypervisor.send = AsyncioMagicMock()
+ node._hypervisor.version = "0.2.16"
+ return json_response
+
+
+ async def test_ethernet_switch_create(
+ self, app: FastAPI,
+ compute_client: AsyncClient,
+ compute_project: Project
+ ) -> None:
+
+ params = {"name": "Ethernet Switch 1"}
+ with asyncio_patch("gns3server.compute.dynamips.nodes.ethernet_switch.EthernetSwitch.create") as mock:
+ response = await compute_client.post(
+ app.url_path_for("compute:create_ethernet_switch", project_id=compute_project.id),
+ json=params
+ )
+ assert mock.called
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["name"] == "Ethernet Switch 1"
+ assert response.json()["project_id"] == compute_project.id
+
+
+ async def test_ethernet_switch_get(
+ 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"]
+ )
)
- assert mock.called
- assert response.status_code == status.HTTP_201_CREATED
-
- json_response = response.json()
- node = compute_project.get_node(json_response["node_id"])
- node._hypervisor = AsyncioMagicMock()
- node._hypervisor.send = AsyncioMagicMock()
- node._hypervisor.version = "0.2.16"
- return json_response
-
-
-async def test_ethernet_switch_create(app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
-
- params = {"name": "Ethernet Switch 1"}
- with asyncio_patch("gns3server.compute.dynamips.nodes.ethernet_switch.EthernetSwitch.create") as mock:
- response = await compute_client.post(
- app.url_path_for("compute:create_ethernet_switch", project_id=compute_project.id),
- json=params
- )
- assert mock.called
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["name"] == "Ethernet Switch 1"
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["name"] == "Ethernet Switch"
assert response.json()["project_id"] == compute_project.id
+ assert response.json()["status"] == "started"
-async def test_ethernet_switch_get(app: FastAPI, compute_client: AsyncClient, compute_project: Project, ethernet_switch: dict) -> None:
+ async def test_ethernet_switch_duplicate(
+ 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"]
- )
- )
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["name"] == "Ethernet Switch"
- assert response.json()["project_id"] == compute_project.id
- assert response.json()["status"] == "started"
+ # create destination switch first
+ params = {"name": "Ethernet Switch 2"}
+ with asyncio_patch("gns3server.compute.dynamips.nodes.ethernet_switch.EthernetSwitch.create") as mock:
+ response = await compute_client.post(
+ app.url_path_for(
+ "compute:create_ethernet_switch",
+ project_id=compute_project.id),
+ json=params
+ )
+ assert mock.called
+ assert response.status_code == status.HTTP_201_CREATED
-
-async def test_ethernet_switch_duplicate(
- app: FastAPI,
- compute_client: AsyncClient,
- compute_project: Project,
- ethernet_switch: dict
-) -> None:
-
- # create destination switch first
- params = {"name": "Ethernet Switch 2"}
- with asyncio_patch("gns3server.compute.dynamips.nodes.ethernet_switch.EthernetSwitch.create") as mock:
+ params = {"destination_node_id": response.json()["node_id"]}
response = await compute_client.post(
app.url_path_for(
- "compute:create_ethernet_switch",
- project_id=compute_project.id),
- json=params
+ "compute:duplicate_ethernet_switch",
+ project_id=ethernet_switch["project_id"],
+ node_id=ethernet_switch["node_id"]), json=params
)
- assert mock.called
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_ethernet_switch",
- project_id=ethernet_switch["project_id"],
- node_id=ethernet_switch["node_id"]), json=params
+
+ async def test_ethernet_switch_update(
+ self,
+ app: FastAPI,
+ compute_client: AsyncClient,
+ compute_project: Project,
+ ethernet_switch: dict
+ ) -> None:
+
+ params = {
+ "name": "test",
+ "console_type": "telnet"
+ }
+
+ 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=params
+ )
+
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["name"] == "test"
+ node = compute_project.get_node(ethernet_switch["node_id"])
+ node._hypervisor.send.assert_called_with("ethsw rename \"Ethernet Switch\" \"test\"")
+
+
+ async def test_ethernet_switch_update_ports(
+ self,
+ app: FastAPI,
+ compute_client: AsyncClient,
+ compute_project: Project,
+ ethernet_switch: dict
+ ) -> None:
+
+ port_params = {
+ "ports_mapping": [
+ {
+ "name": "Ethernet0",
+ "port_number": 0,
+ "type": "qinq",
+ "vlan": 1
+ },
+ {
+ "name": "Ethernet1",
+ "port_number": 1,
+ "type": "qinq",
+ "vlan": 2,
+ "ethertype": "0x88A8"
+ },
+ {
+ "name": "Ethernet2",
+ "port_number": 2,
+ "type": "dot1q",
+ "vlan": 3,
+ },
+ {
+ "name": "Ethernet3",
+ "port_number": 3,
+ "type": "access",
+ "vlan": 4,
+ }
+ ],
+ }
+
+ 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=port_params
+ )
+ assert response.status_code == status.HTTP_200_OK
+
+ nio_params = {
+ "type": "nio_udp",
+ "lport": 4242,
+ "rport": 4343,
+ "rhost": "127.0.0.1"
+ }
+
+ for port_mapping in port_params["ports_mapping"]:
+ port_number = port_mapping["port_number"]
+ vlan = port_mapping["vlan"]
+ port_type = port_mapping["type"]
+ ethertype = port_mapping.get("ethertype", "")
+ url = app.url_path_for(
+ "compute:create_ethernet_switch_nio",
+ project_id=ethernet_switch["project_id"],
+ node_id=ethernet_switch["node_id"],
+ adapter_number="0",
+ port_number=f"{port_number}"
+ )
+ await compute_client.post(url, json=nio_params)
+
+ node = compute_project.get_node(ethernet_switch["node_id"])
+ nio = node.get_nio(port_number)
+ calls = [
+ call.send(f'nio create_udp {nio.name} 4242 127.0.0.1 4343'),
+ call.send(f'ethsw add_nio "Ethernet Switch" {nio.name}'),
+ call.send(f'ethsw set_{port_type}_port "Ethernet Switch" {nio.name} {vlan} {ethertype}'.strip())
+ ]
+ node._hypervisor.send.assert_has_calls(calls)
+ node._hypervisor.send.reset_mock()
+
+
+ @pytest.mark.parametrize(
+ "ports_settings",
+ (
+ (
+ {
+ "name": "Ethernet0",
+ "port_number": 0,
+ "type": "dot42q", # invalid port type
+ "vlan": 1,
+ }
+ ),
+ (
+ {
+ "name": "Ethernet0",
+ "port_number": 0,
+ "type": "access", # missing vlan field
+ }
+ ),
+ (
+ {
+ "name": "Ethernet0",
+ "port_number": 0,
+ "type": "dot1q",
+ "vlan": 1,
+ "ethertype": "0x88A8" # EtherType is only for QinQ
+ }
+ ),
+ (
+ {
+ "name": "Ethernet0",
+ "port_number": 0,
+ "type": "qinq",
+ "vlan": 1,
+ "ethertype": "0x4242" # not a valid EtherType
+ }
+ ),
+ (
+ {
+ "name": "Ethernet0",
+ "port_number": 0,
+ "type": "access",
+ "vlan": 0, # minimum vlan number is 1
+ }
+ ),
+ (
+ {
+ "name": "Ethernet0",
+ "port_number": 0,
+ "type": "access",
+ "vlan": 4242, # maximum vlan number is 4094
+ }
+ ),
+ )
)
- assert response.status_code == status.HTTP_201_CREATED
+ async def test_ethernet_switch_update_ports_invalid(
+ self,
+ app: FastAPI,
+ compute_client: AsyncClient,
+ ethernet_switch: dict,
+ ports_settings: dict,
+ ) -> None:
+
+ port_params = {
+ "ports_mapping": [ports_settings]
+ }
+
+ 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=port_params
+ )
+ assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
-async def test_ethernet_switch_update(
- app: FastAPI,
- compute_client: AsyncClient,
- compute_project: Project,
- ethernet_switch: dict
-) -> None:
+ async def test_ethernet_switch_delete(
+ self, app: FastAPI,
+ compute_client: AsyncClient,
+ ethernet_switch: dict
+ ) -> None:
- params = {
- "name": "test",
- "console_type": "telnet"
- }
-
- 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=params
- )
-
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["name"] == "test"
- node = compute_project.get_node(ethernet_switch["node_id"])
- node._hypervisor.send.assert_called_with("ethsw rename \"Ethernet Switch\" \"test\"")
+ 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"]
+ )
+ )
+ assert response.status_code == status.HTTP_204_NO_CONTENT
-async def test_ethernet_switch_update_ports(
- app: FastAPI,
- compute_client: AsyncClient,
- compute_project: Project,
- ethernet_switch: dict
-) -> None:
+ async def test_ethernet_switch_start(
+ self, app: FastAPI,
+ compute_client: AsyncClient,
+ ethernet_switch: dict
+ ) -> None:
- port_params = {
- "ports_mapping": [
- {
- "name": "Ethernet0",
- "port_number": 0,
- "type": "qinq",
- "vlan": 1
- },
- {
- "name": "Ethernet1",
- "port_number": 1,
- "type": "qinq",
- "vlan": 2,
- "ethertype": "0x88A8"
- },
- {
- "name": "Ethernet2",
- "port_number": 2,
- "type": "dot1q",
- "vlan": 3,
- },
- {
- "name": "Ethernet3",
- "port_number": 3,
- "type": "access",
- "vlan": 4,
- }
- ],
- }
+ 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"])
+ )
+ assert response.status_code == status.HTTP_204_NO_CONTENT
- 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=port_params
- )
- assert response.status_code == status.HTTP_200_OK
- nio_params = {
- "type": "nio_udp",
- "lport": 4242,
- "rport": 4343,
- "rhost": "127.0.0.1"
- }
+ async def test_ethernet_switch_stop(
+ self, app: FastAPI,
+ compute_client: AsyncClient,
+ ethernet_switch: dict
+ ) -> None:
+
+ response = await compute_client.post(
+ app.url_path_for(
+ "compute:stop_ethernet_switch",
+ project_id=ethernet_switch["project_id"],
+ node_id=ethernet_switch["node_id"])
+ )
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ 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"])
+ )
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ 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"])
+ )
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_ethernet_switch_create_udp(
+ self,
+ app: FastAPI,
+ compute_client: AsyncClient,
+ compute_project: Project,
+ ethernet_switch: dict
+ ) -> None:
+
+ params = {
+ "type": "nio_udp",
+ "lport": 4242,
+ "rport": 4343,
+ "rhost": "127.0.0.1"
+ }
- for port_mapping in port_params["ports_mapping"]:
- port_number = port_mapping["port_number"]
- vlan = port_mapping["vlan"]
- port_type = port_mapping["type"]
- ethertype = port_mapping.get("ethertype", "")
url = app.url_path_for(
"compute:create_ethernet_switch_nio",
project_id=ethernet_switch["project_id"],
node_id=ethernet_switch["node_id"],
adapter_number="0",
- port_number=f"{port_number}"
+ port_number="0"
)
- await compute_client.post(url, json=nio_params)
+ response = await compute_client.post(url, json=params)
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["type"] == "nio_udp"
node = compute_project.get_node(ethernet_switch["node_id"])
- nio = node.get_nio(port_number)
+ nio = node.get_nio(0)
calls = [
call.send(f'nio create_udp {nio.name} 4242 127.0.0.1 4343'),
call.send(f'ethsw add_nio "Ethernet Switch" {nio.name}'),
- call.send(f'ethsw set_{port_type}_port "Ethernet Switch" {nio.name} {vlan} {ethertype}'.strip())
+ call.send(f'ethsw set_access_port "Ethernet Switch" {nio.name} 1')
]
node._hypervisor.send.assert_has_calls(calls)
- node._hypervisor.send.reset_mock()
-@pytest.mark.parametrize(
- "ports_settings",
- (
- (
- {
- "name": "Ethernet0",
- "port_number": 0,
- "type": "dot42q", # invalid port type
- "vlan": 1,
- }
- ),
- (
- {
- "name": "Ethernet0",
- "port_number": 0,
- "type": "access", # missing vlan field
- }
- ),
- (
- {
- "name": "Ethernet0",
- "port_number": 0,
- "type": "dot1q",
- "vlan": 1,
- "ethertype": "0x88A8" # EtherType is only for QinQ
- }
- ),
- (
- {
- "name": "Ethernet0",
- "port_number": 0,
- "type": "qinq",
- "vlan": 1,
- "ethertype": "0x4242" # not a valid EtherType
- }
- ),
- (
- {
- "name": "Ethernet0",
- "port_number": 0,
- "type": "access",
- "vlan": 0, # minimum vlan number is 1
- }
- ),
- (
- {
- "name": "Ethernet0",
- "port_number": 0,
- "type": "access",
- "vlan": 4242, # maximum vlan number is 4094
- }
- ),
- )
-)
-async def test_ethernet_switch_update_ports_invalid(
- app: FastAPI,
- compute_client: AsyncClient,
- ethernet_switch: dict,
- ports_settings: dict,
-) -> None:
+ async def test_ethernet_switch_delete_nio(
+ self,
+ app: FastAPI,
+ compute_client: AsyncClient,
+ compute_project: Project,
+ ethernet_switch: dict
+ ) -> None:
- port_params = {
- "ports_mapping": [ports_settings]
- }
+ params = {
+ "type": "nio_udp",
+ "lport": 4242,
+ "rport": 4343,
+ "rhost": "127.0.0.1"
+ }
- response = await compute_client.put(
- app.url_path_for(
- "compute:update_ethernet_switch",
+ url = app.url_path_for(
+ "compute:create_ethernet_switch_nio",
project_id=ethernet_switch["project_id"],
- node_id=ethernet_switch["node_id"]),
- json=port_params
- )
- assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
-
-
-async def test_ethernet_switch_delete(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"],
+ adapter_number="0",
+ port_number="0"
)
- )
- assert response.status_code == status.HTTP_204_NO_CONTENT
+ await compute_client.post(url, json=params)
+ node = compute_project.get_node(ethernet_switch["node_id"])
+ node._hypervisor.send.reset_mock()
+ nio = node.get_nio(0)
-async def test_ethernet_switch_start(app: FastAPI, compute_client: AsyncClient, ethernet_switch: dict) -> None:
-
- response = await compute_client.post(
- app.url_path_for(
- "compute:start_ethernet_switch",
+ url = app.url_path_for(
+ "compute:delete_ethernet_switch_nio",
project_id=ethernet_switch["project_id"],
- node_id=ethernet_switch["node_id"])
- )
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_ethernet_switch_stop(app: FastAPI, compute_client: AsyncClient, ethernet_switch: dict) -> None:
-
- response = await compute_client.post(
- app.url_path_for(
- "compute:stop_ethernet_switch",
- project_id=ethernet_switch["project_id"],
- node_id=ethernet_switch["node_id"])
- )
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_ethernet_switch_suspend(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"])
- )
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_ethernet_switch_reload(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"])
- )
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_ethernet_switch_create_udp(
- app: FastAPI,
- compute_client: AsyncClient,
- compute_project: Project,
- ethernet_switch: dict
-) -> None:
-
- params = {
- "type": "nio_udp",
- "lport": 4242,
- "rport": 4343,
- "rhost": "127.0.0.1"
- }
-
- url = app.url_path_for(
- "compute:create_ethernet_switch_nio",
- 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_201_CREATED
- assert response.json()["type"] == "nio_udp"
-
- node = compute_project.get_node(ethernet_switch["node_id"])
- nio = node.get_nio(0)
- calls = [
- call.send(f'nio create_udp {nio.name} 4242 127.0.0.1 4343'),
- call.send(f'ethsw add_nio "Ethernet Switch" {nio.name}'),
- call.send(f'ethsw set_access_port "Ethernet Switch" {nio.name} 1')
- ]
- node._hypervisor.send.assert_has_calls(calls)
-
-
-async def test_ethernet_switch_delete_nio(
- app: FastAPI,
- compute_client: AsyncClient,
- compute_project: Project,
- ethernet_switch: dict
-) -> None:
-
- params = {
- "type": "nio_udp",
- "lport": 4242,
- "rport": 4343,
- "rhost": "127.0.0.1"
- }
-
- url = app.url_path_for(
- "compute:create_ethernet_switch_nio",
- project_id=ethernet_switch["project_id"],
- node_id=ethernet_switch["node_id"],
- adapter_number="0",
- port_number="0"
- )
- await compute_client.post(url, json=params)
-
- node = compute_project.get_node(ethernet_switch["node_id"])
- node._hypervisor.send.reset_mock()
- nio = node.get_nio(0)
-
- url = app.url_path_for(
- "compute:delete_ethernet_switch_nio",
- project_id=ethernet_switch["project_id"],
- node_id=ethernet_switch["node_id"],
- adapter_number="0",
- port_number="0"
- )
- response = await compute_client.delete(url)
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
- calls = [
- call(f'ethsw remove_nio "Ethernet Switch" {nio.name}'),
- call(f'nio delete {nio.name}')
- ]
- node._hypervisor.send.assert_has_calls(calls)
-
-
-async def test_ethernet_switch_start_capture(app: FastAPI, compute_client: AsyncClient, ethernet_switch: dict) -> None:
-
- 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")
-
- with asyncio_patch("gns3server.compute.dynamips.nodes.ethernet_switch.EthernetSwitch.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_ethernet_switch_stop_capture(app: FastAPI, compute_client: AsyncClient, ethernet_switch: dict) -> None:
-
- url = 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")
-
- with asyncio_patch("gns3server.compute.dynamips.nodes.ethernet_switch.EthernetSwitch.stop_capture") as mock:
- response = await compute_client.post(url)
+ node_id=ethernet_switch["node_id"],
+ adapter_number="0",
+ port_number="0"
+ )
+ response = await compute_client.delete(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
- assert mock.called
+
+ calls = [
+ call(f'ethsw remove_nio "Ethernet Switch" {nio.name}'),
+ call(f'nio delete {nio.name}')
+ ]
+ node._hypervisor.send.assert_has_calls(calls)
+
+
+ async def test_ethernet_switch_start_capture(
+ self,
+ app: FastAPI,
+ compute_client: AsyncClient,
+ ethernet_switch: dict
+ ) -> None:
+
+ 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")
+
+ with asyncio_patch("gns3server.compute.dynamips.nodes.ethernet_switch.EthernetSwitch.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_ethernet_switch_stop_capture(
+ self,
+ app: FastAPI,
+ compute_client: AsyncClient,
+ ethernet_switch: dict
+ ) -> None:
+
+ url = 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")
+
+ with asyncio_patch("gns3server.compute.dynamips.nodes.ethernet_switch.EthernetSwitch.stop_capture") as mock:
+ response = await compute_client.post(url)
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+ assert mock.called
diff --git a/tests/api/routes/compute/test_iou_nodes.py b/tests/api/routes/compute/test_iou_nodes.py
index d894ac30..8343ba33 100644
--- a/tests/api/routes/compute/test_iou_nodes.py
+++ b/tests/api/routes/compute/test_iou_nodes.py
@@ -28,452 +28,502 @@ from unittest.mock import patch
from gns3server.compute.project import Project
-pytestmark = [pytest.mark.asyncio]
+pytestmark = pytest.mark.asyncio
-@pytest.fixture
-def fake_iou_bin(images_dir) -> str:
- """Create a fake IOU image on disk"""
+class TestIOUNodesRoutes:
- path = os.path.join(images_dir, "IOU", "iou.bin")
- with open(path, "w+") as f:
- f.write('\x7fELF\x01\x01\x01')
- os.chmod(path, stat.S_IREAD | stat.S_IEXEC)
- return path
+ @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')
+ os.chmod(path, stat.S_IREAD | stat.S_IEXEC)
+ return path
-@pytest.fixture
-def base_params(tmpdir, fake_iou_bin) -> dict:
- """Return standard parameters"""
+ @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"}
+ return {"application_id": 42, "name": "IOU-TEST-1", "path": "iou.bin"}
-@pytest_asyncio.fixture
-async def vm(app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict) -> dict:
+ @pytest_asyncio.fixture
+ 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)
- assert response.status_code == status.HTTP_201_CREATED
- return response.json()
+ 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(compute_project: Project, vm: dict) -> str:
+ 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")
+ 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(app: FastAPI, compute_client: AsyncClient, compute_project: Project, base_params: dict) -> None:
+ async def test_iou_create(
+ 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)
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["name"] == "IOU-TEST-1"
- assert response.json()["project_id"] == compute_project.id
- assert response.json()["serial_adapters"] == 2
- assert response.json()["ethernet_adapters"] == 2
- assert response.json()["ram"] == 256
- assert response.json()["nvram"] == 128
- assert response.json()["l1_keepalives"] is False
+ 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
+ assert response.json()["serial_adapters"] == 2
+ assert response.json()["ethernet_adapters"] == 2
+ assert response.json()["ram"] == 256
+ assert response.json()["nvram"] == 128
+ assert response.json()["l1_keepalives"] is False
-async def test_iou_create_with_params(app: FastAPI,
- compute_client: AsyncClient,
- compute_project: Project,
- base_params: dict) -> None:
+ async def test_iou_create_with_params(
+ self,
+ app: FastAPI,
+ compute_client: AsyncClient,
+ compute_project: Project,
+ base_params: dict
+ ) -> None:
- params = base_params
- params["ram"] = 1024
- params["nvram"] = 512
- params["serial_adapters"] = 4
- params["ethernet_adapters"] = 0
- params["l1_keepalives"] = True
- params["startup_config_content"] = "hostname test"
- params["use_default_iou_values"] = False
+ params = base_params
+ params["ram"] = 1024
+ params["nvram"] = 512
+ params["serial_adapters"] = 4
+ params["ethernet_adapters"] = 0
+ params["l1_keepalives"] = True
+ 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)
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["name"] == "IOU-TEST-1"
- assert response.json()["project_id"] == compute_project.id
- assert response.json()["serial_adapters"] == 4
- assert response.json()["ethernet_adapters"] == 0
- assert response.json()["ram"] == 1024
- assert response.json()["nvram"] == 512
- assert response.json()["l1_keepalives"] is True
- assert response.json()["use_default_iou_values"] is False
+ 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
+ assert response.json()["serial_adapters"] == 4
+ assert response.json()["ethernet_adapters"] == 0
+ assert response.json()["ram"] == 1024
+ assert response.json()["nvram"] == 512
+ assert response.json()["l1_keepalives"] is True
+ assert response.json()["use_default_iou_values"] is False
- with open(startup_config_file(compute_project, response.json())) as f:
- assert f.read() == "hostname test"
+ with open(self.startup_config_file(compute_project, response.json())) as f:
+ assert f.read() == "hostname test"
-@pytest.mark.parametrize(
- "name, status_code",
- (
- ("valid-name", status.HTTP_201_CREATED),
- ("42name", status.HTTP_409_CONFLICT),
- ("name42", status.HTTP_201_CREATED),
- ("-name", status.HTTP_409_CONFLICT),
- ("name%-test", status.HTTP_409_CONFLICT),
- ("x" * 63, status.HTTP_201_CREATED),
- ("x" * 64, status.HTTP_409_CONFLICT),
- ),
-)
-async def test_iou_create_with_invalid_name(
- 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_iou_node", project_id=compute_project.id), json=base_params
+ @pytest.mark.parametrize(
+ "name, status_code",
+ (
+ ("valid-name", status.HTTP_201_CREATED),
+ ("42name", status.HTTP_409_CONFLICT),
+ ("name42", status.HTTP_201_CREATED),
+ ("-name", status.HTTP_409_CONFLICT),
+ ("name%-test", status.HTTP_409_CONFLICT),
+ ("x" * 63, status.HTTP_201_CREATED),
+ ("x" * 64, status.HTTP_409_CONFLICT),
+ ),
)
- assert response.status_code == status_code
+ 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
+ ) -> None:
+
+ base_params["name"] = name
+ 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_code
-async def test_iou_create_startup_config_already_exist(
- 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"""
+ async def test_iou_create_startup_config_already_exist(
+ 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 = startup_config_file(compute_project, {'node_id': node_id})
- with open(startup_config_file_path, 'w+') as f:
- f.write("echo hello")
+ 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:
+ f.write("echo hello")
- params = base_params
- params["node_id"] = node_id
- params["startup_config_content"] = "hostname test"
+ 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)
- assert response.status_code == status.HTTP_201_CREATED
+ 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(startup_config_file(compute_project, response.json())) as f:
- assert f.read() == "echo hello"
+ with open(self.startup_config_file(compute_project, response.json())) as f:
+ assert f.read() == "echo hello"
-async def test_iou_get(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"]))
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["name"] == "IOU-TEST-1"
- assert response.json()["project_id"] == compute_project.id
- assert response.json()["serial_adapters"] == 2
- assert response.json()["ethernet_adapters"] == 2
- assert response.json()["ram"] == 256
- assert response.json()["nvram"] == 128
- assert response.json()["l1_keepalives"] is False
+ 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
+ assert response.json()["serial_adapters"] == 2
+ assert response.json()["ethernet_adapters"] == 2
+ assert response.json()["ram"] == 256
+ assert response.json()["nvram"] == 128
+ assert response.json()["l1_keepalives"] is False
-async def test_iou_start(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ 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={})
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
+ 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={})
+ assert mock.called
+ assert response.status_code == status.HTTP_204_NO_CONTENT
-async def test_iou_start_with_iourc(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ 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)
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
+ 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)
+ assert mock.called
+ assert response.status_code == status.HTTP_204_NO_CONTENT
-async def test_iou_stop(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ 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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
+ 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"]))
+ assert mock.called
+ assert response.status_code == status.HTTP_204_NO_CONTENT
-async def test_iou_reload(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ 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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
+ 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"]))
+ assert mock.called
+ assert response.status_code == status.HTTP_204_NO_CONTENT
-async def test_iou_delete(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ 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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
+ 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"]))
+ assert mock.called
+ assert response.status_code == status.HTTP_204_NO_CONTENT
-async def test_iou_update(app: FastAPI, compute_client: AsyncClient, vm: dict, free_console_port: int) -> None:
+ async def test_iou_update(
+ self, app: FastAPI,
+ compute_client: AsyncClient,
+ vm: dict,
+ free_console_port: int
+ ) -> None:
- params = {
- "name": "test",
- "console": free_console_port,
- "ram": 512,
- "nvram": 2048,
- "ethernet_adapters": 4,
- "serial_adapters": 0,
- "l1_keepalives": True,
- "use_default_iou_values": True,
- }
+ params = {
+ "name": "test",
+ "console": free_console_port,
+ "ram": 512,
+ "nvram": 2048,
+ "ethernet_adapters": 4,
+ "serial_adapters": 0,
+ "l1_keepalives": True,
+ "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)
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["name"] == "test"
- assert response.json()["console"] == free_console_port
- assert response.json()["ethernet_adapters"] == 4
- assert response.json()["serial_adapters"] == 0
- assert response.json()["ram"] == 512
- assert response.json()["nvram"] == 2048
- assert response.json()["l1_keepalives"] is True
- assert response.json()["use_default_iou_values"] is 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)
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["name"] == "test"
+ assert response.json()["console"] == free_console_port
+ assert response.json()["ethernet_adapters"] == 4
+ assert response.json()["serial_adapters"] == 0
+ assert response.json()["ram"] == 512
+ assert response.json()["nvram"] == 2048
+ assert response.json()["l1_keepalives"] is True
+ assert response.json()["use_default_iou_values"] is True
-async def test_iou_nio_create_udp(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ 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")
- 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(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_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)
- params["filters"] = {}
-
- 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"
-
-
-async def test_iou_nio_create_ethernet(app: FastAPI, compute_client: AsyncClient, vm: dict, ethernet_device: str) -> None:
-
- 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")
-
- 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(app: FastAPI,
- compute_client: AsyncClient,
- vm: dict,
- ethernet_device: str) -> None:
-
- 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")
- 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(app: FastAPI, compute_client: AsyncClient, vm: dict, ethernet_device: str) -> None:
-
- 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")
- with patch("gns3server.compute.base_manager.BaseManager.has_privileged_access", return_value=True):
+ 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_tap"
+ assert response.json()["type"] == "nio_udp"
-async def test_iou_delete_nio(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ 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"
- }
+ 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)
+ await compute_client.post(url, json=params)
+ params["filters"] = {}
- 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
+ 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"
-async def test_iou_start_capture(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ async def test_iou_nio_create_ethernet(
+ self,
+ app: FastAPI,
+ compute_client: AsyncClient,
+ vm: dict,
+ ethernet_device: str
+ ) -> None:
- params = {
- "capture_file_name": "test.pcap",
- "data_link_type": "DLT_EN10MB"
- }
+ params = {
+ "type": "nio_ethernet",
+ "ethernet_device": ethernet_device
+ }
- 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:create_iou_node_nio",
+ project_id=vm["project_id"],
+ node_id=vm["node_id"],
+ adapter_number="1",
+ 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:
+ 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
+ ) -> None:
+
+ 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")
+ 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
+ ) -> None:
+
+ 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")
+ 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_200_OK
- assert mock.called
- assert "test.pcap" in response.json()["pcap_file_path"]
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["type"] == "nio_tap"
-async def test_iou_stop_capture(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ async def test_iou_delete_nio(
+ 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")
+ params = {
+ "type": "nio_udp",
+ "lport": 4242,
+ "rport": 4343,
+ "rhost": "127.0.0.1"
+ }
- 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:
- response = await compute_client.post(url)
- assert response.status_code == status.HTTP_204_NO_CONTENT
- assert mock.called
+ 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)
-# @pytest.mark.asyncio
-# async def test_iou_pcap(compute_api, vm, compute_project):
-#
-# with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.get_nio"):
-# with asyncio_patch("gns3server.compute.iou.IOU.stream_pcap_file"):
-# 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
+ 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")
-
-async def test_images(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"}]
-
-
-async def test_upload_image(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.delete(url)
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_iou_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_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:
+ 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_upload_image_forbidden_location(app: FastAPI, compute_client: AsyncClient) -> None:
+ async def test_iou_stop_capture(self, app: FastAPI, compute_client: AsyncClient, vm: dict) -> 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")
- assert response.status_code == status.HTTP_403_FORBIDDEN
+ 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:
+ response = await compute_client.post(url)
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+ assert mock.called
-async def test_download_image(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")
- 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
+ # @pytest.mark.asyncio
+ # async def test_iou_pcap(compute_api, vm, compute_project):
+ #
+ # with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.get_nio"):
+ # with asyncio_patch("gns3server.compute.iou.IOU.stream_pcap_file"):
+ # 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_download_image_forbidden(app: FastAPI, compute_client: AsyncClient, tmpdir) -> None:
+ async def test_images(self, app: FastAPI, compute_client: AsyncClient, fake_iou_bin: str) -> 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
+ 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"}]
-async def test_iou_duplicate(app: FastAPI, compute_client: AsyncClient, vm: dict, base_params: dict) -> None:
+ async def test_upload_image(self, app: FastAPI, compute_client: AsyncClient, tmpdir) -> 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)
- assert response.status_code == status.HTTP_201_CREATED
+ 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")
+ assert response.status_code == status.HTTP_204_NO_CONTENT
- params = {"destination_node_id": response.json()["node_id"]}
+ with open(str(tmpdir / "test2")) as f:
+ assert f.read() == "TEST"
- 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
+ with open(str(tmpdir / "test2.md5sum")) as f:
+ 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")
+ 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")
+ 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)
+ 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)
+ assert response.status_code == status.HTTP_201_CREATED
diff --git a/tests/api/routes/compute/test_nat_nodes.py b/tests/api/routes/compute/test_nat_nodes.py
index 0f8b0d69..636a538a 100644
--- a/tests/api/routes/compute/test_nat_nodes.py
+++ b/tests/api/routes/compute/test_nat_nodes.py
@@ -27,167 +27,188 @@ from gns3server.compute.project import Project
pytestmark = pytest.mark.asyncio
-@pytest_asyncio.fixture(scope="function")
-async def vm(app: FastAPI, compute_client: AsyncClient, compute_project: Project, ubridge_path: str, on_gns3vm) -> dict:
+class TestNATNodesRoutes:
- 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"})
- assert response.status_code == status.HTTP_201_CREATED
- return response.json()
+ @pytest_asyncio.fixture
+ async def vm(
+ 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"})
+ assert response.status_code == status.HTTP_201_CREATED
+ return response.json()
-async def test_nat_create(app: FastAPI, compute_client: AsyncClient, compute_project: Project, on_gns3vm) -> None:
+ async def test_nat_create(
+ 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"})
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["name"] == "Nat 1"
- assert response.json()["project_id"] == compute_project.id
+ 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"})
+ 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(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"]))
- 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(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_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(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_nat_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)
- params["filters"] = {}
-
- 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"
-
-
-async def test_nat_delete_nio(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_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")
- 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(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"]))
-
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_nat_update(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"})
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["name"] == "test"
-
-
-async def test_nat_start_capture(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_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)
+ 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 mock.called
- assert "test.pcap" in response.json()["pcap_file_path"]
+ assert response.json()["name"] == "Nat 1"
+ assert response.json()["project_id"] == compute_project.id
+ assert response.json()["status"] == "started"
-async def test_nat_stop_capture(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
+ async def test_nat_nio_create_udp(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")
+ params = {
+ "type": "nio_udp",
+ "lport": 4242,
+ "rport": 4343,
+ "rhost": "127.0.0.1"
+ }
- with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.stop_capture") as mock:
- response = await compute_client.post(url)
+ 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"
+ }
+
+ 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")
+
+ await compute_client.post(url, json=params)
+ params["filters"] = {}
+
+ 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"
+
+
+ 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"
+ }
+
+ 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")
+ 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
- assert mock.called
-# @pytest.mark.asyncio
-# async def test_nat_pcap(compute_api, vm, compute_project):
-#
-# with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.get_nio"):
-# with asyncio_patch("gns3server.compute.builtin.Builtin.stream_pcap_file"):
-# response = await compute_client.get("/projects/{project_id}/nat/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_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"]))
+
+ 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"})
+ 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"
+ }
+
+ 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")
+
+ 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):
+ #
+ # with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.get_nio"):
+ # with asyncio_patch("gns3server.compute.builtin.Builtin.stream_pcap_file"):
+ # response = await compute_client.get("/projects/{project_id}/nat/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
diff --git a/tests/api/routes/compute/test_projects.py b/tests/api/routes/compute/test_projects.py
index 669db760..27474044 100644
--- a/tests/api/routes/compute/test_projects.py
+++ b/tests/api/routes/compute/test_projects.py
@@ -30,173 +30,197 @@ from gns3server.compute.project import Project
pytestmark = pytest.mark.asyncio
-@pytest.fixture
-def base_params(tmpdir) -> dict:
- """Return standard parameters"""
+class TestComputeProjectRoutes:
- params = {
- "name": "test",
- "project_id": str(uuid.uuid4())
- }
- return params
+ @pytest.fixture
+ def base_params(self, tmpdir) -> dict:
+ """Return standard parameters"""
+
+ params = {
+ "name": "test",
+ "project_id": str(uuid.uuid4())
+ }
+ return params
-async def test_create_project_without_dir(app: FastAPI, compute_client: AsyncClient, base_params: dict) -> None:
+ async def test_create_project_without_dir(
+ 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
- assert response.json()["project_id"] == base_params["project_id"]
- assert response.json()["name"] == base_params["name"]
+ response = await compute_client.post(app.url_path_for("compute:create_compute_project"), json=base_params)
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["project_id"] == base_params["project_id"]
+ assert response.json()["name"] == base_params["name"]
-async def test_show_project(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.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"]))
- #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
+ #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(app: FastAPI, compute_client: AsyncClient) -> 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"))
- assert response.status_code == status.HTTP_404_NOT_FOUND
+ 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(app: FastAPI, compute_client: AsyncClient) -> dict:
+ async def test_list_projects(self, app: FastAPI, compute_client: AsyncClient) -> dict:
- ProjectManager.instance()._projects = {}
+ ProjectManager.instance()._projects = {}
- params = {"name": "test", "project_id": "51010203-0405-0607-0809-0a0b0c0d0e0f"}
- response = await compute_client.post(app.url_path_for("compute:create_compute_project"), json=params)
- assert response.status_code == status.HTTP_201_CREATED
- params = {"name": "test", "project_id": "52010203-0405-0607-0809-0a0b0c0d0e0b"}
- response = await compute_client.post(app.url_path_for("compute:create_compute_project"), json=params)
- assert response.status_code == status.HTTP_201_CREATED
+ params = {"name": "test", "project_id": "51010203-0405-0607-0809-0a0b0c0d0e0f"}
+ response = await compute_client.post(app.url_path_for("compute:create_compute_project"), json=params)
+ assert response.status_code == status.HTTP_201_CREATED
+ params = {"name": "test", "project_id": "52010203-0405-0607-0809-0a0b0c0d0e0b"}
+ response = await compute_client.post(app.url_path_for("compute:create_compute_project"), json=params)
+ assert response.status_code == status.HTTP_201_CREATED
- response = await compute_client.get(app.url_path_for("compute:get_compute_projects"))
- assert response.status_code == status.HTTP_200_OK
- assert len(response.json()) == 2
- assert "51010203-0405-0607-0809-0a0b0c0d0e0f" in [p["project_id"] for p in response.json()]
+ response = await compute_client.get(app.url_path_for("compute:get_compute_projects"))
+ assert response.status_code == status.HTTP_200_OK
+ 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(app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
+ 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))
- assert response.status_code == status.HTTP_204_NO_CONTENT
- assert mock.called
+ 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))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+ assert mock.called
-async def test_update_project(app: FastAPI, compute_client: AsyncClient, base_params: dict) -> None:
+ 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
+ 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)
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["variables"] == [{"name": "TEST1", "value": "VAL1"}]
+ 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)
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["variables"] == [{"name": "TEST1", "value": "VAL1"}]
-async def test_delete_project_invalid_uuid(app: FastAPI, compute_client: AsyncClient) -> None:
+ 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())))
- assert response.status_code == status.HTTP_404_NOT_FOUND
+ 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(app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
+ 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))
- assert response.status_code == status.HTTP_204_NO_CONTENT
- assert mock.called
+ 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))
+ 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):
-#
-# ProjectHandler._notifications_listening = {compute_project.id: 2}
-# with asyncio_patch("gns3server.compute.project.Project.close", return_value=True) as mock:
-# response = await compute_client.post("/projects/{project_id}/close".format(project_id=compute_project.id))
-# assert response.status_code == status.HTTP_204_NO_CONTENT
-# assert not mock.called
+ # @pytest.mark.asyncio
+ # async def test_close_project_two_client_connected(compute_api, compute_project):
+ #
+ # ProjectHandler._notifications_listening = {compute_project.id: 2}
+ # with asyncio_patch("gns3server.compute.project.Project.close", return_value=True) as mock:
+ # response = await compute_client.post("/projects/{project_id}/close".format(project_id=compute_project.id))
+ # assert response.status_code == status.HTTP_204_NO_CONTENT
+ # assert not mock.called
-async def test_close_project_invalid_uuid(app: FastAPI, compute_client: AsyncClient) -> None:
+ 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())))
- assert response.status_code == status.HTTP_404_NOT_FOUND
+ 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(app: FastAPI, compute_client: AsyncClient) -> None:
+ async def test_get_file(self, app: FastAPI, compute_client: AsyncClient) -> None:
- project = ProjectManager.instance().create_project(project_id="01010203-0405-0607-0809-0a0b0c0d0e0b")
+ project = ProjectManager.instance().create_project(project_id="01010203-0405-0607-0809-0a0b0c0d0e0b")
- with open(os.path.join(project.path, "hello"), "w+") as f:
- f.write("world")
+ 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"))
- 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="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"))
- 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="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"))
- 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"))
+ assert response.status_code == status.HTTP_404_NOT_FOUND
-async def test_get_file_forbidden_location(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
+ 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
+ )
)
- )
- assert response.status_code == status.HTTP_403_FORBIDDEN
+ assert response.status_code == status.HTTP_403_FORBIDDEN
-async def test_write_file(app: FastAPI, compute_client: AsyncClient, config, tmpdir) -> None:
+ 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")
+ 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")
- assert response.status_code == status.HTTP_204_NO_CONTENT
+ 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"
+ 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"))
- assert response.status_code == status.HTTP_404_NOT_FOUND
+ 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(app: FastAPI, compute_client: AsyncClient, config, tmpdir) -> None:
+ async def test_write_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")
+ 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")
- assert response.status_code == status.HTTP_403_FORBIDDEN
+ 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")
+ assert response.status_code == status.HTTP_403_FORBIDDEN
diff --git a/tests/api/routes/compute/test_qemu_nodes.py b/tests/api/routes/compute/test_qemu_nodes.py
index 61144fe2..464b5ddf 100644
--- a/tests/api/routes/compute/test_qemu_nodes.py
+++ b/tests/api/routes/compute/test_qemu_nodes.py
@@ -31,338 +31,327 @@ from gns3server.compute.project import Project
pytestmark = pytest.mark.asyncio
-@pytest.fixture
-def fake_qemu_bin(monkeypatch, tmpdir) -> str:
+class TestQemuNodesRoutes:
- 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(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(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(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(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
- )
- assert response.status_code == status.HTTP_201_CREATED
- return response.json()
-
-
-async def test_qemu_create(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)
- 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(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)
- 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(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)
- 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()["ram"] == 1024
- assert response.json()["hda_disk_image"] == "linuxè½½.img"
- assert response.json()["hda_disk_image_md5sum"] == "fcea920f7412b5da7be0cf42b8c93759"
-
-
-@pytest.mark.parametrize(
- "name, status_code",
- (
- ("valid-name.com", status.HTTP_201_CREATED),
- ("42name", status.HTTP_201_CREATED),
- ("424242", status.HTTP_409_CONFLICT),
- ("name42", status.HTTP_201_CREATED),
- ("name.424242", status.HTTP_409_CONFLICT),
- ("-name", status.HTTP_409_CONFLICT),
- ("name%-test", status.HTTP_409_CONFLICT),
- ("x" * 63, status.HTTP_201_CREATED),
- ("x" * 64, status.HTTP_409_CONFLICT),
- (("x" * 62 + ".") * 4, status.HTTP_201_CREATED),
- ("xx" + ("x" * 62 + ".") * 4, status.HTTP_409_CONFLICT),
- ),
-)
-async def test_qemu_create_with_invalid_name(
- 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(app: FastAPI,
-# compute_client: AsyncClient,
-# compute_project: Project,
-# base_params: dict,
-# fake_qemu_vm: str) -> None:
-#
-# response = await compute_client.post(
-# app.url_path_for("compute:write_compute_project_file", project_id=compute_project.id, file_path="hello.img"),
-# content=b"world"
-# )
-# assert response.status_code == status.HTTP_204_NO_CONTENT
-# params = base_params
-# params["hda_disk_image"] = "hello.img"
-# 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()["hda_disk_image"] == "hello.img"
-# assert response.json()["hda_disk_image_md5sum"] == "7d793037a0760186574b0282f2f435e7"
-
-
-async def test_qemu_get(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"])
- )
- assert response.status_code == status.HTTP_200_OK
- 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"]
- )
-
-
-async def test_qemu_start(app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
-
- with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.start", return_value=True) as mock:
+ @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
+ ) -> None:
+
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:create_qemu_node", project_id=compute_project.id),
+ json=base_params
)
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_qemu_stop(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(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"])
- )
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_qemu_suspend(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"])
- )
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_qemu_resume(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"])
- )
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_qemu_delete(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"])
- )
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_qemu_update(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"
- }
-
- 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
+ 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
+ ) -> None:
+
+ 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
+ ):
+
+ 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)
+ 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
+ ):
+
+ 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)
+ 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()["ram"] == 1024
+ assert response.json()["hda_disk_image"] == "linuxè½½.img"
+ assert response.json()["hda_disk_image_md5sum"] == "fcea920f7412b5da7be0cf42b8c93759"
+
+
+ @pytest.mark.parametrize(
+ "name, status_code",
+ (
+ ("valid-name.com", status.HTTP_201_CREATED),
+ ("42name", status.HTTP_201_CREATED),
+ ("424242", status.HTTP_409_CONFLICT),
+ ("name42", status.HTTP_201_CREATED),
+ ("name.424242", status.HTTP_409_CONFLICT),
+ ("-name", status.HTTP_409_CONFLICT),
+ ("name%-test", status.HTTP_409_CONFLICT),
+ ("x" * 63, status.HTTP_201_CREATED),
+ ("x" * 64, status.HTTP_409_CONFLICT),
+ (("x" * 62 + ".") * 4, status.HTTP_201_CREATED),
+ ("xx" + ("x" * 62 + ".") * 4, status.HTTP_409_CONFLICT),
+ ),
)
- 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(app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
-
- 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"):
+ 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
+ ) -> 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,
+ # base_params: dict,
+ # fake_qemu_vm: str) -> None:
+ #
+ # response = await compute_client.post(
+ # app.url_path_for("compute:write_compute_project_file", project_id=compute_project.id, file_path="hello.img"),
+ # content=b"world"
+ # )
+ # assert response.status_code == status.HTTP_204_NO_CONTENT
+ # params = base_params
+ # params["hda_disk_image"] = "hello.img"
+ # 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()["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
+ ):
+
+ 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"])
+ )
+ assert response.status_code == status.HTTP_200_OK
+ 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"]
+ )
+
+
+ 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"])
+ )
+ 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"])
+ )
+ 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"])
+ )
+ 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"])
+ )
+ 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"])
+ )
+ 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
+ ) -> None:
+
+ 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
+ )
+ 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"
+ }
+
+ 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}
+ )
+
+ 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"
+ )
+ 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"
+ }
+
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}
)
-
- 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"
- )
- 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(app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
-
- params = {
- "type": "nio_udp",
- "lport": 4242,
- "rport": 4343,
- "rhost": "127.0.0.1"
- }
-
- 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}
- )
-
- 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"
- )
-
- await compute_client.post(url, json=params)
- params["filters"] = {}
-
- url = app.url_path_for(
- "compute:update_qemu_node_nio",
- project_id=qemu_vm["project_id"],
- node_id=qemu_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"
-
-
-async def test_qemu_delete_nio(app: FastAPI, compute_client: AsyncClient, qemu_vm: dict) -> None:
-
- 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}
- )
-
+
url = app.url_path_for(
"compute:create_qemu_node_nio",
project_id=qemu_vm["project_id"],
@@ -370,192 +359,285 @@ async def test_qemu_delete_nio(app: FastAPI, compute_client: AsyncClient, qemu_v
adapter_number="1",
port_number="0"
)
+
await compute_client.post(url, json=params)
-
+ params["filters"] = {}
+
url = app.url_path_for(
- "compute:delete_qemu_node_nio",
+ "compute:update_qemu_node_nio",
project_id=qemu_vm["project_id"],
node_id=qemu_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_images(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()
-
-
-async def test_upload_image(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.put(url, json=params)
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["type"] == "nio_udp"
+
+
+ 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"
+ }
+
+ 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}
+ )
+
+ 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"
+ )
+ 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"
+ )
+ response = await compute_client.delete(url)
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(app: FastAPI, compute_client: AsyncClient, tmpdir:str) -> None:
-
- with patch("gns3server.compute.Qemu.get_images_directory", return_value=str(tmpdir)):
-
+
+
+ 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()
+
+
+ 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")
+ 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:
+
+ 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")
+ 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
+ ) -> None:
+
response = await compute_client.post(app.url_path_for("compute:upload_qemu_image",
- filename="test2.ova/test2.vmdk"), content=b"TEST")
+ 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")
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(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")
- assert response.status_code == status.HTTP_403_FORBIDDEN
-
-
-async def test_download_image(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")
- 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(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(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")
- assert response.status_code == status.HTTP_409_CONFLICT
-
-
-# @pytest.mark.asyncio
-# async def test_create_img_relative(app: FastAPI, compute_client: AsyncClient):
-#
-# params = {
-# "qemu_img": "/tmp/qemu-img",
-# "path": "hda.qcow2",
-# "format": "qcow2",
-# "preallocation": "metadata",
-# "cluster_size": 64,
-# "refcount_bits": 12,
-# "lazy_refcounts": "off",
-# "size": 100
-# }
-# 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_create_img_absolute_non_local(app: FastAPI, compute_client: AsyncClient, config) -> None:
-#
-# config.settings.Server.local = False
-# params = {
-# "qemu_img": "/tmp/qemu-img",
-# "path": "/tmp/hda.qcow2",
-# "format": "qcow2",
-# "preallocation": "metadata",
-# "cluster_size": 64,
-# "refcount_bits": 12,
-# "lazy_refcounts": "off",
-# "size": 100
-# }
-# 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 == 403
-#
-#
-# async def test_create_img_absolute_local(app: FastAPI, compute_client: AsyncClient, config) -> None:
-#
-# params = {
-# "qemu_img": "/tmp/qemu-img",
-# "path": "/tmp/hda.qcow2",
-# "format": "qcow2",
-# "preallocation": "metadata",
-# "cluster_size": 64,
-# "refcount_bits": 12,
-# "lazy_refcounts": "off",
-# "size": 100
-# }
-# 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(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(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
- )
-
- 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
- )
- assert response.status_code == status.HTTP_201_CREATED
-
-
-async def test_qemu_create_disk_image(
- 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
- }
-
- with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()) as qemu_img:
+
+ 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:
+
+ 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")
+ assert response.status_code == status.HTTP_409_CONFLICT
+
+
+ # @pytest.mark.asyncio
+ # async def test_create_img_relative(self, app: FastAPI, compute_client: AsyncClient):
+ #
+ # params = {
+ # "qemu_img": "/tmp/qemu-img",
+ # "path": "hda.qcow2",
+ # "format": "qcow2",
+ # "preallocation": "metadata",
+ # "cluster_size": 64,
+ # "refcount_bits": 12,
+ # "lazy_refcounts": "off",
+ # "size": 100
+ # }
+ # 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_create_img_absolute_non_local(self, app: FastAPI, compute_client: AsyncClient, config) -> None:
+ #
+ # config.settings.Server.local = False
+ # params = {
+ # "qemu_img": "/tmp/qemu-img",
+ # "path": "/tmp/hda.qcow2",
+ # "format": "qcow2",
+ # "preallocation": "metadata",
+ # "cluster_size": 64,
+ # "refcount_bits": 12,
+ # "lazy_refcounts": "off",
+ # "size": 100
+ # }
+ # 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 == 403
+ #
+ #
+ # async def test_create_img_absolute_local(self, app: FastAPI, compute_client: AsyncClient, config) -> None:
+ #
+ # params = {
+ # "qemu_img": "/tmp/qemu-img",
+ # "path": "/tmp/hda.qcow2",
+ # "format": "qcow2",
+ # "preallocation": "metadata",
+ # "cluster_size": 64,
+ # "refcount_bits": 12,
+ # "lazy_refcounts": "off",
+ # "size": 100
+ # }
+ # 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
+ ) -> 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
+ )
+
+ 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
+ )
+ 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,
+ ):
+
+ options = {
+ "format": "qcow2",
+ "preallocation": "metadata",
+ "cluster_size": 64,
+ "refcount_bits": 12,
+ "lazy_refcounts": "off",
+ "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"
+ ),
+ json=options
+ )
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+ args, kwargs = qemu_img.call_args
+ assert args == (
+ fake_qemu_img_binary,
+ "create",
+ "-f",
+ "qcow2",
+ "-o",
+ "cluster_size=64",
+ "-o",
+ "lazy_refcounts=off",
+ "-o",
+ "preallocation=metadata",
+ "-o",
+ "refcount_bits=12",
+ os.path.join(qemu_vm["node_directory"], "disk.qcow2"),
+ "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,
+ ):
+
+ 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
+ }
+
response = await compute_client.post(
app.url_path_for(
"compute:create_qemu_disk_image",
@@ -565,202 +647,159 @@ async def test_qemu_create_disk_image(
),
json=options
)
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
- args, kwargs = qemu_img.call_args
- assert args == (
- fake_qemu_img_binary,
- "create",
- "-f",
- "qcow2",
- "-o",
- "cluster_size=64",
- "-o",
- "lazy_refcounts=off",
- "-o",
- "preallocation=metadata",
- "-o",
- "refcount_bits=12",
- os.path.join(qemu_vm["node_directory"], "disk.qcow2"),
- "30M"
- )
-
-
-async def test_qemu_create_disk_image_already_exists(
- 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
- }
-
- 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"
- ),
- 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,
-# 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
-# }
-#
-# with patch("os.path.exists", side_effect=UnicodeEncodeError('error', u"", 1, 2, 'Emulated Unicode Err')):
-# 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=u"\u2019"
-# ),
-# json=options
-# )
-# assert response.status_code == status.HTTP_409_CONFLICT
-
-
-async def test_qemu_update_disk_image(
- 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(
+ 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,
+ # 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
+ # }
+ #
+ # with patch("os.path.exists", side_effect=UnicodeEncodeError('error', u"", 1, 2, 'Emulated Unicode Err')):
+ # 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=u"\u2019"
+ # ),
+ # 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,
+ ) -> 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"
+ ),
+ 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"
+ )
+
+
+ async def test_qemu_delete_disk_image(
+ 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:update_qemu_disk_image",
+ "compute:delete_qemu_disk_image",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
disk_name="disk.qcow2"
- ),
- 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"
+
+
+ async def test_qemu_delete_disk_image_missing_image(
+ 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"
+ )
)
-
-
-async def test_qemu_delete_disk_image(
- 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",
+ 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"
+ }
+
+ url = app.url_path_for(
+ "compute:start_qemu_node_capture",
project_id=qemu_vm["project_id"],
node_id=qemu_vm["node_id"],
- disk_name="disk.qcow2"
+ adapter_number="0",
+ port_number="0"
)
- )
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_qemu_delete_disk_image_missing_image(
- 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",
+
+ 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"],
- disk_name="unknown_image.qcow2"
+ adapter_number="0",
+ port_number="0"
)
- )
- assert response.status_code == status.HTTP_409_CONFLICT
-
-
-@pytest.mark.asyncio
-async def test_qemu_start_capture(app: FastAPI, compute_client: AsyncClient, qemu_vm: dict):
-
- 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"
- )
-
- 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(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"
- )
-
- 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(app: FastAPI, compute_client: AsyncClient, vm, compute_project):
-#
-# with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.get_nio"):
-# with asyncio_patch("gns3server.compute.qemu.Qemu.stream_pcap_file"):
-# response = await compute_client.get("/projects/{project_id}/qemu/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
+
+ 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):
+ #
+ # with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.get_nio"):
+ # with asyncio_patch("gns3server.compute.qemu.Qemu.stream_pcap_file"):
+ # response = await compute_client.get("/projects/{project_id}/qemu/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
diff --git a/tests/api/routes/compute/test_virtualbox_nodes.py b/tests/api/routes/compute/test_virtualbox_nodes.py
index 5a88b6d7..e29f104d 100644
--- a/tests/api/routes/compute/test_virtualbox_nodes.py
+++ b/tests/api/routes/compute/test_virtualbox_nodes.py
@@ -28,221 +28,223 @@ from gns3server.compute.project import Project
pytestmark = pytest.mark.asyncio
-@pytest_asyncio.fixture(scope="function")
-async def vm(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)
- 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(app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
-
- 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)
+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)
+ assert mock.called
assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["name"] == "VM1"
+
+ 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
+ }
+
+ 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)
+ 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"]))
+ 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_get(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(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_vbox_stop(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_vbox_suspend(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_vbox_resume(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_vbox_reload(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_vbox_nio_create_udp(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:
- 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(app: FastAPI, compute_client: AsyncClient, vm):
-#
-# params = {
-# "type": "nio_udp",
-# "lport": 4242,
-# "rport": 4343,
-# "rhost": "127.0.0.1",
-# "filters": {}
-# }
-#
-# with asyncio_patch('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.ethernet_adapters'):
-# with asyncio_patch('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_remove_nio_binding'):
-# response = await compute_client.put("/projects/{project_id}/virtualbox/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_vbox_delete_nio(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:
- 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(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)
- 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(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")
-
- 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
+
+
+ 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"]))
assert mock.called
- assert "test.pcap" in response.json()["pcap_file_path"]
-
-
-@pytest.mark.asyncio
-async def test_virtualbox_stop_capture(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")
-
- 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
+
+
+ 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"]))
assert mock.called
-
-
-# @pytest.mark.asyncio
-# async def test_virtualbox_pcap(app: FastAPI, compute_client: AsyncClient, vm, compute_project):
-#
-# with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.get_nio"):
-# with asyncio_patch("gns3server.compute.virtualbox.VirtualBox.stream_pcap_file"):
-# response = await compute_client.get("/projects/{project_id}/virtualbox/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
+ 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"]))
+ 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"]))
+ 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"]))
+ 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:
+ 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):
+ #
+ # params = {
+ # "type": "nio_udp",
+ # "lport": 4242,
+ # "rport": 4343,
+ # "rhost": "127.0.0.1",
+ # "filters": {}
+ # }
+ #
+ # with asyncio_patch('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.ethernet_adapters'):
+ # with asyncio_patch('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_remove_nio_binding'):
+ # response = await compute_client.put("/projects/{project_id}/virtualbox/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_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:
+ 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)
+ 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")
+
+ 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")
+
+ 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):
+ #
+ # with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.get_nio"):
+ # with asyncio_patch("gns3server.compute.virtualbox.VirtualBox.stream_pcap_file"):
+ # response = await compute_client.get("/projects/{project_id}/virtualbox/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
diff --git a/tests/api/routes/compute/test_vmware_nodes.py b/tests/api/routes/compute/test_vmware_nodes.py
index 088b4db2..ff875ab2 100644
--- a/tests/api/routes/compute/test_vmware_nodes.py
+++ b/tests/api/routes/compute/test_vmware_nodes.py
@@ -28,226 +28,246 @@ from gns3server.compute.project import Project
pytestmark = pytest.mark.asyncio
-@pytest_asyncio.fixture(scope="function")
-async def vm(app: FastAPI, compute_client: AsyncClient, compute_project: Project, vmx_path: str) -> dict:
+class TestVMwareNodesRoutes:
- 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)
- assert mock.called
- assert response.status_code == status.HTTP_201_CREATED
- return response.json()
+ @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
+ }
+
+ 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)
+ assert mock.called
+ assert response.status_code == status.HTTP_201_CREATED
+ return response.json()
-@pytest.fixture
-def vmx_path(tmpdir: str) -> str:
- """
- Return a fake VMX file
- """
-
- path = str(tmpdir / "test.vmx")
- with open(path, 'w+') as f:
- f.write("1")
- return path
-
-
-async def test_vmware_create(app: FastAPI, compute_client: AsyncClient, compute_project: Project, vmx_path: str) -> None:
-
- 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)
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["name"] == "VM1"
+ @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:
+ f.write("1")
+ return path
+
+
+ async def test_vmware_create(
+ self,
+ app: FastAPI,
+ compute_client: AsyncClient,
+ compute_project: Project,
+ vmx_path: str
+ ) -> None:
+
+ 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)
+ 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
+ ) -> None:
+
+ 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_get(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"]))
- 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(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_vmware_stop(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_vmware_suspend(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_vmware_resume(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_vmware_reload(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"]))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_vmware_nio_create_udp(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:
- 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(app: FastAPI, compute_client: AsyncClient, vm):
-#
-# params = {
-# "type": "nio_udp",
-# "lport": 4242,
-# "rport": 4343,
-# "rhost": "127.0.0.1",
-# "filters": {}
-# }
-#
-# with asyncio_patch('gns3server.compute.vmware.vmware_vm.VMwareVM._ubridge_send'):
-# with asyncio_patch('gns3server.compute.vmware.vmware_vm.VMwareVM.ethernet_adapters'):
-# with patch('gns3server.compute.vmware.vmware_vm.VMwareVM._get_vnet') as mock:
-# 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(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:
- 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(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)
- 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(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")
-
- 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
+
+
+ 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"]))
assert mock.called
- assert "test.pcap" in response.json()["pcap_file_path"]
-
-
-async def test_vmware_stop_capture(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")
-
- 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
+
+
+ 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"]))
assert mock.called
-
-
-# @pytest.mark.asyncio
-# async def test_vmware_pcap(app: FastAPI, compute_client: AsyncClient, vm, compute_project):
-#
-# with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.get_nio"):
-# with asyncio_patch("gns3server.compute.vmware.VMware.stream_pcap_file"):
-# response = await compute_client.get("/projects/{project_id}/vmware/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
+ 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"]))
+ 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"]))
+ 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"]))
+ 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:
+ 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):
+ #
+ # params = {
+ # "type": "nio_udp",
+ # "lport": 4242,
+ # "rport": 4343,
+ # "rhost": "127.0.0.1",
+ # "filters": {}
+ # }
+ #
+ # with asyncio_patch('gns3server.compute.vmware.vmware_vm.VMwareVM._ubridge_send'):
+ # with asyncio_patch('gns3server.compute.vmware.vmware_vm.VMwareVM.ethernet_adapters'):
+ # with patch('gns3server.compute.vmware.vmware_vm.VMwareVM._get_vnet') as mock:
+ # 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:
+ 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
+ ) -> 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)
+ 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")
+
+ 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")
+
+ 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):
+ #
+ # with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.get_nio"):
+ # with asyncio_patch("gns3server.compute.vmware.VMware.stream_pcap_file"):
+ # response = await compute_client.get("/projects/{project_id}/vmware/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
diff --git a/tests/api/routes/compute/test_vpcs_nodes.py b/tests/api/routes/compute/test_vpcs_nodes.py
index f0b69366..0bf98781 100644
--- a/tests/api/routes/compute/test_vpcs_nodes.py
+++ b/tests/api/routes/compute/test_vpcs_nodes.py
@@ -28,251 +28,279 @@ from gns3server.compute.project import Project
pytestmark = pytest.mark.asyncio
-@pytest_asyncio.fixture
-async def vm(app: FastAPI, compute_client: AsyncClient, compute_project: Project) -> None:
+class TestVPCSNodesRoutes:
- 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)
- assert response.status_code == status.HTTP_201_CREATED
- return response.json()
-
-
-async def test_vpcs_create(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)
- 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(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"]))
- 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(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)
- 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(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)
- 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(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")
-
- 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(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")
-
- 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
-
- params["filters"] = {}
- 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"
-
-
-async def test_vpcs_delete_nio(app: FastAPI, compute_client: AsyncClient, vm: dict) -> None:
-
- params = {
- "type": "nio_udp",
- "lport": 4242,
- "rport": 4343,
- "rhost": "127.0.0.1"
- }
-
- with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM._ubridge_send"):
+ @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)
+ 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)
+ 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
+ ) -> None:
+
+ 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
+ ) -> 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)
+ 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
+ ) -> 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)
+ 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")
- await compute_client.post(url, json=params)
-
- url = app.url_path_for("compute:delete_vpcs_node_nio",
+
+ 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"
+ }
+
+ 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")
- response = await compute_client.delete(url)
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_vpcs_start(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(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(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(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_duplicate(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)
- 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)
- assert response.status_code == status.HTTP_201_CREATED
-
-
-async def test_vpcs_update(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)
- 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(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")
-
- 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:
+
+ 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_200_OK
+ assert response.status_code == status.HTTP_201_CREATED
+
+ params["filters"] = {}
+ 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"
+
+
+ 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"
+ }
+
+ 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")
+ 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")
+ 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 "test.pcap" in response.json()["pcap_file_path"]
-
-
-async def test_vpcs_stop_capture(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")
-
- 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
+
+
+ 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
-
-
-# @pytest.mark.asyncio
-# async def test_vpcs_pcap(app: FastAPI, compute_client: AsyncClient, vm, compute_project: Project):
-#
-# with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.get_nio"):
-# with asyncio_patch("gns3server.compute.vpcs.VPCS.stream_pcap_file"):
-# response = await compute_client.get("/projects/{project_id}/vpcs/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
+ 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_duplicate(
+ 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)
+ 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)
+ 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
+ ) -> 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)
+ 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")
+
+ 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")
+
+ 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):
+ #
+ # with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.get_nio"):
+ # with asyncio_patch("gns3server.compute.vpcs.VPCS.stream_pcap_file"):
+ # response = await compute_client.get("/projects/{project_id}/vpcs/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
diff --git a/tests/api/routes/controller/test_controller.py b/tests/api/routes/controller/test_controller.py
index 50c64c73..ddd33aa8 100644
--- a/tests/api/routes/controller/test_controller.py
+++ b/tests/api/routes/controller/test_controller.py
@@ -27,43 +27,45 @@ from gns3server.config import Config
pytestmark = pytest.mark.asyncio
-async def test_shutdown_local(app: FastAPI, client: AsyncClient, config: Config) -> None:
+class TestControllerRoutes:
- os.kill = MagicMock()
- config.settings.Server.local = True
- response = await client.post(app.url_path_for("shutdown"))
- assert response.status_code == status.HTTP_204_NO_CONTENT
- assert os.kill.called
-
-
-async def test_shutdown_non_local(app: FastAPI, client: AsyncClient, config: Config) -> None:
-
- response = await client.post(app.url_path_for("shutdown"))
- assert response.status_code == status.HTTP_403_FORBIDDEN
-
-
-# @pytest.mark.asyncio
-# async def test_debug(controller_api, config, tmpdir):
-#
-# config._main_config_file = str(tmpdir / "test.conf")
-# config.set("Server", "local", True)
-# response = await controller_api.post('/debug')
-# assert response.status_code == 201
-# debug_dir = os.path.join(config.config_dir, "debug")
-# assert os.path.exists(debug_dir)
-# assert os.path.exists(os.path.join(debug_dir, "controller.txt"))
-#
-#
-# @pytest.mark.asyncio
-# async def test_debug_non_local(controller_api, config, tmpdir):
-#
-# config._main_config_file = str(tmpdir / "test.conf")
-# config.set("Server", "local", False)
-# response = await controller_api.post('/debug')
-# assert response.status_code == 403
-
-
-async def test_statistics_output(app: FastAPI, client: AsyncClient) -> None:
-
- response = await client.get(app.url_path_for("statistics"))
- assert response.status_code == status.HTTP_200_OK
+ async def test_shutdown_local(self, app: FastAPI, client: AsyncClient, config: Config) -> None:
+
+ os.kill = MagicMock()
+ config.settings.Server.local = True
+ response = await client.post(app.url_path_for("shutdown"))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+ assert os.kill.called
+
+
+ async def test_shutdown_non_local(self, app: FastAPI, client: AsyncClient, config: Config) -> None:
+
+ response = await client.post(app.url_path_for("shutdown"))
+ assert response.status_code == status.HTTP_403_FORBIDDEN
+
+
+ # @pytest.mark.asyncio
+ # async def test_debug(controller_api, config, tmpdir):
+ #
+ # config._main_config_file = str(tmpdir / "test.conf")
+ # config.set("Server", "local", True)
+ # response = await controller_api.post('/debug')
+ # assert response.status_code == 201
+ # debug_dir = os.path.join(config.config_dir, "debug")
+ # assert os.path.exists(debug_dir)
+ # assert os.path.exists(os.path.join(debug_dir, "controller.txt"))
+ #
+ #
+ # @pytest.mark.asyncio
+ # async def test_debug_non_local(controller_api, config, tmpdir):
+ #
+ # config._main_config_file = str(tmpdir / "test.conf")
+ # config.set("Server", "local", False)
+ # response = await controller_api.post('/debug')
+ # assert response.status_code == 403
+
+
+ async def test_statistics_output(self, app: FastAPI, client: AsyncClient) -> None:
+
+ response = await client.get(app.url_path_for("statistics"))
+ assert response.status_code == status.HTTP_200_OK
diff --git a/tests/api/routes/controller/test_drawings.py b/tests/api/routes/controller/test_drawings.py
index c5fcec38..62f00d5f 100644
--- a/tests/api/routes/controller/test_drawings.py
+++ b/tests/api/routes/controller/test_drawings.py
@@ -26,89 +26,91 @@ from gns3server.controller.project import Project
pytestmark = pytest.mark.asyncio
-async def test_create_drawing(app: FastAPI, client: AsyncClient, project: Project) -> None:
+class TestDrawingsRoutes:
- params = {
- "svg": '',
- "x": 10,
- "y": 20,
- "z": 0
- }
-
- response = await client.post(app.url_path_for("create_drawing", project_id=project.id), json=params)
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["drawing_id"] is not None
-
-
-async def test_get_drawing(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- params = {
- "svg": '',
- "x": 10,
- "y": 20,
- "z": 0
- }
-
- response = await client.post(app.url_path_for("create_drawing", project_id=project.id), json=params)
- response = await client.get(app.url_path_for(
- "get_drawing",
- project_id=project.id,
- drawing_id=response.json()["drawing_id"])
- )
- assert response.status_code == 200
- assert response.json()["x"] == 10
-
-
-async def test_update_drawing(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- params = {
- "svg": '',
- "x": 10,
- "y": 20,
- "z": 0
- }
-
- response = await client.post(app.url_path_for("create_drawing", project_id=project.id), json=params)
- response = await client.put(app.url_path_for(
- "update_drawing",
- project_id=project.id,
- drawing_id=response.json()["drawing_id"]),
- json={"x": 42}
- )
-
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["x"] == 42
-
-
-async def test_all_drawings(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- params = {
- "svg": '',
- "x": 10,
- "y": 20,
- "z": 0
- }
-
- await client.post(app.url_path_for("create_drawing", project_id=project.id), json=params)
- response = await client.get(app.url_path_for("get_drawings", project_id=project.id))
- assert response.status_code == status.HTTP_200_OK
- assert len(response.json()) == 1
-
- # test listing links from a closed project
- await project.close(ignore_notification=True)
- response = await client.get(app.url_path_for("get_drawings", project_id=project.id))
- assert response.status_code == status.HTTP_200_OK
- assert len(response.json()) == 1
-
-
-async def test_delete_drawing(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- drawing = Drawing(project)
- project._drawings = {drawing.id: drawing}
- response = await client.delete(app.url_path_for(
- "delete_drawing",
- project_id=project.id,
- drawing_id=drawing.id)
- )
- assert response.status_code == status.HTTP_204_NO_CONTENT
- assert drawing.id not in project.drawings
+ async def test_create_drawing(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ params = {
+ "svg": '',
+ "x": 10,
+ "y": 20,
+ "z": 0
+ }
+
+ response = await client.post(app.url_path_for("create_drawing", project_id=project.id), json=params)
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["drawing_id"] is not None
+
+
+ async def test_get_drawing(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ params = {
+ "svg": '',
+ "x": 10,
+ "y": 20,
+ "z": 0
+ }
+
+ response = await client.post(app.url_path_for("create_drawing", project_id=project.id), json=params)
+ response = await client.get(app.url_path_for(
+ "get_drawing",
+ project_id=project.id,
+ drawing_id=response.json()["drawing_id"])
+ )
+ assert response.status_code == 200
+ assert response.json()["x"] == 10
+
+
+ async def test_update_drawing(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ params = {
+ "svg": '',
+ "x": 10,
+ "y": 20,
+ "z": 0
+ }
+
+ response = await client.post(app.url_path_for("create_drawing", project_id=project.id), json=params)
+ response = await client.put(app.url_path_for(
+ "update_drawing",
+ project_id=project.id,
+ drawing_id=response.json()["drawing_id"]),
+ json={"x": 42}
+ )
+
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["x"] == 42
+
+
+ async def test_all_drawings(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ params = {
+ "svg": '',
+ "x": 10,
+ "y": 20,
+ "z": 0
+ }
+
+ await client.post(app.url_path_for("create_drawing", project_id=project.id), json=params)
+ response = await client.get(app.url_path_for("get_drawings", project_id=project.id))
+ assert response.status_code == status.HTTP_200_OK
+ assert len(response.json()) == 1
+
+ # test listing links from a closed project
+ await project.close(ignore_notification=True)
+ response = await client.get(app.url_path_for("get_drawings", project_id=project.id))
+ assert response.status_code == status.HTTP_200_OK
+ assert len(response.json()) == 1
+
+
+ async def test_delete_drawing(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ drawing = Drawing(project)
+ project._drawings = {drawing.id: drawing}
+ response = await client.delete(app.url_path_for(
+ "delete_drawing",
+ project_id=project.id,
+ drawing_id=drawing.id)
+ )
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+ assert drawing.id not in project.drawings
diff --git a/tests/api/routes/controller/test_gns3vm.py b/tests/api/routes/controller/test_gns3vm.py
index bb41f1ce..ce10bfb8 100644
--- a/tests/api/routes/controller/test_gns3vm.py
+++ b/tests/api/routes/controller/test_gns3vm.py
@@ -24,32 +24,34 @@ from tests.utils import asyncio_patch
pytestmark = pytest.mark.asyncio
-async def test_list_vms(app: FastAPI, client: AsyncClient) -> None:
+class TestGNS3VMRoutes:
- with asyncio_patch("gns3server.controller.gns3vm.vmware_gns3_vm.VMwareGNS3VM.list", return_value=[{"vmname": "test"}]):
- response = await client.get(app.url_path_for("get_vms", engine="vmware"))
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == [
- {
- "vmname": "test"
- }
- ]
-
-
-async def test_engines(app: FastAPI, client: AsyncClient) -> None:
-
- response = await client.get(app.url_path_for("get_engines"))
- assert response.status_code == status.HTTP_200_OK
- assert len(response.json()) > 0
-
-
-async def test_put_gns3vm(app: FastAPI, client: AsyncClient) -> None:
-
- response = await client.put(app.url_path_for("update_gns3vm_settings"), json={"vmname": "TEST VM"})
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["vmname"] == "TEST VM"
-
-
-async def test_get_gns3vm(app: FastAPI, client: AsyncClient) -> None:
- response = await client.get(app.url_path_for("get_gns3vm_settings"))
- assert response.status_code == status.HTTP_200_OK
+ async def test_list_vms(self, app: FastAPI, client: AsyncClient) -> None:
+
+ with asyncio_patch("gns3server.controller.gns3vm.vmware_gns3_vm.VMwareGNS3VM.list", return_value=[{"vmname": "test"}]):
+ response = await client.get(app.url_path_for("get_vms", engine="vmware"))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json() == [
+ {
+ "vmname": "test"
+ }
+ ]
+
+
+ async def test_engines(self, app: FastAPI, client: AsyncClient) -> None:
+
+ response = await client.get(app.url_path_for("get_engines"))
+ assert response.status_code == status.HTTP_200_OK
+ assert len(response.json()) > 0
+
+
+ async def test_put_gns3vm(self, app: FastAPI, client: AsyncClient) -> None:
+
+ response = await client.put(app.url_path_for("update_gns3vm_settings"), json={"vmname": "TEST VM"})
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["vmname"] == "TEST VM"
+
+
+ async def test_get_gns3vm(self, app: FastAPI, client: AsyncClient) -> None:
+ response = await client.get(app.url_path_for("get_gns3vm_settings"))
+ assert response.status_code == status.HTTP_200_OK
diff --git a/tests/api/routes/controller/test_links.py b/tests/api/routes/controller/test_links.py
index ab6bf476..2103ddaa 100644
--- a/tests/api/routes/controller/test_links.py
+++ b/tests/api/routes/controller/test_links.py
@@ -35,30 +35,88 @@ from gns3server.controller.udp_link import UDPLink
pytestmark = pytest.mark.asyncio
-@pytest_asyncio.fixture
-async def nodes(compute: Compute, project: Project) -> Tuple[Node, Node]:
+class TestLinkRoutes:
- response = MagicMock()
- response.json = {"console": 2048}
- compute.post = AsyncioMagicMock(return_value=response)
-
- node1 = await project.add_node(compute, "node1", None, node_type="qemu")
- node1._ports = [EthernetPort("E0", 0, 0, 3)]
- node2 = await project.add_node(compute, "node2", None, node_type="qemu")
- node2._ports = [EthernetPort("E0", 0, 2, 4)]
- return node1, node2
-
-
-async def test_create_link(app: FastAPI, client: AsyncClient, project: Project, nodes: Tuple[Node, Node]) -> None:
-
- node1, node2 = nodes
-
- filters = {
- "latency": [10],
- "frequency_drop": [50]
- }
-
- with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as mock:
+ @pytest_asyncio.fixture
+ async def nodes(self, compute: Compute, project: Project) -> Tuple[Node, Node]:
+
+ response = MagicMock()
+ response.json = {"console": 2048}
+ compute.post = AsyncioMagicMock(return_value=response)
+
+ node1 = await project.add_node(compute, "node1", None, node_type="qemu")
+ node1._ports = [EthernetPort("E0", 0, 0, 3)]
+ node2 = await project.add_node(compute, "node2", None, node_type="qemu")
+ node2._ports = [EthernetPort("E0", 0, 2, 4)]
+ return node1, node2
+
+
+ async def test_create_link(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ nodes: Tuple[Node, Node]
+ ) -> None:
+
+ node1, node2 = nodes
+
+ filters = {
+ "latency": [10],
+ "frequency_drop": [50]
+ }
+
+ with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as mock:
+ response = await client.post(app.url_path_for("create_link", project_id=project.id), json={
+ "nodes": [
+ {
+ "node_id": node1.id,
+ "adapter_number": 0,
+ "port_number": 3,
+ "label": {
+ "text": "Text",
+ "x": 42,
+ "y": 0
+ }
+ },
+ {
+ "node_id": node2.id,
+ "adapter_number": 2,
+ "port_number": 4
+ }
+ ],
+ "filters": filters
+ })
+
+ assert mock.called
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["link_id"] is not None
+ assert len(response.json()["nodes"]) == 2
+ assert response.json()["nodes"][0]["label"]["x"] == 42
+ assert len(project.links) == 1
+ assert list(project.links.values())[0].filters == filters
+
+
+ async def test_create_link_failure(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ compute: Compute,
+ project: Project
+ ) -> None:
+ """
+ Make sure the link is deleted if we failed to create it.
+
+ The failure is triggered by connecting the link to itself
+ """
+
+ response = MagicMock()
+ response.json = {"console": 2048}
+ compute.post = AsyncioMagicMock(return_value=response)
+
+ node1 = await project.add_node(compute, "node1", None, node_type="qemu")
+ node1._ports = [EthernetPort("E0", 0, 0, 3), EthernetPort("E0", 0, 0, 4)]
+
response = await client.post(app.url_path_for("create_link", project_id=project.id), json={
"nodes": [
{
@@ -71,6 +129,168 @@ async def test_create_link(app: FastAPI, client: AsyncClient, project: Project,
"y": 0
}
},
+ {
+ "node_id": node1.id,
+ "adapter_number": 0,
+ "port_number": 4
+ }
+ ]
+ })
+
+ assert response.status_code == status.HTTP_409_CONFLICT
+ assert len(project.links) == 0
+
+
+ async def test_get_link(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ nodes: Tuple[Node, Node]
+ ) -> None:
+
+ node1, node2 = nodes
+ with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as mock:
+ response = await client.post(app.url_path_for("create_link", project_id=project.id), json={
+ "nodes": [
+ {
+ "node_id": node1.id,
+ "adapter_number": 0,
+ "port_number": 3,
+ "label": {
+ "text": "Text",
+ "x": 42,
+ "y": 0
+ }
+ },
+ {
+ "node_id": node2.id,
+ "adapter_number": 2,
+ "port_number": 4
+ }
+ ]
+ })
+
+ assert mock.called
+ link_id = response.json()["link_id"]
+ assert response.json()["nodes"][0]["label"]["x"] == 42
+ response = await client.get(app.url_path_for("get_link", project_id=project.id, link_id=link_id))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["nodes"][0]["label"]["x"] == 42
+
+
+ async def test_update_link_suspend(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ nodes: Tuple[Node, Node]
+ ) -> None:
+
+ node1, node2 = nodes
+ with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as mock:
+ response = await client.post(app.url_path_for("create_link", project_id=project.id), json={
+ "nodes": [
+ {
+ "node_id": node1.id,
+ "adapter_number": 0,
+ "port_number": 3,
+ "label": {
+ "text": "Text",
+ "x": 42,
+ "y": 0
+ }
+ },
+ {
+ "node_id": node2.id,
+ "adapter_number": 2,
+ "port_number": 4
+ }
+ ]
+ })
+
+ assert mock.called
+ link_id = response.json()["link_id"]
+ assert response.json()["nodes"][0]["label"]["x"] == 42
+
+ response = await client.put(app.url_path_for("update_link", project_id=project.id, link_id=link_id), json={
+ "nodes": [
+ {
+ "node_id": node1.id,
+ "adapter_number": 0,
+ "port_number": 3,
+ "label": {
+ "text": "Hello",
+ "x": 64,
+ "y": 0
+ }
+ },
+ {
+ "node_id": node2.id,
+ "adapter_number": 2,
+ "port_number": 4
+ }
+ ],
+ "suspend": True
+ })
+
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["nodes"][0]["label"]["x"] == 64
+ assert response.json()["suspend"]
+ assert response.json()["filters"] == {}
+
+
+ async def test_update_link(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ nodes: Tuple[Node, Node]
+ ) -> None:
+
+ filters = {
+ "latency": [10],
+ "frequency_drop": [50]
+ }
+
+ node1, node2 = nodes
+ with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as mock:
+ response = await client.post(app.url_path_for("create_link", project_id=project.id), json={
+ "nodes": [
+ {
+ "node_id": node1.id,
+ "adapter_number": 0,
+ "port_number": 3,
+ "label": {
+ "text": "Text",
+ "x": 42,
+ "y": 0
+ }
+ },
+ {
+ "node_id": node2.id,
+ "adapter_number": 2,
+ "port_number": 4
+ }
+ ]
+ })
+
+ assert mock.called
+ link_id = response.json()["link_id"]
+ assert response.json()["nodes"][0]["label"]["x"] == 42
+
+ response = await client.put(app.url_path_for("update_link", project_id=project.id, link_id=link_id), json={
+ "nodes": [
+ {
+ "node_id": node1.id,
+ "adapter_number": 0,
+ "port_number": 3,
+ "label": {
+ "text": "Hello",
+ "x": 64,
+ "y": 0
+ }
+ },
{
"node_id": node2.id,
"adapter_number": 2,
@@ -79,309 +299,127 @@ async def test_create_link(app: FastAPI, client: AsyncClient, project: Project,
],
"filters": filters
})
-
- assert mock.called
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["link_id"] is not None
- assert len(response.json()["nodes"]) == 2
- assert response.json()["nodes"][0]["label"]["x"] == 42
- assert len(project.links) == 1
- assert list(project.links.values())[0].filters == filters
-
-
-async def test_create_link_failure(app: FastAPI, client: AsyncClient, compute: Compute, project: Project) -> None:
- """
- Make sure the link is deleted if we failed to create it.
-
- The failure is triggered by connecting the link to itself
- """
-
- response = MagicMock()
- response.json = {"console": 2048}
- compute.post = AsyncioMagicMock(return_value=response)
-
- node1 = await project.add_node(compute, "node1", None, node_type="qemu")
- node1._ports = [EthernetPort("E0", 0, 0, 3), EthernetPort("E0", 0, 0, 4)]
-
- response = await client.post(app.url_path_for("create_link", project_id=project.id), json={
- "nodes": [
+
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["nodes"][0]["label"]["x"] == 64
+ assert list(project.links.values())[0].filters == filters
+
+
+ async def test_list_link(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ nodes: Tuple[Node, Node]
+ ) -> None:
+
+ filters = {
+ "latency": [10],
+ "frequency_drop": [50]
+ }
+
+ node1, node2 = nodes
+ nodes = [
{
"node_id": node1.id,
"adapter_number": 0,
- "port_number": 3,
- "label": {
- "text": "Text",
- "x": 42,
- "y": 0
- }
+ "port_number": 3
},
{
- "node_id": node1.id,
- "adapter_number": 0,
+ "node_id": node2.id,
+ "adapter_number": 2,
"port_number": 4
}
]
- })
-
- assert response.status_code == status.HTTP_409_CONFLICT
- assert len(project.links) == 0
-
-
-async def test_get_link(app: FastAPI, client: AsyncClient, project: Project, nodes: Tuple[Node, Node]) -> None:
-
- node1, node2 = nodes
- with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as mock:
- response = await client.post(app.url_path_for("create_link", project_id=project.id), json={
- "nodes": [
- {
- "node_id": node1.id,
- "adapter_number": 0,
- "port_number": 3,
- "label": {
- "text": "Text",
- "x": 42,
- "y": 0
- }
- },
- {
- "node_id": node2.id,
- "adapter_number": 2,
- "port_number": 4
- }
- ]
- })
-
- assert mock.called
- link_id = response.json()["link_id"]
- assert response.json()["nodes"][0]["label"]["x"] == 42
- response = await client.get(app.url_path_for("get_link", project_id=project.id, link_id=link_id))
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["nodes"][0]["label"]["x"] == 42
-
-
-async def test_update_link_suspend(app: FastAPI, client: AsyncClient, project: Project, nodes: Tuple[Node, Node]) -> None:
-
- node1, node2 = nodes
- with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as mock:
- response = await client.post(app.url_path_for("create_link", project_id=project.id), json={
- "nodes": [
- {
- "node_id": node1.id,
- "adapter_number": 0,
- "port_number": 3,
- "label": {
- "text": "Text",
- "x": 42,
- "y": 0
- }
- },
- {
- "node_id": node2.id,
- "adapter_number": 2,
- "port_number": 4
- }
- ]
- })
-
- assert mock.called
- link_id = response.json()["link_id"]
- assert response.json()["nodes"][0]["label"]["x"] == 42
-
- response = await client.put(app.url_path_for("update_link", project_id=project.id, link_id=link_id), json={
- "nodes": [
- {
- "node_id": node1.id,
- "adapter_number": 0,
- "port_number": 3,
- "label": {
- "text": "Hello",
- "x": 64,
- "y": 0
- }
- },
- {
- "node_id": node2.id,
- "adapter_number": 2,
- "port_number": 4
- }
- ],
- "suspend": True
- })
-
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["nodes"][0]["label"]["x"] == 64
- assert response.json()["suspend"]
- assert response.json()["filters"] == {}
-
-
-async def test_update_link(app: FastAPI, client: AsyncClient, project: Project, nodes: Tuple[Node, Node]) -> None:
-
- filters = {
- "latency": [10],
- "frequency_drop": [50]
- }
-
- node1, node2 = nodes
- with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as mock:
- response = await client.post(app.url_path_for("create_link", project_id=project.id), json={
- "nodes": [
- {
- "node_id": node1.id,
- "adapter_number": 0,
- "port_number": 3,
- "label": {
- "text": "Text",
- "x": 42,
- "y": 0
- }
- },
- {
- "node_id": node2.id,
- "adapter_number": 2,
- "port_number": 4
- }
- ]
- })
-
- assert mock.called
- link_id = response.json()["link_id"]
- assert response.json()["nodes"][0]["label"]["x"] == 42
-
- response = await client.put(app.url_path_for("update_link", project_id=project.id, link_id=link_id), json={
- "nodes": [
- {
- "node_id": node1.id,
- "adapter_number": 0,
- "port_number": 3,
- "label": {
- "text": "Hello",
- "x": 64,
- "y": 0
- }
- },
- {
- "node_id": node2.id,
- "adapter_number": 2,
- "port_number": 4
- }
- ],
- "filters": filters
- })
-
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["nodes"][0]["label"]["x"] == 64
- assert list(project.links.values())[0].filters == filters
-
-
-async def test_list_link(app: FastAPI, client: AsyncClient, project: Project, nodes: Tuple[Node, Node]) -> None:
-
- filters = {
- "latency": [10],
- "frequency_drop": [50]
- }
-
- node1, node2 = nodes
- nodes = [
- {
- "node_id": node1.id,
- "adapter_number": 0,
- "port_number": 3
- },
- {
- "node_id": node2.id,
- "adapter_number": 2,
- "port_number": 4
- }
- ]
- with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as mock:
- await client.post(app.url_path_for("create_link", project_id=project.id), json={
- "nodes": nodes,
- "filters": filters
- })
-
- assert mock.called
- response = await client.get(app.url_path_for("get_links", project_id=project.id))
- assert response.status_code == status.HTTP_200_OK
- assert len(response.json()) == 1
- assert response.json()[0]["filters"] == filters
-
- # test listing links from a closed project
- await project.close(ignore_notification=True)
- response = await client.get(app.url_path_for("get_links", project_id=project.id))
- assert response.status_code == status.HTTP_200_OK
- assert len(response.json()) == 1
- assert response.json()[0]["filters"] == filters
-
-
-async def test_reset_link(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- link = UDPLink(project)
- project._links = {link.id: link}
- with asyncio_patch("gns3server.controller.udp_link.UDPLink.delete") as delete_mock:
- with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as create_mock:
- response = await client.post(app.url_path_for("reset_link", project_id=project.id, link_id=link.id))
- assert delete_mock.called
- assert create_mock.called
- assert response.status_code == status.HTTP_200_OK
-
-
-async def test_start_capture(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- link = Link(project)
- project._links = {link.id: link}
- with asyncio_patch("gns3server.controller.link.Link.start_capture") as mock:
- response = await client.post(app.url_path_for("start_capture", project_id=project.id, link_id=link.id), json={})
+ with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as mock:
+ await client.post(app.url_path_for("create_link", project_id=project.id), json={
+ "nodes": nodes,
+ "filters": filters
+ })
+
assert mock.called
- assert response.status_code == status.HTTP_201_CREATED
-
-
-async def test_stop_capture(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- link = Link(project)
- project._links = {link.id: link}
- with asyncio_patch("gns3server.controller.link.Link.stop_capture") as mock:
- response = await client.post(app.url_path_for("stop_capture", project_id=project.id, link_id=link.id))
+ response = await client.get(app.url_path_for("get_links", project_id=project.id))
+ assert response.status_code == status.HTTP_200_OK
+ assert len(response.json()) == 1
+ assert response.json()[0]["filters"] == filters
+
+ # test listing links from a closed project
+ await project.close(ignore_notification=True)
+ response = await client.get(app.url_path_for("get_links", project_id=project.id))
+ assert response.status_code == status.HTTP_200_OK
+ assert len(response.json()) == 1
+ assert response.json()[0]["filters"] == filters
+
+
+ async def test_reset_link(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ link = UDPLink(project)
+ project._links = {link.id: link}
+ with asyncio_patch("gns3server.controller.udp_link.UDPLink.delete") as delete_mock:
+ with asyncio_patch("gns3server.controller.udp_link.UDPLink.create") as create_mock:
+ response = await client.post(app.url_path_for("reset_link", project_id=project.id, link_id=link.id))
+ assert delete_mock.called
+ assert create_mock.called
+ assert response.status_code == status.HTTP_200_OK
+
+
+ async def test_start_capture(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ link = Link(project)
+ project._links = {link.id: link}
+ with asyncio_patch("gns3server.controller.link.Link.start_capture") as mock:
+ response = await client.post(app.url_path_for("start_capture", project_id=project.id, link_id=link.id), json={})
+ assert mock.called
+ assert response.status_code == status.HTTP_201_CREATED
+
+
+ async def test_stop_capture(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ link = Link(project)
+ project._links = {link.id: link}
+ with asyncio_patch("gns3server.controller.link.Link.stop_capture") as mock:
+ response = await client.post(app.url_path_for("stop_capture", project_id=project.id, link_id=link.id))
+ assert mock.called
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ # async def test_pcap(controller_api, http_client, project):
+ #
+ # async def pcap_capture():
+ # async with http_client.get(controller_api.get_url("/projects/{}/links/{}/pcap".format(project.id, link.id))) as response:
+ # response.body = await response.content.read(5)
+ # print("READ", response.body)
+ # return response
+ #
+ # with asyncio_patch("gns3server.controller.link.Link.capture_node") as mock:
+ # link = Link(project)
+ # link._capture_file_name = "test"
+ # link._capturing = True
+ # with open(link.capture_file_path, "w+") as f:
+ # f.write("hello")
+ # project._links = {link.id: link}
+ # response = await pcap_capture()
+ # assert mock.called
+ # assert response.status_code == 200
+ # assert b'hello' == response.body
+
+
+ async def test_delete_link(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ link = Link(project)
+ project._links = {link.id: link}
+ with asyncio_patch("gns3server.controller.link.Link.delete") as mock:
+ response = await client.delete(app.url_path_for("delete_link", project_id=project.id, link_id=link.id))
assert mock.called
assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-# async def test_pcap(controller_api, http_client, project):
-#
-# async def pcap_capture():
-# async with http_client.get(controller_api.get_url("/projects/{}/links/{}/pcap".format(project.id, link.id))) as response:
-# response.body = await response.content.read(5)
-# print("READ", response.body)
-# return response
-#
-# with asyncio_patch("gns3server.controller.link.Link.capture_node") as mock:
-# link = Link(project)
-# link._capture_file_name = "test"
-# link._capturing = True
-# with open(link.capture_file_path, "w+") as f:
-# f.write("hello")
-# project._links = {link.id: link}
-# response = await pcap_capture()
-# assert mock.called
-# assert response.status_code == 200
-# assert b'hello' == response.body
-
-
-async def test_delete_link(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- link = Link(project)
- project._links = {link.id: link}
- with asyncio_patch("gns3server.controller.link.Link.delete") as mock:
- response = await client.delete(app.url_path_for("delete_link", project_id=project.id, link_id=link.id))
- assert mock.called
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_list_filters(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- link = Link(project)
- project._links = {link.id: link}
- with patch("gns3server.controller.link.Link.available_filters", return_value=FILTERS) as mock:
- response = await client.get(app.url_path_for("get_filters", project_id=project.id, link_id=link.id))
- assert mock.called
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == FILTERS
+
+
+ async def test_list_filters(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ link = Link(project)
+ project._links = {link.id: link}
+ with patch("gns3server.controller.link.Link.available_filters", return_value=FILTERS) as mock:
+ response = await client.get(app.url_path_for("get_filters", project_id=project.id, link_id=link.id))
+ assert mock.called
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json() == FILTERS
diff --git a/tests/api/routes/controller/test_nodes.py b/tests/api/routes/controller/test_nodes.py
index 534fe136..46f42e4a 100644
--- a/tests/api/routes/controller/test_nodes.py
+++ b/tests/api/routes/controller/test_nodes.py
@@ -31,416 +31,537 @@ from gns3server.controller.compute import Compute
pytestmark = pytest.mark.asyncio
-@pytest.fixture
-def node(project: Project, compute: Compute) -> Node:
-
- node = Node(project, compute, "test", node_type="vpcs")
- project._nodes[node.id] = node
- return node
-
-
-async def test_create_node(app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
-
- response = MagicMock()
- response.json = {"console": 2048}
- compute.post = AsyncioMagicMock(return_value=response)
-
- response = await client.post(app.url_path_for("create_node", project_id=project.id), json={
- "name": "test",
- "node_type": "vpcs",
- "compute_id": "example.com",
- "properties": {
- "startup_script": "echo test"
- }
- })
-
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["name"] == "test"
- assert "name" not in response.json()["properties"]
-
-
-async def test_list_node(app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
-
- response = MagicMock()
- response.json = {"console": 2048}
- compute.post = AsyncioMagicMock(return_value=response)
-
- await client.post(app.url_path_for("create_node", project_id=project.id), json={
- "name": "test",
- "node_type": "vpcs",
- "compute_id": "example.com",
- "properties": {
- "startup_script": "echo test"
- }
- })
-
- response = await client.get(app.url_path_for("get_nodes", project_id=project.id))
- assert response.status_code == status.HTTP_200_OK
- assert response.json()[0]["name"] == "test"
-
- # test listing nodes from a closed project
- await project.close(ignore_notification=True)
- response = await client.get(app.url_path_for("get_nodes", project_id=project.id))
- assert response.status_code == status.HTTP_200_OK
- assert response.json()[0]["name"] == "test"
-
-
-async def test_get_node(app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
-
- response = MagicMock()
- response.json = {"console": 2048}
- compute.post = AsyncioMagicMock(return_value=response)
-
- response = await client.post(app.url_path_for("create_node", project_id=project.id), json={
- "name": "test",
- "node_type": "vpcs",
- "compute_id": "example.com",
- "properties": {
- "startup_script": "echo test"
- }
- })
-
- response = await client.get(app.url_path_for("get_node", project_id=project.id, node_id=response.json()["node_id"]))
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["name"] == "test"
-
-
-async def test_update_node(app: FastAPI, client: AsyncClient, project: Project, compute: Compute, node: Node) -> None:
-
- response = MagicMock()
- response.json = {"console": 2048}
- compute.put = AsyncioMagicMock(return_value=response)
-
- response = await client.put(app.url_path_for("update_node", project_id=project.id, node_id=node.id), json={
- "name": "test",
- "node_type": "vpcs",
- "compute_id": "example.com",
- "properties": {
- "startup_script": "echo test"
- }
- })
-
- assert response.status_code == 200
- assert response.json()["name"] == "test"
- assert "name" not in response.json()["properties"]
-
-
-async def test_start_all_nodes(app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
-
- compute.post = AsyncioMagicMock()
- response = await client.post(app.url_path_for("start_all_nodes", project_id=project.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_stop_all_nodes(app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
-
- compute.post = AsyncioMagicMock()
- response = await client.post(app.url_path_for("stop_all_nodes", project_id=project.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_suspend_all_nodes(app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
-
- compute.post = AsyncioMagicMock()
- response = await client.post(app.url_path_for("suspend_all_nodes", project_id=project.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_reload_all_nodes(app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
-
- compute.post = AsyncioMagicMock()
- response = await client.post(app.url_path_for("reload_all_nodes", project_id=project.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_reset_console_all_nodes(app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
-
- compute.post = AsyncioMagicMock()
- response = await client.post(app.url_path_for("reset_console_all_nodes", project_id=project.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_start_node(app: FastAPI, client: AsyncClient, project: Project, compute: Compute, node: Node) -> None:
-
- compute.post = AsyncioMagicMock()
- response = await client.post(app.url_path_for("start_node", project_id=project.id, node_id=node.id), json={})
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_stop_node(app: FastAPI, client: AsyncClient, project: Project, compute: Compute, node: Node) -> None:
-
- compute.post = AsyncioMagicMock()
- response = await client.post(app.url_path_for("stop_node", project_id=project.id, node_id=node.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-async def test_suspend_node(app: FastAPI, client: AsyncClient, project: Project, compute: Compute, node: Node) -> None:
-
- compute.post = AsyncioMagicMock()
- response = await client.post(app.url_path_for("suspend_node", project_id=project.id, node_id=node.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_reload_node(app: FastAPI, client: AsyncClient, project: Project, compute: Compute, node: Node):
-
- compute.post = AsyncioMagicMock()
- response = await client.post(app.url_path_for("reload_node", project_id=project.id, node_id=node.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_isolate_node(app: FastAPI, client: AsyncClient, project: Project, compute: Compute, node: Node):
-
- compute.post = AsyncioMagicMock()
- response = await client.post(app.url_path_for("isolate_node", project_id=project.id, node_id=node.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_unisolate_node(app: FastAPI, client: AsyncClient, project: Project, compute: Compute, node: Node):
-
- compute.post = AsyncioMagicMock()
- response = await client.post(app.url_path_for("unisolate_node", project_id=project.id, node_id=node.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_duplicate_node(
- app: FastAPI,
- client: AsyncClient,
- project: Project,
- compute: Compute,
- node: Node) -> None:
-
- response = MagicMock()
- response.json({"console": 2035})
- compute.post = AsyncioMagicMock(return_value=response)
-
- response = await client.post(app.url_path_for("duplicate_node", project_id=project.id, node_id=node.id),
- json={"x": 10, "y": 5, "z": 0})
- assert response.status_code == status.HTTP_201_CREATED
-
-
-async def test_delete_node(app: FastAPI, client: AsyncClient, project: Project, compute: Compute, node: Node) -> None:
-
- compute.post = AsyncioMagicMock()
- response = await client.delete(app.url_path_for("delete_node", project_id=project.id, node_id=node.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_dynamips_idle_pc(
- app: FastAPI,
- client: AsyncClient,
- project: Project,
- compute: Compute,
- node: Node
-) -> None:
-
- response = MagicMock()
- response.json = {"idlepc": "0x60606f54"}
- compute.get = AsyncioMagicMock(return_value=response)
-
- node._node_type = "dynamips" # force Dynamips node type
- response = await client.get(app.url_path_for("auto_idlepc", project_id=project.id, node_id=node.id))
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["idlepc"] == "0x60606f54"
-
-
-async def test_dynamips_idle_pc_wrong_node_type(
- app: FastAPI,
- client: AsyncClient,
- project: Project,
- compute: Compute,
- node: Node
-) -> None:
-
- response = await client.get(app.url_path_for("auto_idlepc", project_id=project.id, node_id=node.id))
- assert response.status_code == status.HTTP_400_BAD_REQUEST
-
-
-async def test_dynamips_idlepc_proposals(
- app: FastAPI,
- client: AsyncClient,
- project: Project,
- compute: Compute,
- node: Node
-) -> None:
-
- response = MagicMock()
- response.json = ["0x60606f54", "0x33805a22"]
- compute.get = AsyncioMagicMock(return_value=response)
-
- node._node_type = "dynamips" # force Dynamips node type
- response = await client.get(app.url_path_for("idlepc_proposals", project_id=project.id, node_id=node.id))
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == ["0x60606f54", "0x33805a22"]
-
-
-async def test_dynamips_idlepc_proposals_wrong_node_type(
- app: FastAPI,
- client: AsyncClient,
- project: Project,
- compute: Compute,
- node: Node
-) -> None:
-
- response = await client.get(app.url_path_for("idlepc_proposals", project_id=project.id, node_id=node.id))
- assert response.status_code == status.HTTP_400_BAD_REQUEST
-
-
-async def test_qemu_disk_image_create(
- app: FastAPI,
- client: AsyncClient,
- project: Project,
- compute: Compute,
- node: Node
-) -> None:
-
- response = MagicMock()
- compute.post = AsyncioMagicMock(return_value=response)
-
- node._node_type = "qemu" # force Qemu node type
- response = await client.post(
- app.url_path_for("create_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2"),
- json={"format": "qcow2", "size": 30}
- )
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_qemu_disk_image_create_wrong_node_type(
- app: FastAPI,
- client: AsyncClient,
- project: Project,
- compute: Compute,
- node: Node
-) -> None:
-
- response = await client.post(
- app.url_path_for("create_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2"),
- json={"format": "qcow2", "size": 30}
- )
- assert response.status_code == status.HTTP_400_BAD_REQUEST
-
-
-async def test_qemu_disk_image_update(
- app: FastAPI,
- client: AsyncClient,
- project: Project,
- compute: Compute,
- node: Node
-) -> None:
-
- response = MagicMock()
- compute.put = AsyncioMagicMock(return_value=response)
-
- node._node_type = "qemu" # force Qemu node type
- response = await client.put(
- app.url_path_for("update_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2"),
- json={"extend": 10}
- )
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_qemu_disk_image_update_wrong_node_type(
- app: FastAPI,
- client: AsyncClient,
- project: Project,
- compute: Compute,
- node: Node
-) -> None:
-
- response = await client.put(
- app.url_path_for("update_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2"),
- json={"extend": 10}
- )
- assert response.status_code == status.HTTP_400_BAD_REQUEST
-
-
-async def test_qemu_disk_image_delete(
- app: FastAPI,
- client: AsyncClient,
- project: Project,
- compute: Compute,
- node: Node
-) -> None:
-
- response = MagicMock()
- compute.delete = AsyncioMagicMock(return_value=response)
-
- node._node_type = "qemu" # force Qemu node type
- response = await client.delete(
- app.url_path_for("delete_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2")
- )
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
-
-async def test_qemu_disk_image_delete_wrong_node_type(
- app: FastAPI,
- client: AsyncClient,
- project: Project,
- compute: Compute,
- node: Node
-) -> None:
-
- response = await client.delete(
- app.url_path_for("delete_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2")
- )
- assert response.status_code == status.HTTP_400_BAD_REQUEST
-
-
-async def test_get_file(app: FastAPI, client: AsyncClient, project: Project, compute: Compute, node: Node) -> None:
-
- response = MagicMock()
- response.body = b"world"
- response.status = status.HTTP_200_OK
- compute.http_query = AsyncioMagicMock(return_value=response)
-
- response = await client.get(app.url_path_for("get_file", project_id=project.id, node_id=node.id, file_path="hello"))
- assert response.status_code == status.HTTP_200_OK
- assert response.content == b'world'
-
- compute.http_query.assert_called_with(
- "GET",
- "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello".format(
+class TestNodeRoutes:
+
+
+ @pytest.fixture
+ def node(self, project: Project, compute: Compute) -> Node:
+
+ node = Node(project, compute, "test", node_type="vpcs")
+ project._nodes[node.id] = node
+ return node
+
+
+ async def test_create_node(self, app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
+
+ response = MagicMock()
+ response.json = {"console": 2048}
+ compute.post = AsyncioMagicMock(return_value=response)
+
+ response = await client.post(app.url_path_for("create_node", project_id=project.id), json={
+ "name": "test",
+ "node_type": "vpcs",
+ "compute_id": "example.com",
+ "properties": {
+ "startup_script": "echo test"
+ }
+ })
+
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["name"] == "test"
+ assert "name" not in response.json()["properties"]
+
+
+ async def test_list_node(self, app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
+
+ response = MagicMock()
+ response.json = {"console": 2048}
+ compute.post = AsyncioMagicMock(return_value=response)
+
+ await client.post(app.url_path_for("create_node", project_id=project.id), json={
+ "name": "test",
+ "node_type": "vpcs",
+ "compute_id": "example.com",
+ "properties": {
+ "startup_script": "echo test"
+ }
+ })
+
+ response = await client.get(app.url_path_for("get_nodes", project_id=project.id))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()[0]["name"] == "test"
+
+ # test listing nodes from a closed project
+ await project.close(ignore_notification=True)
+ response = await client.get(app.url_path_for("get_nodes", project_id=project.id))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()[0]["name"] == "test"
+
+
+ async def test_get_node(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute
+ ) -> None:
+
+ response = MagicMock()
+ response.json = {"console": 2048}
+ compute.post = AsyncioMagicMock(return_value=response)
+
+ response = await client.post(app.url_path_for("create_node", project_id=project.id), json={
+ "name": "test",
+ "node_type": "vpcs",
+ "compute_id": "example.com",
+ "properties": {
+ "startup_script": "echo test"
+ }
+ })
+
+ response = await client.get(app.url_path_for("get_node", project_id=project.id, node_id=response.json()["node_id"]))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["name"] == "test"
+
+
+ async def test_update_node(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = MagicMock()
+ response.json = {"console": 2048}
+ compute.put = AsyncioMagicMock(return_value=response)
+
+ response = await client.put(app.url_path_for("update_node", project_id=project.id, node_id=node.id), json={
+ "name": "test",
+ "node_type": "vpcs",
+ "compute_id": "example.com",
+ "properties": {
+ "startup_script": "echo test"
+ }
+ })
+
+ assert response.status_code == 200
+ assert response.json()["name"] == "test"
+ assert "name" not in response.json()["properties"]
+
+
+ async def test_start_all_nodes(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute
+ ) -> None:
+
+ compute.post = AsyncioMagicMock()
+ response = await client.post(app.url_path_for("start_all_nodes", project_id=project.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_stop_all_nodes(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute
+ ) -> None:
+
+ compute.post = AsyncioMagicMock()
+ response = await client.post(app.url_path_for("stop_all_nodes", project_id=project.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_suspend_all_nodes(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute
+ ) -> None:
+
+ compute.post = AsyncioMagicMock()
+ response = await client.post(app.url_path_for("suspend_all_nodes", project_id=project.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_reload_all_nodes(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute
+ ) -> None:
+
+ compute.post = AsyncioMagicMock()
+ response = await client.post(app.url_path_for("reload_all_nodes", project_id=project.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_reset_console_all_nodes(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute
+ ) -> None:
+
+ compute.post = AsyncioMagicMock()
+ response = await client.post(app.url_path_for("reset_console_all_nodes", project_id=project.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_start_node(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ compute.post = AsyncioMagicMock()
+ response = await client.post(app.url_path_for("start_node", project_id=project.id, node_id=node.id), json={})
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_stop_node(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ compute.post = AsyncioMagicMock()
+ response = await client.post(app.url_path_for("stop_node", project_id=project.id, node_id=node.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+ async def test_suspend_node(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ compute.post = AsyncioMagicMock()
+ response = await client.post(app.url_path_for("suspend_node", project_id=project.id, node_id=node.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_reload_node(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ):
+
+ compute.post = AsyncioMagicMock()
+ response = await client.post(app.url_path_for("reload_node", project_id=project.id, node_id=node.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_isolate_node(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ):
+
+ compute.post = AsyncioMagicMock()
+ response = await client.post(app.url_path_for("isolate_node", project_id=project.id, node_id=node.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_unisolate_node(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ compute.post = AsyncioMagicMock()
+ response = await client.post(app.url_path_for("unisolate_node", project_id=project.id, node_id=node.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_duplicate_node(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = MagicMock()
+ response.json({"console": 2035})
+ compute.post = AsyncioMagicMock(return_value=response)
+
+ response = await client.post(app.url_path_for("duplicate_node", project_id=project.id, node_id=node.id),
+ json={"x": 10, "y": 5, "z": 0})
+ assert response.status_code == status.HTTP_201_CREATED
+
+
+ async def test_delete_node(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ compute.post = AsyncioMagicMock()
+ response = await client.delete(app.url_path_for("delete_node", project_id=project.id, node_id=node.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_dynamips_idle_pc(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = MagicMock()
+ response.json = {"idlepc": "0x60606f54"}
+ compute.get = AsyncioMagicMock(return_value=response)
+
+ node._node_type = "dynamips" # force Dynamips node type
+ response = await client.get(app.url_path_for("auto_idlepc", project_id=project.id, node_id=node.id))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["idlepc"] == "0x60606f54"
+
+
+ async def test_dynamips_idle_pc_wrong_node_type(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = await client.get(app.url_path_for("auto_idlepc", project_id=project.id, node_id=node.id))
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+
+ async def test_dynamips_idlepc_proposals(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = MagicMock()
+ response.json = ["0x60606f54", "0x33805a22"]
+ compute.get = AsyncioMagicMock(return_value=response)
+
+ node._node_type = "dynamips" # force Dynamips node type
+ response = await client.get(app.url_path_for("idlepc_proposals", project_id=project.id, node_id=node.id))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json() == ["0x60606f54", "0x33805a22"]
+
+
+ async def test_dynamips_idlepc_proposals_wrong_node_type(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = await client.get(app.url_path_for("idlepc_proposals", project_id=project.id, node_id=node.id))
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+
+ async def test_qemu_disk_image_create(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = MagicMock()
+ compute.post = AsyncioMagicMock(return_value=response)
+
+ node._node_type = "qemu" # force Qemu node type
+ response = await client.post(
+ app.url_path_for("create_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2"),
+ json={"format": "qcow2", "size": 30}
+ )
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_qemu_disk_image_create_wrong_node_type(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = await client.post(
+ app.url_path_for("create_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2"),
+ json={"format": "qcow2", "size": 30}
+ )
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+
+ async def test_qemu_disk_image_update(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = MagicMock()
+ compute.put = AsyncioMagicMock(return_value=response)
+
+ node._node_type = "qemu" # force Qemu node type
+ response = await client.put(
+ app.url_path_for("update_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2"),
+ json={"extend": 10}
+ )
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_qemu_disk_image_update_wrong_node_type(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = await client.put(
+ app.url_path_for("update_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2"),
+ json={"extend": 10}
+ )
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+
+ async def test_qemu_disk_image_delete(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = MagicMock()
+ compute.delete = AsyncioMagicMock(return_value=response)
+
+ node._node_type = "qemu" # force Qemu node type
+ response = await client.delete(
+ app.url_path_for("delete_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2")
+ )
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+
+ async def test_qemu_disk_image_delete_wrong_node_type(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = await client.delete(
+ app.url_path_for("delete_disk_image", project_id=project.id, node_id=node.id, disk_name="hda_disk.qcow2")
+ )
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+
+ async def test_get_file(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ response = MagicMock()
+ response.body = b"world"
+ response.status = status.HTTP_200_OK
+ compute.http_query = AsyncioMagicMock(return_value=response)
+
+ response = await client.get(app.url_path_for("get_file", project_id=project.id, node_id=node.id, file_path="hello"))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.content == b'world'
+
+ compute.http_query.assert_called_with(
+ "GET",
+ "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello".format(
+ project_id=project.id,
+ node_id=node.id),
+ timeout=None,
+ raw=True)
+
+ response = await client.get(app.url_path_for(
+ "get_file",
project_id=project.id,
- node_id=node.id),
- timeout=None,
- raw=True)
-
- response = await client.get(app.url_path_for(
- "get_file",
- project_id=project.id,
- node_id=node.id,
- file_path="../hello"))
- assert response.status_code == status.HTTP_404_NOT_FOUND
-
-
-async def test_post_file(app: FastAPI, client: AsyncClient, project: Project, compute: Compute, node: Node) -> None:
-
- compute.http_query = AsyncioMagicMock()
- response = await client.post(app.url_path_for(
- "post_file",
- project_id=project.id,
- node_id=node.id,
- file_path="hello"), content=b"hello")
- assert response.status_code == status.HTTP_201_CREATED
-
- compute.http_query.assert_called_with("POST", "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello".format(project_id=project.id, node_id=node.id), data=b'hello', timeout=None, raw=True)
-
- response = await client.get("/projects/{project_id}/nodes/{node_id}/files/../hello".format(project_id=project.id, node_id=node.id))
- assert response.status_code == status.HTTP_404_NOT_FOUND
-
-
-# @pytest.mark.asyncio
-# async def test_get_and_post_with_nested_paths_normalization(controller_api, project, node, compute):
-#
-# response = MagicMock()
-# response.body = b"world"
-# compute.http_query = AsyncioMagicMock(return_value=response)
-# response = await controller_api.get("/projects/{project_id}/nodes/{node_id}/files/hello\\nested".format(project_id=project.id, node_id=node.id))
-# assert response.status_code == 200
-# assert response.content == b'world'
-#
-# compute.http_query.assert_called_with("GET", "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello/nested".format(project_id=project.id, node_id=node.id), timeout=None, raw=True)
-#
-# compute.http_query = AsyncioMagicMock()
-# response = await controller_api.post("/projects/{project_id}/nodes/{node_id}/files/hello\\nested".format(project_id=project.id, node_id=node.id), body=b"hello", raw=True)
-# assert response.status_code == 201
-#
-# compute.http_query.assert_called_with("POST", "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello/nested".format(project_id=project.id, node_id=node.id), data=b'hello', timeout=None, raw=True)
+ node_id=node.id,
+ file_path="../hello"))
+ assert response.status_code == status.HTTP_404_NOT_FOUND
+
+
+ async def test_post_file(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ compute: Compute,
+ node: Node
+ ) -> None:
+
+ compute.http_query = AsyncioMagicMock()
+ response = await client.post(app.url_path_for(
+ "post_file",
+ project_id=project.id,
+ node_id=node.id,
+ file_path="hello"), content=b"hello")
+ assert response.status_code == status.HTTP_201_CREATED
+
+ compute.http_query.assert_called_with("POST", "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello".format(project_id=project.id, node_id=node.id), data=b'hello', timeout=None, raw=True)
+
+ response = await client.get("/projects/{project_id}/nodes/{node_id}/files/../hello".format(project_id=project.id, node_id=node.id))
+ assert response.status_code == status.HTTP_404_NOT_FOUND
+
+
+ # @pytest.mark.asyncio
+ # async def test_get_and_post_with_nested_paths_normalization(controller_api, project, node, compute):
+ #
+ # response = MagicMock()
+ # response.body = b"world"
+ # compute.http_query = AsyncioMagicMock(return_value=response)
+ # response = await controller_api.get("/projects/{project_id}/nodes/{node_id}/files/hello\\nested".format(project_id=project.id, node_id=node.id))
+ # assert response.status_code == 200
+ # assert response.content == b'world'
+ #
+ # compute.http_query.assert_called_with("GET", "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello/nested".format(project_id=project.id, node_id=node.id), timeout=None, raw=True)
+ #
+ # compute.http_query = AsyncioMagicMock()
+ # response = await controller_api.post("/projects/{project_id}/nodes/{node_id}/files/hello\\nested".format(project_id=project.id, node_id=node.id), body=b"hello", raw=True)
+ # assert response.status_code == 201
+ #
+ # compute.http_query.assert_called_with("POST", "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello/nested".format(project_id=project.id, node_id=node.id), data=b'hello', timeout=None, raw=True)
diff --git a/tests/api/routes/controller/test_projects.py b/tests/api/routes/controller/test_projects.py
index e1eac28b..cd3439c0 100644
--- a/tests/api/routes/controller/test_projects.py
+++ b/tests/api/routes/controller/test_projects.py
@@ -34,491 +34,544 @@ from gns3server.controller.compute import Compute
pytestmark = pytest.mark.asyncio
-@pytest_asyncio.fixture
-async def project(app: FastAPI, client: AsyncClient, controller: Controller) -> Project:
+class TestControllerProjectRoutes:
- project_id = str(uuid.uuid4())
- params = {"name": "test", "project_id": project_id}
- await client.post(app.url_path_for("create_project"), json=params)
- return controller.get_project(project_id)
-
-
-async def test_create_project_with_path(app: FastAPI, client: AsyncClient, controller: Controller, config) -> None:
-
- params = {"name": "test", "path": str(config.settings.Server.projects_path), "project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f"}
- response = await client.post(app.url_path_for("create_project"), json=params)
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["name"] == "test"
- assert response.json()["project_id"] == "00010203-0405-0607-0809-0a0b0c0d0e0f"
- assert response.json()["status"] == "opened"
-
-
-async def test_create_project_without_dir(app: FastAPI, client: AsyncClient, controller: Controller) -> None:
-
- params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f"}
- response = await client.post(app.url_path_for("create_project"), json=params)
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["project_id"] == "10010203-0405-0607-0809-0a0b0c0d0e0f"
- assert response.json()["name"] == "test"
-
-
-async def test_create_project_with_uuid(app: FastAPI, client: AsyncClient, controller: Controller) -> None:
-
- params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f"}
- response = await client.post(app.url_path_for("create_project"), json=params)
- assert response.status_code == 201
- assert response.json()["project_id"] == "30010203-0405-0607-0809-0a0b0c0d0e0f"
- assert response.json()["name"] == "test"
-
-
-async def test_create_project_with_variables(app: FastAPI, client: AsyncClient, controller: Controller) -> None:
-
- variables = [
- {"name": "TEST1"},
- {"name": "TEST2", "value": "value1"}
- ]
- params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f", "variables": variables}
- response = await client.post(app.url_path_for("create_project"), json=params)
- assert response.status_code == 201
- assert response.json()["variables"] == [
- {"name": "TEST1"},
- {"name": "TEST2", "value": "value1"}
- ]
-
-
-async def test_create_project_with_supplier(app: FastAPI, client: AsyncClient, controller: Controller) -> None:
-
- supplier = {
- 'logo': 'logo.png',
- 'url': 'http://example.com/'
- }
- params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f", "supplier": supplier}
- response = await client.post(app.url_path_for("create_project"), json=params)
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["supplier"] == supplier
-
-
-async def test_update_project(app: FastAPI, client: AsyncClient, controller: Controller) -> None:
-
- params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f"}
- response = await client.post(app.url_path_for("create_project"), json=params)
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["project_id"] == "10010203-0405-0607-0809-0a0b0c0d0e0f"
- assert response.json()["name"] == "test"
-
- params = {"name": "test2"}
- response = await client.put(app.url_path_for("update_project", project_id="10010203-0405-0607-0809-0a0b0c0d0e0f"),
- json=params)
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["name"] == "test2"
-
-
-async def test_update_project_with_variables(app: FastAPI, client: AsyncClient, controller: Controller) -> None:
-
- variables = [
- {"name": "TEST1"},
- {"name": "TEST2", "value": "value1"}
- ]
- params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f", "variables": variables}
- response = await client.post(app.url_path_for("create_project"), json=params)
- assert response.status_code == status.HTTP_201_CREATED
-
- params = {"name": "test2"}
- response = await client.put(app.url_path_for("update_project", project_id="10010203-0405-0607-0809-0a0b0c0d0e0f"),
- json=params)
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["variables"] == variables
-
-
-async def test_list_projects(app: FastAPI, client: AsyncClient, controller: Controller) -> None:
-
- params = {"name": "test", "project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f"}
- await client.post(app.url_path_for("create_project"), json=params)
- response = await client.get(app.url_path_for("get_projects"))
- assert response.status_code == status.HTTP_200_OK
- projects = response.json()
- assert projects[0]["name"] == "test"
-
-
-async def test_get_project(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- response = await client.get(app.url_path_for("get_project", project_id=project.id))
- assert response.status_code == status.HTTP_200_OK
- assert response.json()["name"] == "test"
-
-
-async def test_delete_project(app: FastAPI, client: AsyncClient, project: Project, controller: Controller) -> None:
-
- with asyncio_patch("gns3server.controller.project.Project.delete", return_value=True) as mock:
- response = await client.delete(app.url_path_for("delete_project", project_id=project.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
- assert mock.called
- assert project not in controller.projects
-
-
-async def test_delete_project_invalid_uuid(app: FastAPI, client: AsyncClient) -> None:
-
- response = await client.delete(app.url_path_for("delete_project", project_id=str(uuid.uuid4())))
- assert response.status_code == status.HTTP_404_NOT_FOUND
-
-
-async def test_close_project(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- with asyncio_patch("gns3server.controller.project.Project.close", return_value=True) as mock:
- response = await client.post(app.url_path_for("close_project", project_id=project.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
- assert mock.called
-
-
-async def test_open_project(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- with asyncio_patch("gns3server.controller.project.Project.open", return_value=True) as mock:
- response = await client.post(app.url_path_for("open_project", project_id=project.id))
+ @pytest_asyncio.fixture
+ async def project(self, app: FastAPI, client: AsyncClient, controller: Controller) -> Project:
+
+ project_id = str(uuid.uuid4())
+ params = {"name": "test", "project_id": project_id}
+ await client.post(app.url_path_for("create_project"), json=params)
+ return controller.get_project(project_id)
+
+
+ async def test_create_project_with_path(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ controller: Controller,
+ config
+ ) -> None:
+
+ params = {"name": "test", "path": str(config.settings.Server.projects_path), "project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f"}
+ response = await client.post(app.url_path_for("create_project"), json=params)
assert response.status_code == status.HTTP_201_CREATED
- assert mock.called
-
-
-async def test_load_project(app: FastAPI, client: AsyncClient, project: Project, config) -> None:
-
- with asyncio_patch("gns3server.controller.Controller.load_project", return_value=project) as mock:
- response = await client.post(app.url_path_for("load_project"), json={"path": "/tmp/test.gns3"})
+ assert response.json()["name"] == "test"
+ assert response.json()["project_id"] == "00010203-0405-0607-0809-0a0b0c0d0e0f"
+ assert response.json()["status"] == "opened"
+
+
+ async def test_create_project_without_dir(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ controller: Controller
+ ) -> None:
+
+ params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f"}
+ response = await client.post(app.url_path_for("create_project"), json=params)
assert response.status_code == status.HTTP_201_CREATED
- mock.assert_called_with("/tmp/test.gns3")
- assert response.json()["project_id"] == project.id
+ assert response.json()["project_id"] == "10010203-0405-0607-0809-0a0b0c0d0e0f"
+ assert response.json()["name"] == "test"
+
+
+ async def test_create_project_with_uuid(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ controller: Controller
+ ) -> None:
+
+ params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f"}
+ response = await client.post(app.url_path_for("create_project"), json=params)
+ assert response.status_code == 201
+ assert response.json()["project_id"] == "30010203-0405-0607-0809-0a0b0c0d0e0f"
+ assert response.json()["name"] == "test"
+
+
+ async def test_create_project_with_variables(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ controller: Controller
+ ) -> None:
+
+ variables = [
+ {"name": "TEST1"},
+ {"name": "TEST2", "value": "value1"}
+ ]
+ params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f", "variables": variables}
+ response = await client.post(app.url_path_for("create_project"), json=params)
+ assert response.status_code == 201
+ assert response.json()["variables"] == [
+ {"name": "TEST1"},
+ {"name": "TEST2", "value": "value1"}
+ ]
+
-
-# @pytest.mark.asyncio
-# async def test_notification(controller_api, http_client, project, controller):
-#
-# async with http_client.get(controller_api.get_url("/projects/{project_id}/notifications".format(project_id=project.id))) as response:
-# response.body = await response.content.read(200)
-# controller.notification.project_emit("node.created", {"a": "b"})
-# response.body += await response.content.readany()
-# assert response.status_code == 200
-# assert b'"action": "ping"' in response.body
-# assert b'"cpu_usage_percent"' in response.body
-# assert b'{"action": "node.created", "event": {"a": "b"}}\n' in response.body
-# assert project.status_code == "opened"
-#
-#
-# @pytest.mark.asyncio
-# async def test_notification_invalid_id(controller_api):
-#
-# response = await controller_api.get("/projects/{project_id}/notifications".format(project_id=uuid.uuid4()))
-# assert response.status_code == 404
-
-
-# @pytest.mark.asyncio
-# async def test_notification_ws(controller_api, http_client, controller, project):
-#
-# ws = await http_client.ws_connect(controller_api.get_url("/projects/{project_id}/notifications/ws".format(project_id=project.id)))
-# answer = await ws.receive()
-# answer = json.loads(answer.data)
-# assert answer["action"] == "ping"
-#
-# controller.notification.project_emit("test", {})
-# answer = await ws.receive()
-# answer = json.loads(answer.data)
-# assert answer["action"] == "test"
-#
-# if not ws.closed:
-# await ws.close()
-#
-# assert project.status_code == "opened"
-
-
-async def test_export_with_images(app: FastAPI, client: AsyncClient, tmpdir, project: Project) -> None:
-
- project.dump = MagicMock()
- os.makedirs(project.path, exist_ok=True)
- with open(os.path.join(project.path, 'a'), 'w+') as f:
- f.write('hello')
-
- os.makedirs(str(tmpdir / "IOS"))
- with open(str(tmpdir / "IOS" / "test.image"), "w+") as f:
- f.write("AAA")
-
- topology = {
- "topology": {
- "nodes": [
- {
- "properties": {
- "image": "test.image"
- },
- "node_type": "dynamips"
- }
- ]
+ async def test_create_project_with_supplier(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ controller: Controller
+ ) -> None:
+
+ supplier = {
+ 'logo': 'logo.png',
+ 'url': 'http://example.com/'
}
- }
- with open(os.path.join(project.path, "test.gns3"), 'w+') as f:
- json.dump(topology, f)
-
- with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS")):
- response = await client.get(app.url_path_for("export_project", project_id=project.id),
- params={"include_images": "yes"})
- assert response.status_code == status.HTTP_200_OK
- assert response.headers['CONTENT-TYPE'] == 'application/gns3project'
- assert response.headers['CONTENT-DISPOSITION'] == 'attachment; filename="{}.gns3project"'.format(project.name)
-
- with open(str(tmpdir / 'project.zip'), 'wb+') as f:
- f.write(response.content)
-
- with zipfile_zstd.ZipFile(str(tmpdir / 'project.zip')) as myzip:
- with myzip.open("a") as myfile:
- content = myfile.read()
- assert content == b"hello"
- myzip.getinfo("images/IOS/test.image")
-
-
-async def test_export_without_images(app: FastAPI, client: AsyncClient, tmpdir, project: Project) -> None:
-
- project.dump = MagicMock()
- os.makedirs(project.path, exist_ok=True)
- with open(os.path.join(project.path, 'a'), 'w+') as f:
- f.write('hello')
-
- os.makedirs(str(tmpdir / "IOS"))
- with open(str(tmpdir / "IOS" / "test.image"), "w+") as f:
- f.write("AAA")
-
- topology = {
- "topology": {
- "nodes": [
- {
- "properties": {
- "image": "test.image"
- },
- "node_type": "dynamips"
- }
- ]
+ params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f", "supplier": supplier}
+ response = await client.post(app.url_path_for("create_project"), json=params)
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["supplier"] == supplier
+
+
+ async def test_update_project(self, app: FastAPI, client: AsyncClient, controller: Controller) -> None:
+
+ params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f"}
+ response = await client.post(app.url_path_for("create_project"), json=params)
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["project_id"] == "10010203-0405-0607-0809-0a0b0c0d0e0f"
+ assert response.json()["name"] == "test"
+
+ params = {"name": "test2"}
+ response = await client.put(app.url_path_for("update_project", project_id="10010203-0405-0607-0809-0a0b0c0d0e0f"),
+ json=params)
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["name"] == "test2"
+
+
+ async def test_update_project_with_variables(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ controller: Controller
+ ) -> None:
+
+ variables = [
+ {"name": "TEST1"},
+ {"name": "TEST2", "value": "value1"}
+ ]
+ params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f", "variables": variables}
+ response = await client.post(app.url_path_for("create_project"), json=params)
+ assert response.status_code == status.HTTP_201_CREATED
+
+ params = {"name": "test2"}
+ response = await client.put(app.url_path_for("update_project", project_id="10010203-0405-0607-0809-0a0b0c0d0e0f"),
+ json=params)
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["variables"] == variables
+
+
+ async def test_list_projects(self, app: FastAPI, client: AsyncClient, controller: Controller) -> None:
+
+ params = {"name": "test", "project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f"}
+ await client.post(app.url_path_for("create_project"), json=params)
+ response = await client.get(app.url_path_for("get_projects"))
+ assert response.status_code == status.HTTP_200_OK
+ projects = response.json()
+ assert projects[0]["name"] == "test"
+
+
+ async def test_get_project(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ response = await client.get(app.url_path_for("get_project", project_id=project.id))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["name"] == "test"
+
+
+ async def test_delete_project(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project,
+ controller: Controller
+ ) -> None:
+
+ with asyncio_patch("gns3server.controller.project.Project.delete", return_value=True) as mock:
+ response = await client.delete(app.url_path_for("delete_project", project_id=project.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+ assert mock.called
+ assert project not in controller.projects
+
+
+ async def test_delete_project_invalid_uuid(self, app: FastAPI, client: AsyncClient) -> None:
+
+ response = await client.delete(app.url_path_for("delete_project", project_id=str(uuid.uuid4())))
+ assert response.status_code == status.HTTP_404_NOT_FOUND
+
+
+ async def test_close_project(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ with asyncio_patch("gns3server.controller.project.Project.close", return_value=True) as mock:
+ response = await client.post(app.url_path_for("close_project", project_id=project.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+ assert mock.called
+
+
+ async def test_open_project(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ with asyncio_patch("gns3server.controller.project.Project.open", return_value=True) as mock:
+ response = await client.post(app.url_path_for("open_project", project_id=project.id))
+ assert response.status_code == status.HTTP_201_CREATED
+ assert mock.called
+
+
+ async def test_load_project(self, app: FastAPI, client: AsyncClient, project: Project, config) -> None:
+
+ with asyncio_patch("gns3server.controller.Controller.load_project", return_value=project) as mock:
+ response = await client.post(app.url_path_for("load_project"), json={"path": "/tmp/test.gns3"})
+ assert response.status_code == status.HTTP_201_CREATED
+ mock.assert_called_with("/tmp/test.gns3")
+ assert response.json()["project_id"] == project.id
+
+
+ # @pytest.mark.asyncio
+ # async def test_notification(controller_api, http_client, project, controller):
+ #
+ # async with http_client.get(controller_api.get_url("/projects/{project_id}/notifications".format(project_id=project.id))) as response:
+ # response.body = await response.content.read(200)
+ # controller.notification.project_emit("node.created", {"a": "b"})
+ # response.body += await response.content.readany()
+ # assert response.status_code == 200
+ # assert b'"action": "ping"' in response.body
+ # assert b'"cpu_usage_percent"' in response.body
+ # assert b'{"action": "node.created", "event": {"a": "b"}}\n' in response.body
+ # assert project.status_code == "opened"
+ #
+ #
+ # @pytest.mark.asyncio
+ # async def test_notification_invalid_id(controller_api):
+ #
+ # response = await controller_api.get("/projects/{project_id}/notifications".format(project_id=uuid.uuid4()))
+ # assert response.status_code == 404
+
+
+ # @pytest.mark.asyncio
+ # async def test_notification_ws(controller_api, http_client, controller, project):
+ #
+ # ws = await http_client.ws_connect(controller_api.get_url("/projects/{project_id}/notifications/ws".format(project_id=project.id)))
+ # answer = await ws.receive()
+ # answer = json.loads(answer.data)
+ # assert answer["action"] == "ping"
+ #
+ # controller.notification.project_emit("test", {})
+ # answer = await ws.receive()
+ # answer = json.loads(answer.data)
+ # assert answer["action"] == "test"
+ #
+ # if not ws.closed:
+ # await ws.close()
+ #
+ # assert project.status_code == "opened"
+
+
+ async def test_export_with_images(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ tmpdir,
+ project: Project
+ ) -> None:
+
+ project.dump = MagicMock()
+ os.makedirs(project.path, exist_ok=True)
+ with open(os.path.join(project.path, 'a'), 'w+') as f:
+ f.write('hello')
+
+ os.makedirs(str(tmpdir / "IOS"))
+ with open(str(tmpdir / "IOS" / "test.image"), "w+") as f:
+ f.write("AAA")
+
+ topology = {
+ "topology": {
+ "nodes": [
+ {
+ "properties": {
+ "image": "test.image"
+ },
+ "node_type": "dynamips"
+ }
+ ]
+ }
}
- }
- with open(os.path.join(project.path, "test.gns3"), 'w+') as f:
- json.dump(topology, f)
-
- with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS"),):
- response = await client.get(app.url_path_for("export_project", project_id=project.id),
- params={"include_images": "0"})
- assert response.status_code == status.HTTP_200_OK
- assert response.headers['CONTENT-TYPE'] == 'application/gns3project'
- assert response.headers['CONTENT-DISPOSITION'] == 'attachment; filename="{}.gns3project"'.format(project.name)
-
- with open(str(tmpdir / 'project.zip'), 'wb+') as f:
- f.write(response.content)
-
- with zipfile_zstd.ZipFile(str(tmpdir / 'project.zip')) as myzip:
- with myzip.open("a") as myfile:
- content = myfile.read()
- assert content == b"hello"
- # Image should not exported
- with pytest.raises(KeyError):
- myzip.getinfo("images/IOS/test.image")
-
-
-@pytest.mark.parametrize(
- "compression, compression_level, status_code",
- (
- ("none", None, status.HTTP_200_OK),
- ("none", 4, status.HTTP_400_BAD_REQUEST),
- ("zip", None, status.HTTP_200_OK),
- ("zip", 1, status.HTTP_200_OK),
- ("zip", 12, status.HTTP_400_BAD_REQUEST),
- ("bzip2", None, status.HTTP_200_OK),
- ("bzip2", 1, status.HTTP_200_OK),
- ("bzip2", 13, status.HTTP_400_BAD_REQUEST),
- ("lzma", None, status.HTTP_200_OK),
- ("lzma", 1, status.HTTP_400_BAD_REQUEST),
- ("zstd", None, status.HTTP_200_OK),
- ("zstd", 12, status.HTTP_200_OK),
- ("zstd", 23, status.HTTP_400_BAD_REQUEST),
- )
-)
-async def test_export_compression(
- app: FastAPI,
- client: AsyncClient,
- tmpdir,
- project: Project,
- compression: str,
- compression_level: int,
- status_code: int
-) -> None:
-
- project.dump = MagicMock()
- os.makedirs(project.path, exist_ok=True)
-
- topology = {
- "topology": {
- "nodes": [
- {
- "node_type": "qemu"
- }
- ]
- }
- }
- with open(os.path.join(project.path, "test.gns3"), 'w+') as f:
- json.dump(topology, f)
-
- params = {"compression": compression}
- if compression_level:
- params["compression_level"] = compression_level
- response = await client.get(app.url_path_for("export_project", project_id=project.id), params=params)
- assert response.status_code == status_code
-
- if response.status_code == status.HTTP_200_OK:
+ with open(os.path.join(project.path, "test.gns3"), 'w+') as f:
+ json.dump(topology, f)
+
+ with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS")):
+ response = await client.get(app.url_path_for("export_project", project_id=project.id),
+ params={"include_images": "yes"})
+ assert response.status_code == status.HTTP_200_OK
assert response.headers['CONTENT-TYPE'] == 'application/gns3project'
assert response.headers['CONTENT-DISPOSITION'] == 'attachment; filename="{}.gns3project"'.format(project.name)
-
+
with open(str(tmpdir / 'project.zip'), 'wb+') as f:
f.write(response.content)
-
+
with zipfile_zstd.ZipFile(str(tmpdir / 'project.zip')) as myzip:
- with myzip.open("project.gns3") as myfile:
- myfile.read()
-
-
-async def test_get_file(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- os.makedirs(project.path, exist_ok=True)
- with open(os.path.join(project.path, 'hello'), 'w+') as f:
- f.write('world')
-
- response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path="hello"))
- assert response.status_code == status.HTTP_200_OK
- assert response.content == b"world"
-
- response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path="false"))
- assert response.status_code == status.HTTP_404_NOT_FOUND
-
- response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path="../hello"))
- assert response.status_code == status.HTTP_404_NOT_FOUND
-
-
-async def test_get_file_forbidden_location(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- file_path = "foo/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
- response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path=file_path))
- assert response.status_code == status.HTTP_403_FORBIDDEN
-
-
-async def test_write_file(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- response = await client.post(app.url_path_for("write_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 client.post(app.url_path_for("write_file", project_id=project.id, file_path="../hello"))
- assert response.status_code == status.HTTP_404_NOT_FOUND
-
-
-async def test_write_file_forbidden_location(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- file_path = "%2e%2e/hello"
- response = await client.post(app.url_path_for("write_file", project_id=project.id, file_path=file_path),
- content=b"world")
- assert response.status_code == status.HTTP_403_FORBIDDEN
-
-
-async def test_write_and_get_file_with_leading_slashes_in_filename(
- app: FastAPI,
- client: AsyncClient,
- project: Project) -> None:
-
- response = await client.post(app.url_path_for("write_file", project_id=project.id, file_path="//hello"),
- content=b"world")
- assert response.status_code == status.HTTP_403_FORBIDDEN
-
- response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path="//hello"))
- assert response.status_code == status.HTTP_403_FORBIDDEN
-
-
-async def test_import(app: FastAPI, client: AsyncClient, tmpdir, controller: Controller) -> None:
-
- with zipfile_zstd.ZipFile(str(tmpdir / "test.zip"), 'w') as myzip:
- myzip.writestr("project.gns3", b'{"project_id": "c6992992-ac72-47dc-833b-54aa334bcd05", "version": "2.0.0", "name": "test"}')
- myzip.writestr("demo", b"hello")
-
- project_id = str(uuid.uuid4())
- with open(str(tmpdir / "test.zip"), "rb") as f:
- response = await client.post(app.url_path_for("import_project", project_id=project_id), content=f.read())
- assert response.status_code == status.HTTP_201_CREATED
-
- project = controller.get_project(project_id)
- with open(os.path.join(project.path, "demo")) as f:
- content = f.read()
- assert content == "hello"
-
-
-async def test_import_with_project_name(app: FastAPI, client: AsyncClient, tmpdir, controller: Controller) -> None:
-
- with zipfile_zstd.ZipFile(str(tmpdir / "test.zip"), 'w') as myzip:
- myzip.writestr("project.gns3", b'{"project_id": "c6992992-ac72-47dc-833b-54aa334bcd05", "version": "2.0.0", "name": "test"}')
- myzip.writestr("demo", b"hello")
-
- project_id = str(uuid.uuid4())
- with open(str(tmpdir / "test.zip"), "rb") as f:
- response = await client.post(
- app.url_path_for("import_project", project_id=project_id),
- content=f.read(),
- params={"name": "my-imported-project-name"}
- )
- assert response.status_code == status.HTTP_201_CREATED
- project = controller.get_project(project_id)
- assert project.name == "my-imported-project-name"
-
-
-async def test_duplicate(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- response = await client.post(app.url_path_for("duplicate_project", project_id=project.id), json={"name": "hello"})
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["name"] == "hello"
-
-
-async def test_lock_unlock(app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
-
- # add a drawing and node to the project
- params = {
- "svg": '',
- "x": 10,
- "y": 20,
- "z": 0
- }
-
- response = await client.post(app.url_path_for("create_drawing", project_id=project.id), json=params)
- assert response.status_code == status.HTTP_201_CREATED
-
- response = MagicMock()
- response.json = {"console": 2048}
- compute.post = AsyncioMagicMock(return_value=response)
-
- response = await client.post(app.url_path_for("create_node", project_id=project.id), json={
- "name": "test",
- "node_type": "vpcs",
- "compute_id": "example.com",
- "properties": {
- "startup_script": "echo test"
+ with myzip.open("a") as myfile:
+ content = myfile.read()
+ assert content == b"hello"
+ myzip.getinfo("images/IOS/test.image")
+
+
+ async def test_export_without_images(self, app: FastAPI, client: AsyncClient, tmpdir, project: Project) -> None:
+
+ project.dump = MagicMock()
+ os.makedirs(project.path, exist_ok=True)
+ with open(os.path.join(project.path, 'a'), 'w+') as f:
+ f.write('hello')
+
+ os.makedirs(str(tmpdir / "IOS"))
+ with open(str(tmpdir / "IOS" / "test.image"), "w+") as f:
+ f.write("AAA")
+
+ topology = {
+ "topology": {
+ "nodes": [
+ {
+ "properties": {
+ "image": "test.image"
+ },
+ "node_type": "dynamips"
+ }
+ ]
+ }
}
- })
- assert response.status_code == status.HTTP_201_CREATED
-
- response = await client.post(app.url_path_for("lock_project", project_id=project.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
- for drawing in project.drawings.values():
- assert drawing.locked is True
- for node in project.nodes.values():
- assert node.locked is True
-
- response = await client.get(app.url_path_for("locked_project", project_id=project.id))
- assert response.status_code == status.HTTP_200_OK
- assert response.json() is True
-
- response = await client.post(app.url_path_for("unlock_project", project_id=project.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
- for drawing in project.drawings.values():
- assert drawing.locked is False
- for node in project.nodes.values():
- assert node.locked is False
+ with open(os.path.join(project.path, "test.gns3"), 'w+') as f:
+ json.dump(topology, f)
+
+ with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS"),):
+ response = await client.get(app.url_path_for("export_project", project_id=project.id),
+ params={"include_images": "0"})
+ assert response.status_code == status.HTTP_200_OK
+ assert response.headers['CONTENT-TYPE'] == 'application/gns3project'
+ assert response.headers['CONTENT-DISPOSITION'] == 'attachment; filename="{}.gns3project"'.format(project.name)
+
+ with open(str(tmpdir / 'project.zip'), 'wb+') as f:
+ f.write(response.content)
+
+ with zipfile_zstd.ZipFile(str(tmpdir / 'project.zip')) as myzip:
+ with myzip.open("a") as myfile:
+ content = myfile.read()
+ assert content == b"hello"
+ # Image should not exported
+ with pytest.raises(KeyError):
+ myzip.getinfo("images/IOS/test.image")
+
+
+ @pytest.mark.parametrize(
+ "compression, compression_level, status_code",
+ (
+ ("none", None, status.HTTP_200_OK),
+ ("none", 4, status.HTTP_400_BAD_REQUEST),
+ ("zip", None, status.HTTP_200_OK),
+ ("zip", 1, status.HTTP_200_OK),
+ ("zip", 12, status.HTTP_400_BAD_REQUEST),
+ ("bzip2", None, status.HTTP_200_OK),
+ ("bzip2", 1, status.HTTP_200_OK),
+ ("bzip2", 13, status.HTTP_400_BAD_REQUEST),
+ ("lzma", None, status.HTTP_200_OK),
+ ("lzma", 1, status.HTTP_400_BAD_REQUEST),
+ ("zstd", None, status.HTTP_200_OK),
+ ("zstd", 12, status.HTTP_200_OK),
+ ("zstd", 23, status.HTTP_400_BAD_REQUEST),
+ )
+ )
+ async def test_export_compression(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ tmpdir,
+ project: Project,
+ compression: str,
+ compression_level: int,
+ status_code: int
+ ) -> None:
+
+ project.dump = MagicMock()
+ os.makedirs(project.path, exist_ok=True)
+
+ topology = {
+ "topology": {
+ "nodes": [
+ {
+ "node_type": "qemu"
+ }
+ ]
+ }
+ }
+ with open(os.path.join(project.path, "test.gns3"), 'w+') as f:
+ json.dump(topology, f)
+
+ params = {"compression": compression}
+ if compression_level:
+ params["compression_level"] = compression_level
+ response = await client.get(app.url_path_for("export_project", project_id=project.id), params=params)
+ assert response.status_code == status_code
+
+ if response.status_code == status.HTTP_200_OK:
+ assert response.headers['CONTENT-TYPE'] == 'application/gns3project'
+ assert response.headers['CONTENT-DISPOSITION'] == 'attachment; filename="{}.gns3project"'.format(project.name)
+
+ with open(str(tmpdir / 'project.zip'), 'wb+') as f:
+ f.write(response.content)
+
+ with zipfile_zstd.ZipFile(str(tmpdir / 'project.zip')) as myzip:
+ with myzip.open("project.gns3") as myfile:
+ myfile.read()
+
+
+ async def test_get_file(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ os.makedirs(project.path, exist_ok=True)
+ with open(os.path.join(project.path, 'hello'), 'w+') as f:
+ f.write('world')
+
+ response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path="hello"))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.content == b"world"
+
+ response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path="false"))
+ assert response.status_code == status.HTTP_404_NOT_FOUND
+
+ response = await client.get(app.url_path_for("get_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, client: AsyncClient, project: Project) -> None:
+
+ file_path = "foo/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
+ response = await client.get(app.url_path_for("get_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, client: AsyncClient, project: Project) -> None:
+
+ response = await client.post(app.url_path_for("write_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 client.post(app.url_path_for("write_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, client: AsyncClient, project: Project) -> None:
+
+ file_path = "%2e%2e/hello"
+ response = await client.post(app.url_path_for("write_file", project_id=project.id, file_path=file_path),
+ content=b"world")
+ assert response.status_code == status.HTTP_403_FORBIDDEN
+
+
+ async def test_write_and_get_file_with_leading_slashes_in_filename(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ project: Project) -> None:
+
+ response = await client.post(app.url_path_for("write_file", project_id=project.id, file_path="//hello"),
+ content=b"world")
+ assert response.status_code == status.HTTP_403_FORBIDDEN
+
+ response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path="//hello"))
+ assert response.status_code == status.HTTP_403_FORBIDDEN
+
+
+ async def test_import(self, app: FastAPI, client: AsyncClient, tmpdir, controller: Controller) -> None:
+
+ with zipfile_zstd.ZipFile(str(tmpdir / "test.zip"), 'w') as myzip:
+ myzip.writestr("project.gns3", b'{"project_id": "c6992992-ac72-47dc-833b-54aa334bcd05", "version": "2.0.0", "name": "test"}')
+ myzip.writestr("demo", b"hello")
+
+ project_id = str(uuid.uuid4())
+ with open(str(tmpdir / "test.zip"), "rb") as f:
+ response = await client.post(app.url_path_for("import_project", project_id=project_id), content=f.read())
+ assert response.status_code == status.HTTP_201_CREATED
+
+ project = controller.get_project(project_id)
+ with open(os.path.join(project.path, "demo")) as f:
+ content = f.read()
+ assert content == "hello"
+
+
+ async def test_import_with_project_name(
+ self,
+ app: FastAPI,
+ client: AsyncClient,
+ tmpdir,
+ controller: Controller
+ ) -> None:
+
+ with zipfile_zstd.ZipFile(str(tmpdir / "test.zip"), 'w') as myzip:
+ myzip.writestr("project.gns3", b'{"project_id": "c6992992-ac72-47dc-833b-54aa334bcd05", "version": "2.0.0", "name": "test"}')
+ myzip.writestr("demo", b"hello")
+
+ project_id = str(uuid.uuid4())
+ with open(str(tmpdir / "test.zip"), "rb") as f:
+ response = await client.post(
+ app.url_path_for("import_project", project_id=project_id),
+ content=f.read(),
+ params={"name": "my-imported-project-name"}
+ )
+ assert response.status_code == status.HTTP_201_CREATED
+ project = controller.get_project(project_id)
+ assert project.name == "my-imported-project-name"
+
+
+ async def test_duplicate(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ response = await client.post(app.url_path_for("duplicate_project", project_id=project.id), json={"name": "hello"})
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["name"] == "hello"
+
+
+ async def test_lock_unlock(self, app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
+
+ # add a drawing and node to the project
+ params = {
+ "svg": '',
+ "x": 10,
+ "y": 20,
+ "z": 0
+ }
+
+ response = await client.post(app.url_path_for("create_drawing", project_id=project.id), json=params)
+ assert response.status_code == status.HTTP_201_CREATED
+
+ response = MagicMock()
+ response.json = {"console": 2048}
+ compute.post = AsyncioMagicMock(return_value=response)
+
+ response = await client.post(app.url_path_for("create_node", project_id=project.id), json={
+ "name": "test",
+ "node_type": "vpcs",
+ "compute_id": "example.com",
+ "properties": {
+ "startup_script": "echo test"
+ }
+ })
+ assert response.status_code == status.HTTP_201_CREATED
+
+ response = await client.post(app.url_path_for("lock_project", project_id=project.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+ for drawing in project.drawings.values():
+ assert drawing.locked is True
+ for node in project.nodes.values():
+ assert node.locked is True
+
+ response = await client.get(app.url_path_for("locked_project", project_id=project.id))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json() is True
+
+ response = await client.post(app.url_path_for("unlock_project", project_id=project.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+ for drawing in project.drawings.values():
+ assert drawing.locked is False
+ for node in project.nodes.values():
+ assert node.locked is False
diff --git a/tests/api/routes/controller/test_snapshots.py b/tests/api/routes/controller/test_snapshots.py
index 3058cdad..531c3fe2 100644
--- a/tests/api/routes/controller/test_snapshots.py
+++ b/tests/api/routes/controller/test_snapshots.py
@@ -30,47 +30,49 @@ from gns3server.controller.snapshot import Snapshot
pytestmark = pytest.mark.asyncio
-@pytest_asyncio.fixture
-async def project(app: FastAPI, client: AsyncClient, controller: Controller) -> Project:
+class TestSnapshotRoutes:
- u = str(uuid.uuid4())
- params = {"name": "test", "project_id": u}
- await client.post(app.url_path_for("create_project"), json=params)
- project = controller.get_project(u)
- return project
-
-
-@pytest_asyncio.fixture
-async def snapshot(project: Project):
-
- snapshot = await project.snapshot("test")
- return snapshot
-
-
-async def test_list_snapshots(app: FastAPI, client: AsyncClient, project: Project, snapshot: Snapshot) -> None:
-
- assert snapshot.name == "test"
- response = await client.get(app.url_path_for("get_snapshots", project_id=project.id))
- assert response.status_code == status.HTTP_200_OK
- assert len(response.json()) == 1
-
-
-async def test_delete_snapshot(app: FastAPI, client: AsyncClient, project: Project, snapshot: Snapshot) -> None:
-
- response = await client.delete(app.url_path_for("delete_snapshot", project_id=project.id, snapshot_id=snapshot.id))
- assert response.status_code == status.HTTP_204_NO_CONTENT
- assert not os.path.exists(snapshot.path)
-
-
-async def test_restore_snapshot(app: FastAPI, client: AsyncClient, project: Project, snapshot: Snapshot) -> None:
-
- response = await client.post(app.url_path_for("restore_snapshot", project_id=project.id, snapshot_id=snapshot.id))
- assert response.status_code == status.HTTP_201_CREATED
- assert response.json()["name"] == project.name
-
-
-async def test_create_snapshot(app: FastAPI, client: AsyncClient, project: Project) -> None:
-
- response = await client.post(app.url_path_for("create_snapshot", project_id=project.id), json={"name": "snap1"})
- assert response.status_code == status.HTTP_201_CREATED
- assert len(os.listdir(os.path.join(project.path, "snapshots"))) == 1
+ @pytest_asyncio.fixture
+ async def project(self, app: FastAPI, client: AsyncClient, controller: Controller) -> Project:
+
+ u = str(uuid.uuid4())
+ params = {"name": "test", "project_id": u}
+ await client.post(app.url_path_for("create_project"), json=params)
+ controller_project = controller.get_project(u)
+ return controller_project
+
+
+ @pytest_asyncio.fixture
+ async def snapshot(self, project: Project):
+
+ controller_snapshot = await project.snapshot("test")
+ return controller_snapshot
+
+
+ async def test_list_snapshots(self, app: FastAPI, client: AsyncClient, project: Project, snapshot: Snapshot) -> None:
+
+ assert snapshot.name == "test"
+ response = await client.get(app.url_path_for("get_snapshots", project_id=project.id))
+ assert response.status_code == status.HTTP_200_OK
+ assert len(response.json()) == 1
+
+
+ async def test_delete_snapshot(self, app: FastAPI, client: AsyncClient, project: Project, snapshot: Snapshot) -> None:
+
+ response = await client.delete(app.url_path_for("delete_snapshot", project_id=project.id, snapshot_id=snapshot.id))
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+ assert not os.path.exists(snapshot.path)
+
+
+ async def test_restore_snapshot(self, app: FastAPI, client: AsyncClient, project: Project, snapshot: Snapshot) -> None:
+
+ response = await client.post(app.url_path_for("restore_snapshot", project_id=project.id, snapshot_id=snapshot.id))
+ assert response.status_code == status.HTTP_201_CREATED
+ assert response.json()["name"] == project.name
+
+
+ async def test_create_snapshot(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
+
+ response = await client.post(app.url_path_for("create_snapshot", project_id=project.id), json={"name": "snap1"})
+ assert response.status_code == status.HTTP_201_CREATED
+ assert len(os.listdir(os.path.join(project.path, "snapshots"))) == 1
diff --git a/tests/api/routes/controller/test_symbols.py b/tests/api/routes/controller/test_symbols.py
index c6941bdb..24e60720 100644
--- a/tests/api/routes/controller/test_symbols.py
+++ b/tests/api/routes/controller/test_symbols.py
@@ -28,41 +28,43 @@ from gns3server.controller import Controller
pytestmark = pytest.mark.asyncio
-async def test_symbols(app: FastAPI, client: AsyncClient) -> None:
+class TestSymbolRoutes:
- response = await client.get(app.url_path_for("get_symbols"))
-
- assert response.status_code == status.HTTP_200_OK
- assert {
- 'symbol_id': ':/symbols/classic/firewall.svg',
- 'filename': 'firewall.svg',
- 'builtin': True,
- 'theme': 'Classic'
- } in response.json()
-
-
-async def test_get(app: FastAPI, client: AsyncClient, controller: Controller) -> None:
-
- controller.symbols.theme = "Classic"
- url = app.url_path_for("get_symbol", symbol_id=urllib.parse.quote(':/symbols/classic/firewall.svg'))
- response = await client.get(url)
- assert response.status_code == status.HTTP_200_OK
- assert response.headers['CONTENT-TYPE'] == 'image/svg+xml'
- assert response.headers['CONTENT-LENGTH'] == '9381'
- assert '' in response.text
-
- # Reply with the default symbol
- response = await client.get(app.url_path_for("get_symbol", symbol_id="404.png"))
- assert response.status_code == status.HTTP_200_OK
-
-
-async def test_upload(app: FastAPI, client: AsyncClient, symbols_dir: str) -> None:
-
- response = await client.post(app.url_path_for("upload_symbol", symbol_id="test2"), content=b"TEST")
- assert response.status_code == status.HTTP_204_NO_CONTENT
-
- with open(os.path.join(symbols_dir, "test2")) as f:
- assert f.read() == "TEST"
-
- response = await client.get(app.url_path_for("get_symbol", symbol_id="test2"))
- assert response.status_code == status.HTTP_200_OK
+ async def test_symbols(self, app: FastAPI, client: AsyncClient) -> None:
+
+ response = await client.get(app.url_path_for("get_symbols"))
+
+ assert response.status_code == status.HTTP_200_OK
+ assert {
+ 'symbol_id': ':/symbols/classic/firewall.svg',
+ 'filename': 'firewall.svg',
+ 'builtin': True,
+ 'theme': 'Classic'
+ } in response.json()
+
+
+ async def test_get(self, app: FastAPI, client: AsyncClient, controller: Controller) -> None:
+
+ controller.symbols.theme = "Classic"
+ url = app.url_path_for("get_symbol", symbol_id=urllib.parse.quote(':/symbols/classic/firewall.svg'))
+ response = await client.get(url)
+ assert response.status_code == status.HTTP_200_OK
+ assert response.headers['CONTENT-TYPE'] == 'image/svg+xml'
+ assert response.headers['CONTENT-LENGTH'] == '9381'
+ assert '' in response.text
+
+ # Reply with the default symbol
+ response = await client.get(app.url_path_for("get_symbol", symbol_id="404.png"))
+ assert response.status_code == status.HTTP_200_OK
+
+
+ async def test_upload(self, app: FastAPI, client: AsyncClient, symbols_dir: str) -> None:
+
+ response = await client.post(app.url_path_for("upload_symbol", symbol_id="test2"), content=b"TEST")
+ assert response.status_code == status.HTTP_204_NO_CONTENT
+
+ with open(os.path.join(symbols_dir, "test2")) as f:
+ assert f.read() == "TEST"
+
+ response = await client.get(app.url_path_for("get_symbol", symbol_id="test2"))
+ assert response.status_code == status.HTTP_200_OK
diff --git a/tests/api/routes/controller/test_users.py b/tests/api/routes/controller/test_users.py
index 416fe45b..87ea7470 100644
--- a/tests/api/routes/controller/test_users.py
+++ b/tests/api/routes/controller/test_users.py
@@ -254,22 +254,6 @@ class TestUserLogin:
assert "token_type" in response.json()
assert response.json().get("token_type") == "bearer"
- async def test_user_can_authenticate_using_json(
- self,
- app: FastAPI,
- unauthorized_client: AsyncClient,
- test_user: User,
- config: Config
- ) -> None:
-
- credentials = {
- "username": test_user.username,
- "password": "user1_password",
- }
- response = await unauthorized_client.post(app.url_path_for("authenticate"), json=credentials)
- assert response.status_code == status.HTTP_200_OK
- assert response.json().get("access_token")
-
@pytest.mark.parametrize(
"username, password, status_code",
(
@@ -299,7 +283,19 @@ class TestUserLogin:
assert response.status_code == status_code
assert "access_token" not in response.json()
- async def test_user_can_use_token_as_url_param(
+
+class TestUnauthorizedUser:
+
+ async def test_user_cannot_access_own_data_if_not_authenticated(
+ self, app: FastAPI,
+ unauthorized_client: AsyncClient,
+ test_user: User,
+ ) -> None:
+
+ response = await unauthorized_client.get(app.url_path_for("get_logged_in_user"))
+ assert response.status_code == status.HTTP_401_UNAUTHORIZED
+
+ async def test_user_can_authenticate_using_json(
self,
app: FastAPI,
unauthorized_client: AsyncClient,
@@ -311,15 +307,14 @@ class TestUserLogin:
"username": test_user.username,
"password": "user1_password",
}
-
response = await unauthorized_client.post(app.url_path_for("authenticate"), json=credentials)
assert response.status_code == status.HTTP_200_OK
- token = response.json().get("access_token")
+ assert response.json().get("access_token")
+ token = response.json().get("access_token")
response = await unauthorized_client.get(app.url_path_for("statistics"), params={"token": token})
assert response.status_code == status.HTTP_200_OK
-
class TestUserMe:
async def test_authenticated_user_can_retrieve_own_data(
@@ -336,15 +331,6 @@ class TestUserMe:
assert user.email == test_user.email
assert user.user_id == test_user.user_id
- async def test_user_cannot_access_own_data_if_not_authenticated(
- self, app: FastAPI,
- unauthorized_client: AsyncClient,
- test_user: User,
- ) -> None:
-
- response = await unauthorized_client.get(app.url_path_for("get_logged_in_user"))
- assert response.status_code == status.HTTP_401_UNAUTHORIZED
-
async def test_authenticated_user_can_update_own_data(
self,
app: FastAPI,
diff --git a/tests/api/routes/controller/test_version.py b/tests/api/routes/controller/test_version.py
index 27ca7cb3..1e229ddd 100644
--- a/tests/api/routes/controller/test_version.py
+++ b/tests/api/routes/controller/test_version.py
@@ -25,38 +25,41 @@ from gns3server.version import __version__
pytestmark = pytest.mark.asyncio
-async def test_version_output(app: FastAPI, client: AsyncClient) -> None:
-
- response = await client.get(app.url_path_for("get_version"))
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == {'controller_host': '127.0.0.1', 'local': False, 'version': __version__}
+class TestVersionRoutes:
-async def test_version_input(app: FastAPI, client: AsyncClient) -> None:
+ async def test_version_output(self, app: FastAPI, client: AsyncClient) -> None:
- params = {'version': __version__}
- response = await client.post(app.url_path_for("check_version"), json=params)
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == {'version': __version__}
-
-
-async def test_version_invalid_input(app: FastAPI, client: AsyncClient) -> None:
-
- params = {'version': "0.4.2"}
- response = await client.post(app.url_path_for("check_version"), json=params)
- assert response.status_code == status.HTTP_409_CONFLICT
- assert response.json() == {'message': 'Client version 0.4.2 is not the same as server version {}'.format(__version__)}
-
-
-async def test_version_invalid_input_schema(app: FastAPI, client: AsyncClient) -> None:
-
- params = {'version': "0.4.2", "bla": "blu"}
- response = await client.post(app.url_path_for("check_version"), json=params)
- assert response.status_code == status.HTTP_409_CONFLICT
-
-
-async def test_version_invalid_json(app: FastAPI, client: AsyncClient) -> None:
-
- params = "BOUM"
- response = await client.post(app.url_path_for("check_version"), json=params)
- assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
+ response = await client.get(app.url_path_for("get_version"))
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json() == {'controller_host': '127.0.0.1', 'local': False, 'version': __version__}
+
+
+ async def test_version_input(self, app: FastAPI, client: AsyncClient) -> None:
+
+ params = {'version': __version__}
+ response = await client.post(app.url_path_for("check_version"), json=params)
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json() == {'version': __version__}
+
+
+ async def test_version_invalid_input(self, app: FastAPI, client: AsyncClient) -> None:
+
+ params = {'version': "0.4.2"}
+ response = await client.post(app.url_path_for("check_version"), json=params)
+ assert response.status_code == status.HTTP_409_CONFLICT
+ assert response.json() == {'message': 'Client version 0.4.2 is not the same as server version {}'.format(__version__)}
+
+
+ async def test_version_invalid_input_schema(self, app: FastAPI, client: AsyncClient) -> None:
+
+ params = {'version': "0.4.2", "bla": "blu"}
+ response = await client.post(app.url_path_for("check_version"), json=params)
+ assert response.status_code == status.HTTP_409_CONFLICT
+
+
+ async def test_version_invalid_json(self, app: FastAPI, client: AsyncClient) -> None:
+
+ params = "BOUM"
+ response = await client.post(app.url_path_for("check_version"), json=params)
+ assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
diff --git a/tests/api/routes/test_index.py b/tests/api/routes/test_index.py
index 08dcc090..93cef6dd 100644
--- a/tests/api/routes/test_index.py
+++ b/tests/api/routes/test_index.py
@@ -29,55 +29,57 @@ from gns3server.utils.get_resource import get_resource
pytestmark = pytest.mark.asyncio
-def get_static(filename):
+class TestIndexRoutes:
- current_dir = os.path.dirname(os.path.abspath(__file__))
- return os.path.join(os.path.abspath(os.path.join(current_dir, '../..', '..', 'gns3server', 'static')), filename)
+ def get_static(self, filename):
+
+ current_dir = os.path.dirname(os.path.abspath(__file__))
+ return os.path.join(os.path.abspath(os.path.join(current_dir, '../..', '..', 'gns3server', 'static')), filename)
-async def test_debug(app: FastAPI, client: AsyncClient) -> None:
+ async def test_debug(self, app: FastAPI, client: AsyncClient) -> None:
- response = await client.get(app.url_path_for("debug"))
- assert response.status_code == status.HTTP_200_OK
- html = response.read().decode()
- assert "Website" in html
- assert __version__ in html
-
-
-# @pytest.mark.asyncio
-# async def test_controller(http_client, controller):
-#
-# await controller.add_project(name="test")
-# response = await http_client.get('/controller')
-# assert "test" in await response.text()
-# assert response.status_code == 200
-#
-#
-# @pytest.mark.asyncio
-# async def test_compute(http_client):
-#
-# response = await http_client.get('/compute')
-# assert response.status_code == 200
-
-
-# @pytest.mark.asyncio
-# async def test_project(http_client, controller):
-#
-# project = await controller.add_project(name="test")
-# response = await http_client.get('/projects/{}'.format(project.id))
-# assert response.status_code == 200
-
-
-async def test_web_ui(app: FastAPI, client: AsyncClient) -> None:
-
- response = await client.get(app.url_path_for("web_ui", file_path="index.html"))
- assert response.status_code == status.HTTP_200_OK
-
-
-async def test_web_ui_not_found(app: FastAPI, client: AsyncClient, tmpdir: str) -> None:
-
- with patch('gns3server.utils.get_resource.get_resource') as mock:
- mock.return_value = str(tmpdir)
- response = await client.get(app.url_path_for("web_ui", file_path="not-found.txt"))
- # should serve web-ui/index.html
+ response = await client.get(app.url_path_for("debug"))
assert response.status_code == status.HTTP_200_OK
+ html = response.read().decode()
+ assert "Website" in html
+ assert __version__ in html
+
+
+ # @pytest.mark.asyncio
+ # async def test_controller(http_client, controller):
+ #
+ # await controller.add_project(name="test")
+ # response = await http_client.get('/controller')
+ # assert "test" in await response.text()
+ # assert response.status_code == 200
+ #
+ #
+ # @pytest.mark.asyncio
+ # async def test_compute(http_client):
+ #
+ # response = await http_client.get('/compute')
+ # assert response.status_code == 200
+
+
+ # @pytest.mark.asyncio
+ # async def test_project(http_client, controller):
+ #
+ # project = await controller.add_project(name="test")
+ # response = await http_client.get('/projects/{}'.format(project.id))
+ # assert response.status_code == 200
+
+
+ async def test_web_ui(self, app: FastAPI, client: AsyncClient) -> None:
+
+ response = await client.get(app.url_path_for("web_ui", file_path="index.html"))
+ assert response.status_code == status.HTTP_200_OK
+
+
+ async def test_web_ui_not_found(self, app: FastAPI, client: AsyncClient, tmpdir: str) -> None:
+
+ with patch('gns3server.utils.get_resource.get_resource') as mock:
+ mock.return_value = str(tmpdir)
+ response = await client.get(app.url_path_for("web_ui", file_path="not-found.txt"))
+ # should serve web-ui/index.html
+ assert response.status_code == status.HTTP_200_OK
diff --git a/tests/api/routes/test_routes.py b/tests/api/routes/test_routes.py
index 40870ee1..dc69cfca 100644
--- a/tests/api/routes/test_routes.py
+++ b/tests/api/routes/test_routes.py
@@ -44,40 +44,49 @@ ALLOWED_CONTROLLER_ENDPOINTS = [
("/v3/symbols/default_symbols", "GET")
]
+class TestRoutes:
-# Controller endpoints have a OAuth2 bearer token authentication
-async def test_controller_endpoints_require_authentication(app: FastAPI, unauthorized_client: AsyncClient) -> None:
+ # Controller endpoints have a OAuth2 bearer token authentication
+ async def test_controller_endpoints_require_authentication(
+ self,
+ app: FastAPI,
+ unauthorized_client: AsyncClient
+ ) -> None:
- for route in app.routes:
- if isinstance(route, APIRoute):
- for method in list(route.methods):
- if (route.path, method) not in ALLOWED_CONTROLLER_ENDPOINTS:
- response = await getattr(unauthorized_client, method.lower())(route.path)
- assert response.status_code == status.HTTP_401_UNAUTHORIZED
- elif isinstance(route, APIWebSocketRoute):
- params = {"token": "wrong_token"}
- async with AsyncClient(base_url="http://test-api", transport=ASGIWebSocketTransport(app)) as client:
- async with aconnect_ws(route.path, client, params=params) as ws:
- json_notification = await ws.receive_json()
- assert json_notification['event'] == {
- 'message': 'Could not authenticate while connecting to controller WebSocket: Could not validate credentials'
- }
-
-
-# Compute endpoints have a basic HTTP authentication
-async def test_compute_endpoints_require_authentication(app: FastAPI, unauthorized_client: AsyncClient) -> None:
-
- for route in app.routes:
- if isinstance(route, Mount):
- for compute_route in route.routes:
- if isinstance(compute_route, APIRoute):
- for method in list(compute_route.methods):
- response = await getattr(unauthorized_client, method.lower())(route.path + compute_route.path)
+ for route in app.routes:
+ if isinstance(route, APIRoute):
+ for method in list(route.methods):
+ if (route.path, method) not in ALLOWED_CONTROLLER_ENDPOINTS:
+ response = await getattr(unauthorized_client, method.lower())(route.path)
assert response.status_code == status.HTTP_401_UNAUTHORIZED
- elif isinstance(compute_route, APIWebSocketRoute):
- async with AsyncClient(base_url="http://test-api", transport=ASGIWebSocketTransport(app)) as client:
- async with aconnect_ws(route.path + compute_route.path, client, auth=("wrong_user", "password123")) as ws:
- json_notification = await ws.receive_json()
- assert json_notification['event'] == {
- 'message': 'Could not authenticate while connecting to compute WebSocket: Could not validate credentials'
- }
+ elif isinstance(route, APIWebSocketRoute):
+ params = {"token": "wrong_token"}
+ async with AsyncClient(base_url="http://test-api", transport=ASGIWebSocketTransport(app=app)) as client:
+ async with aconnect_ws(route.path, client, params=params) as ws:
+ json_notification = await ws.receive_json()
+ assert json_notification['event'] == {
+ 'message': 'Could not authenticate while connecting to controller WebSocket: Could not validate credentials'
+ }
+
+
+ # Compute endpoints have a basic HTTP authentication
+ async def test_compute_endpoints_require_authentication(
+ self,
+ app: FastAPI,
+ unauthorized_client: AsyncClient
+ ) -> None:
+
+ for route in app.routes:
+ if isinstance(route, Mount):
+ for compute_route in route.routes:
+ if isinstance(compute_route, APIRoute):
+ for method in list(compute_route.methods):
+ response = await getattr(unauthorized_client, method.lower())(route.path + compute_route.path)
+ assert response.status_code == status.HTTP_401_UNAUTHORIZED
+ elif isinstance(compute_route, APIWebSocketRoute):
+ async with AsyncClient(base_url="http://test-api", transport=ASGIWebSocketTransport(app=app)) as client:
+ async with aconnect_ws(route.path + compute_route.path, client, auth=("wrong_user", "password123")) as ws:
+ json_notification = await ws.receive_json()
+ assert json_notification['event'] == {
+ 'message': 'Could not authenticate while connecting to compute WebSocket: Could not validate credentials'
+ }
diff --git a/tests/compute/builtin/nodes/test_cloud.py b/tests/compute/builtin/nodes/test_cloud.py
index 7a482260..0f7d3401 100644
--- a/tests/compute/builtin/nodes/test_cloud.py
+++ b/tests/compute/builtin/nodes/test_cloud.py
@@ -25,6 +25,8 @@ from gns3server.compute.nios.nio_udp import NIOUDP
from tests.utils import asyncio_patch
+pytestmark = pytest.mark.asyncio
+
@pytest.fixture
def nio():
@@ -39,7 +41,6 @@ async def manager():
return m
-@pytest.mark.asyncio
async def test_json_with_ports(on_gns3vm, compute_project, manager):
ports = [
@@ -78,7 +79,7 @@ async def test_json_with_ports(on_gns3vm, compute_project, manager):
}
-def test_json_without_ports(on_gns3vm, compute_project, manager):
+async def test_json_without_ports(on_gns3vm, compute_project, manager):
"""
If no interface is provide the cloud is pre-fill with non special interfaces
"""
@@ -117,7 +118,6 @@ def test_json_without_ports(on_gns3vm, compute_project, manager):
}
-@pytest.mark.asyncio
async def test_update_port_mappings(on_gns3vm, compute_project):
"""
We don't allow an empty interface in the middle of port list
@@ -158,7 +158,6 @@ async def test_update_port_mappings(on_gns3vm, compute_project):
assert cloud.ports_mapping == ports1
-@pytest.mark.asyncio
async def test_linux_ethernet_raw_add_nio(linux_platform, compute_project, nio):
ports = [
{
@@ -186,7 +185,6 @@ async def test_linux_ethernet_raw_add_nio(linux_platform, compute_project, nio):
])
-@pytest.mark.asyncio
async def test_linux_ethernet_raw_add_nio_bridge(linux_platform, compute_project, nio):
"""
Bridge can't be connected directly to a cloud we use a tap in the middle
diff --git a/tests/conftest.py b/tests/conftest.py
index 30b3a6b0..0cf8be86 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,5 +1,4 @@
import pytest
-import asyncio
import pytest_asyncio
import tempfile
import shutil
@@ -13,6 +12,7 @@ import stat
from fastapi import FastAPI
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from httpx import AsyncClient
+from httpx_ws.transport import ASGIWebSocketTransport
from unittest.mock import MagicMock, patch
from pathlib import Path
@@ -34,25 +34,14 @@ sys._called_from_test = True
sys.original_platform = sys.platform
-# https://github.com/pytest-dev/pytest-asyncio/issues/68
-# this event_loop is used by pytest-asyncio, and redefining it
-# is currently the only way of changing the scope of this fixture
-@pytest.fixture(scope="class")
-def event_loop(request):
-
- loop = asyncio.get_event_loop_policy().new_event_loop()
- yield loop
- loop.close()
-
-
-@pytest_asyncio.fixture(scope="class")
+@pytest_asyncio.fixture(loop_scope="class", scope="class")
async def app() -> FastAPI:
from gns3server.api.server import app as gns3app
yield gns3app
-@pytest_asyncio.fixture(scope="class")
+@pytest_asyncio.fixture(loop_scope="class", scope="class")
async def db_engine():
db_url = os.getenv("GNS3_TEST_DATABASE_URI", "sqlite+aiosqlite:///:memory:") # "sqlite:///./sql_test_app.db"
@@ -61,7 +50,7 @@ async def db_engine():
#await engine.sync_engine.dispose()
-@pytest_asyncio.fixture(scope="class")
+@pytest_asyncio.fixture(loop_scope="class", scope="class")
async def db_session(db_engine):
# recreate database tables for each class
@@ -82,7 +71,7 @@ async def db_session(db_engine):
await session.close()
-@pytest_asyncio.fixture
+@pytest_asyncio.fixture(loop_scope="class", scope="class")
async def base_client(app: FastAPI, db_session: AsyncSession) -> AsyncClient:
async def _get_test_db():
@@ -94,14 +83,14 @@ async def base_client(app: FastAPI, db_session: AsyncSession) -> AsyncClient:
app.dependency_overrides[get_db_session] = _get_test_db
async with AsyncClient(
- app=app,
base_url="http://test-api",
- headers={"Content-Type": "application/json"}
+ headers={"Content-Type": "application/json"},
+ transport=ASGIWebSocketTransport(app=app)
) as async_client:
yield async_client
-@pytest_asyncio.fixture
+@pytest_asyncio.fixture(loop_scope="class", scope="class")
async def test_user(db_session: AsyncSession) -> User:
new_user = schemas.UserCreate(
@@ -121,7 +110,7 @@ async def test_user(db_session: AsyncSession) -> User:
return user
-@pytest_asyncio.fixture
+@pytest_asyncio.fixture(loop_scope="class", scope="class")
async def test_compute(db_session: AsyncSession) -> Compute:
new_compute = schemas.ComputeCreate(
@@ -140,12 +129,12 @@ async def test_compute(db_session: AsyncSession) -> Compute:
return await compute_repo.create_compute(new_compute)
-@pytest.fixture
+@pytest_asyncio.fixture(loop_scope="class", scope="class")
def unauthorized_client(base_client: AsyncClient, test_user: User) -> AsyncClient:
return base_client
-@pytest.fixture
+@pytest_asyncio.fixture(loop_scope="class", scope="class")
def authorized_client(base_client: AsyncClient, test_user: User) -> AsyncClient:
access_token = auth_service.create_access_token(test_user.username)
@@ -156,7 +145,7 @@ def authorized_client(base_client: AsyncClient, test_user: User) -> AsyncClient:
return base_client
-@pytest_asyncio.fixture
+@pytest_asyncio.fixture(loop_scope="class", scope="class")
async def client(base_client: AsyncClient) -> AsyncClient:
# The super admin is automatically created when the users table is created
@@ -169,7 +158,7 @@ async def client(base_client: AsyncClient) -> AsyncClient:
return base_client
-@pytest_asyncio.fixture
+@pytest_asyncio.fixture(loop_scope="class", scope="class")
async def compute_client(base_client: AsyncClient) -> AsyncClient:
# default compute username is 'gns3'
diff --git a/tests/pytest.ini b/tests/pytest.ini
new file mode 100644
index 00000000..88c111a5
--- /dev/null
+++ b/tests/pytest.ini
@@ -0,0 +1,2 @@
+[pytest]
+asyncio_default_fixture_loop_scope=function