Migration to FastAPI

This commit is contained in:
grossmj committed 2020-10-02 16:07:50 +09:30
1 parent c12b675691
commit eb3cb8a41f
224 files changed
+11254 -13517

No files matched your search

File renamed without changes.
+9 -4
View File
@@ -31,13 +31,15 @@ def nio():
@pytest.fixture
async def manager(loop):
@pytest.mark.asyncio
async def manager():
m = MagicMock()
m.module_name = "builtins"
return m
@pytest.mark.asyncio
async def test_json_with_ports(on_gns3vm, compute_project, manager):
ports = [
@@ -115,7 +117,8 @@ def test_json_without_ports(on_gns3vm, compute_project, manager):
}
async def test_update_port_mappings(loop, on_gns3vm, compute_project):
@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
"""
@@ -155,7 +158,8 @@ async def test_update_port_mappings(loop, on_gns3vm, compute_project):
assert cloud.ports_mapping == ports1
async def test_linux_ethernet_raw_add_nio(loop, linux_platform, compute_project, nio):
@pytest.mark.asyncio
async def test_linux_ethernet_raw_add_nio(linux_platform, compute_project, nio):
ports = [
{
"interface": "eth0",
@@ -182,7 +186,8 @@ async def test_linux_ethernet_raw_add_nio(loop, linux_platform, compute_project,
])
async def test_linux_ethernet_raw_add_nio_bridge(loop, 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
"""
+10 -1
View File
@@ -24,7 +24,8 @@ from gns3server.compute.docker.docker_error import DockerError, DockerHttp404Err
@pytest.fixture
async def vm(loop):
@pytest.mark.asyncio
async def vm():
vm = Docker()
vm._connected = True
@@ -33,6 +34,7 @@ async def vm(loop):
return vm
@pytest.mark.asyncio
async def test_query_success(vm):
response = MagicMock()
@@ -55,6 +57,7 @@ async def test_query_success(vm):
assert data == {"c": False}
@pytest.mark.asyncio
async def test_query_error(vm):
response = MagicMock()
@@ -75,6 +78,7 @@ async def test_query_error(vm):
timeout=300)
@pytest.mark.asyncio
async def test_query_error_json(vm):
response = MagicMock()
@@ -95,6 +99,7 @@ async def test_query_error_json(vm):
timeout=300)
@pytest.mark.asyncio
async def test_list_images():
response = [
@@ -134,6 +139,7 @@ async def test_list_images():
assert {"image": "ubuntu:quantal"} in images
@pytest.mark.asyncio
async def test_pull_image():
class Response:
@@ -162,6 +168,7 @@ async def test_pull_image():
mock.assert_called_with("POST", "images/create", params={"fromImage": "ubuntu"}, timeout=None)
@pytest.mark.asyncio
async def test_docker_check_connection_docker_minimum_version(vm):
response = {
@@ -176,6 +183,7 @@ async def test_docker_check_connection_docker_minimum_version(vm):
await vm._check_connection()
@pytest.mark.asyncio
async def test_docker_check_connection_docker_preferred_version_against_newer(vm):
response = {
@@ -189,6 +197,7 @@ async def test_docker_check_connection_docker_preferred_version_against_newer(vm
assert vm._api_version == DOCKER_PREFERRED_API_VERSION
@pytest.mark.asyncio
async def test_docker_check_connection_docker_preferred_version_against_older(vm):
response = {
+68 -2
View File
@@ -34,7 +34,8 @@ from unittest.mock import patch, MagicMock, call
@pytest.fixture()
async def manager(loop, port_manager):
@pytest.mark.asyncio
async def manager(port_manager):
m = Docker.instance()
m.port_manager = port_manager
@@ -42,7 +43,8 @@ async def manager(loop, port_manager):
@pytest.fixture(scope="function")
async def vm(loop, compute_project, manager):
@pytest.mark.asyncio
async def vm(compute_project, manager):
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest", aux_type="none")
vm._cid = "e90e34656842"
@@ -85,6 +87,7 @@ def test_start_command(vm):
assert vm.start_command is None
@pytest.mark.asyncio
async def test_create(compute_project, manager):
response = {
@@ -126,6 +129,7 @@ async def test_create(compute_project, manager):
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_create_with_tag(compute_project, manager):
response = {
@@ -167,6 +171,7 @@ async def test_create_with_tag(compute_project, manager):
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_create_vnc(compute_project, manager):
response = {
@@ -216,6 +221,7 @@ async def test_create_vnc(compute_project, manager):
assert vm._console_type == "vnc"
@pytest.mark.asyncio
async def test_create_with_extra_hosts(compute_project, manager):
extra_hosts = "test:199.199.199.1\ntest2:199.199.199.1"
@@ -233,6 +239,7 @@ async def test_create_with_extra_hosts(compute_project, manager):
assert vm._extra_hosts == extra_hosts
@pytest.mark.asyncio
async def test_create_with_extra_hosts_wrong_format(compute_project, manager):
extra_hosts = "test"
@@ -248,6 +255,7 @@ async def test_create_with_extra_hosts_wrong_format(compute_project, manager):
await vm.create()
@pytest.mark.asyncio
async def test_create_with_empty_extra_hosts(compute_project, manager):
extra_hosts = "test:\n"
@@ -264,6 +272,7 @@ async def test_create_with_empty_extra_hosts(compute_project, manager):
assert len([ e for e in called_kwargs["data"]["Env"] if "GNS3_EXTRA_HOSTS" in e]) == 0
@pytest.mark.asyncio
async def test_create_with_project_variables(compute_project, manager):
response = {
"Id": "e90e34656806",
@@ -287,6 +296,7 @@ async def test_create_with_project_variables(compute_project, manager):
compute_project.variables = None
@pytest.mark.asyncio
async def test_create_start_cmd(compute_project, manager):
response = {
@@ -329,6 +339,7 @@ async def test_create_start_cmd(compute_project, manager):
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_create_environment(compute_project, manager):
"""
Allow user to pass an environment. User can't override our
@@ -353,6 +364,7 @@ async def test_create_environment(compute_project, manager):
]
@pytest.mark.asyncio
async def test_create_environment_with_last_new_line_character(compute_project, manager):
"""
Allow user to pass an environment. User can't override our
@@ -377,6 +389,7 @@ async def test_create_environment_with_last_new_line_character(compute_project,
]
@pytest.mark.asyncio
async def test_create_image_not_available(compute_project, manager):
call = 0
@@ -431,6 +444,7 @@ async def test_create_image_not_available(compute_project, manager):
mock_pull.assert_called_with("ubuntu:latest")
@pytest.mark.asyncio
async def test_create_with_user(compute_project, manager):
response = {
@@ -476,6 +490,8 @@ async def test_create_with_user(compute_project, manager):
})
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_create_with_extra_volumes_invalid_format_1(compute_project, manager):
response = {
@@ -489,6 +505,7 @@ async def test_create_with_extra_volumes_invalid_format_1(compute_project, manag
await vm.create()
@pytest.mark.asyncio
async def test_create_with_extra_volumes_invalid_format_2(compute_project, manager):
response = {
@@ -502,6 +519,7 @@ async def test_create_with_extra_volumes_invalid_format_2(compute_project, manag
await vm.create()
@pytest.mark.asyncio
async def test_create_with_extra_volumes_invalid_format_3(compute_project, manager):
response = {
@@ -515,6 +533,7 @@ async def test_create_with_extra_volumes_invalid_format_3(compute_project, manag
await vm.create()
@pytest.mark.asyncio
async def test_create_with_extra_volumes_duplicate_1_image(compute_project, manager):
response = {
@@ -562,6 +581,7 @@ async def test_create_with_extra_volumes_duplicate_1_image(compute_project, mana
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_create_with_extra_volumes_duplicate_2_user(compute_project, manager):
response = {
@@ -604,6 +624,7 @@ async def test_create_with_extra_volumes_duplicate_2_user(compute_project, manag
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_create_with_extra_volumes_duplicate_3_subdir(compute_project, manager):
response = {
@@ -646,6 +667,7 @@ async def test_create_with_extra_volumes_duplicate_3_subdir(compute_project, man
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_create_with_extra_volumes_duplicate_4_backslash(compute_project, manager):
response = {
@@ -688,6 +710,7 @@ async def test_create_with_extra_volumes_duplicate_4_backslash(compute_project,
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_create_with_extra_volumes_duplicate_5_subdir_issue_1595(compute_project, manager):
response = {
@@ -729,6 +752,7 @@ async def test_create_with_extra_volumes_duplicate_5_subdir_issue_1595(compute_p
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_create_with_extra_volumes_duplicate_6_subdir_issue_1595(compute_project, manager):
response = {
@@ -770,6 +794,7 @@ async def test_create_with_extra_volumes_duplicate_6_subdir_issue_1595(compute_p
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_create_with_extra_volumes(compute_project, manager):
response = {
@@ -819,6 +844,7 @@ async def test_create_with_extra_volumes(compute_project, manager):
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_get_container_state(vm):
response = {
@@ -848,6 +874,7 @@ async def test_get_container_state(vm):
assert await vm._get_container_state() == "exited"
@pytest.mark.asyncio
async def test_is_running(vm):
response = {
@@ -864,6 +891,7 @@ async def test_is_running(vm):
assert await vm.is_running() is True
@pytest.mark.asyncio
async def test_pause(vm):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock:
@@ -873,6 +901,7 @@ async def test_pause(vm):
assert vm.status == "suspended"
@pytest.mark.asyncio
async def test_unpause(vm):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock:
@@ -880,6 +909,7 @@ async def test_unpause(vm):
mock.assert_called_with("POST", "containers/e90e34656842/unpause")
@pytest.mark.asyncio
async def test_start(vm, manager, free_console_port):
assert vm.status != "started"
@@ -908,6 +938,7 @@ async def test_start(vm, manager, free_console_port):
assert vm.status == "started"
@pytest.mark.asyncio
async def test_start_namespace_failed(vm, manager, free_console_port):
assert vm.status != "started"
@@ -932,6 +963,7 @@ async def test_start_namespace_failed(vm, manager, free_console_port):
assert vm.status == "stopped"
@pytest.mark.asyncio
async def test_start_without_nio(vm):
"""
If no nio exists we will create one.
@@ -955,6 +987,7 @@ async def test_start_without_nio(vm):
assert vm.status == "started"
@pytest.mark.asyncio
async def test_start_unpause(vm):
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="paused"):
@@ -964,6 +997,7 @@ async def test_start_unpause(vm):
assert vm.status == "started"
@pytest.mark.asyncio
async def test_restart(vm):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock:
@@ -971,6 +1005,7 @@ async def test_restart(vm):
mock.assert_called_with("POST", "containers/e90e34656842/restart")
@pytest.mark.asyncio
async def test_stop(vm):
mock = MagicMock()
@@ -987,6 +1022,7 @@ async def test_stop(vm):
assert vm._fix_permissions.called
@pytest.mark.asyncio
async def test_stop_paused_container(vm):
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="paused"):
@@ -997,6 +1033,7 @@ async def test_stop_paused_container(vm):
assert mock_unpause.called
@pytest.mark.asyncio
async def test_update(vm):
response = {
@@ -1045,6 +1082,7 @@ async def test_update(vm):
assert vm.aux == original_aux
@pytest.mark.asyncio
async def test_update_vnc(vm):
response = {
@@ -1068,6 +1106,7 @@ async def test_update_vnc(vm):
assert vm.aux == original_aux
@pytest.mark.asyncio
async def test_update_running(vm):
response = {
@@ -1117,6 +1156,7 @@ async def test_update_running(vm):
assert vm.start.called
@pytest.mark.asyncio
async def test_delete(vm):
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="stopped"):
@@ -1125,6 +1165,7 @@ async def test_delete(vm):
mock_query.assert_called_with("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
@pytest.mark.asyncio
async def test_close(vm, port_manager):
nio = {"type": "nio_udp",
@@ -1143,6 +1184,7 @@ async def test_close(vm, port_manager):
assert "4242" not in port_manager.udp_ports
@pytest.mark.asyncio
async def test_close_vnc(vm):
vm._console_type = "vnc"
@@ -1158,6 +1200,7 @@ async def test_close_vnc(vm):
assert vm._xvfb_process.terminate.called
@pytest.mark.asyncio
async def test_get_namespace(vm):
response = {
@@ -1170,6 +1213,7 @@ async def test_get_namespace(vm):
mock_query.assert_called_with("GET", "containers/e90e34656842/json")
@pytest.mark.asyncio
async def test_add_ubridge_connection(vm):
nio = {"type": "nio_udp",
@@ -1195,6 +1239,7 @@ async def test_add_ubridge_connection(vm):
vm._ubridge_hypervisor.assert_has_calls(calls, any_order=True)
@pytest.mark.asyncio
async def test_add_ubridge_connection_none_nio(vm):
nio = None
@@ -1214,6 +1259,7 @@ async def test_add_ubridge_connection_none_nio(vm):
vm._ubridge_hypervisor.assert_has_calls(calls, any_order=True)
@pytest.mark.asyncio
async def test_add_ubridge_connection_invalid_adapter_number(vm):
nio = {"type": "nio_udp",
@@ -1225,6 +1271,7 @@ async def test_add_ubridge_connection_invalid_adapter_number(vm):
await vm._add_ubridge_connection(nio, 12)
@pytest.mark.asyncio
async def test_add_ubridge_connection_no_free_interface(vm):
nio = {"type": "nio_udp",
@@ -1241,6 +1288,7 @@ async def test_add_ubridge_connection_no_free_interface(vm):
await vm._add_ubridge_connection(nio, 0)
@pytest.mark.asyncio
async def test_adapter_add_nio_binding_1(vm):
nio = {"type": "nio_udp",
@@ -1252,6 +1300,7 @@ async def test_adapter_add_nio_binding_1(vm):
assert vm._ethernet_adapters[0].get_nio(0) == nio
@pytest.mark.asyncio
async def test_adapter_udpate_nio_binding_bridge_not_started(vm):
vm._ubridge_apply_filters = AsyncioMagicMock()
@@ -1266,6 +1315,7 @@ async def test_adapter_udpate_nio_binding_bridge_not_started(vm):
assert vm._ubridge_apply_filters.called is False
@pytest.mark.asyncio
async def test_adapter_add_nio_binding_invalid_adapter(vm):
nio = {"type": "nio_udp",
@@ -1277,6 +1327,7 @@ async def test_adapter_add_nio_binding_invalid_adapter(vm):
await vm.adapter_add_nio_binding(12, nio)
@pytest.mark.asyncio
async def test_adapter_remove_nio_binding(vm):
vm.ubridge = MagicMock()
@@ -1296,12 +1347,14 @@ async def test_adapter_remove_nio_binding(vm):
delete_ubridge_mock.assert_any_call('bridge remove_nio_udp bridge0 4242 127.0.0.1 4343')
@pytest.mark.asyncio
async def test_adapter_remove_nio_binding_invalid_adapter(vm):
with pytest.raises(DockerError):
await vm.adapter_remove_nio_binding(12)
@pytest.mark.asyncio
async def test_start_capture(vm, tmpdir, manager, free_console_port):
output_file = str(tmpdir / "test.pcap")
@@ -1311,6 +1364,7 @@ async def test_start_capture(vm, tmpdir, manager, free_console_port):
assert vm._ethernet_adapters[0].get_nio(0).capturing
@pytest.mark.asyncio
async def test_stop_capture(vm, tmpdir, manager, free_console_port):
output_file = str(tmpdir / "test.pcap")
@@ -1322,6 +1376,7 @@ async def test_stop_capture(vm, tmpdir, manager, free_console_port):
assert vm._ethernet_adapters[0].get_nio(0).capturing is False
@pytest.mark.asyncio
async def test_get_log(vm):
async def read():
@@ -1335,6 +1390,7 @@ async def test_get_log(vm):
mock.assert_called_with("GET", "containers/e90e34656842/logs", params={"stderr": 1, "stdout": 1}, data={})
@pytest.mark.asyncio
async def test_get_image_information(compute_project, manager):
response = {}
@@ -1345,6 +1401,7 @@ async def test_get_image_information(compute_project, manager):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_mount_binds(vm):
image_infos = {
@@ -1366,6 +1423,7 @@ async def test_mount_binds(vm):
assert os.path.exists(dst)
@pytest.mark.asyncio
async def test_start_vnc(vm):
vm.console_resolution = "1280x1024"
@@ -1378,6 +1436,7 @@ async def test_start_vnc(vm):
mock_wait.assert_called_with("/tmp/.X11-unix/X{}".format(vm._display))
@pytest.mark.asyncio
async def test_start_vnc_missing(vm):
with patch("shutil.which", return_value=None):
@@ -1385,6 +1444,7 @@ async def test_start_vnc_missing(vm):
await vm._start_vnc()
@pytest.mark.asyncio
async def test_start_aux(vm):
with asyncio_patch("asyncio.subprocess.create_subprocess_exec", return_value=MagicMock()) as mock_exec:
@@ -1392,6 +1452,7 @@ async def test_start_aux(vm):
mock_exec.assert_called_with('docker', 'exec', '-i', 'e90e34656842', '/gns3/bin/busybox', 'script', '-qfc', 'while true; do TERM=vt100 /gns3/bin/busybox sh; done', '/dev/null', stderr=asyncio.subprocess.STDOUT, stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE)
@pytest.mark.asyncio
async def test_create_network_interfaces(vm):
vm.adapters = 5
@@ -1407,6 +1468,7 @@ async def test_create_network_interfaces(vm):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_fix_permission(vm):
vm._volumes = ["/etc"]
@@ -1419,6 +1481,7 @@ async def test_fix_permission(vm):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_fix_permission_not_running(vm):
vm._volumes = ["/etc"]
@@ -1432,6 +1495,7 @@ async def test_fix_permission_not_running(vm):
assert process.wait.called
@pytest.mark.asyncio
async def test_read_console_output_with_binary_mode(vm):
class InputStreamMock(object):
@@ -1456,6 +1520,7 @@ async def test_read_console_output_with_binary_mode(vm):
output_stream.feed_data.assert_called_once_with(b"test")
@pytest.mark.asyncio
async def test_cpus(compute_project, manager):
response = {
@@ -1497,6 +1562,7 @@ async def test_cpus(compute_project, manager):
assert vm._cid == "e90e34656806"
@pytest.mark.asyncio
async def test_memory(compute_project, manager):
response = {
@@ -29,7 +29,8 @@ from tests.utils import asyncio_patch, AsyncioMagicMock
@pytest.fixture
async def manager(loop, port_manager):
@pytest.mark.asyncio
async def manager(port_manager):
m = Dynamips.instance()
m.port_manager = port_manager
@@ -85,6 +86,7 @@ def test_release_dynamips_id(manager):
manager.release_dynamips_id(project_2, 0)
@pytest.mark.asyncio
async def test_project_closed(manager, compute_project):
manager._dynamips_ids[compute_project.id] = set([1, 2, 3])
@@ -97,6 +99,7 @@ async def test_project_closed(manager, compute_project):
assert compute_project.id not in manager._dynamips_ids
@pytest.mark.asyncio
async def test_duplicate_node(manager, compute_project):
"""
Duplicate dynamips do nothing it's manage outside the
@@ -27,7 +27,8 @@ from gns3server.config import Config
@pytest.fixture
async def manager(loop, port_manager):
@pytest.mark.asyncio
async def manager(port_manager):
m = Dynamips.instance()
m.port_manager = port_manager
@@ -64,6 +65,7 @@ def test_convert_project_before_2_0_0_b3(compute_project, manager):
assert not os.path.exists(os.path.join(wdir, node_id, "c7200_i2_nvram"))
@pytest.mark.asyncio
async def test_router_invalid_dynamips_path(compute_project, manager):
config = Config.instance()
+16 -2
View File
@@ -37,7 +37,8 @@ if not sys.platform.startswith("win"):
@pytest.fixture
async def manager(loop, port_manager):
@pytest.mark.asyncio
async def manager(port_manager):
m = IOU.instance()
m.port_manager = port_manager
@@ -45,7 +46,8 @@ async def manager(loop, port_manager):
@pytest.fixture(scope="function")
async def vm(loop, compute_project, manager, tmpdir, fake_iou_bin, iourc_file):
@pytest.mark.asyncio
async def vm(compute_project, manager, tmpdir, fake_iou_bin, iourc_file):
vm = IOUVM("test", str(uuid.uuid4()), compute_project, manager, application_id=1)
config = manager.config.get_section_config("IOU")
@@ -92,6 +94,7 @@ def test_vm_startup_config_content(compute_project, manager):
assert vm.id == "00010203-0405-0607-0808-0a0b0c0d0e0f"
@pytest.mark.asyncio
async def test_start(vm):
mock_process = MagicMock()
@@ -114,6 +117,7 @@ async def test_start(vm):
vm._ubridge_send.assert_any_call("iol_bridge start IOL-BRIDGE-513")
@pytest.mark.asyncio
async def test_start_with_iourc(vm, tmpdir):
fake_file = str(tmpdir / "iourc")
@@ -136,6 +140,7 @@ async def test_start_with_iourc(vm, tmpdir):
assert kwargs["env"]["IOURC"] == fake_file
@pytest.mark.asyncio
async def test_rename_nvram_file(vm):
"""
It should rename the nvram file to the correct name before launching the VM
@@ -152,6 +157,7 @@ async def test_rename_nvram_file(vm):
assert os.path.exists(os.path.join(vm.working_dir, "vlan.dat-0000{}".format(vm.application_id)))
@pytest.mark.asyncio
async def test_stop(vm):
process = MagicMock()
@@ -176,6 +182,7 @@ async def test_stop(vm):
process.terminate.assert_called_with()
@pytest.mark.asyncio
async def test_reload(vm, fake_iou_bin):
process = MagicMock()
@@ -200,6 +207,7 @@ async def test_reload(vm, fake_iou_bin):
process.terminate.assert_called_with()
@pytest.mark.asyncio
async def test_close(vm, port_manager):
vm._start_ubridge = AsyncioMagicMock(return_value=True)
@@ -252,6 +260,7 @@ def test_create_netmap_config(vm):
assert "513:15/3 1:15/3" in content
@pytest.mark.asyncio
async def test_build_command(vm):
assert await vm._build_command() == [vm.path, str(vm.application_id)]
@@ -316,6 +325,7 @@ def test_change_name(vm):
assert f.read() == "no service password-encryption\nhostname charlie\nno ip icmp rate-limit unreachable"
@pytest.mark.asyncio
async def test_library_check(vm):
with asyncio_patch("gns3server.utils.asyncio.subprocess_check_output", return_value=""):
@@ -326,6 +336,7 @@ async def test_library_check(vm):
await vm._library_check()
@pytest.mark.asyncio
async def test_enable_l1_keepalives(vm):
with asyncio_patch("gns3server.utils.asyncio.subprocess_check_output", return_value="***************************************************************\n\n-l Enable Layer 1 keepalive messages\n-u <n> UDP port base for distributed networks\n"):
@@ -341,6 +352,7 @@ async def test_enable_l1_keepalives(vm):
assert command == ["test"]
@pytest.mark.asyncio
async def test_start_capture(vm, tmpdir, manager, free_console_port):
output_file = str(tmpdir / "test.pcap")
@@ -350,6 +362,7 @@ async def test_start_capture(vm, tmpdir, manager, free_console_port):
assert vm._adapters[0].get_nio(0).capturing
@pytest.mark.asyncio
async def test_stop_capture(vm, tmpdir, manager, free_console_port):
output_file = str(tmpdir / "test.pcap")
@@ -366,6 +379,7 @@ def test_get_legacy_vm_workdir():
assert IOU.get_legacy_vm_workdir(42, "bla") == "iou/device-42"
@pytest.mark.asyncio
async def test_invalid_iou_file(vm, iourc_file):
hostname = socket.gethostname()
+2 -1
View File
@@ -66,7 +66,8 @@ def test_invalid_empty_file(tmpdir):
@pytest.mark.skipif(qemu_img() is None, reason="qemu-img is not available")
async def test_rebase(loop, tmpdir):
@pytest.mark.asyncio
async def test_rebase(tmpdir):
shutil.copy("tests/resources/empty8G.qcow2", str(tmpdir / "empty16G.qcow2"))
shutil.copy("tests/resources/linked.qcow2", str(tmpdir / "linked.qcow2"))
+8
View File
@@ -38,6 +38,7 @@ def fake_qemu_img_binary(tmpdir):
return bin_path
@pytest.mark.asyncio
async def test_get_qemu_version():
with asyncio_patch("gns3server.compute.qemu.subprocess_check_output", return_value="QEMU emulator version 2.2.0, Copyright (c) 2003-2008 Fabrice Bellard"):
@@ -48,6 +49,7 @@ async def test_get_qemu_version():
assert version == "2.2.0"
@pytest.mark.asyncio
async def test_binary_list(monkeypatch, tmpdir):
monkeypatch.setenv("PATH", str(tmpdir))
@@ -88,6 +90,7 @@ async def test_binary_list(monkeypatch, tmpdir):
assert {"path": os.path.join(os.environ["PATH"], "hello"), "version": version} not in qemus
@pytest.mark.asyncio
async def test_img_binary_list(monkeypatch, tmpdir):
monkeypatch.setenv("PATH", str(tmpdir))
@@ -117,6 +120,7 @@ def test_get_legacy_vm_workdir():
assert Qemu.get_legacy_vm_workdir(42, "bla") == os.path.join("qemu", "vm-42")
@pytest.mark.asyncio
async def test_create_image_abs_path(tmpdir, fake_qemu_img_binary):
options = {
@@ -148,6 +152,7 @@ async def test_create_image_abs_path(tmpdir, fake_qemu_img_binary):
)
@pytest.mark.asyncio
async def test_create_image_relative_path(tmpdir, fake_qemu_img_binary):
options = {
@@ -168,6 +173,7 @@ async def test_create_image_relative_path(tmpdir, fake_qemu_img_binary):
)
@pytest.mark.asyncio
async def test_create_image_exist(tmpdir, fake_qemu_img_binary):
open(str(tmpdir / "hda.qcow2"), "w+").close()
@@ -182,6 +188,7 @@ async def test_create_image_exist(tmpdir, fake_qemu_img_binary):
assert not process.called
@pytest.mark.asyncio
async def test_create_image_with_not_supported_characters_by_filesystem(tmpdir, fake_qemu_img_binary):
open(str(tmpdir / "hda.qcow2"), "w+").close()
@@ -202,6 +209,7 @@ async def test_create_image_with_not_supported_characters_by_filesystem(tmpdir,
assert not process.called
@pytest.mark.asyncio
async def test_get_kvm_archs_kvm_ok():
with patch("os.path.exists", return_value=True):
+44 -1
View File
@@ -34,7 +34,8 @@ from gns3server.compute.notification_manager import NotificationManager
@pytest.fixture
async def manager(loop, port_manager):
@pytest.mark.asyncio
async def manager(port_manager):
m = Qemu.instance()
m.port_manager = port_manager
@@ -67,6 +68,7 @@ def fake_qemu_binary(monkeypatch, tmpdir):
@pytest.fixture(scope="function")
@pytest.mark.asyncio
async def vm(compute_project, manager, fake_qemu_binary, fake_qemu_img_binary):
manager.port_manager.console_host = "127.0.0.1"
@@ -87,6 +89,7 @@ def running_subprocess_mock():
return mm
@pytest.mark.asyncio
async def test_vm(compute_project, manager, fake_qemu_binary):
vm = QemuVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager, qemu_path=fake_qemu_binary)
@@ -94,6 +97,7 @@ async def test_vm(compute_project, manager, fake_qemu_binary):
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0f"
@pytest.mark.asyncio
async def test_vm_create(tmpdir, compute_project, manager, fake_qemu_binary):
fake_img = str(tmpdir / 'hello')
@@ -110,6 +114,7 @@ async def test_vm_create(tmpdir, compute_project, manager, fake_qemu_binary):
assert os.path.exists(str(tmpdir / 'hello.md5sum'))
@pytest.mark.asyncio
async def test_vm_invalid_qemu_with_platform(compute_project, manager, fake_qemu_binary):
vm = QemuVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager, qemu_path="/usr/fake/bin/qemu-system-64", platform="x86_64")
@@ -118,6 +123,7 @@ async def test_vm_invalid_qemu_with_platform(compute_project, manager, fake_qemu
assert vm.platform == "x86_64"
@pytest.mark.asyncio
async def test_vm_invalid_qemu_without_platform(compute_project, manager, fake_qemu_binary):
vm = QemuVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager, qemu_path="/usr/fake/bin/qemu-system-x86_64")
@@ -126,6 +132,7 @@ async def test_vm_invalid_qemu_without_platform(compute_project, manager, fake_q
assert vm.platform == "x86_64"
@pytest.mark.asyncio
async def test_is_running(vm, running_subprocess_mock):
vm._process = None
@@ -136,6 +143,7 @@ async def test_is_running(vm, running_subprocess_mock):
assert vm.is_running() is False
@pytest.mark.asyncio
async def test_start(vm, running_subprocess_mock):
vm.manager.get_qemu_version = AsyncioMagicMock(return_value="3.1.0")
@@ -146,6 +154,7 @@ async def test_start(vm, running_subprocess_mock):
assert vm.command_line == ' '.join(mock.call_args[0])
@pytest.mark.asyncio
async def test_stop(vm, running_subprocess_mock):
process = running_subprocess_mock
@@ -166,6 +175,7 @@ async def test_stop(vm, running_subprocess_mock):
process.terminate.assert_called_with()
@pytest.mark.asyncio
async def test_termination_callback(vm):
vm.status = "started"
@@ -181,6 +191,7 @@ async def test_termination_callback(vm):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_termination_callback_error(vm, tmpdir):
with open(str(tmpdir / "qemu.log"), "w+") as f:
@@ -204,6 +215,7 @@ async def test_termination_callback_error(vm, tmpdir):
assert event["message"] == "QEMU process has stopped, return code: 1\nBOOMM"
@pytest.mark.asyncio
async def test_reload(vm):
with asyncio_patch("gns3server.compute.qemu.QemuVM._control_vm") as mock:
@@ -211,6 +223,7 @@ async def test_reload(vm):
assert mock.called_with("system_reset")
@pytest.mark.asyncio
async def test_suspend(vm):
control_vm_result = MagicMock()
@@ -220,6 +233,7 @@ async def test_suspend(vm):
assert mock.called_with("system_reset")
@pytest.mark.asyncio
async def test_add_nio_binding_udp(vm):
nio = Qemu.instance().create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1", "filters": {}})
@@ -228,6 +242,7 @@ async def test_add_nio_binding_udp(vm):
assert nio.lport == 4242
@pytest.mark.asyncio
async def test_port_remove_nio_binding(vm):
nio = Qemu.instance().create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1", "filters": {}})
@@ -236,6 +251,7 @@ async def test_port_remove_nio_binding(vm):
assert vm._ethernet_adapters[0].ports[0] is None
@pytest.mark.asyncio
async def test_close(vm, port_manager):
vm.manager.get_qemu_version = AsyncioMagicMock(return_value="3.1.0")
@@ -335,6 +351,7 @@ def test_set_qemu_path_kvm_binary(vm, fake_qemu_binary):
assert vm.platform == "x86_64"
@pytest.mark.asyncio
async def test_set_platform(compute_project, manager):
manager.config_disk = None # avoids conflict with config.img support
@@ -349,6 +366,7 @@ async def test_set_platform(compute_project, manager):
assert vm.qemu_path == "/bin/qemu-system-x86_64"
@pytest.mark.asyncio
async def test_disk_options(vm, tmpdir, fake_qemu_img_binary):
vm._hda_disk_image = str(tmpdir / "test.qcow2")
@@ -363,6 +381,7 @@ async def test_disk_options(vm, tmpdir, fake_qemu_img_binary):
assert options == ['-drive', 'file=' + os.path.join(vm.working_dir, "hda_disk.qcow2") + ',if=ide,index=0,media=disk,id=drive0']
@pytest.mark.asyncio
async def test_cdrom_option(vm, tmpdir, fake_qemu_img_binary):
vm.manager.get_qemu_version = AsyncioMagicMock(return_value="3.1.0")
@@ -374,6 +393,7 @@ async def test_cdrom_option(vm, tmpdir, fake_qemu_img_binary):
assert ' '.join(['-cdrom', str(tmpdir / "test.iso")]) in ' '.join(options)
@pytest.mark.asyncio
async def test_bios_option(vm, tmpdir, fake_qemu_img_binary):
vm.manager.get_qemu_version = AsyncioMagicMock(return_value="3.1.0")
@@ -383,6 +403,7 @@ async def test_bios_option(vm, tmpdir, fake_qemu_img_binary):
assert ' '.join(['-bios', str(tmpdir / "test.img")]) in ' '.join(options)
@pytest.mark.asyncio
async def test_vnc_option(vm, fake_qemu_img_binary):
vm._console_type = 'vnc'
@@ -391,6 +412,7 @@ async def test_vnc_option(vm, fake_qemu_img_binary):
assert '-vnc 127.0.0.1:5' in ' '.join(options)
@pytest.mark.asyncio
async def test_spice_option(vm, fake_qemu_img_binary):
vm._console_type = 'spice'
@@ -400,6 +422,7 @@ async def test_spice_option(vm, fake_qemu_img_binary):
assert '-vga qxl' in ' '.join(options)
@pytest.mark.asyncio
async def test_disk_options_multiple_disk(vm, tmpdir, fake_qemu_img_binary):
vm._hda_disk_image = str(tmpdir / "test0.qcow2")
@@ -423,6 +446,7 @@ async def test_disk_options_multiple_disk(vm, tmpdir, fake_qemu_img_binary):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_set_process_priority(vm, fake_qemu_img_binary):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()) as process:
@@ -436,6 +460,7 @@ async def test_set_process_priority(vm, fake_qemu_img_binary):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_set_process_priority_normal(vm, fake_qemu_img_binary):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()) as process:
@@ -452,6 +477,7 @@ def test_json(vm, compute_project):
assert json["project_id"] == compute_project.id
@pytest.mark.asyncio
async def test_control_vm(vm):
vm._process = MagicMock()
@@ -463,6 +489,7 @@ async def test_control_vm(vm):
assert res is None
@pytest.mark.asyncio
async def test_control_vm_expect_text(vm, running_subprocess_mock):
vm._process = running_subprocess_mock
@@ -481,6 +508,7 @@ async def test_control_vm_expect_text(vm, running_subprocess_mock):
assert res == "epic product"
@pytest.mark.asyncio
async def test_build_command(vm, fake_qemu_binary):
vm.manager.get_qemu_version = AsyncioMagicMock(return_value="3.1.0")
@@ -513,6 +541,7 @@ async def test_build_command(vm, fake_qemu_binary):
]
@pytest.mark.asyncio
async def test_build_command_manual_uuid(vm):
"""
If user has set a uuid we keep it
@@ -527,6 +556,7 @@ async def test_build_command_manual_uuid(vm):
assert vm.id not in cmd
@pytest.mark.asyncio
async def test_build_command_kvm(linux_platform, vm, fake_qemu_binary):
"""
Qemu 2.4 introduce an issue with KVM
@@ -563,6 +593,7 @@ async def test_build_command_kvm(linux_platform, vm, fake_qemu_binary):
]
@pytest.mark.asyncio
async def test_build_command_kvm_2_4(linux_platform, vm, fake_qemu_binary):
"""
Qemu 2.4 introduce an issue with KVM
@@ -602,6 +633,7 @@ async def test_build_command_kvm_2_4(linux_platform, vm, fake_qemu_binary):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_build_command_without_display(vm):
vm.manager.get_qemu_version = AsyncioMagicMock(return_value="2.5.0")
@@ -611,6 +643,7 @@ async def test_build_command_without_display(vm):
assert "-nographic" in cmd
@pytest.mark.asyncio
async def test_build_command_two_adapters(vm, fake_qemu_binary):
vm.manager.get_qemu_version = AsyncioMagicMock(return_value="2.5.0")
@@ -648,6 +681,7 @@ async def test_build_command_two_adapters(vm, fake_qemu_binary):
]
@pytest.mark.asyncio
async def test_build_command_two_adapters_mac_address(vm):
"""
Should support multiple base vmac address
@@ -675,6 +709,7 @@ async def test_build_command_two_adapters_mac_address(vm):
assert "e1000,mac={},netdev=gns3-1".format(mac_1) in cmd
@pytest.mark.asyncio
async def test_build_command_large_number_of_adapters(vm):
"""
When we have more than 28 interface we need to add a pci bridge for
@@ -721,6 +756,7 @@ async def test_build_command_large_number_of_adapters(vm):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_build_command_with_invalid_options(vm):
vm.options = "'test"
@@ -738,6 +774,7 @@ def test_hda_disk_image(vm, images_dir):
assert vm.hda_disk_image == force_unix_path(os.path.join(images_dir, "QEMU", "test2"))
@pytest.mark.asyncio
async def test_hda_disk_image_non_linked_clone(vm, images_dir, compute_project, manager, fake_qemu_binary):
"""
Two non linked can't use the same image at the same time
@@ -854,18 +891,21 @@ def test_get_qemu_img(vm, tmpdir):
# vm._get_qemu_img()
@pytest.mark.asyncio
async def test_run_with_hardware_acceleration_darwin(darwin_platform, vm):
vm.manager.config.set("Qemu", "enable_hardware_acceleration", False)
assert await vm._run_with_hardware_acceleration("qemu-system-x86_64", "") is False
@pytest.mark.asyncio
async def test_run_with_hardware_acceleration_windows(windows_platform, vm):
vm.manager.config.set("Qemu", "enable_hardware_acceleration", False)
assert await vm._run_with_hardware_acceleration("qemu-system-x86_64", "") is False
@pytest.mark.asyncio
async def test_run_with_kvm_linux(linux_platform, vm):
with patch("os.path.exists", return_value=True) as os_path:
@@ -874,6 +914,7 @@ async def test_run_with_kvm_linux(linux_platform, vm):
os_path.assert_called_with("/dev/kvm")
@pytest.mark.asyncio
async def test_run_with_kvm_linux_options_no_kvm(linux_platform, vm):
with patch("os.path.exists", return_value=True) as os_path:
@@ -881,6 +922,7 @@ async def test_run_with_kvm_linux_options_no_kvm(linux_platform, vm):
assert await vm._run_with_hardware_acceleration("qemu-system-x86_64", "-no-kvm") is False
@pytest.mark.asyncio
async def test_run_with_kvm_not_x86(linux_platform, vm):
with patch("os.path.exists", return_value=True):
@@ -889,6 +931,7 @@ async def test_run_with_kvm_not_x86(linux_platform, vm):
await vm._run_with_hardware_acceleration("qemu-system-arm", "")
@pytest.mark.asyncio
async def test_run_with_kvm_linux_dev_kvm_missing(linux_platform, vm):
with patch("os.path.exists", return_value=False):
+6 -1
View File
@@ -30,7 +30,8 @@ from gns3server.compute.nios.nio_udp import NIOUDP
@pytest.fixture(scope="function")
async def manager(loop, port_manager):
@pytest.mark.asyncio
async def manager(port_manager):
m = VPCS.instance()
m.port_manager = port_manager
@@ -78,6 +79,7 @@ def test_console_vnc_invalid(compute_project, manager):
node.console = 2012
@pytest.mark.asyncio
async def test_close(node, port_manager):
assert node.console is not None
@@ -132,6 +134,7 @@ def test_change_aux_port(compute_project, manager, port_manager):
port_manager.reserve_tcp_port(port1, node.project)
@pytest.mark.asyncio
async def test_update_ubridge_udp_connection(node):
filters = {
@@ -146,6 +149,7 @@ async def test_update_ubridge_udp_connection(node):
mock.assert_called_with("VPCS-10", filters)
@pytest.mark.asyncio
async def test_ubridge_apply_filters(node):
filters = OrderedDict((
@@ -158,6 +162,7 @@ async def test_ubridge_apply_filters(node):
node._ubridge_send.assert_any_call("bridge add_packet_filter VPCS-10 filter0 latency 10")
@pytest.mark.asyncio
async def test_ubridge_apply_bpf_filters(node):
filters = {
+15 -2
View File
@@ -29,7 +29,8 @@ from gns3server.utils import force_unix_path
@pytest.fixture(scope="function")
async def vpcs(loop, port_manager):
@pytest.mark.asyncio
async def vpcs(port_manager):
VPCS._instance = None
vpcs = VPCS.instance()
@@ -38,7 +39,8 @@ async def vpcs(loop, port_manager):
@pytest.fixture(scope="function")
async def qemu(loop, port_manager):
@pytest.mark.asyncio
async def qemu(port_manager):
Qemu._instance = None
Qemu._init_config_disk = MagicMock() # do not create the config.img image
@@ -47,6 +49,7 @@ async def qemu(loop, port_manager):
return qemu
@pytest.mark.asyncio
async def test_create_node_new_topology(compute_project, vpcs):
node_id = str(uuid.uuid4())
@@ -54,6 +57,7 @@ async def test_create_node_new_topology(compute_project, vpcs):
assert node in compute_project.nodes
@pytest.mark.asyncio
async def test_create_twice_same_node_new_topology(compute_project, vpcs):
compute_project._nodes = set()
@@ -65,6 +69,7 @@ async def test_create_twice_same_node_new_topology(compute_project, vpcs):
assert len(compute_project.nodes) == 1
@pytest.mark.asyncio
async def test_create_node_new_topology_without_uuid(compute_project, vpcs):
node = await vpcs.create_node("PC 1", compute_project.id, None)
@@ -72,6 +77,7 @@ async def test_create_node_new_topology_without_uuid(compute_project, vpcs):
assert len(node.id) == 36
@pytest.mark.asyncio
async def test_create_node_old_topology(compute_project, tmpdir, vpcs):
with patch("gns3server.compute.project.Project.is_local", return_value=True):
@@ -232,6 +238,7 @@ def test_get_relative_image_path(qemu, tmpdir, config):
assert qemu.get_relative_image_path(path5) == path5
@pytest.mark.asyncio
async def test_list_images(qemu, tmpdir):
fake_images = ["a.qcow2", "b.qcow2", ".blu.qcow2", "a.qcow2.md5sum"]
@@ -248,6 +255,7 @@ async def test_list_images(qemu, tmpdir):
]
@pytest.mark.asyncio
async def test_list_images_recursives(qemu, tmpdir):
tmp_images_dir = os.path.join(tmpdir, "images")
@@ -271,18 +279,21 @@ async def test_list_images_recursives(qemu, tmpdir):
]
@pytest.mark.asyncio
async def test_list_images_empty(qemu, tmpdir):
with patch("gns3server.compute.Qemu.get_images_directory", return_value=str(tmpdir)):
assert await qemu.list_images() == []
@pytest.mark.asyncio
async def test_list_images_directory_not_exist(qemu):
with patch("gns3server.compute.Qemu.get_images_directory", return_value="/bla"):
assert await qemu.list_images() == []
@pytest.mark.asyncio
async def test_delete_node(vpcs, compute_project):
compute_project._nodes = set()
@@ -295,6 +306,7 @@ async def test_delete_node(vpcs, compute_project):
assert node not in compute_project.nodes
@pytest.mark.asyncio
async def test_duplicate_vpcs(vpcs, compute_project):
source_node_id = str(uuid.uuid4())
@@ -309,6 +321,7 @@ async def test_duplicate_vpcs(vpcs, compute_project):
assert startup == "set pcname PC-2\nip dhcp\n".strip()
@pytest.mark.asyncio
async def test_duplicate_ethernet_switch(compute_project):
with asyncio_patch('gns3server.compute.dynamips.nodes.ethernet_switch.EthernetSwitch.create'):
@@ -15,11 +15,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import uuid
from gns3server.compute.notification_manager import NotificationManager
@pytest.mark.asyncio
async def test_queue():
NotificationManager.reset()
@@ -37,6 +39,7 @@ async def test_queue():
assert len(notifications._listeners) == 0
@pytest.mark.asyncio
async def test_queue_json():
NotificationManager.reset()
@@ -54,6 +57,7 @@ async def test_queue_json():
assert len(notifications._listeners) == 0
@pytest.mark.asyncio
async def test_queue_json_meta():
NotificationManager.reset()
@@ -72,6 +76,7 @@ async def test_queue_json_meta():
assert len(notifications._listeners) == 0
@pytest.mark.asyncio
async def test_queue_ping():
"""
If we don't send a message during a long time (0.5 seconds)
+23 -5
View File
@@ -19,21 +19,21 @@
import os
import sys
import uuid
import asyncio
import pytest
import aiohttp
from uuid import uuid4
from unittest.mock import patch
from tests.utils import asyncio_patch
from gns3server.compute.project import Project
from gns3server.compute.notification_manager import NotificationManager
from gns3server.compute.compute_error import ComputeError, ComputeForbiddenError
from gns3server.compute.vpcs import VPCS, VPCSVM
from gns3server.config import Config
@pytest.fixture(scope="function")
async def manager(loop, port_manager):
@pytest.mark.asyncio
async def manager(port_manager):
m = VPCS.instance()
m.port_manager = port_manager
@@ -41,18 +41,21 @@ async def manager(loop, port_manager):
@pytest.fixture(scope="function")
@pytest.mark.asyncio
async def node(compute_project, manager):
node = manager.create_node("test", compute_project.id, "00010203-0405-0607-0809-0a0b0c0d0e0f")
return await node
@pytest.mark.asyncio
async def test_affect_uuid():
p = Project(project_id='00010203-0405-0607-0809-0a0b0c0d0e0f')
assert p.id == '00010203-0405-0607-0809-0a0b0c0d0e0f'
@pytest.mark.asyncio
async def test_clean_tmp_directory():
"""
The tmp directory should be clean at project open and close
@@ -69,6 +72,7 @@ async def test_clean_tmp_directory():
assert not os.path.exists(path)
@pytest.mark.asyncio
async def test_path(projects_dir):
directory = projects_dir
@@ -79,6 +83,7 @@ async def test_path(projects_dir):
assert os.path.exists(os.path.join(directory, p.id))
@pytest.mark.asyncio
async def test_init_path(tmpdir):
with patch("gns3server.compute.project.Project.is_local", return_value=True):
@@ -86,14 +91,16 @@ async def test_init_path(tmpdir):
assert p.path == str(tmpdir)
@pytest.mark.asyncio
async def test_changing_path_not_allowed(tmpdir):
with patch("gns3server.compute.project.Project.is_local", return_value=False):
with pytest.raises(aiohttp.web.HTTPForbidden):
with pytest.raises(ComputeForbiddenError):
p = Project(project_id=str(uuid4()))
p.path = str(tmpdir)
@pytest.mark.asyncio
async def test_variables():
variables = [{"name": "VAR1", "value": "VAL1"}]
@@ -101,6 +108,7 @@ async def test_variables():
assert p.variables == variables
@pytest.mark.asyncio
async def test_json():
p = Project(project_id=str(uuid4()))
@@ -111,6 +119,7 @@ async def test_json():
}
@pytest.mark.asyncio
async def test_json_with_variables():
variables = [{"name": "VAR1", "value": "VAL1"}]
@@ -122,6 +131,7 @@ async def test_json_with_variables():
}
@pytest.mark.asyncio
async def test_node_working_directory(node, projects_dir):
directory = projects_dir
@@ -131,6 +141,7 @@ async def test_node_working_directory(node, projects_dir):
assert os.path.exists(p.node_working_directory(node))
@pytest.mark.asyncio
async def test_node_working_path(node, projects_dir):
directory = projects_dir
@@ -141,6 +152,7 @@ async def test_node_working_path(node, projects_dir):
assert not os.path.exists(p.node_working_path(node))
@pytest.mark.asyncio
async def test_project_delete():
project = Project(project_id=str(uuid4()))
@@ -151,17 +163,19 @@ async def test_project_delete():
@pytest.mark.skipif(not sys.platform.startswith("win") and os.getuid() == 0, reason="Root can delete any project")
@pytest.mark.asyncio
async def test_project_delete_permission_issue():
project = Project(project_id=str(uuid4()))
directory = project.path
assert os.path.exists(directory)
os.chmod(directory, 0)
with pytest.raises(aiohttp.web.HTTPInternalServerError):
with pytest.raises(ComputeError):
await project.delete()
os.chmod(directory, 700)
@pytest.mark.asyncio
async def test_project_add_node(manager):
project = Project(project_id=str(uuid4()))
@@ -170,6 +184,7 @@ async def test_project_add_node(manager):
assert len(project.nodes) == 1
@pytest.mark.asyncio
async def test_project_close(node, compute_project):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.close") as mock:
@@ -178,6 +193,7 @@ async def test_project_close(node, compute_project):
assert node.id not in node.manager._nodes
@pytest.mark.asyncio
async def test_list_files(tmpdir):
with patch("gns3server.config.Config.get_section_config", return_value={"projects_path": str(tmpdir)}):
@@ -204,6 +220,7 @@ async def test_list_files(tmpdir):
]
@pytest.mark.asyncio
async def test_emit():
with NotificationManager.instance().queue() as queue:
@@ -216,6 +233,7 @@ async def test_emit():
assert context["project_id"] == project.id
@pytest.mark.asyncio
async def test_update_project():
variables = [{"name": "TEST", "value": "VAL"}]
+2 -2
View File
@@ -15,9 +15,9 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import aiohttp
import pytest
from gns3server.compute.compute_error import ComputeNotFoundError
from gns3server.compute.project_manager import ProjectManager
@@ -31,5 +31,5 @@ def test_create_project():
def test_project_not_found():
pm = ProjectManager.instance()
with pytest.raises(aiohttp.web.HTTPNotFound):
with pytest.raises(ComputeNotFoundError):
pm.get_project('00010203-0405-0607-0809-000000000000')
-187
View File
@@ -1,187 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2020 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import asyncio
from tests.utils import asyncio_patch, AsyncioMagicMock
from unittest.mock import patch, MagicMock, ANY
from gns3server.compute.traceng.traceng_vm import TraceNGVM
from gns3server.compute.traceng.traceng_error import TraceNGError
from gns3server.compute.traceng import TraceNG
from gns3server.compute.notification_manager import NotificationManager
@pytest.fixture
async def manager(loop, port_manager):
m = TraceNG.instance()
m.port_manager = port_manager
return m
@pytest.fixture(scope="function")
async def vm(compute_project, manager, ubridge_path):
vm = TraceNGVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager)
vm._start_ubridge = AsyncioMagicMock()
vm._ubridge_hypervisor = MagicMock()
vm._ubridge_hypervisor.is_running.return_value = True
return vm
async def test_vm(project, manager):
vm = TraceNGVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
assert vm.name == "test"
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0f"
async def test_vm_invalid_traceng_path(vm, manager):
with patch("gns3server.compute.traceng.traceng_vm.TraceNGVM._traceng_path", return_value="/tmp/fake/path/traceng"):
with pytest.raises(TraceNGError):
nio = manager.create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
await vm.port_add_nio_binding(0, nio)
await vm.start()
assert vm.name == "test"
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0e"
async def test_start(vm):
process = MagicMock()
process.returncode = None
with NotificationManager.instance().queue() as queue:
await queue.get(1) # Ping
vm.ip_address = "192.168.1.1"
with patch("sys.platform", return_value="win"):
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM._check_requirements", return_value=True):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=process) as mock_exec:
await vm.start("192.168.1.2")
assert mock_exec.call_args[0] == (vm._traceng_path(),
'-u',
'-c',
ANY,
'-v',
ANY,
'-b',
'127.0.0.1',
'-s',
'ICMP',
'-f',
'192.168.1.1',
'192.168.1.2')
assert vm.is_running()
assert vm.command_line == ' '.join(mock_exec.call_args[0])
(action, event, kwargs) = await queue.get(1)
assert action == "node.updated"
assert event == vm
async def test_stop(vm):
process = MagicMock()
# Wait process kill success
future = asyncio.Future()
future.set_result(True)
process.wait.return_value = future
process.returncode = None
vm.ip_address = "192.168.1.1"
with NotificationManager.instance().queue() as queue:
with patch("sys.platform", return_value="win"):
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM._check_requirements", return_value=True):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=process):
nio = TraceNG.instance().create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1", "filters": {}})
await vm.port_add_nio_binding(0, nio)
vm._ubridge_send = AsyncioMagicMock()
await vm.start("192.168.1.2")
assert vm.is_running()
with asyncio_patch("gns3server.utils.asyncio.wait_for_process_termination"):
await vm.stop()
assert vm.is_running() is False
process.terminate.assert_called_with()
await queue.get(1) #  Ping
await queue.get(1) #  Started
(action, event, kwargs) = await queue.get(1)
assert action == "node.updated"
assert event == vm
async def test_reload(vm):
process = MagicMock()
# Wait process kill success
future = asyncio.Future()
future.set_result(True)
process.wait.return_value = future
process.returncode = None
vm.ip_address = "192.168.1.1"
with patch("sys.platform", return_value="win"):
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM._check_requirements", return_value=True):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=process):
nio = TraceNG.instance().create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1", "filters": {}})
await vm.port_add_nio_binding(0, nio)
vm._ubridge_send = AsyncioMagicMock()
await vm.start("192.168.1.2")
assert vm.is_running()
with asyncio_patch("gns3server.utils.asyncio.wait_for_process_termination"):
await vm.reload()
assert vm.is_running() is True
#if sys.platform.startswith("win"):
# process.send_signal.assert_called_with(1)
#else:
process.terminate.assert_called_with()
async def test_add_nio_binding_udp(vm):
nio = TraceNG.instance().create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1", "filters": {}})
await vm.port_add_nio_binding(0, nio)
assert nio.lport == 4242
async def test_port_remove_nio_binding(vm):
nio = TraceNG.instance().create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
await vm.port_add_nio_binding(0, nio)
await vm.port_remove_nio_binding(0)
assert vm._ethernet_adapter.ports[0] is None
async def test_close(vm):
vm.ip_address = "192.168.1.1"
with patch("sys.platform", return_value="win"):
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM._check_requirements", return_value=True):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()):
await vm.start("192.168.1.2")
await vm.close()
assert vm.is_running() is False
@@ -29,7 +29,7 @@ from tests.utils import asyncio_patch
@pytest.fixture
async def manager(loop, port_manager):
async def manager(port_manager):
m = VirtualBox.instance()
m.port_manager = port_manager
@@ -72,6 +72,7 @@ def test_vboxmanage_path(manager, tmpdir):
assert manager.find_vboxmanage() == path
@pytest.mark.asyncio
async def test_list_vms(manager):
vm_list = ['"Windows 8.1" {27b4d095-ff5f-4ac4-bb9d-5f2c7861c1f1}',
@@ -25,7 +25,8 @@ from gns3server.compute.virtualbox import VirtualBox
@pytest.fixture
async def manager(loop, port_manager):
@pytest.mark.asyncio
async def manager(port_manager):
m = VirtualBox.instance()
m.port_manager = port_manager
@@ -33,11 +34,13 @@ async def manager(loop, port_manager):
@pytest.fixture(scope="function")
@pytest.mark.asyncio
async def vm(compute_project, manager):
return VirtualBoxVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager, "test", False)
@pytest.mark.asyncio
async def test_vm(compute_project, manager):
vm = VirtualBoxVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager, "test", False)
@@ -46,6 +49,7 @@ async def test_vm(compute_project, manager):
assert vm.vmname == "test"
@pytest.mark.asyncio
async def test_rename_vmname(compute_project, manager):
"""
Rename a VM is not allowed when using a running linked clone
@@ -75,6 +79,7 @@ async def test_rename_vmname(compute_project, manager):
assert vm._modify_vm.called
@pytest.mark.asyncio
async def test_vm_valid_virtualbox_api_version(compute_project, manager):
with asyncio_patch("gns3server.compute.virtualbox.VirtualBox.execute", return_value=["API version: 4_3"]):
@@ -83,6 +88,7 @@ async def test_vm_valid_virtualbox_api_version(compute_project, manager):
await vm.create()
@pytest.mark.asyncio
async def test_vm_invalid_virtualbox_api_version(compute_project, manager):
with asyncio_patch("gns3server.compute.virtualbox.VirtualBox.execute", return_value=["API version: 4_2"]):
@@ -91,6 +97,7 @@ async def test_vm_invalid_virtualbox_api_version(compute_project, manager):
await vm.create()
@pytest.mark.asyncio
async def test_vm_adapter_add_nio_binding_adapter_not_exist(vm, manager, free_console_port):
nio = manager.create_nio({"type": "nio_udp", "lport": free_console_port, "rport": free_console_port, "rhost": "127.0.0.1"})
+2 -1
View File
@@ -22,7 +22,8 @@ from gns3server.compute.vmware import VMware
@pytest.fixture
async def manager(loop, port_manager):
@pytest.mark.asyncio
async def manager(port_manager):
m = VMware.instance()
m.port_manager = port_manager
+7 -2
View File
@@ -16,14 +16,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import asyncio
from gns3server.compute.vmware.vmware_vm import VMwareVM
from gns3server.compute.vmware import VMware
@pytest.fixture
async def manager(loop, port_manager):
@pytest.mark.asyncio
async def manager(port_manager):
m = VMware.instance()
m.port_manager = port_manager
@@ -31,6 +31,7 @@ async def manager(loop, port_manager):
@pytest.fixture(scope="function")
@pytest.mark.asyncio
async def vm(compute_project, manager, tmpdir):
fake_vmx = str(tmpdir / "test.vmx")
@@ -38,12 +39,14 @@ async def vm(compute_project, manager, tmpdir):
return VMwareVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager, fake_vmx, False)
@pytest.mark.asyncio
async def test_vm(vm):
assert vm.name == "test"
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0f"
@pytest.mark.asyncio
async def test_json(vm, tmpdir, compute_project):
assert vm.__json__()["node_directory"] is not None
@@ -52,6 +55,7 @@ async def test_json(vm, tmpdir, compute_project):
assert vm.__json__()["node_directory"] is not None
@pytest.mark.asyncio
async def test_start_capture(vm, tmpdir, manager, free_console_port):
output_file = str(tmpdir / "test.pcap")
@@ -62,6 +66,7 @@ async def test_start_capture(vm, tmpdir, manager, free_console_port):
assert vm._ethernet_adapters[0].get_nio(0).capturing
@pytest.mark.asyncio
async def test_stop_capture(vm, tmpdir, manager, free_console_port):
output_file = str(tmpdir / "test.pcap")
+3
View File
@@ -25,6 +25,7 @@ from gns3server.compute.vpcs.vpcs_error import VPCSError
from gns3server.compute.project_manager import ProjectManager
@pytest.mark.asyncio
async def test_get_mac_id(compute_project, port_manager):
# Cleanup the VPCS object
@@ -44,6 +45,7 @@ async def test_get_mac_id(compute_project, port_manager):
assert vpcs.get_mac_id(vm3_id) == 0
@pytest.mark.asyncio
async def test_get_mac_id_multiple_project(port_manager):
# Cleanup the VPCS object
@@ -63,6 +65,7 @@ async def test_get_mac_id_multiple_project(port_manager):
assert vpcs.get_mac_id(vm3_id) == 0
@pytest.mark.asyncio
async def test_get_mac_id_no_id_available(compute_project, port_manager):
# Cleanup the VPCS object
+17 -2
View File
@@ -31,7 +31,8 @@ from gns3server.compute.notification_manager import NotificationManager
@pytest.fixture
async def manager(loop, port_manager):
@pytest.mark.asyncio
async def manager(port_manager):
m = VPCS.instance()
m.port_manager = port_manager
@@ -39,7 +40,8 @@ async def manager(loop, port_manager):
@pytest.fixture(scope="function")
async def vm(loop, compute_project, manager, tmpdir, ubridge_path):
@pytest.mark.asyncio
async def vm(compute_project, manager, tmpdir, ubridge_path):
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager)
vm._vpcs_version = parse_version("0.9")
@@ -49,6 +51,7 @@ async def vm(loop, compute_project, manager, tmpdir, ubridge_path):
return vm
@pytest.mark.asyncio
async def test_vm(compute_project, manager):
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager)
@@ -56,6 +59,7 @@ async def test_vm(compute_project, manager):
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0f"
@pytest.mark.asyncio
async def test_vm_check_vpcs_version(vm):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.subprocess_check_output", return_value="Welcome to Virtual PC Simulator, version 0.9"):
@@ -63,6 +67,7 @@ async def test_vm_check_vpcs_version(vm):
assert vm._vpcs_version == parse_version("0.9")
@pytest.mark.asyncio
async def test_vm_check_vpcs_version_0_6_1(vm):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.subprocess_check_output", return_value="Welcome to Virtual PC Simulator, version 0.6.1"):
@@ -70,6 +75,7 @@ async def test_vm_check_vpcs_version_0_6_1(vm):
assert vm._vpcs_version == parse_version("0.6.1")
@pytest.mark.asyncio
async def test_vm_invalid_vpcs_version(vm, manager):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.subprocess_check_output", return_value="Welcome to Virtual PC Simulator, version 0.1"):
@@ -81,6 +87,7 @@ async def test_vm_invalid_vpcs_version(vm, manager):
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0f"
@pytest.mark.asyncio
async def test_vm_invalid_vpcs_path(vm, manager):
with patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM._vpcs_path", return_value="/tmp/fake/path/vpcs"):
@@ -92,6 +99,7 @@ async def test_vm_invalid_vpcs_path(vm, manager):
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0e"
@pytest.mark.asyncio
async def test_start(vm):
process = MagicMock()
@@ -125,6 +133,7 @@ async def test_start(vm):
assert event == vm
@pytest.mark.asyncio
async def test_start_0_6_1(vm):
"""
Version 0.6.1 doesn't have the -R options. It's not require
@@ -157,6 +166,7 @@ async def test_start_0_6_1(vm):
assert vm.is_running()
@pytest.mark.asyncio
async def test_stop(vm):
process = MagicMock()
@@ -193,6 +203,7 @@ async def test_stop(vm):
assert event == vm
@pytest.mark.asyncio
async def test_reload(vm):
process = MagicMock()
@@ -221,6 +232,7 @@ async def test_reload(vm):
process.terminate.assert_called_with()
@pytest.mark.asyncio
async def test_add_nio_binding_udp(vm):
nio = VPCS.instance().create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1", "filters": {}})
@@ -229,6 +241,7 @@ async def test_add_nio_binding_udp(vm):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_add_nio_binding_tap(vm, ethernet_device):
with patch("gns3server.compute.base_manager.BaseManager.has_privileged_access", return_value=True):
@@ -237,6 +250,7 @@ async def test_add_nio_binding_tap(vm, ethernet_device):
assert nio.tap_device == ethernet_device
@pytest.mark.asyncio
async def test_port_remove_nio_binding(vm):
nio = VPCS.instance().create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
@@ -312,6 +326,7 @@ def test_change_name(vm):
assert f.read() == "set pcname beta"
@pytest.mark.asyncio
async def test_close(vm):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM._check_requirements", return_value=True):
+25 -13
View File
@@ -2,26 +2,41 @@ import pytest
import asyncio
import tempfile
import shutil
import weakref
import sys
import os
from aiohttp import web
from unittest.mock import MagicMock, patch
from pathlib import Path
from gns3server.web.route import Route
from gns3server.controller import Controller
from gns3server.config import Config
from gns3server.compute import MODULES
from gns3server.compute.port_manager import PortManager
from gns3server.compute.project_manager import ProjectManager
# this import will register all handlers
from gns3server.handlers import *
from .handlers.api.base import Query
from .endpoints.base import Query
sys._called_from_test = True
sys.original_platform = sys.platform
from fastapi.testclient import TestClient
from gns3server.app import app
from httpx import AsyncClient
# @pytest.fixture
# async def client(controller):
#
# async with AsyncClient(app=app, base_url="http://test") as ac:
# response = await ac.get("/")
#
# assert response.status_code == 200
# assert response.json() == {"message": "Tomato"}
#
# return TestClient(app)
if sys.platform.startswith("win"):
@pytest.yield_fixture(scope="session")
@@ -35,13 +50,9 @@ if sys.platform.startswith("win"):
@pytest.fixture(scope='function')
async def http_client(aiohttp_client):
def http_client():
app = web.Application()
app['websockets'] = weakref.WeakSet()
for method, route, handler in Route.get_routes():
app.router.add_route(method, route, handler)
return await aiohttp_client(app)
return AsyncClient(app=app, base_url="http://test-api")
@pytest.fixture
@@ -72,7 +83,8 @@ def compute(controller):
@pytest.fixture
async def project(loop, tmpdir, controller):
@pytest.mark.asyncio
async def project(tmpdir, controller):
return await controller.add_project(name="Test")
File renamed without changes.
@@ -27,6 +27,7 @@ def gns3vm(controller):
return RemoteGNS3VM(controller)
@pytest.mark.asyncio
async def test_list(gns3vm, controller):
await controller.add_compute("r1", name="R1", host="r1.local", connect=False)
@@ -34,6 +35,7 @@ async def test_list(gns3vm, controller):
assert res == [{"vmname": "R1"}]
@pytest.mark.asyncio
async def test_start(gns3vm, controller):
await controller.add_compute("r1",
@@ -55,7 +57,8 @@ async def test_start(gns3vm, controller):
assert gns3vm.password == "world"
async def test_start_invalid_vm(loop, gns3vm, controller):
@pytest.mark.asyncio
async def test_start_invalid_vm(gns3vm, controller):
await controller.add_compute("r1",
name="R1",
@@ -16,23 +16,23 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import asyncio
from tests.utils import asyncio_patch, AsyncioMagicMock
from tests.utils import asyncio_patch
from gns3server.utils.asyncio import wait_run_in_executor
from unittest.mock import patch
from gns3server.controller.gns3vm.virtualbox_gns3_vm import VirtualBoxGNS3VM
@pytest.fixture
async def gns3vm(loop, controller):
@pytest.mark.asyncio
async def gns3vm(controller):
vm = VirtualBoxGNS3VM(controller)
vm.vmname = "GNS3 VM"
return vm
@pytest.mark.asyncio
async def test_look_for_interface(gns3vm):
showvminfo = """
@@ -68,6 +68,7 @@ GuestMemoryBalloon=0
# assert res == -1
@pytest.mark.asyncio
async def test_cpu_vendor_id(gns3vm):
from cpuinfo import get_cpu_info
@@ -21,7 +21,8 @@ from gns3server.controller.gns3vm.vmware_gns3_vm import VMwareGNS3VM
@pytest.fixture
async def gns3vm(loop, controller):
@pytest.mark.asyncio
async def gns3vm(controller):
vm = VMwareGNS3VM(controller)
vm.vmname = "GNS3 VM"
@@ -34,6 +35,7 @@ def vmx_path(tmpdir):
return str(tmpdir / "vmwware_vm.vmx")
@pytest.mark.asyncio
async def test_set_extra_options(gns3vm, vmx_path, windows_platform):
gns3vm._vmx_path = vmx_path
+43 -18
View File
@@ -17,11 +17,11 @@
import json
import pytest
import aiohttp
from unittest.mock import patch, MagicMock
from gns3server.controller.project import Project
from gns3server.controller.compute import Compute, ComputeConflict
from gns3server.controller.controller_error import ControllerError, ControllerNotFoundError
from tests.utils import asyncio_patch, AsyncioMagicMock
@@ -78,6 +78,7 @@ def test_name():
assert c.name == "https://azertyuiopq...@example.com:84"
@pytest.mark.asyncio
async def test_compute_httpQuery(compute):
response = MagicMock()
@@ -89,6 +90,7 @@ async def test_compute_httpQuery(compute):
assert compute._auth is None
@pytest.mark.asyncio
async def test_compute_httpQueryAuth(compute):
response = MagicMock()
@@ -104,7 +106,8 @@ async def test_compute_httpQueryAuth(compute):
assert compute._auth.password == "toor"
# async def test_compute_httpQueryNotConnected(compute, controller):
# @pytest.mark.asyncio
#async def test_compute_httpQueryNotConnected(compute, controller):
#
# controller._notification = MagicMock()
# compute._connected = False
@@ -121,7 +124,8 @@ async def test_compute_httpQueryAuth(compute):
# await compute.close()
# async def test_compute_httpQueryNotConnectedGNS3vmNotRunning(compute, controller):
# @pytest.mark.asyncio
#async def test_compute_httpQueryNotConnectedGNS3vmNotRunning(compute, controller):
# """
# We are not connected to the remote and it's a GNS3 VM. So we need to start it
# """
@@ -147,6 +151,7 @@ async def test_compute_httpQueryAuth(compute):
# await compute.close()
@pytest.mark.asyncio
async def test_compute_httpQueryNotConnectedInvalidVersion(compute):
compute._connected = False
@@ -154,12 +159,13 @@ async def test_compute_httpQueryNotConnectedInvalidVersion(compute):
response.read = AsyncioMagicMock(return_value=json.dumps({"version": "1.42.4"}).encode())
response.status = 200
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
await compute.post("/projects", {"a": "b"})
mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=None, timeout=20)
await compute.close()
@pytest.mark.asyncio
async def test_compute_httpQueryNotConnectedNonGNS3Server(compute):
compute._connected = False
@@ -167,12 +173,13 @@ async def test_compute_httpQueryNotConnectedNonGNS3Server(compute):
response.read = AsyncioMagicMock(return_value=b'Blocked by super antivirus')
response.status = 200
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
await compute.post("/projects", {"a": "b"})
mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=None, timeout=20)
await compute.close()
@pytest.mark.asyncio
async def test_compute_httpQueryNotConnectedNonGNS3Server2(compute):
compute._connected = False
@@ -180,22 +187,24 @@ async def test_compute_httpQueryNotConnectedNonGNS3Server2(compute):
response.read = AsyncioMagicMock(return_value=b'{}')
response.status = 200
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
await compute.post("/projects", {"a": "b"})
mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=None, timeout=20)
@pytest.mark.asyncio
async def test_compute_httpQueryError(compute):
response = MagicMock()
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
response.status = 404
with pytest.raises(aiohttp.web.HTTPNotFound):
with pytest.raises(ControllerNotFoundError):
await compute.post("/projects", {"a": "b"})
assert mock.called
await compute.close()
@pytest.mark.asyncio
async def test_compute_httpQueryConflictError(compute):
response = MagicMock()
@@ -208,6 +217,7 @@ async def test_compute_httpQueryConflictError(compute):
await compute.close()
@pytest.mark.asyncio
async def test_compute_httpQuery_project(compute):
response = MagicMock()
@@ -219,12 +229,14 @@ async def test_compute_httpQuery_project(compute):
await compute.close()
# FIXME: https://github.com/aio-libs/aiohttp/issues/2525
# async def test_connectNotification(compute):
# @pytest.mark.asyncio
#async def test_connectNotification(compute):
#
# ws_mock = AsyncioMagicMock()
# call = 0
#
# async def receive():
# @pytest.mark.asyncio
#async def receive():
# nonlocal call
# call += 1
# if call == 1:
@@ -256,7 +268,8 @@ async def test_compute_httpQuery_project(compute):
#
# call = 0
#
# async def receive():
# @pytest.mark.asyncio
#async def receive():
# nonlocal call
# call += 1
# if call == 1:
@@ -280,6 +293,7 @@ async def test_compute_httpQuery_project(compute):
# assert args[1]["memory_usage_percent"] == 80.7
# assert args[1]["cpu_usage_percent"] == 35.7
@pytest.mark.asyncio
async def test_json(compute):
compute.user = "test"
@@ -290,16 +304,17 @@ async def test_json(compute):
"host": "example.com",
"port": 84,
"user": "test",
"cpu_usage_percent": None,
"memory_usage_percent": None,
"disk_usage_percent": None,
"cpu_usage_percent": 0,
"memory_usage_percent": 0,
"disk_usage_percent": 0,
"connected": True,
"last_error": None,
"capabilities": {
"version": None,
"cpus": None,
"memory": None,
"disk_size": None,
"version": "",
"platform": "",
"cpus": 0,
"memory": 0,
"disk_size": 0,
"node_types": []
}
}
@@ -312,6 +327,7 @@ async def test_json(compute):
}
@pytest.mark.asyncio
async def test_downloadFile(project, compute):
response = MagicMock()
@@ -322,6 +338,7 @@ async def test_downloadFile(project, compute):
await compute.close()
@pytest.mark.asyncio
async def test_close(compute):
assert compute.connected is True
@@ -329,6 +346,7 @@ async def test_close(compute):
assert compute.connected is False
@pytest.mark.asyncio
async def test_update(compute, controller):
compute._controller._notification = MagicMock()
@@ -344,6 +362,7 @@ async def test_update(compute, controller):
assert compute._controller.save.called
@pytest.mark.asyncio
async def test_forward_get(compute):
response = MagicMock()
@@ -354,17 +373,19 @@ async def test_forward_get(compute):
await compute.close()
@pytest.mark.asyncio
async def test_forward_404(compute):
response = MagicMock()
response.status = 404
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
with pytest.raises(aiohttp.web_exceptions.HTTPNotFound):
with pytest.raises(ControllerNotFoundError):
await compute.forward("GET", "qemu", "images")
assert mock.called
await compute.close()
@pytest.mark.asyncio
async def test_forward_post(compute):
response = MagicMock()
@@ -375,6 +396,7 @@ async def test_forward_post(compute):
await compute.close()
@pytest.mark.asyncio
async def test_images(compute):
"""
Will return image on compute
@@ -397,6 +419,7 @@ async def test_images(compute):
]
@pytest.mark.asyncio
async def test_list_files(project, compute):
res = [{"path": "test"}]
@@ -409,6 +432,7 @@ async def test_list_files(project, compute):
await compute.close()
@pytest.mark.asyncio
async def test_interfaces(compute):
res = [
@@ -430,6 +454,7 @@ async def test_interfaces(compute):
await compute.close()
@pytest.mark.asyncio
async def test_get_ip_on_same_subnet(controller):
compute1 = Compute("compute1", host="192.168.1.1", controller=controller)
+27 -5
View File
@@ -20,11 +20,11 @@ import uuid
import json
import pytest
import socket
import aiohttp
from unittest.mock import MagicMock, patch
from tests.utils import AsyncioMagicMock, asyncio_patch
from gns3server.controller.compute import Compute
from gns3server.controller.controller_error import ControllerError, ControllerNotFoundError
from gns3server.version import __version__
@@ -110,6 +110,7 @@ def test_import_computes_1_x(controller, controller_config_path):
assert compute.password is None
@pytest.mark.asyncio
async def test_load_projects(controller, projects_dir):
controller.save()
@@ -121,6 +122,7 @@ async def test_load_projects(controller, projects_dir):
mock_load_project.assert_called_with(os.path.join(projects_dir, "project1", "project1.gns3"), load=False)
@pytest.mark.asyncio
async def test_add_compute(controller):
controller._notification = MagicMock()
@@ -134,15 +136,17 @@ async def test_add_compute(controller):
assert len(controller.computes) == 2
@pytest.mark.asyncio
async def test_addDuplicateCompute(controller):
controller._notification = MagicMock()
c = await controller.add_compute(compute_id="test1", name="Test", connect=False)
assert len(controller.computes) == 1
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
await controller.add_compute(compute_id="test2", name="Test", connect=False)
@pytest.mark.asyncio
async def test_deleteCompute(controller, controller_config_path):
c = await controller.add_compute(compute_id="test1", connect=False)
@@ -158,6 +162,7 @@ async def test_deleteCompute(controller, controller_config_path):
assert c.connected is False
@pytest.mark.asyncio
async def test_deleteComputeProjectOpened(controller, controller_config_path):
"""
When you delete a compute the project using it are close
@@ -190,6 +195,7 @@ async def test_deleteComputeProjectOpened(controller, controller_config_path):
assert project2.status == "opened"
@pytest.mark.asyncio
async def test_addComputeConfigFile(controller, controller_config_path):
await controller.add_compute(compute_id="test1", name="Test", connect=False)
@@ -209,14 +215,16 @@ async def test_addComputeConfigFile(controller, controller_config_path):
]
@pytest.mark.asyncio
async def test_getCompute(controller):
compute = await controller.add_compute(compute_id="test1", connect=False)
assert controller.get_compute("test1") == compute
with pytest.raises(aiohttp.web.HTTPNotFound):
with pytest.raises(ControllerNotFoundError):
assert controller.get_compute("dsdssd")
@pytest.mark.asyncio
async def test_has_compute(controller):
await controller.add_compute(compute_id="test1", connect=False)
@@ -224,6 +232,7 @@ async def test_has_compute(controller):
assert not controller.has_compute("test2")
@pytest.mark.asyncio
async def test_add_project(controller):
uuid1 = str(uuid.uuid4())
@@ -236,16 +245,18 @@ async def test_add_project(controller):
assert len(controller.projects) == 2
@pytest.mark.asyncio
async def test_addDuplicateProject(controller):
uuid1 = str(uuid.uuid4())
uuid2 = str(uuid.uuid4())
await controller.add_project(project_id=uuid1, name="Test")
assert len(controller.projects) == 1
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
await controller.add_project(project_id=uuid2, name="Test")
@pytest.mark.asyncio
async def test_remove_project(controller):
uuid1 = str(uuid.uuid4())
@@ -255,6 +266,7 @@ async def test_remove_project(controller):
assert len(controller.projects) == 0
@pytest.mark.asyncio
async def test_addProject_with_compute(controller):
uuid1 = str(uuid.uuid4())
@@ -264,15 +276,17 @@ async def test_addProject_with_compute(controller):
await controller.add_project(project_id=uuid1, name="Test")
@pytest.mark.asyncio
async def test_getProject(controller):
uuid1 = str(uuid.uuid4())
project = await controller.add_project(project_id=uuid1, name="Test")
assert controller.get_project(uuid1) == project
with pytest.raises(aiohttp.web.HTTPNotFound):
with pytest.raises(ControllerNotFoundError):
assert controller.get_project("dsdssd")
@pytest.mark.asyncio
async def test_start(controller):
controller.gns3vm.settings = {
@@ -288,6 +302,7 @@ async def test_start(controller):
assert controller.computes["local"].name == socket.gethostname()
@pytest.mark.asyncio
async def test_start_vm(controller):
"""
Start the controller with a GNS3 VM
@@ -309,6 +324,7 @@ async def test_start_vm(controller):
assert len(controller.computes) == 2 # Local compute and vm are created
@pytest.mark.asyncio
async def test_stop(controller):
c = await controller.add_compute(compute_id="test1", connect=False)
@@ -317,6 +333,7 @@ async def test_stop(controller):
assert c.connected is False
@pytest.mark.asyncio
async def test_stop_vm(controller):
"""
Stop GNS3 VM if configured
@@ -335,6 +352,7 @@ async def test_stop_vm(controller):
assert mock.called
@pytest.mark.asyncio
async def test_suspend_vm(controller):
"""
Suspend GNS3 VM if configured
@@ -353,6 +371,7 @@ async def test_suspend_vm(controller):
assert mock.called
@pytest.mark.asyncio
async def test_keep_vm(controller):
"""
Keep GNS3 VM if configured
@@ -371,6 +390,7 @@ async def test_keep_vm(controller):
assert not mock.called
@pytest.mark.asyncio
async def test_get_free_project_name(controller):
await controller.add_project(project_id=str(uuid.uuid4()), name="Test")
@@ -380,6 +400,7 @@ async def test_get_free_project_name(controller):
assert controller.get_free_project_name("Hello") == "Hello"
@pytest.mark.asyncio
async def test_load_base_files(controller, config, tmpdir):
config.set_section_config("Server", {"configs_path": str(tmpdir)})
@@ -451,6 +472,7 @@ def test_load_templates(controller):
assert cloud_uuid == template.id
@pytest.mark.asyncio
async def test_autoidlepc(controller):
controller._computes["local"] = AsyncioMagicMock()
+1
View File
@@ -68,6 +68,7 @@ def test_json(project):
}
@pytest.mark.asyncio
async def test_update(drawing, project, controller):
controller._notification = AsyncioMagicMock()
+17 -5
View File
@@ -19,7 +19,6 @@
import os
import json
import pytest
import aiohttp
import zipfile
from pathlib import Path
@@ -30,10 +29,12 @@ from tests.utils import AsyncioMagicMock, AsyncioBytesIO
from gns3server.controller.project import Project
from gns3server.controller.export_project import export_project, _is_exportable
from gns3server.utils.asyncio import aiozipstream
from gns3server.controller.controller_error import ControllerError
@pytest.fixture
async def project(loop, controller):
@pytest.mark.asyncio
async def project(controller):
p = Project(controller=controller, name="test")
p.dump = MagicMock()
@@ -41,6 +42,7 @@ async def project(loop, controller):
@pytest.fixture
@pytest.mark.asyncio
async def node(controller, project):
compute = MagicMock()
@@ -54,6 +56,7 @@ async def node(controller, project):
return node
@pytest.mark.asyncio
async def write_file(path, z):
with open(path, 'wb') as f:
@@ -72,6 +75,7 @@ def test_exportable_files():
assert not _is_exportable("test/project-files/snapshots/test.gns3p")
@pytest.mark.asyncio
async def test_export(tmpdir, project):
path = project.path
@@ -138,6 +142,7 @@ async def test_export(tmpdir, project):
assert topo["computes"] == []
@pytest.mark.asyncio
async def test_export_vm(tmpdir, project):
"""
If data is on a remote server export it locally before
@@ -175,6 +180,7 @@ async def test_export_vm(tmpdir, project):
assert content == b"HELLO"
@pytest.mark.asyncio
async def test_export_disallow_running(tmpdir, project, node):
"""
Disallow export when a node is running
@@ -196,11 +202,12 @@ async def test_export_disallow_running(tmpdir, project, node):
json.dump(topology, f)
node._status = "started"
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
with aiozipstream.ZipFile() as z:
await export_project(z, project, str(tmpdir))
@pytest.mark.asyncio
async def test_export_disallow_some_type(tmpdir, project):
"""
Disallow export for some node type
@@ -221,7 +228,7 @@ async def test_export_disallow_some_type(tmpdir, project):
with open(os.path.join(path, "test.gns3"), 'w+') as f:
json.dump(topology, f)
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
with aiozipstream.ZipFile() as z:
await export_project(z, project, str(tmpdir))
with aiozipstream.ZipFile() as z:
@@ -242,11 +249,12 @@ async def test_export_disallow_some_type(tmpdir, project):
}
with open(os.path.join(path, "test.gns3"), 'w+') as f:
json.dump(topology, f)
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
with aiozipstream.ZipFile() as z:
await export_project(z, project, str(tmpdir), allow_all_nodes=True)
@pytest.mark.asyncio
async def test_export_fix_path(tmpdir, project):
"""
Fix absolute image path, except for Docker
@@ -288,6 +296,7 @@ async def test_export_fix_path(tmpdir, project):
assert topology["topology"]["nodes"][1]["properties"]["image"] == "gns3/webterm:lastest"
@pytest.mark.asyncio
async def test_export_with_images(tmpdir, project):
"""
Fix absolute image path
@@ -323,6 +332,7 @@ async def test_export_with_images(tmpdir, project):
myzip.getinfo("images/IOS/test.image")
@pytest.mark.asyncio
async def test_export_keep_compute_id(tmpdir, project):
"""
If we want to restore the same computes we could ask to keep them
@@ -362,6 +372,7 @@ async def test_export_keep_compute_id(tmpdir, project):
assert len(topo["computes"]) == 1
@pytest.mark.asyncio
async def test_export_images_from_vm(tmpdir, project):
"""
If data is on a remote server export it locally before
@@ -426,6 +437,7 @@ async def test_export_images_from_vm(tmpdir, project):
assert content == b"IMAGE"
@pytest.mark.asyncio
async def test_export_with_ignoring_snapshots(tmpdir, project):
with open(os.path.join(project.path, "test.gns3"), 'w+') as f:
+8 -3
View File
@@ -47,7 +47,8 @@ def dummy_gns3vm(controller, dummy_engine):
return vm
async def test_list(loop, controller):
@pytest.mark.asyncio
async def test_list(controller):
vm = GNS3VM(controller)
with asyncio_patch("gns3server.controller.gns3vm.vmware_gns3_vm.VMwareGNS3VM.list", return_value=[{"vmname": "test", "vmx_path": "test"}]):
@@ -60,14 +61,16 @@ async def test_list(loop, controller):
await vm.list("hyperv")
async def test_json(loop, controller):
@pytest.mark.asyncio
async def test_json(controller):
vm = GNS3VM(controller)
assert vm.__json__() == vm._settings
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not working well on Windows")
async def test_update_settings(loop, controller):
@pytest.mark.asyncio
async def test_update_settings(controller):
vm = GNS3VM(controller)
vm.settings = {
@@ -85,6 +88,7 @@ async def test_update_settings(loop, controller):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not working well on Windows")
@pytest.mark.asyncio
async def test_auto_start(controller, dummy_gns3vm, dummy_engine):
"""
When start the compute should be add to the controller
@@ -102,6 +106,7 @@ async def test_auto_start(controller, dummy_gns3vm, dummy_engine):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not working well on Windows")
@pytest.mark.asyncio
async def test_auto_start_with_error(controller, dummy_gns3vm, dummy_engine):
dummy_engine.start.side_effect = GNS3VMError("Dummy error")
+19 -6
View File
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import os
import uuid
import json
@@ -26,6 +27,7 @@ from gns3server.controller.import_project import import_project, _move_files_to_
from gns3server.version import __version__
@pytest.mark.asyncio
async def test_import_project(tmpdir, controller):
project_id = str(uuid.uuid4())
@@ -71,6 +73,7 @@ async def test_import_project(tmpdir, controller):
assert project.name != "test"
@pytest.mark.asyncio
async def test_import_project_override(tmpdir, controller):
"""
In the case of snapshot we will import a project for
@@ -106,6 +109,7 @@ async def test_import_project_override(tmpdir, controller):
assert project.name == "test"
@pytest.mark.asyncio
async def test_import_upgrade(tmpdir, controller):
"""
Topology made for previous GNS3 version are upgraded during the process
@@ -135,6 +139,7 @@ async def test_import_upgrade(tmpdir, controller):
assert topo["version"] == __version__
@pytest.mark.asyncio
async def test_import_with_images(tmpdir, controller):
project_id = str(uuid.uuid4())
@@ -166,7 +171,8 @@ async def test_import_with_images(tmpdir, controller):
assert os.path.exists(path), path
async def test_import_iou_linux_no_vm(loop, linux_platform, tmpdir, controller):
@pytest.mark.asyncio
async def test_import_iou_linux_no_vm(linux_platform, tmpdir, controller):
"""
On non linux host IOU should be local if we don't have a GNS3 VM
"""
@@ -210,7 +216,8 @@ async def test_import_iou_linux_no_vm(loop, linux_platform, tmpdir, controller):
assert topo["topology"]["nodes"][0]["compute_id"] == "local"
async def test_import_iou_linux_with_vm(loop, linux_platform, tmpdir, controller):
@pytest.mark.asyncio
async def test_import_iou_linux_with_vm(linux_platform, tmpdir, controller):
"""
On non linux host IOU should be vm if we have a GNS3 VM configured
"""
@@ -255,7 +262,8 @@ async def test_import_iou_linux_with_vm(loop, linux_platform, tmpdir, controller
assert topo["topology"]["nodes"][0]["compute_id"] == "vm"
async def test_import_nat_non_linux(loop, windows_platform, tmpdir, controller):
@pytest.mark.asyncio
async def test_import_nat_non_linux(windows_platform, tmpdir, controller):
"""
On non linux host NAT should be moved to the GNS3 VM
"""
@@ -300,7 +308,8 @@ async def test_import_nat_non_linux(loop, windows_platform, tmpdir, controller):
assert topo["topology"]["nodes"][0]["compute_id"] == "vm"
async def test_import_iou_non_linux(loop, windows_platform, tmpdir, controller):
@pytest.mark.asyncio
async def test_import_iou_non_linux(windows_platform, tmpdir, controller):
"""
On non linux host IOU should be moved to the GNS3 VM
"""
@@ -356,7 +365,8 @@ async def test_import_iou_non_linux(loop, windows_platform, tmpdir, controller):
mock.assert_called_with(controller._computes["vm"], project_id, project.path, os.path.join('project-files', 'iou', topo["topology"]["nodes"][0]['node_id']))
async def test_import_node_id(loop, linux_platform, tmpdir, controller):
@pytest.mark.asyncio
async def test_import_node_id(linux_platform, tmpdir, controller):
"""
When importing a node, node_id should change
"""
@@ -449,7 +459,8 @@ async def test_import_node_id(loop, linux_platform, tmpdir, controller):
assert os.path.exists(os.path.join(project.path, "project-files", "iou", topo["topology"]["nodes"][0]["node_id"], "startup.cfg"))
async def test_import_keep_compute_id(loop, windows_platform, tmpdir, controller):
@pytest.mark.asyncio
async def test_import_keep_compute_id(windows_platform, tmpdir, controller):
"""
On linux host IOU should be moved to the GNS3 VM
"""
@@ -494,6 +505,7 @@ async def test_import_keep_compute_id(loop, windows_platform, tmpdir, controller
assert topo["topology"]["nodes"][0]["compute_id"] == "local"
@pytest.mark.asyncio
async def test_move_files_to_compute(tmpdir):
project_id = str(uuid.uuid4())
@@ -510,6 +522,7 @@ async def test_move_files_to_compute(tmpdir):
assert not os.path.exists(str(tmpdir / "project-files" / "docker"))
@pytest.mark.asyncio
async def test_import_project_name_and_location(tmpdir, controller):
"""
Import a project with a different location and name
+21 -5
View File
@@ -16,17 +16,18 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import aiohttp
from unittest.mock import MagicMock
from gns3server.controller.link import Link
from gns3server.controller.node import Node
from gns3server.controller.ports.ethernet_port import EthernetPort
from gns3server.controller.ports.serial_port import SerialPort
from gns3server.controller.controller_error import ControllerError
from tests.utils import AsyncioBytesIO, AsyncioMagicMock
@pytest.fixture
@pytest.mark.asyncio
async def link(project, compute):
node1 = Node(project, compute, "node1", node_type="qemu")
@@ -48,6 +49,7 @@ def test_eq(project, link):
assert link != Link(project)
@pytest.mark.asyncio
async def test_add_node(project, compute):
node1 = Node(project, compute, "node1", node_type="qemu")
@@ -83,6 +85,7 @@ async def test_add_node(project, compute):
assert link in node2.links
@pytest.mark.asyncio
async def test_add_node_already_connected(project, compute):
"""
Raise an error if we try to use an already connected port
@@ -104,10 +107,11 @@ async def test_add_node_already_connected(project, compute):
assert link.create.called
link2 = Link(project)
link2.create = AsyncioMagicMock()
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
await link2.add_node(node1, 0, 4)
@pytest.mark.asyncio
async def test_add_node_cloud(project, compute):
node1 = Node(project, compute, "node1", node_type="qemu")
@@ -123,6 +127,7 @@ async def test_add_node_cloud(project, compute):
await link.add_node(node2, 0, 4)
@pytest.mark.asyncio
async def test_add_node_cloud_to_cloud(project, compute):
"""
Cloud to cloud connection is not allowed
@@ -138,10 +143,11 @@ async def test_add_node_cloud_to_cloud(project, compute):
link._project.emit_notification = MagicMock()
await link.add_node(node1, 0, 4)
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
await link.add_node(node2, 0, 4)
@pytest.mark.asyncio
async def test_add_node_same_node(project, compute):
"""
Connection to the same node is not allowed
@@ -155,10 +161,11 @@ async def test_add_node_same_node(project, compute):
link._project.emit_notification = MagicMock()
await link.add_node(node1, 0, 4)
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
await link.add_node(node1, 0, 5)
@pytest.mark.asyncio
async def test_add_node_serial_to_ethernet(project, compute):
"""
Serial to ethernet connection is not allowed
@@ -174,10 +181,11 @@ async def test_add_node_serial_to_ethernet(project, compute):
link._project.emit_notification = MagicMock()
await link.add_node(node1, 0, 4)
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
await link.add_node(node2, 0, 4)
@pytest.mark.asyncio
async def test_json(project, compute):
node1 = Node(project, compute, "node1", node_type="qemu")
@@ -247,6 +255,7 @@ async def test_json(project, compute):
}
@pytest.mark.asyncio
async def test_json_serial_link(project, compute):
node1 = Node(project, compute, "node1", node_type="qemu")
@@ -261,6 +270,7 @@ async def test_json_serial_link(project, compute):
assert link.__json__()["link_type"] == "serial"
@pytest.mark.asyncio
async def test_default_capture_file_name(project, compute):
node1 = Node(project, compute, "Hello@", node_type="qemu")
@@ -275,8 +285,10 @@ async def test_default_capture_file_name(project, compute):
assert link.default_capture_file_name() == "Hello_0-4_to_w0rld_1-3.pcap"
@pytest.mark.asyncio
async def test_start_capture(link):
async def fake_reader():
return AsyncioBytesIO()
@@ -288,6 +300,7 @@ async def test_start_capture(link):
link._project.emit_notification.assert_called_with("link.updated", link.__json__())
@pytest.mark.asyncio
async def test_stop_capture(link):
link._capturing = True
@@ -297,6 +310,7 @@ async def test_stop_capture(link):
link._project.emit_notification.assert_called_with("link.updated", link.__json__())
@pytest.mark.asyncio
async def test_delete(project, compute):
node1 = Node(project, compute, "node1", node_type="qemu")
@@ -316,6 +330,7 @@ async def test_delete(project, compute):
assert link not in node2.links
@pytest.mark.asyncio
async def test_update_filters(project, compute):
node1 = Node(project, compute, "node1", node_type="qemu")
@@ -346,6 +361,7 @@ async def test_update_filters(project, compute):
assert link.update.called
@pytest.mark.asyncio
async def test_available_filters(project, compute):
node1 = Node(project, compute, "node1", node_type="ethernet_switch")
+21
View File
@@ -101,6 +101,7 @@ def test_empty_properties(compute, project):
assert "category" not in node.properties # Controller only
@pytest.mark.asyncio
async def test_eq(compute, project, node, controller):
assert node == Node(project, compute, "demo1", node_id=node.id, node_type="qemu")
@@ -186,6 +187,7 @@ def test_init_without_uuid(project, compute):
assert node.id is not None
@pytest.mark.asyncio
async def test_create(node, compute):
node._console = 2048
@@ -206,6 +208,7 @@ async def test_create(node, compute):
assert node._properties == {"startup_script": "echo test"}
@pytest.mark.asyncio
async def test_create_image_missing(node, compute):
node._console = 2048
@@ -228,6 +231,7 @@ async def test_create_image_missing(node, compute):
#assert node._upload_missing_image.called is True
@pytest.mark.asyncio
async def test_create_base_script(node, config, compute, tmpdir):
config.set_section_config("Server", {"configs_path": str(tmpdir)})
@@ -303,6 +307,7 @@ def test_label_with_default_label_font(node):
assert node.label["style"] == None #"font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #ff0000;fill-opacity: 1.0;"
@pytest.mark.asyncio
async def test_update(node, compute, project, controller):
response = MagicMock()
@@ -326,6 +331,7 @@ async def test_update(node, compute, project, controller):
assert project.dump.called
@pytest.mark.asyncio
async def test_update_properties(node, compute, controller):
"""
properties will be updated by the answer from compute
@@ -354,6 +360,7 @@ async def test_update_properties(node, compute, controller):
#controller._notification.emit.assert_called_with("node.updated", node_notif)
@pytest.mark.asyncio
async def test_update_only_controller(node, compute):
"""
When updating property used only on controller we don't need to
@@ -374,6 +381,7 @@ async def test_update_only_controller(node, compute):
assert not node._project.emit_notification.called
@pytest.mark.asyncio
async def test_update_no_changes(node, compute):
"""
We don't call the compute node if all compute properties has not changed
@@ -391,6 +399,7 @@ async def test_update_no_changes(node, compute):
assert node.x == 43
@pytest.mark.asyncio
async def test_start(node, compute):
compute.post = AsyncioMagicMock()
@@ -399,6 +408,7 @@ async def test_start(node, compute):
compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/start".format(node.project.id, node.id), timeout=240)
@pytest.mark.asyncio
async def test_start_iou(compute, project, controller):
node = Node(project, compute, "demo",
@@ -415,6 +425,7 @@ async def test_start_iou(compute, project, controller):
compute.post.assert_called_with("/projects/{}/iou/nodes/{}/start".format(node.project.id, node.id), timeout=240, data={"license_check": True, "iourc_content": "aa"})
@pytest.mark.asyncio
async def test_stop(node, compute):
compute.post = AsyncioMagicMock()
@@ -423,6 +434,7 @@ async def test_stop(node, compute):
compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/stop".format(node.project.id, node.id), timeout=240, dont_connect=True)
@pytest.mark.asyncio
async def test_suspend(node, compute):
compute.post = AsyncioMagicMock()
@@ -430,6 +442,7 @@ async def test_suspend(node, compute):
compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/suspend".format(node.project.id, node.id), timeout=240)
@pytest.mark.asyncio
async def test_reload(node, compute):
compute.post = AsyncioMagicMock()
@@ -437,6 +450,7 @@ async def test_reload(node, compute):
compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/reload".format(node.project.id, node.id), timeout=240)
@pytest.mark.asyncio
async def test_create_without_console(node, compute):
"""
None properties should be send. Because it can mean the emulator doesn't support it
@@ -458,24 +472,28 @@ async def test_create_without_console(node, compute):
assert node._properties == {"test_value": "success", "startup_script": "echo test"}
@pytest.mark.asyncio
async def test_delete(node, compute):
await node.destroy()
compute.delete.assert_called_with("/projects/{}/vpcs/nodes/{}".format(node.project.id, node.id))
@pytest.mark.asyncio
async def test_post(node, compute):
await node.post("/test", {"a": "b"})
compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/test".format(node.project.id, node.id), data={"a": "b"})
@pytest.mark.asyncio
async def test_delete(node, compute):
await node.delete("/test")
compute.delete.assert_called_with("/projects/{}/vpcs/nodes/{}/test".format(node.project.id, node.id))
@pytest.mark.asyncio
async def test_dynamips_idle_pc(node, compute):
node._node_type = "dynamips"
@@ -486,6 +504,7 @@ async def test_dynamips_idle_pc(node, compute):
compute.get.assert_called_with("/projects/{}/dynamips/nodes/{}/auto_idlepc".format(node.project.id, node.id), timeout=240)
@pytest.mark.asyncio
async def test_dynamips_idlepc_proposals(node, compute):
node._node_type = "dynamips"
@@ -496,6 +515,7 @@ async def test_dynamips_idlepc_proposals(node, compute):
compute.get.assert_called_with("/projects/{}/dynamips/nodes/{}/idlepc_proposals".format(node.project.id, node.id), timeout=240)
@pytest.mark.asyncio
async def test_upload_missing_image(compute, controller, images_dir):
project = Project(str(uuid.uuid4()), controller=controller)
@@ -535,6 +555,7 @@ def test_get_port(node):
assert port is None
@pytest.mark.asyncio
async def test_parse_node_response(node):
"""
When a node is updated we notify the links connected to it
+6
View File
@@ -22,6 +22,7 @@ from tests.utils import AsyncioMagicMock
@pytest.fixture
@pytest.mark.asyncio
async def node(project):
compute = MagicMock()
@@ -33,6 +34,7 @@ async def node(project):
return await project.add_node(compute, "test", None, node_type="vpcs", properties={"startup_config": "test.cfg"})
@pytest.mark.asyncio
async def test_emit_to_all(controller, project):
"""
Send an event to all if we don't have a project id in the event
@@ -49,6 +51,7 @@ async def test_emit_to_all(controller, project):
assert len(notif._project_listeners[project.id]) == 0
@pytest.mark.asyncio
async def test_emit_to_project(controller, project):
"""
Send an event to a project listeners
@@ -67,6 +70,7 @@ async def test_emit_to_project(controller, project):
assert len(notif._project_listeners[project.id]) == 0
@pytest.mark.asyncio
async def test_dispatch(controller, project):
notif = controller.notification
@@ -78,6 +82,7 @@ async def test_dispatch(controller, project):
assert msg == ('test', {}, {})
@pytest.mark.asyncio
async def test_dispatch_ping(controller, project):
notif = controller.notification
@@ -89,6 +94,7 @@ async def test_dispatch_ping(controller, project):
assert msg == ('ping', {'compute_id': 12}, {})
@pytest.mark.asyncio
async def test_dispatch_node_updated(controller, node, project):
"""
When we receive a node.updated notification from compute
+57 -12
View File
@@ -20,7 +20,6 @@ import os
import sys
import uuid
import pytest
import aiohttp
from unittest.mock import MagicMock
from tests.utils import AsyncioMagicMock, asyncio_patch
from unittest.mock import patch
@@ -30,10 +29,12 @@ from gns3server.controller.project import Project
from gns3server.controller.template import Template
from gns3server.controller.node import Node
from gns3server.controller.ports.ethernet_port import EthernetPort
from gns3server.controller.controller_error import ControllerError, ControllerNotFoundError, ControllerForbiddenError
from gns3server.config import Config
@pytest.fixture
@pytest.mark.asyncio
async def node(controller, project):
compute = MagicMock()
@@ -45,6 +46,7 @@ async def node(controller, project):
return node
@pytest.mark.asyncio
async def test_affect_uuid():
p = Project(name="Test")
@@ -53,6 +55,7 @@ async def test_affect_uuid():
assert p.id == '00010203-0405-0607-0809-0a0b0c0d0e0f'
@pytest.mark.asyncio
async def test_json():
p = Project(name="Test")
@@ -80,6 +83,7 @@ async def test_json():
}
@pytest.mark.asyncio
async def test_update(controller):
project = Project(controller=controller, name="Hello")
@@ -90,6 +94,7 @@ async def test_update(controller):
project.emit_notification.assert_any_call("project.updated", project.__json__())
@pytest.mark.asyncio
async def test_update_on_compute(controller):
variables = [{"name": "TEST", "value": "VAL1"}]
@@ -102,6 +107,7 @@ async def test_update_on_compute(controller):
compute.put.assert_any_call('/projects/{}'.format(project.id), {"variables": variables})
@pytest.mark.asyncio
async def test_path(projects_dir):
directory = projects_dir
@@ -118,10 +124,11 @@ def test_path_exist(tmpdir):
"""
os.makedirs(str(tmpdir / "demo"))
with pytest.raises(aiohttp.web.HTTPForbidden):
with pytest.raises(ControllerForbiddenError):
Project(name="Test", path=str(tmpdir / "demo"))
@pytest.mark.asyncio
async def test_init_path(tmpdir):
p = Project(path=str(tmpdir), project_id=str(uuid4()), name="Test")
@@ -129,13 +136,15 @@ async def test_init_path(tmpdir):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_changing_path_with_quote_not_allowed(tmpdir):
with pytest.raises(aiohttp.web.HTTPForbidden):
with pytest.raises(ControllerForbiddenError):
p = Project(project_id=str(uuid4()), name="Test")
p.path = str(tmpdir / "project\"53")
@pytest.mark.asyncio
async def test_captures_directory(tmpdir):
p = Project(path=str(tmpdir / "capturestest"), name="Test")
@@ -143,6 +152,7 @@ async def test_captures_directory(tmpdir):
assert os.path.exists(p.captures_directory)
@pytest.mark.asyncio
async def test_add_node_local(controller):
"""
For a local server we send the project path
@@ -174,6 +184,7 @@ async def test_add_node_local(controller):
project.emit_notification.assert_any_call("node.created", node.__json__())
@pytest.mark.asyncio
async def test_add_node_non_local(controller):
"""
For a non local server we do not send the project path
@@ -201,6 +212,7 @@ async def test_add_node_non_local(controller):
project.emit_notification.assert_any_call("node.created", node.__json__())
@pytest.mark.asyncio
async def test_add_node_iou(controller):
"""
Test if an application ID is allocated for IOU nodes
@@ -222,6 +234,7 @@ async def test_add_node_iou(controller):
assert node3.properties["application_id"] == 3
@pytest.mark.asyncio
async def test_add_node_iou_with_multiple_projects(controller):
"""
Test if an application ID is allocated for IOU nodes with different projects already opened
@@ -274,6 +287,7 @@ async def test_add_node_iou_with_multiple_projects(controller):
assert node12.properties["application_id"] == 3
@pytest.mark.asyncio
async def test_add_node_iou_with_multiple_projects_different_computes(controller):
"""
Test if an application ID is allocated for IOU nodes with different projects already opened
@@ -309,6 +323,7 @@ async def test_add_node_iou_with_multiple_projects_different_computes(controller
assert node6.properties["application_id"] == 4
@pytest.mark.asyncio
async def test_add_node_iou_no_id_available(controller):
"""
Test if an application ID is allocated for IOU nodes
@@ -321,13 +336,14 @@ async def test_add_node_iou_no_id_available(controller):
response = MagicMock()
compute.post = AsyncioMagicMock(return_value=response)
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
for i in range(1, 513):
prop = {"properties": {"application_id": i}}
project._nodes[i] = Node(project, compute, "Node{}".format(i), node_id=i, node_type="iou", **prop)
await project.add_node(compute, "test1", None, node_type="iou")
@pytest.mark.asyncio
async def test_add_node_from_template(controller):
"""
For a local server we send the project path
@@ -361,6 +377,7 @@ async def test_add_node_from_template(controller):
project.emit_notification.assert_any_call("node.created", node.__json__())
@pytest.mark.asyncio
async def test_add_builtin_node_from_template(controller):
"""
For a local server we send the project path
@@ -394,6 +411,7 @@ async def test_add_builtin_node_from_template(controller):
project.emit_notification.assert_any_call("node.created", node.__json__())
@pytest.mark.asyncio
async def test_delete_node(controller):
"""
For a local server we send the project path
@@ -415,6 +433,7 @@ async def test_delete_node(controller):
project.emit_notification.assert_any_call("node.deleted", node.__json__())
@pytest.mark.asyncio
async def test_delete_locked_node(controller):
"""
For a local server we send the project path
@@ -431,10 +450,11 @@ async def test_delete_locked_node(controller):
node = await project.add_node(compute, "test", None, node_type="vpcs", properties={"startup_config": "test.cfg"})
assert node.id in project._nodes
node.locked = True
with pytest.raises(aiohttp.web_exceptions.HTTPConflict):
with pytest.raises(ControllerError):
await project.delete_node(node.id)
@pytest.mark.asyncio
async def test_delete_node_delete_link(controller):
"""
Delete a node delete all the node connected
@@ -461,6 +481,7 @@ async def test_delete_node_delete_link(controller):
project.emit_notification.assert_any_call("link.deleted", link.__json__())
@pytest.mark.asyncio
async def test_get_node(controller):
compute = MagicMock()
@@ -473,15 +494,16 @@ async def test_get_node(controller):
vm = await project.add_node(compute, "test", None, node_type="vpcs", properties={"startup_config": "test.cfg"})
assert project.get_node(vm.id) == vm
with pytest.raises(aiohttp.web_exceptions.HTTPNotFound):
with pytest.raises(ControllerNotFoundError):
project.get_node("test")
# Raise an error if the project is not opened
await project.close()
with pytest.raises(aiohttp.web.HTTPForbidden):
with pytest.raises(ControllerForbiddenError):
project.get_node(vm.id)
@pytest.mark.asyncio
async def test_list_nodes(controller):
compute = MagicMock()
@@ -500,6 +522,7 @@ async def test_list_nodes(controller):
assert isinstance(project.nodes, dict)
@pytest.mark.asyncio
async def test_add_link(project):
compute = MagicMock()
@@ -522,6 +545,7 @@ async def test_add_link(project):
project.emit_notification.assert_any_call("link.created", link.__json__())
@pytest.mark.asyncio
async def test_list_links(project):
compute = MagicMock()
@@ -536,6 +560,7 @@ async def test_list_links(project):
assert len(project.links) == 1
@pytest.mark.asyncio
async def test_get_link(project):
compute = MagicMock()
@@ -546,10 +571,11 @@ async def test_get_link(project):
link = await project.add_link()
assert project.get_link(link.id) == link
with pytest.raises(aiohttp.web_exceptions.HTTPNotFound):
with pytest.raises(ControllerNotFoundError):
project.get_link("test")
@pytest.mark.asyncio
async def test_delete_link(project):
compute = MagicMock()
@@ -566,6 +592,7 @@ async def test_delete_link(project):
assert len(project._links) == 0
@pytest.mark.asyncio
async def test_add_drawing(project):
project.emit_notification = MagicMock()
@@ -574,15 +601,17 @@ async def test_add_drawing(project):
project.emit_notification.assert_any_call("drawing.created", drawing.__json__())
@pytest.mark.asyncio
async def test_get_drawing(project):
drawing = await project.add_drawing(None)
assert project.get_drawing(drawing.id) == drawing
with pytest.raises(aiohttp.web_exceptions.HTTPNotFound):
with pytest.raises(ControllerNotFoundError):
project.get_drawing("test")
@pytest.mark.asyncio
async def test_list_drawing(project):
await project.add_drawing(None)
@@ -592,6 +621,7 @@ async def test_list_drawing(project):
assert len(project.drawings) == 1
@pytest.mark.asyncio
async def test_delete_drawing(project):
assert len(project._drawings) == 0
@@ -603,6 +633,7 @@ async def test_delete_drawing(project):
assert len(project._drawings) == 0
@pytest.mark.asyncio
async def test_clean_pictures(project):
"""
When a project is close old pictures should be removed
@@ -617,6 +648,7 @@ async def test_clean_pictures(project):
assert not os.path.exists(os.path.join(project.pictures_directory, "test2.png"))
@pytest.mark.asyncio
async def test_clean_pictures_and_keep_supplier_logo(project):
"""
When a project is close old pictures should be removed
@@ -638,6 +670,7 @@ async def test_clean_pictures_and_keep_supplier_logo(project):
assert os.path.exists(os.path.join(project.pictures_directory, "logo.png"))
@pytest.mark.asyncio
async def test_delete(project):
assert os.path.exists(project.path)
@@ -645,6 +678,7 @@ async def test_delete(project):
assert not os.path.exists(project.path)
@pytest.mark.asyncio
async def test_dump(projects_dir):
directory = projects_dir
@@ -656,6 +690,7 @@ async def test_dump(projects_dir):
assert "00010203-0405-0607-0809-0a0b0c0d0e0f" in content
@pytest.mark.asyncio
async def test_open_close(controller):
project = Project(controller=controller, name="Test")
@@ -671,6 +706,7 @@ async def test_open_close(controller):
project.emit_notification.assert_any_call("project.closed", project.__json__())
@pytest.mark.asyncio
async def test_open_auto_start(controller):
project = Project(controller=controller, name="Test", auto_start=True)
@@ -691,6 +727,7 @@ def test_is_running(project, node):
assert project.is_running() is True
@pytest.mark.asyncio
async def test_duplicate(project, controller):
"""
Duplicate a project, the node should remain on the remote server
@@ -743,10 +780,11 @@ def test_get_snapshot(project):
snapshot = list(project.snapshots.values())[0]
assert project.get_snapshot(snapshot.id) == snapshot
with pytest.raises(aiohttp.web_exceptions.HTTPNotFound):
with pytest.raises(ControllerNotFoundError):
project.get_snapshot("BLU")
@pytest.mark.asyncio
async def test_delete_snapshot(project):
os.makedirs(os.path.join(project.path, "snapshots"))
@@ -758,12 +796,13 @@ async def test_delete_snapshot(project):
await project.delete_snapshot(snapshot.id)
with pytest.raises(aiohttp.web_exceptions.HTTPNotFound):
with pytest.raises(ControllerNotFoundError):
project.get_snapshot(snapshot.id)
assert not os.path.exists(os.path.join(project.path, "snapshots", "test1.gns3project"))
@pytest.mark.asyncio
async def test_snapshot(project):
"""
Create a snapshot
@@ -777,10 +816,11 @@ async def test_snapshot(project):
assert list(project.snapshots.values())[0].name == "test1"
# Raise a conflict if name is already use
with pytest.raises(aiohttp.web_exceptions.HTTPConflict):
with pytest.raises(ControllerError):
snapshot = await project.snapshot("test1")
@pytest.mark.asyncio
async def test_start_all(project):
compute = MagicMock()
@@ -797,6 +837,7 @@ async def test_start_all(project):
assert len(compute.post.call_args_list) == 10
@pytest.mark.asyncio
async def test_stop_all(project):
compute = MagicMock()
@@ -813,6 +854,7 @@ async def test_stop_all(project):
assert len(compute.post.call_args_list) == 10
@pytest.mark.asyncio
async def test_suspend_all(project):
compute = MagicMock()
@@ -829,6 +871,7 @@ async def test_suspend_all(project):
assert len(compute.post.call_args_list) == 10
@pytest.mark.asyncio
async def test_console_reset_all(project):
compute = MagicMock()
@@ -845,6 +888,7 @@ async def test_console_reset_all(project):
assert len(compute.post.call_args_list) == 10
@pytest.mark.asyncio
async def test_node_name(project):
compute = MagicMock()
@@ -870,6 +914,7 @@ async def test_node_name(project):
assert node.name == "R3"
@pytest.mark.asyncio
async def test_duplicate_node(project):
compute = MagicMock()
+5 -3
View File
@@ -18,7 +18,6 @@
import json
import pytest
import aiohttp
from tests.utils import asyncio_patch
@@ -146,7 +145,8 @@ def demo_topology():
}
# async def test_load_project(controller, tmpdir, demo_topology, http_client):
# @pytest.mark.asyncio
#async def test_load_project(controller, tmpdir, demo_topology, http_client):
#
# with open(str(tmpdir / "demo.gns3"), "w+") as f:
# json.dump(demo_topology, f)
@@ -170,6 +170,7 @@ def demo_topology():
# assert project.scene_width == 700
@pytest.mark.asyncio
async def test_open(controller, tmpdir):
simple_topology = {
@@ -208,7 +209,8 @@ async def test_open(controller, tmpdir):
assert project.scene_width == 700
# async def test_open_missing_compute(controller, tmpdir, demo_topology, http_client):
# @pytest.mark.asyncio
#async def test_open_missing_compute(controller, tmpdir, demo_topology, http_client):
# """
# If a compute is missing the project should not be open and the .gns3 should
# be the one before opening the project
+1
View File
@@ -70,6 +70,7 @@ def test_json(project):
}
@pytest.mark.asyncio
async def test_restore(project, controller):
compute = AsyncioMagicMock()
+7 -4
View File
@@ -18,16 +18,17 @@
import json
import uuid
import pytest
import aiohttp
from unittest.mock import MagicMock
from tests.utils import asyncio_patch
from gns3server.controller.project import Project
from gns3server.controller.compute import Compute
from gns3server.controller.topology import project_to_topology, load_topology, GNS3_FILE_FORMAT_REVISION
from gns3server.controller.controller_error import ControllerError
from gns3server.version import __version__
@pytest.mark.asyncio
async def test_project_to_topology_empty(tmpdir):
project = Project(name="Test")
@@ -61,6 +62,7 @@ async def test_project_to_topology_empty(tmpdir):
}
@pytest.mark.asyncio
async def test_basic_topology(controller):
project = Project(name="Test", controller=controller)
@@ -86,6 +88,7 @@ async def test_basic_topology(controller):
assert topo["topology"]["drawings"][0] == drawing.__json__(topology_dump=True)
@pytest.mark.asyncio
async def test_project_to_topology(controller):
variables = [
@@ -132,7 +135,7 @@ def test_load_topology(tmpdir):
def test_load_topology_file_error(tmpdir):
path = str(tmpdir / "test.gns3")
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
load_topology(path)
@@ -143,7 +146,7 @@ def test_load_topology_file_error_schema_error(tmpdir):
json.dump({
"revision": GNS3_FILE_FORMAT_REVISION
}, f)
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
load_topology(path)
@@ -165,7 +168,7 @@ def test_load_newer_topology(tmpdir):
path = str(tmpdir / "test.gns3")
with open(path, "w+") as f:
json.dump(data, f)
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
load_topology(path)
+12 -4
View File
@@ -16,15 +16,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import aiohttp
from unittest.mock import MagicMock
from tests.utils import AsyncioMagicMock
from gns3server.controller.udp_link import UDPLink
from gns3server.controller.ports.ethernet_port import EthernetPort
from gns3server.controller.node import Node
from gns3server.controller.controller_error import ControllerError
@pytest.mark.asyncio
async def test_create(project):
compute1 = MagicMock()
@@ -90,6 +91,7 @@ async def test_create(project):
}, timeout=120)
@pytest.mark.asyncio
async def test_create_one_side_failure(project):
compute1 = MagicMock()
@@ -129,13 +131,13 @@ async def test_create_one_side_failure(project):
response.json = {"udp_port": 2048}
return response
elif "/adapters" in path:
raise aiohttp.web.HTTPConflict(text="Error when creating the NIO")
raise ControllerError("Error when creating the NIO")
compute1.post.side_effect = compute1_callback
compute1.host = "example.com"
compute2.post.side_effect = compute2_callback
compute2.host = "example.org"
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
await link.add_node(node2, 3, 1)
compute1.post.assert_any_call("/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id), data={
@@ -159,6 +161,7 @@ async def test_create_one_side_failure(project):
compute1.delete.assert_any_call("/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id), timeout=120)
@pytest.mark.asyncio
async def test_delete(project):
compute1 = MagicMock()
@@ -180,6 +183,7 @@ async def test_delete(project):
compute2.delete.assert_any_call("/projects/{}/vpcs/nodes/{}/adapters/3/ports/1/nio".format(project.id, node2.id), timeout=120)
@pytest.mark.asyncio
async def test_choose_capture_side(project):
"""
The link capture should run on the optimal node
@@ -230,13 +234,14 @@ async def test_choose_capture_side(project):
await link.add_node(node_vpcs, 0, 4)
await link.add_node(node_iou, 3, 1)
with pytest.raises(aiohttp.web.HTTPConflict):
with pytest.raises(ControllerError):
link._choose_capture_side()
# If you start a node you can capture on it
node_vpcs._status = "started"
assert link._choose_capture_side()["node"] == node_vpcs
@pytest.mark.asyncio
async def test_capture(project):
compute1 = MagicMock()
@@ -265,6 +270,7 @@ async def test_capture(project):
compute1.post.assert_any_call("/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/stop_capture".format(project.id, node_vpcs.id))
@pytest.mark.asyncio
async def test_node_updated(project):
"""
If a node stop when capturing we stop the capture
@@ -286,6 +292,7 @@ async def test_node_updated(project):
assert link.stop_capture.called
@pytest.mark.asyncio
async def test_update(project):
compute1 = MagicMock()
@@ -365,6 +372,7 @@ async def test_update(project):
}, timeout=120)
@pytest.mark.asyncio
async def test_update_suspend(project):
compute1 = MagicMock()
compute2 = MagicMock()
File renamed without changes.
@@ -15,14 +15,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Base code use for all API tests"""
"""
Base code use for all API tests
"""
import json
import re
import asyncio
import aiohttp
import os
import pytest
class Query:
@@ -56,52 +54,36 @@ class Query:
return self._request("PATCH", path, **kwargs)
def get_url(self, path):
if self._api_version is None:
return "/{}{}".format(self._prefix, path)
return "/v{}{}{}".format(self._api_version, self._prefix, path)
# async def websocket(self, path):
# """
# Return a websocket connected to the path
# """
#
# #self._session = aiohttp.ClientSession()
# response = await self._http_client.ws_connect(self.get_url(path))
# return response
#
# # async def go_request(future):
# # self._session = aiohttp.ClientSession()
# # response = await self._session.ws_connect(self.get_url(path))
# # future.set_result(response)
# #
# # future = asyncio.Future()
# # asyncio.ensure_future(go_request(future))
# # self._loop.run_until_complete(future)
# # return future.result()
@pytest.mark.asyncio
async def _request(self, method, path, body=None, raw=False, **kwargs):
if body is not None and raw is False:
body = json.dumps(body)
async with self._http_client.request(method, self.get_url(path), data=body, **kwargs) as response:
response.body = await response.read()
x_route = response.headers.get('X-Route', None)
if x_route is not None:
response.route = x_route.replace("/v{}".format(self._api_version), "")
response.route = response.route .replace(self._prefix, "")
async with self._http_client as ac:
response = await ac.request(method, self.get_url(path), data=body, **kwargs)
#response.body = await response.read()
# x_route = response.headers.get('X-Route', None)
# if x_route is not None:
# response.route = x_route.replace("/v{}".format(self._api_version), "")
# response.route = response.route.replace(self._prefix, "")
#response.json = {}
#response.html = ""
if response.body is not None:
if response.content_type == "application/json":
if response.content is not None:
if response.headers.get("content-type") == "application/json":
try:
response.json = await response.json(encoding="utf-8")
response.json = response.json(encoding="utf-8")
except ValueError:
response.json = None
else:
try:
response.html = await response.text("utf-8")
except UnicodeDecodeError:
response.html = None
# else:
# try:
# response.html = response.text
# except UnicodeDecodeError:
# response.html = None
return response
View File
Whitespace-only changes.
@@ -25,10 +25,11 @@ from gns3server.utils.path import get_default_project_directory
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_get(compute_api, windows_platform):
response = await compute_api.get('/capabilities')
assert response.status == 200
assert response.status_code == 200
assert response.json == {'node_types': ['cloud', 'ethernet_hub', 'ethernet_switch', 'nat', 'vpcs', 'virtualbox', 'dynamips', 'frame_relay_switch', 'atm_switch', 'qemu', 'vmware', 'traceng', 'docker', 'iou'],
'version': __version__,
'platform': sys.platform,
@@ -39,10 +40,11 @@ async def test_get(compute_api, windows_platform):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_get_on_gns3vm(compute_api, on_gns3vm):
response = await compute_api.get('/capabilities')
assert response.status == 200
assert response.status_code == 200
assert response.json == {'node_types': ['cloud', 'ethernet_hub', 'ethernet_switch', 'nat', 'vpcs', 'virtualbox', 'dynamips', 'frame_relay_switch', 'atm_switch', 'qemu', 'vmware', 'traceng', 'docker', 'iou'],
'version': __version__,
'platform': sys.platform,
@@ -17,38 +17,41 @@
import pytest
from unittest.mock import patch
from tests.utils import asyncio_patch
@pytest.fixture(scope="function")
@pytest.mark.asyncio
async def vm(compute_api, compute_project, on_gns3vm):
with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud._start_ubridge"):
response = await compute_api.post("/projects/{project_id}/cloud/nodes".format(project_id=compute_project.id), {"name": "Cloud 1"})
assert response.status == 201
assert response.status_code == 201
return response.json
@pytest.mark.asyncio
async def test_cloud_create(compute_api, compute_project):
with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud._start_ubridge"):
response = await compute_api.post("/projects/{project_id}/cloud/nodes".format(project_id=compute_project.id), {"name": "Cloud 1"})
assert response.status == 201
assert response.route == "/projects/{project_id}/cloud/nodes"
assert response.status_code == 201
assert response.json["name"] == "Cloud 1"
assert response.json["project_id"] == compute_project.id
@pytest.mark.asyncio
async def test_cloud_get(compute_api, compute_project, vm):
response = await compute_api.get("/projects/{project_id}/cloud/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 200
assert response.route == "/projects/{project_id}/cloud/nodes/{node_id}"
assert response.status_code == 200
assert response.json["name"] == "Cloud 1"
assert response.json["project_id"] == compute_project.id
assert response.json["status"] == "started"
@pytest.mark.asyncio
async def test_cloud_nio_create_udp(compute_api, vm):
params = {"type": "nio_udp",
@@ -57,11 +60,11 @@ async def test_cloud_nio_create_udp(compute_api, vm):
"rhost": "127.0.0.1"}
response = await compute_api.post("/projects/{project_id}/cloud/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.route == r"/projects/{project_id}/cloud/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201
assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_cloud_nio_update_udp(compute_api, vm):
params = {"type": "nio_udp",
@@ -72,11 +75,11 @@ async def test_cloud_nio_update_udp(compute_api, vm):
await compute_api.post("/projects/{project_id}/cloud/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
params["filters"] = {}
response = await compute_api.put("/projects/{project_id}/cloud/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201, response.body.decode()
assert response.route == r"/projects/{project_id}/cloud/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201, response.body.decode()
assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_cloud_delete_nio(compute_api, vm):
params = {"type": "nio_udp",
@@ -87,23 +90,25 @@ async def test_cloud_delete_nio(compute_api, vm):
await compute_api.post("/projects/{project_id}/cloud/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud._start_ubridge"):
response = await compute_api.delete("/projects/{project_id}/cloud/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.route == r"/projects/{project_id}/cloud/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 204
@pytest.mark.asyncio
async def test_cloud_delete(compute_api, vm):
response = await compute_api.delete("/projects/{project_id}/cloud/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_cloud_update(compute_api, vm):
response = await compute_api.put("/projects/{project_id}/cloud/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), {"name": "test"})
assert response.status == 200
assert response.status_code == 200
assert response.json["name"] == "test"
@pytest.mark.asyncio
async def test_cloud_start_capture(compute_api, vm):
params = {
@@ -113,22 +118,28 @@ async def test_cloud_start_capture(compute_api, vm):
with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud.start_capture") as mock:
response = await compute_api.post("/projects/{project_id}/cloud/nodes/{node_id}/adapters/0/ports/0/start_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 200
assert response.status_code == 200
assert mock.called
assert "test.pcap" in response.json["pcap_file_path"]
@pytest.mark.asyncio
async def test_cloud_stop_capture(compute_api, vm):
with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud.stop_capture") as mock:
response = await compute_api.post("/projects/{project_id}/cloud/nodes/{node_id}/adapters/0/ports/0/stop_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.status_code == 204
assert mock.called
async def test_cloud_pcap(compute_api, vm, compute_project):
with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud.get_nio"):
with asyncio_patch("gns3server.compute.builtin.Builtin.stream_pcap_file"):
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"]), raw=True)
assert response.status == 200
# @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
#
@@ -18,18 +18,45 @@
import os
import pytest
from gns3server.version import __version__
@pytest.mark.asyncio
async def test_udp_allocation(compute_api, compute_project):
response = await compute_api.post('/projects/{}/ports/udp'.format(compute_project.id), {})
assert response.status == 201
assert response.status_code == 201
assert response.json['udp_port'] is not None
# Netfifaces is not available on Travis
@pytest.mark.skipif(os.environ.get("TRAVIS", False) is not False, reason="Not supported on Travis")
@pytest.mark.asyncio
async def test_interfaces(compute_api):
response = await compute_api.get('/network/interfaces')
assert response.status == 200
assert response.status_code == 200
assert isinstance(response.json, list)
@pytest.mark.asyncio
async def test_version_output(compute_api, config):
config.set("Server", "local", "true")
response = await compute_api.get('/version')
assert response.status_code == 200
assert response.json == {'local': True, 'version': __version__}
# @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_statistics_output(compute_api):
response = await compute_api.get('/statistics')
assert response.status_code == 200
@@ -53,23 +53,24 @@ def base_params():
@pytest.fixture
@pytest.mark.asyncio
async def vm(compute_api, compute_project, base_params):
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_api.post("/projects/{project_id}/docker/nodes".format(project_id=compute_project.id), base_params)
assert response.status == 201
assert response.status_code == 201
return response.json
@pytest.mark.asyncio
async def test_docker_create(compute_api, compute_project, base_params):
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_api.post("/projects/{project_id}/docker/nodes".format(project_id=compute_project.id), base_params)
assert response.status == 201
assert response.route == "/projects/{project_id}/docker/nodes"
assert response.status_code == 201
assert response.json["name"] == "PC TEST 1"
assert response.json["project_id"] == compute_project.id
assert response.json["container_id"] == "8bd8153ea8f5"
@@ -80,54 +81,61 @@ async def test_docker_create(compute_api, compute_project, base_params):
assert response.json["extra_hosts"] == "test:127.0.0.1"
@pytest.mark.asyncio
async def test_docker_start(compute_api, vm):
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.start", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/docker/nodes/{node_id}/start".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_docker_stop(compute_api, vm):
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.stop", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/docker/nodes/{node_id}/stop".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_docker_reload(compute_api, vm):
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.restart", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/docker/nodes/{node_id}/reload".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_docker_delete(compute_api, vm):
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.delete", return_value=True) as mock:
response = await compute_api.delete("/projects/{project_id}/docker/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_docker_pause(compute_api, vm):
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.pause", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/docker/nodes/{node_id}/pause".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_docker_unpause(compute_api, vm):
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.unpause", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/docker/nodes/{node_id}/unpause".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_docker_nio_create_udp(compute_api, vm):
params = {
@@ -137,11 +145,11 @@ async def test_docker_nio_create_udp(compute_api, vm):
"rhost": "127.0.0.1"}
response = await compute_api.post("/projects/{project_id}/docker/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.route == r"/projects/{project_id}/docker/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201
assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_docker_update_nio(compute_api, vm):
params = {
@@ -152,21 +160,21 @@ async def test_docker_update_nio(compute_api, vm):
}
response = await compute_api.post("/projects/{project_id}/docker/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.status_code == 201
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.adapter_update_nio_binding"):
response = await compute_api.put("/projects/{project_id}/docker/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201, response.body.decode()
assert response.route == r"/projects/{project_id}/docker/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201, response.body.decode()
@pytest.mark.asyncio
async def test_docker_delete_nio(compute_api, vm):
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.adapter_remove_nio_binding"):
response = await compute_api.delete("/projects/{project_id}/docker/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.route == r"/projects/{project_id}/docker/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 204
@pytest.mark.asyncio
async def test_docker_update(compute_api, vm, free_console_port):
params = {
@@ -179,8 +187,9 @@ async def test_docker_update(compute_api, vm, free_console_port):
with asyncio_patch("gns3server.compute.docker.docker_vm.DockerVM.update") as mock:
response = await compute_api.put("/projects/{project_id}/docker/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status_code == 200
assert mock.called
assert response.status == 200
assert response.json["name"] == "test"
assert response.json["console"] == free_console_port
assert response.json["start_command"] == "yes"
@@ -188,30 +197,37 @@ async def test_docker_update(compute_api, vm, free_console_port):
assert response.json["extra_hosts"] == "test:127.0.0.1"
@pytest.mark.asyncio
async def test_docker_start_capture(compute_api, vm):
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_api.post("/projects/{project_id}/docker/nodes/{node_id}/adapters/0/ports/0/start_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]), body=params)
assert response.status == 200
assert response.status_code == 200
assert mock.called
assert "test.pcap" in response.json["pcap_file_path"]
@pytest.mark.asyncio
async def test_docker_stop_capture(compute_api, vm):
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_api.post("/projects/{project_id}/docker/nodes/{node_id}/adapters/0/ports/0/stop_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.status_code == 204
assert mock.called
async def test_docker_duplicate(compute_api, vm):
@pytest.mark.asyncio
async def test_docker_duplicate(compute_api, compute_project, base_params, vm):
params = {"destination_node_id": str(uuid.uuid4())}
with asyncio_patch("gns3server.compute.docker.Docker.duplicate_node", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/docker/nodes/{node_id}/duplicate".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert mock.called
assert response.status == 201
# 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_api.post("/projects/{project_id}/docker/nodes".format(project_id=compute_project.id), base_params)
assert response.status_code == 201
params = {"destination_node_id": response.json["node_id"]}
response = await compute_api.post("/projects/{project_id}/docker/nodes/{node_id}/duplicate".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status_code == 201
@@ -160,11 +160,12 @@ def fake_file(tmpdir):
return path
@pytest.mark.asyncio
async def test_images(compute_api, tmpdir, fake_image, fake_file):
with patch("gns3server.utils.images.default_images_directory", return_value=str(tmpdir)):
response = await compute_api.get("/dynamips/images")
assert response.status == 200
assert response.status_code == 200
assert response.json == [{"filename": "7200.bin",
"path": "7200.bin",
"filesize": 7,
@@ -172,10 +173,11 @@ async def test_images(compute_api, tmpdir, fake_image, fake_file):
}]
@pytest.mark.asyncio
async def test_upload_image(compute_api, images_dir):
response = await compute_api.post("/dynamips/images/test2", body="TEST", raw=True)
assert response.status == 204
response = await compute_api.post("/dynamips/images/test2", body=b"TEST", raw=True)
assert response.status_code == 204
with open(os.path.join(images_dir, "IOS", "test2")) as f:
assert f.read() == "TEST"
@@ -186,6 +188,7 @@ async def test_upload_image(compute_api, images_dir):
@pytest.mark.skipif(not sys.platform.startswith("win") and os.getuid() == 0, reason="Root can delete any image")
@pytest.mark.asyncio
async def test_upload_image_permission_denied(compute_api, images_dir):
os.makedirs(os.path.join(images_dir, "IOS"), exist_ok=True)
@@ -193,5 +196,5 @@ async def test_upload_image_permission_denied(compute_api, images_dir):
f.write("")
os.chmod(os.path.join(images_dir, "IOS", "test2.tmp"), 0)
response = await compute_api.post("/dynamips/images/test2", body="TEST", raw=True)
assert response.status == 409
response = await compute_api.post("/dynamips/images/test2", body=b"TEST", raw=True)
assert response.status_code == 409
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2015 GNS3 Technologies Inc.
# Copyright (C) 2020 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -46,10 +46,11 @@ def base_params(tmpdir, fake_iou_bin):
@pytest.fixture
@pytest.mark.asyncio
async def vm(compute_api, compute_project, base_params):
response = await compute_api.post("/projects/{project_id}/iou/nodes".format(project_id=compute_project.id), base_params)
assert response.status == 201
assert response.status_code == 201
return response.json
@@ -60,11 +61,11 @@ def startup_config_file(compute_project, vm):
return os.path.join(directory, "startup-config.cfg")
@pytest.mark.asyncio
async def test_iou_create(compute_api, compute_project, base_params):
response = await compute_api.post("/projects/{project_id}/iou/nodes".format(project_id=compute_project.id), base_params)
assert response.status == 201
assert response.route == "/projects/{project_id}/iou/nodes"
assert response.status_code == 201
assert response.json["name"] == "PC TEST 1"
assert response.json["project_id"] == compute_project.id
assert response.json["serial_adapters"] == 2
@@ -74,6 +75,7 @@ async def test_iou_create(compute_api, compute_project, base_params):
assert response.json["l1_keepalives"] is False
@pytest.mark.asyncio
async def test_iou_create_with_params(compute_api, compute_project, base_params):
params = base_params
@@ -86,8 +88,7 @@ async def test_iou_create_with_params(compute_api, compute_project, base_params)
params["use_default_iou_values"] = False
response = await compute_api.post("/projects/{project_id}/iou/nodes".format(project_id=compute_project.id), params)
assert response.status == 201
assert response.route == "/projects/{project_id}/iou/nodes"
assert response.status_code == 201
assert response.json["name"] == "PC TEST 1"
assert response.json["project_id"] == compute_project.id
assert response.json["serial_adapters"] == 4
@@ -101,6 +102,7 @@ async def test_iou_create_with_params(compute_api, compute_project, base_params)
assert f.read() == "hostname test"
@pytest.mark.asyncio
async def test_iou_create_startup_config_already_exist(compute_api, compute_project, base_params):
"""We don't erase a startup-config if already exist at project creation"""
@@ -114,18 +116,17 @@ async def test_iou_create_startup_config_already_exist(compute_api, compute_proj
params["startup_config_content"] = "hostname test"
response = await compute_api.post("/projects/{project_id}/iou/nodes".format(project_id=compute_project.id), params)
assert response.status == 201
assert response.route == "/projects/{project_id}/iou/nodes"
assert response.status_code == 201
with open(startup_config_file(compute_project, response.json)) as f:
assert f.read() == "echo hello"
@pytest.mark.asyncio
async def test_iou_get(compute_api, compute_project, vm):
response = await compute_api.get("/projects/{project_id}/iou/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 200
assert response.route == "/projects/{project_id}/iou/nodes/{node_id}"
assert response.status_code == 200
assert response.json["name"] == "PC TEST 1"
assert response.json["project_id"] == compute_project.id
assert response.json["serial_adapters"] == 2
@@ -135,51 +136,56 @@ async def test_iou_get(compute_api, compute_project, vm):
assert response.json["l1_keepalives"] is False
@pytest.mark.asyncio
async def test_iou_start(compute_api, vm):
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.start", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/iou/nodes/{node_id}/start".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 200
assert response.json["name"] == "PC TEST 1"
assert response.status_code == 204
@pytest.mark.asyncio
async def test_iou_start_with_iourc(compute_api, vm):
params = {"iourc_content": "test"}
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.start", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/iou/nodes/{node_id}/start".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert mock.called
assert response.status == 200
assert response.status_code == 204
response = await compute_api.get("/projects/{project_id}/iou/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 200
assert response.status_code == 200
@pytest.mark.asyncio
async def test_iou_stop(compute_api, vm):
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.stop", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/iou/nodes/{node_id}/stop".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_iou_reload(compute_api, vm):
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM.reload", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/iou/nodes/{node_id}/reload".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_iou_delete(compute_api, vm):
with asyncio_patch("gns3server.compute.iou.IOU.delete_node", return_value=True) as mock:
response = await compute_api.delete("/projects/{project_id}/iou/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_iou_update(compute_api, vm, free_console_port):
params = {
@@ -194,7 +200,7 @@ async def test_iou_update(compute_api, vm, free_console_port):
}
response = await compute_api.put("/projects/{project_id}/iou/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 200
assert response.status_code == 200
assert response.json["name"] == "test"
assert response.json["console"] == free_console_port
assert response.json["ethernet_adapters"] == 4
@@ -205,6 +211,7 @@ async def test_iou_update(compute_api, vm, free_console_port):
assert response.json["use_default_iou_values"] is True
@pytest.mark.asyncio
async def test_iou_nio_create_udp(compute_api, vm):
params = {"type": "nio_udp",
@@ -213,11 +220,11 @@ async def test_iou_nio_create_udp(compute_api, vm):
"rhost": "127.0.0.1"}
response = await compute_api.post("/projects/{project_id}/iou/nodes/{node_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.route == r"/projects/{project_id}/iou/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201
assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_iou_nio_update_udp(compute_api, vm):
params = {"type": "nio_udp",
@@ -229,11 +236,11 @@ async def test_iou_nio_update_udp(compute_api, vm):
params["filters"] = {}
response = await compute_api.put("/projects/{project_id}/iou/nodes/{node_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201, response.body.decode()
assert response.route == r"/projects/{project_id}/iou/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201, response.body.decode()
assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_iou_nio_create_ethernet(compute_api, vm, ethernet_device):
params = {
@@ -242,12 +249,12 @@ async def test_iou_nio_create_ethernet(compute_api, vm, ethernet_device):
}
response = await compute_api.post("/projects/{project_id}/iou/nodes/{node_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.route == r"/projects/{project_id}/iou/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201
assert response.json["type"] == "nio_ethernet"
assert response.json["ethernet_device"] == ethernet_device
@pytest.mark.asyncio
async def test_iou_nio_create_ethernet_different_port(compute_api, vm, ethernet_device):
params = {
@@ -256,12 +263,12 @@ async def test_iou_nio_create_ethernet_different_port(compute_api, vm, ethernet_
}
response = await compute_api.post("/projects/{project_id}/iou/nodes/{node_id}/adapters/0/ports/3/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.route == r"/projects/{project_id}/iou/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201
assert response.json["type"] == "nio_ethernet"
assert response.json["ethernet_device"] == ethernet_device
@pytest.mark.asyncio
async def test_iou_nio_create_tap(compute_api, vm, ethernet_device):
params = {
@@ -271,11 +278,11 @@ async def test_iou_nio_create_tap(compute_api, vm, ethernet_device):
with patch("gns3server.compute.base_manager.BaseManager.has_privileged_access", return_value=True):
response = await compute_api.post("/projects/{project_id}/iou/nodes/{node_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.route == r"/projects/{project_id}/iou/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201
assert response.json["type"] == "nio_tap"
@pytest.mark.asyncio
async def test_iou_delete_nio(compute_api, vm):
params = {
@@ -287,10 +294,10 @@ async def test_iou_delete_nio(compute_api, vm):
await compute_api.post("/projects/{project_id}/iou/nodes/{node_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
response = await compute_api.delete("/projects/{project_id}/iou/nodes/{node_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.route == r"/projects/{project_id}/iou/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 204
@pytest.mark.asyncio
async def test_iou_start_capture(compute_api, vm):
params = {
@@ -300,40 +307,44 @@ async def test_iou_start_capture(compute_api, vm):
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_api.post("/projects/{project_id}/iou/nodes/{node_id}/adapters/0/ports/0/start_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 200
assert response.status_code == 200
assert mock.called
assert "test.pcap" in response.json["pcap_file_path"]
@pytest.mark.asyncio
async def test_iou_stop_capture(compute_api, vm):
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_api.post("/projects/{project_id}/iou/nodes/{node_id}/adapters/0/ports/0/stop_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.status_code == 204
assert mock.called
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_api.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 == 200
# @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_api.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 == 200
@pytest.mark.asyncio
async def test_images(compute_api, fake_iou_bin):
response = await compute_api.get("/iou/images")
assert response.status == 200
assert response.status_code == 200
assert response.json == [{"filename": "iou.bin", "path": "iou.bin", "filesize": 7, "md5sum": "e573e8f5c93c6c00783f20c7a170aa6c"}]
@pytest.mark.asyncio
async def test_image_vm(compute_api, tmpdir):
with patch("gns3server.compute.IOU.get_images_directory", return_value=str(tmpdir)):
response = await compute_api.post("/iou/images/test2", body="TEST", raw=True)
assert response.status == 204
assert response.status_code == 204
with open(str(tmpdir / "test2")) as f:
assert f.read() == "TEST"
@@ -343,10 +354,13 @@ async def test_image_vm(compute_api, tmpdir):
assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
async def test_iou_duplicate(compute_api, vm):
@pytest.mark.asyncio
async def test_iou_duplicate(compute_api, compute_project, vm, base_params):
params = {"destination_node_id": str(uuid.uuid4())}
with asyncio_patch("gns3server.compute.iou.IOU.duplicate_node", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/iou/nodes/{node_id}/duplicate".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert mock.called
assert response.status == 201
# create destination node first
response = await compute_api.post("/projects/{project_id}/iou/nodes".format(project_id=compute_project.id), base_params)
assert response.status_code == 201
params = {"destination_node_id": response.json["node_id"]}
response = await compute_api.post("/projects/{project_id}/iou/nodes/{node_id}/duplicate".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status_code == 201
@@ -21,34 +21,36 @@ from tests.utils import asyncio_patch
@pytest.fixture(scope="function")
@pytest.mark.asyncio
async def vm(compute_api, compute_project, ubridge_path, on_gns3vm):
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat._start_ubridge"):
response = await compute_api.post("/projects/{project_id}/nat/nodes".format(project_id=compute_project.id), {"name": "Nat 1"})
assert response.status == 201
assert response.status_code == 201
return response.json
@pytest.mark.asyncio
async def test_nat_create(compute_api, compute_project, on_gns3vm):
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat._start_ubridge"):
response = await compute_api.post("/projects/{project_id}/nat/nodes".format(project_id=compute_project.id), {"name": "Nat 1"})
assert response.status == 201
assert response.route == "/projects/{project_id}/nat/nodes"
assert response.status_code == 201
assert response.json["name"] == "Nat 1"
assert response.json["project_id"] == compute_project.id
@pytest.mark.asyncio
async def test_nat_get(compute_api, compute_project, vm):
response = await compute_api.get("/projects/{project_id}/nat/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 200
assert response.route == "/projects/{project_id}/nat/nodes/{node_id}"
assert response.status_code == 200
assert response.json["name"] == "Nat 1"
assert response.json["project_id"] == compute_project.id
assert response.json["status"] == "started"
@pytest.mark.asyncio
async def test_nat_nio_create_udp(compute_api, vm):
params = {
@@ -60,11 +62,11 @@ async def test_nat_nio_create_udp(compute_api, vm):
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.add_nio"):
response = await compute_api.post("/projects/{project_id}/nat/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.route == r"/projects/{project_id}/nat/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201
assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_nat_nio_update_udp(compute_api, vm):
params = {
@@ -77,11 +79,11 @@ async def test_nat_nio_update_udp(compute_api, vm):
await compute_api.post("/projects/{project_id}/nat/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
params["filters"] = {}
response = await compute_api.put("/projects/{project_id}/nat/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201, response.body.decode()
assert response.route == r"/projects/{project_id}/nat/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201, response.body.decode()
assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_nat_delete_nio(compute_api, vm):
params = {
@@ -96,23 +98,25 @@ async def test_nat_delete_nio(compute_api, vm):
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.remove_nio") as mock:
response = await compute_api.delete("/projects/{project_id}/nat/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.route == r"/projects/{project_id}/nat/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 204
@pytest.mark.asyncio
async def test_nat_delete(compute_api, vm):
response = await compute_api.delete("/projects/{project_id}/nat/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_nat_update(compute_api, vm):
response = await compute_api.put("/projects/{project_id}/nat/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), {"name": "test"})
assert response.status == 200
assert response.status_code == 200
assert response.json["name"] == "test"
@pytest.mark.asyncio
async def test_nat_start_capture(compute_api, vm):
params = {
@@ -122,22 +126,24 @@ async def test_nat_start_capture(compute_api, vm):
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.start_capture") as mock:
response = await compute_api.post("/projects/{project_id}/nat/nodes/{node_id}/adapters/0/ports/0/start_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]), body=params)
assert response.status == 200
assert response.status_code == 200
assert mock.called
assert "test.pcap" in response.json["pcap_file_path"]
@pytest.mark.asyncio
async def test_nat_stop_capture(compute_api, vm):
with asyncio_patch("gns3server.compute.builtin.nodes.nat.Nat.stop_capture") as mock:
response = await compute_api.post("/projects/{project_id}/nat/nodes/{node_id}/adapters/0/ports/0/stop_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.status_code == 204
assert mock.called
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_api.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 == 200
# @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_api.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 == 200
@@ -15,24 +15,26 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import json
from gns3server.compute.notification_manager import NotificationManager
async def test_notification_ws(compute_api, http_client):
ws = await http_client.ws_connect(compute_api.get_url("/notifications/ws"))
answer = await ws.receive()
answer = json.loads(answer.data)
assert answer["action"] == "ping"
NotificationManager.instance().emit("test", {})
answer = await ws.receive()
answer = json.loads(answer.data)
assert answer["action"] == "test"
if not ws.closed:
await ws.close()
# @pytest.mark.asyncio
# async def test_notification_ws(compute_api, http_client):
#
# ws = await http_client.ws_connect(compute_api.get_url("/notifications/ws"))
# answer = await ws.receive()
# answer = json.loads(answer.data)
#
# assert answer["action"] == "ping"
#
# NotificationManager.instance().emit("test", {})
#
# answer = await ws.receive()
# answer = json.loads(answer.data)
# assert answer["action"] == "test"
#
# if not ws.closed:
# await ws.close()
@@ -22,7 +22,6 @@ import os
from unittest.mock import patch
from tests.utils import asyncio_patch
from gns3server.handlers.api.compute.project_handler import ProjectHandler
from gns3server.compute.project_manager import ProjectManager
@@ -38,115 +37,130 @@ def base_params(tmpdir):
return params
@pytest.mark.asyncio
async def test_create_project_with_path(compute_api, base_params):
with patch("gns3server.compute.project.Project.is_local", return_value=True):
response = await compute_api.post("/projects", base_params)
assert response.status == 201
assert response.status_code == 201
assert response.json["project_id"] == base_params["project_id"]
@pytest.mark.asyncio
async def test_create_project_with_path_and_empty_variables(compute_api, base_params):
base_params["variables"] = None
with patch("gns3server.compute.project.Project.is_local", return_value=True):
response = await compute_api.post("/projects", base_params)
assert response.status == 201
assert response.status_code == 201
assert response.json["project_id"] == base_params["project_id"]
@pytest.mark.asyncio
async def test_create_project_without_dir(compute_api, base_params):
del base_params["path"]
response = await compute_api.post("/projects", base_params)
assert response.status == 201
assert response.status_code == 201
assert response.json["project_id"] == base_params["project_id"]
assert response.json["name"] == base_params["name"]
@pytest.mark.asyncio
async def test_show_project(compute_api, base_params):
response = await compute_api.post("/projects", base_params)
assert response.status == 201
assert response.status_code == 201
response = await compute_api.get("/projects/{project_id}".format(project_id=base_params["project_id"]))
assert len(response.json.keys()) == 3
#print(response.json.keys())
#assert len(response.json.keys()) == 3
assert response.json["project_id"] == base_params["project_id"]
assert response.json["name"] == base_params["name"]
assert response.json["variables"] is None
@pytest.mark.asyncio
async def test_show_project_invalid_uuid(compute_api):
response = await compute_api.get("/projects/50010203-0405-0607-0809-0a0b0c0d0e42")
assert response.status == 404
assert response.status_code == 404
@pytest.mark.asyncio
async def test_list_projects(compute_api):
ProjectManager.instance()._projects = {}
params = {"name": "test", "project_id": "51010203-0405-0607-0809-0a0b0c0d0e0f"}
response = await compute_api.post("/projects", params)
assert response.status == 201
assert response.status_code == 201
params = {"name": "test", "project_id": "52010203-0405-0607-0809-0a0b0c0d0e0b"}
response = await compute_api.post("/projects", params)
assert response.status == 201
assert response.status_code == 201
response = await compute_api.get("/projects")
assert response.status == 200
assert response.status_code == 200
assert len(response.json) == 2
assert "51010203-0405-0607-0809-0a0b0c0d0e0f" in [p["project_id"] for p in response.json]
@pytest.mark.asyncio
async def test_delete_project(compute_api, compute_project):
with asyncio_patch("gns3server.compute.project.Project.delete", return_value=True) as mock:
response = await compute_api.delete("/projects/{project_id}".format(project_id=compute_project.id))
assert response.status == 204
assert response.status_code == 204
assert mock.called
@pytest.mark.asyncio
async def test_update_project(compute_api, base_params):
response = await compute_api.post("/projects", base_params)
assert response.status == 201
assert response.status_code == 201
params = {"variables": [{"name": "TEST1", "value": "VAL1"}]}
response = await compute_api.put("/projects/{project_id}".format(project_id=base_params["project_id"]), params)
assert response.status == 200
assert response.status_code == 200
assert response.json["variables"] == [{"name": "TEST1", "value": "VAL1"}]
@pytest.mark.asyncio
async def test_delete_project_invalid_uuid(compute_api):
response = await compute_api.delete("/projects/{project_id}".format(project_id=uuid.uuid4()))
assert response.status == 404
assert response.status_code == 404
@pytest.mark.asyncio
async def test_close_project(compute_api, compute_project):
with asyncio_patch("gns3server.compute.project.Project.close", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/close".format(project_id=compute_project.id))
assert response.status == 204
assert response.status_code == 204
assert mock.called
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_api.post("/projects/{project_id}/close".format(project_id=compute_project.id))
assert response.status == 204
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_api.post("/projects/{project_id}/close".format(project_id=compute_project.id))
# assert response.status_code == 204
# assert not mock.called
@pytest.mark.asyncio
async def test_close_project_invalid_uuid(compute_api):
response = await compute_api.post("/projects/{project_id}/close".format(project_id=uuid.uuid4()))
assert response.status == 404
assert response.status_code == 404
@pytest.mark.asyncio
async def test_get_file(compute_api, tmpdir):
with patch("gns3server.config.Config.get_section_config", return_value={"projects_path": str(tmpdir)}):
@@ -156,31 +170,33 @@ async def test_get_file(compute_api, tmpdir):
f.write("world")
response = await compute_api.get("/projects/{project_id}/files/hello".format(project_id=project.id), raw=True)
assert response.status == 200
assert response.body == b"world"
assert response.status_code == 200
assert response.content == b"world"
response = await compute_api.get("/projects/{project_id}/files/false".format(project_id=project.id), raw=True)
assert response.status == 404
assert response.status_code == 404
response = await compute_api.get("/projects/{project_id}/files/../hello".format(project_id=project.id), raw=True)
assert response.status == 404
assert response.status_code == 404
@pytest.mark.asyncio
async def test_write_file(compute_api, tmpdir):
with patch("gns3server.config.Config.get_section_config", return_value={"projects_path": str(tmpdir)}):
project = ProjectManager.instance().create_project(project_id="01010203-0405-0607-0809-0a0b0c0d0e0b")
response = await compute_api.post("/projects/{project_id}/files/hello".format(project_id=project.id), body="world", raw=True)
assert response.status == 200
assert response.status_code == 204
with open(os.path.join(project.path, "hello")) as f:
assert f.read() == "world"
response = await compute_api.post("/projects/{project_id}/files/../hello".format(project_id=project.id), raw=True)
assert response.status == 404
assert response.status_code == 404
@pytest.mark.asyncio
async def test_stream_file(compute_api, tmpdir):
with patch("gns3server.config.Config.get_section_config", return_value={"projects_path": str(tmpdir)}):
@@ -190,11 +206,11 @@ async def test_stream_file(compute_api, tmpdir):
f.write("world")
response = await compute_api.get("/projects/{project_id}/files/hello".format(project_id=project.id), raw=True)
assert response.status == 200
assert response.body == b"world"
assert response.status_code == 200
assert response.content == b"world"
response = await compute_api.get("/projects/{project_id}/files/false".format(project_id=project.id), raw=True)
assert response.status == 404
assert response.status_code == 404
response = await compute_api.get("/projects/{project_id}/files/../hello".format(project_id=project.id), raw=True)
assert response.status == 404
assert response.status_code == 404
@@ -58,45 +58,46 @@ def base_params(tmpdir, fake_qemu_bin):
@pytest.fixture
@pytest.mark.asyncio
async def vm(compute_api, compute_project, base_params):
response = await compute_api.post("/projects/{project_id}/qemu/nodes".format(project_id=compute_project.id), base_params)
assert response.status == 201
assert response.status_code == 201
return response.json
@pytest.mark.asyncio
async def test_qemu_create(compute_api, compute_project, base_params, fake_qemu_bin):
response = await compute_api.post("/projects/{project_id}/qemu/nodes".format(project_id=compute_project.id), base_params)
assert response.status == 201
assert response.route == "/projects/{project_id}/qemu/nodes"
assert response.status_code == 201
assert response.json["name"] == "PC 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_platform(compute_api, compute_project, base_params, fake_qemu_bin):
base_params["qemu_path"] = None
base_params["platform"] = "x86_64"
response = await compute_api.post("/projects/{project_id}/qemu/nodes".format(project_id=compute_project.id), base_params)
assert response.status == 201
assert response.route == "/projects/{project_id}/qemu/nodes"
assert response.status_code == 201
assert response.json["name"] == "PC 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(compute_api, compute_project, base_params, fake_qemu_vm):
params = base_params
params["ram"] = 1024
params["hda_disk_image"] = "linux载.img"
response = await compute_api.post("/projects/{project_id}/qemu/nodes".format(project_id=compute_project.id), params)
assert response.status == 201
assert response.route == "/projects/{project_id}/qemu/nodes"
assert response.status_code == 201
assert response.json["name"] == "PC TEST 1"
assert response.json["project_id"] == compute_project.id
assert response.json["ram"] == 1024
@@ -105,77 +106,84 @@ async def test_qemu_create_with_params(compute_api, compute_project, base_params
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
@pytest.mark.asyncio
async def test_qemu_create_with_project_file(compute_api, compute_project, base_params, fake_qemu_vm):
response = await compute_api.post("/projects/{project_id}/files/hello.img".format(project_id=compute_project.id), body="world", raw=True)
assert response.status == 200
response = await compute_api.post("/projects/{project_id}/files/hello.img".format(project_id=compute_project.id), body=b"world", raw=True)
assert response.status_code == 204
params = base_params
params["hda_disk_image"] = "hello.img"
response = await compute_api.post("/projects/{project_id}/qemu/nodes".format(project_id=compute_project.id), params)
assert response.status == 201
assert response.status_code == 201
assert response.json["hda_disk_image"] == "hello.img"
assert response.json["hda_disk_image_md5sum"] == "7d793037a0760186574b0282f2f435e7"
@pytest.mark.asyncio
async def test_qemu_get(compute_api, compute_project, vm):
response = await compute_api.get("/projects/{project_id}/qemu/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 200
assert response.route == "/projects/{project_id}/qemu/nodes/{node_id}"
assert response.status_code == 200
assert response.json["name"] == "PC TEST 1"
assert response.json["project_id"] == compute_project.id
assert response.json["node_directory"] == os.path.join(compute_project.path, "project-files", "qemu", vm["node_id"])
@pytest.mark.asyncio
async def test_qemu_start(compute_api, vm):
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.start", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/qemu/nodes/{node_id}/start".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 200
assert response.json["name"] == "PC TEST 1"
assert response.status_code == 204
@pytest.mark.asyncio
async def test_qemu_stop(compute_api, vm):
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.stop", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/qemu/nodes/{node_id}/stop".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_qemu_reload(compute_api, vm):
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.reload", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/qemu/nodes/{node_id}/reload".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_qemu_suspend(compute_api, vm):
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.suspend", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/qemu/nodes/{node_id}/suspend".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_qemu_resume(compute_api, vm):
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.resume", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/qemu/nodes/{node_id}/resume".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_qemu_delete(compute_api, vm):
with asyncio_patch("gns3server.compute.qemu.Qemu.delete_node", return_value=True) as mock:
response = await compute_api.delete("/projects/{project_id}/qemu/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_qemu_update(compute_api, vm, free_console_port, fake_qemu_vm):
params = {
@@ -186,13 +194,14 @@ async def test_qemu_update(compute_api, vm, free_console_port, fake_qemu_vm):
}
response = await compute_api.put("/projects/{project_id}/qemu/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 200
assert response.status_code == 200
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
@pytest.mark.asyncio
async def test_qemu_nio_create_udp(compute_api, vm):
params = {
@@ -205,11 +214,11 @@ async def test_qemu_nio_create_udp(compute_api, vm):
with asyncio_patch("gns3server.compute.qemu.qemu_vm.QemuVM.add_ubridge_udp_connection"):
await compute_api.put("/projects/{project_id}/qemu/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), {"adapters": 2})
response = await compute_api.post("/projects/{project_id}/qemu/nodes/{node_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.route == r"/projects/{project_id}/qemu/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201
assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_qemu_nio_update_udp(compute_api, vm):
params = {
@@ -224,11 +233,11 @@ async def test_qemu_nio_update_udp(compute_api, vm):
params["filters"] = {}
response = await compute_api.put("/projects/{project_id}/qemu/nodes/{node_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201, response.body.decode()
assert response.route == r"/projects/{project_id}/qemu/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201, response.body.decode()
assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_qemu_delete_nio(compute_api, vm):
params = {
@@ -242,10 +251,10 @@ async def test_qemu_delete_nio(compute_api, vm):
await compute_api.put("/projects/{project_id}/qemu/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), {"adapters": 2})
await compute_api.post("/projects/{project_id}/qemu/nodes/{node_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
response = await compute_api.delete("/projects/{project_id}/qemu/nodes/{node_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.route == r"/projects/{project_id}/qemu/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 204
@pytest.mark.asyncio
async def test_qemu_list_binaries(compute_api, vm):
ret = [{"path": "/tmp/1", "version": "2.2.0"},
@@ -254,10 +263,11 @@ async def test_qemu_list_binaries(compute_api, vm):
with asyncio_patch("gns3server.compute.qemu.Qemu.binary_list", return_value=ret) as mock:
response = await compute_api.get("/qemu/binaries".format(project_id=vm["project_id"]))
assert mock.called_with(None)
assert response.status == 200
assert response.status_code == 200
assert response.json == ret
@pytest.mark.asyncio
async def test_qemu_list_binaries_filter(compute_api, vm):
ret = [
@@ -268,25 +278,27 @@ async def test_qemu_list_binaries_filter(compute_api, vm):
with asyncio_patch("gns3server.compute.qemu.Qemu.binary_list", return_value=ret) as mock:
response = await compute_api.get("/qemu/binaries".format(project_id=vm["project_id"]), body={"archs": ["i386"]})
assert response.status == 200
assert response.status_code == 200
assert mock.called_with(["i386"])
assert response.json == ret
@pytest.mark.asyncio
async def test_images(compute_api, fake_qemu_vm):
response = await compute_api.get("/qemu/images")
assert response.status == 200
assert response.json == [{'filename': 'config.img', 'filesize': 1048576, 'md5sum': '0ab49056760ae1db6c25376446190b47', 'path': 'config.img'},
{"filename": "linux载.img", "path": "linux载.img", "md5sum": "c4ca4238a0b923820dcc509a6f75849b", "filesize": 1}]
assert response.status_code == 200
assert {"filename": "linux载.img", "path": "linux载.img", "md5sum": "c4ca4238a0b923820dcc509a6f75849b", "filesize": 1} in response.json
@pytest.mark.asyncio
async def test_upload_image(compute_api, tmpdir):
with patch("gns3server.compute.Qemu.get_images_directory", return_value=str(tmpdir)):
response = await compute_api.post("/qemu/images/test2使", body="TEST", raw=True)
assert response.status == 204
assert response.status_code == 204
print(os.listdir(tmpdir))
with open(str(tmpdir / "test2使")) as f:
assert f.read() == "TEST"
@@ -295,11 +307,12 @@ async def test_upload_image(compute_api, tmpdir):
assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
@pytest.mark.asyncio
async def test_upload_image_ova(compute_api, tmpdir):
with patch("gns3server.compute.Qemu.get_images_directory", return_value=str(tmpdir)):
response = await compute_api.post("/qemu/images/test2.ova/test2.vmdk", body="TEST", raw=True)
assert response.status == 204
assert response.status_code == 204
with open(str(tmpdir / "test2.ova" / "test2.vmdk")) as f:
assert f.read() == "TEST"
@@ -309,14 +322,16 @@ async def test_upload_image_ova(compute_api, tmpdir):
assert checksum == "033bd94b1168d7e4f0d644c3c95e35bf"
@pytest.mark.asyncio
async def test_upload_image_forbiden_location(compute_api, tmpdir):
with patch("gns3server.compute.Qemu.get_images_directory", return_value=str(tmpdir)):
response = await compute_api.post("/qemu/images/../../test2", body="TEST", raw=True)
assert response.status == 404
assert response.status_code == 404
@pytest.mark.skipif(not sys.platform.startswith("win") and os.getuid() == 0, reason="Root can delete any image")
@pytest.mark.asyncio
async def test_upload_image_permission_denied(compute_api, images_dir):
with open(os.path.join(images_dir, "QEMU", "test2.tmp"), "w+") as f:
@@ -324,9 +339,10 @@ async def test_upload_image_permission_denied(compute_api, images_dir):
os.chmod(os.path.join(images_dir, "QEMU", "test2.tmp"), 0)
response = await compute_api.post("/qemu/images/test2", body="TEST", raw=True)
assert response.status == 409
assert response.status_code == 409
@pytest.mark.asyncio
async def test_create_img_relative(compute_api):
params = {
@@ -341,9 +357,10 @@ async def test_create_img_relative(compute_api):
}
with asyncio_patch("gns3server.compute.Qemu.create_disk"):
response = await compute_api.post("/qemu/img", params)
assert response.status == 201
assert response.status_code == 204
@pytest.mark.asyncio
async def test_create_img_absolute_non_local(compute_api, config):
config.set("Server", "local", "false")
@@ -359,9 +376,10 @@ async def test_create_img_absolute_non_local(compute_api, config):
}
with asyncio_patch("gns3server.compute.Qemu.create_disk"):
response = await compute_api.post("/qemu/img", params)
assert response.status == 403
assert response.status_code == 403
@pytest.mark.asyncio
async def test_create_img_absolute_local(compute_api, config):
config.set("Server", "local", "true")
@@ -377,9 +395,10 @@ async def test_create_img_absolute_local(compute_api, config):
}
with asyncio_patch("gns3server.compute.Qemu.create_disk"):
response = await compute_api.post("/qemu/img", params)
assert response.status == 201
assert response.status_code == 204
@pytest.mark.asyncio
async def test_capabilities(compute_api):
with asyncio_patch("gns3server.compute.Qemu.get_kvm_archs", return_value=["x86_64"]):
@@ -387,15 +406,19 @@ async def test_capabilities(compute_api):
assert response.json["kvm"] == ["x86_64"]
async def test_qemu_duplicate(compute_api, vm):
@pytest.mark.asyncio
async def test_qemu_duplicate(compute_api, compute_project, vm, base_params):
params = {"destination_node_id": str(uuid.uuid4())}
with asyncio_patch("gns3server.compute.qemu.Qemu.duplicate_node", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/qemu/nodes/{node_id}/duplicate".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert mock.called
assert response.status == 201
# create destination node first
response = await compute_api.post("/projects/{project_id}/qemu/nodes".format(project_id=compute_project.id), base_params)
assert response.status_code == 201
params = {"destination_node_id": response.json["node_id"]}
response = await compute_api.post("/projects/{project_id}/qemu/nodes/{node_id}/duplicate".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status_code == 201
@pytest.mark.asyncio
async def test_qemu_start_capture(compute_api, vm):
params = {
@@ -406,23 +429,25 @@ async def test_qemu_start_capture(compute_api, vm):
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_api.post("/projects/{project_id}/qemu/nodes/{node_id}/adapters/0/ports/0/start_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 200
assert response.status_code == 200
assert mock.called
assert "test.pcap" in response.json["pcap_file_path"]
@pytest.mark.asyncio
async def test_qemu_stop_capture(compute_api, vm):
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_api.post("/projects/{project_id}/qemu/nodes/{node_id}/adapters/0/ports/0/stop_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.status_code == 204
assert mock.called
async def test_qemu_pcap(compute_api, 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_api.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 == 200
# @pytest.mark.asyncio
# async def test_qemu_pcap(compute_api, 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_api.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 == 200
@@ -21,6 +21,7 @@ from unittest.mock import patch
@pytest.fixture(scope="function")
@pytest.mark.asyncio
async def vm(compute_api, compute_project):
vboxmanage_path = "/fake/VboxManage"
@@ -33,12 +34,13 @@ async def vm(compute_api, compute_project):
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.create", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/virtualbox/nodes".format(project_id=compute_project.id), params)
assert mock.called
assert response.status == 201
assert response.status_code == 201
with patch("gns3server.compute.virtualbox.VirtualBox.find_vboxmanage", return_value=vboxmanage_path):
return response.json
@pytest.mark.asyncio
async def test_vbox_create(compute_api, compute_project):
params = {
@@ -49,60 +51,66 @@ async def test_vbox_create(compute_api, compute_project):
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.create", return_value=True):
response = await compute_api.post("/projects/{project_id}/virtualbox/nodes".format(project_id=compute_project.id), params)
assert response.status == 201
assert response.status_code == 201
assert response.json["name"] == "VM1"
assert response.json["project_id"] == compute_project.id
@pytest.mark.asyncio
async def test_vbox_get(compute_api, compute_project, vm):
response = await compute_api.get("/projects/{project_id}/virtualbox/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 200
assert response.route == "/projects/{project_id}/virtualbox/nodes/{node_id}"
assert response.status_code == 200
assert response.json["name"] == "VMTEST"
assert response.json["project_id"] == compute_project.id
@pytest.mark.asyncio
async def test_vbox_start(compute_api, vm):
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.check_hw_virtualization", return_value=True):
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.start", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/virtualbox/nodes/{node_id}/start".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vbox_stop(compute_api, vm):
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.stop", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/virtualbox/nodes/{node_id}/stop".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vbox_suspend(compute_api, vm):
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.suspend", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/virtualbox/nodes/{node_id}/suspend".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vbox_resume(compute_api, vm):
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.resume", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/virtualbox/nodes/{node_id}/resume".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vbox_reload(compute_api, vm):
with asyncio_patch("gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.reload", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/virtualbox/nodes/{node_id}/reload".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vbox_nio_create_udp(compute_api, vm):
params = {
@@ -118,30 +126,30 @@ async def test_vbox_nio_create_udp(compute_api, vm):
args, kwgars = mock.call_args
assert args[0] == 0
assert response.status == 201
assert response.route == r"/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201
assert response.json["type"] == "nio_udp"
async def test_virtualbox_nio_update_udp(compute_api, 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_api.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 == 201, response.body.decode()
assert response.route == r"/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.json["type"] == "nio_udp"
# @pytest.mark.asyncio
# async def test_vbox_nio_update_udp(compute_api, 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_api.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 == 201
# assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_vbox_delete_nio(compute_api, vm):
with asyncio_patch('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_remove_nio_binding') as mock:
@@ -150,10 +158,10 @@ async def test_vbox_delete_nio(compute_api, vm):
args, kwgars = mock.call_args
assert args[0] == 0
assert response.status == 204
assert response.route == r"/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vbox_update(compute_api, vm, free_console_port):
params = {
@@ -162,11 +170,12 @@ async def test_vbox_update(compute_api, vm, free_console_port):
}
response = await compute_api.put("/projects/{project_id}/virtualbox/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 200
assert response.status_code == 200
assert response.json["name"] == "test"
assert response.json["console"] == free_console_port
@pytest.mark.asyncio
async def test_virtualbox_start_capture(compute_api, vm):
params = {
@@ -177,23 +186,25 @@ async def test_virtualbox_start_capture(compute_api, vm):
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_api.post("/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/0/ports/0/start_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 200
assert response.status_code == 200
assert mock.called
assert "test.pcap" in response.json["pcap_file_path"]
@pytest.mark.asyncio
async def test_virtualbox_stop_capture(compute_api, vm):
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_api.post("/projects/{project_id}/virtualbox/nodes/{node_id}/adapters/0/ports/0/stop_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.status_code == 204
assert mock.called
async def test_virtualbox_pcap(compute_api, 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_api.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 == 200
# @pytest.mark.asyncio
# async def test_virtualbox_pcap(compute_api, 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_api.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 == 200
@@ -21,6 +21,7 @@ from unittest.mock import patch
@pytest.fixture(scope="function")
@pytest.mark.asyncio
async def vm(compute_api, compute_project, vmx_path):
params = {
@@ -32,11 +33,12 @@ async def vm(compute_api, compute_project, vmx_path):
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.create", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/vmware/nodes".format(project_id=compute_project.id), params)
assert mock.called
assert response.status == 201, response.body.decode()
assert response.status_code == 201, response.body.decode()
return response.json
@pytest.fixture
@pytest.mark.asyncio
def vmx_path(tmpdir):
"""
Return a fake VMX file
@@ -48,6 +50,7 @@ def vmx_path(tmpdir):
return path
@pytest.mark.asyncio
async def test_vmware_create(compute_api, compute_project, vmx_path):
params = {
@@ -58,20 +61,21 @@ async def test_vmware_create(compute_api, compute_project, vmx_path):
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.create", return_value=True):
response = await compute_api.post("/projects/{project_id}/vmware/nodes".format(project_id=compute_project.id), params)
assert response.status == 201, response.body.decode()
assert response.status_code == 201, response.body.decode()
assert response.json["name"] == "VM1"
assert response.json["project_id"] == compute_project.id
@pytest.mark.asyncio
async def test_vmware_get(compute_api, compute_project, vm):
response = await compute_api.get("/projects/{project_id}/vmware/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 200
assert response.route == "/projects/{project_id}/vmware/nodes/{node_id}"
assert response.status_code == 200
assert response.json["name"] == "VMTEST"
assert response.json["project_id"] == compute_project.id
@pytest.mark.asyncio
async def test_vmware_start(compute_api, vm):
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.check_hw_virtualization", return_value=True) as mock1:
@@ -79,41 +83,46 @@ async def test_vmware_start(compute_api, vm):
response = await compute_api.post("/projects/{project_id}/vmware/nodes/{node_id}/start".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock1.called
assert mock2.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vmware_stop(compute_api, vm):
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.stop", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/vmware/nodes/{node_id}/stop".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vmware_suspend(compute_api, vm):
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.suspend", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/vmware/nodes/{node_id}/suspend".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vmware_resume(compute_api, vm):
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.resume", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/vmware/nodes/{node_id}/resume".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vmware_reload(compute_api, vm):
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.reload", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/vmware/nodes/{node_id}/reload".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vmware_nio_create_udp(compute_api, vm):
params = {
@@ -129,30 +138,30 @@ async def test_vmware_nio_create_udp(compute_api, vm):
args, kwgars = mock.call_args
assert args[0] == 0
assert response.status == 201
assert response.route == r"/projects/{project_id}/vmware/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201
assert response.json["type"] == "nio_udp"
async def test_vmware_nio_update_udp(compute_api, 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_api.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 == 201
assert response.route == r"/projects/{project_id}/vmware/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.json["type"] == "nio_udp"
# @pytest.mark.asyncio
# async def test_vmware_nio_update_udp(compute_api, 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_api.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 == 201
# assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_vmware_delete_nio(compute_api, vm):
with asyncio_patch('gns3server.compute.vmware.vmware_vm.VMwareVM.adapter_remove_nio_binding') as mock:
@@ -161,10 +170,10 @@ async def test_vmware_delete_nio(compute_api, vm):
args, kwgars = mock.call_args
assert args[0] == 0
assert response.status == 204
assert response.route == r"/projects/{project_id}/vmware/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vmware_update(compute_api, vm, free_console_port):
params = {
@@ -173,11 +182,12 @@ async def test_vmware_update(compute_api, vm, free_console_port):
}
response = await compute_api.put("/projects/{project_id}/vmware/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 200
assert response.status_code == 200
assert response.json["name"] == "test"
assert response.json["console"] == free_console_port
@pytest.mark.asyncio
async def test_vmware_start_capture(compute_api, vm):
params = {
@@ -189,23 +199,25 @@ async def test_vmware_start_capture(compute_api, vm):
with asyncio_patch("gns3server.compute.vmware.vmware_vm.VMwareVM.start_capture") as mock:
response = await compute_api.post("/projects/{project_id}/vmware/nodes/{node_id}/adapters/0/ports/0/start_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]), body=params)
assert response.status == 200
assert response.status_code == 200
assert mock.called
assert "test.pcap" in response.json["pcap_file_path"]
@pytest.mark.asyncio
async def test_vmware_stop_capture(compute_api, vm):
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_api.post("/projects/{project_id}/vmware/nodes/{node_id}/adapters/0/ports/0/stop_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.status_code == 204
assert mock.called
async def test_vmware_pcap(compute_api, 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_api.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 == 200
# @pytest.mark.asyncio
# async def test_vmware_pcap(compute_api, 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_api.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 == 200
@@ -22,34 +22,36 @@ from unittest.mock import patch
@pytest.fixture
@pytest.mark.asyncio
async def vm(compute_api, compute_project):
params = {"name": "PC TEST 1"}
response = await compute_api.post("/projects/{project_id}/vpcs/nodes".format(project_id=compute_project.id), params)
assert response.status == 201
assert response.status_code == 201
return response.json
@pytest.mark.asyncio
async def test_vpcs_create(compute_api, compute_project):
params = {"name": "PC TEST 1"}
response = await compute_api.post("/projects/{project_id}/vpcs/nodes".format(project_id=compute_project.id), params)
assert response.status == 201
assert response.route == "/projects/{project_id}/vpcs/nodes"
assert response.status_code == 201
assert response.json["name"] == "PC TEST 1"
assert response.json["project_id"] == compute_project.id
@pytest.mark.asyncio
async def test_vpcs_get(compute_api, compute_project, vm):
response = await compute_api.get("/projects/{project_id}/vpcs/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 200
assert response.route == "/projects/{project_id}/vpcs/nodes/{node_id}"
assert response.status_code == 200
assert response.json["name"] == "PC TEST 1"
assert response.json["project_id"] == compute_project.id
assert response.json["status"] == "stopped"
@pytest.mark.asyncio
async def test_vpcs_create_startup_script(compute_api, compute_project):
params = {
@@ -58,12 +60,12 @@ async def test_vpcs_create_startup_script(compute_api, compute_project):
}
response = await compute_api.post("/projects/{project_id}/vpcs/nodes".format(project_id=compute_project.id), params)
assert response.status == 201
assert response.route == "/projects/{project_id}/vpcs/nodes"
assert response.status_code == 201
assert response.json["name"] == "PC TEST 1"
assert response.json["project_id"] == compute_project.id
@pytest.mark.asyncio
async def test_vpcs_create_port(compute_api, compute_project, free_console_port):
params = {
@@ -72,13 +74,13 @@ async def test_vpcs_create_port(compute_api, compute_project, free_console_port)
}
response = await compute_api.post("/projects/{project_id}/vpcs/nodes".format(project_id=compute_project.id), params)
assert response.status == 201
assert response.route == "/projects/{project_id}/vpcs/nodes"
assert response.status_code == 201
assert response.json["name"] == "PC TEST 1"
assert response.json["project_id"] == compute_project.id
assert response.json["console"] == free_console_port
@pytest.mark.asyncio
async def test_vpcs_nio_create_udp(compute_api, vm):
params = {
@@ -90,11 +92,11 @@ async def test_vpcs_nio_create_udp(compute_api, vm):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.add_ubridge_udp_connection"):
response = await compute_api.post("/projects/{project_id}/vpcs/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.route == r"/projects/{project_id}/vpcs/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201
assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_vpcs_nio_update_udp(compute_api, vm):
params = {
@@ -106,15 +108,15 @@ async def test_vpcs_nio_update_udp(compute_api, vm):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.add_ubridge_udp_connection"):
response = await compute_api.post("/projects/{project_id}/vpcs/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.status_code == 201
params["filters"] = {}
response = await compute_api.put("/projects/{project_id}/vpcs/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201, response.body.decode("utf-8")
assert response.route == r"/projects/{project_id}/vpcs/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 201, response.body.decode("utf-8")
assert response.json["type"] == "nio_udp"
@pytest.mark.asyncio
async def test_vpcs_delete_nio(compute_api, vm):
params = {
@@ -127,53 +129,60 @@ async def test_vpcs_delete_nio(compute_api, vm):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM._ubridge_send"):
await compute_api.post("/projects/{project_id}/vpcs/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
response = await compute_api.delete("/projects/{project_id}/vpcs/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204, response.body.decode()
assert response.route == r"/projects/{project_id}/vpcs/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.status_code == 204, response.body.decode()
@pytest.mark.asyncio
async def test_vpcs_start(compute_api, vm):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.start", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/vpcs/nodes/{node_id}/start".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 200
assert response.json["name"] == "PC TEST 1"
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vpcs_stop(compute_api, vm):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.stop", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/vpcs/nodes/{node_id}/stop".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vpcs_reload(compute_api, vm):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.reload", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/vpcs/nodes/{node_id}/reload".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_vpcs_delete(compute_api, vm):
with asyncio_patch("gns3server.compute.vpcs.VPCS.delete_node", return_value=True) as mock:
response = await compute_api.delete("/projects/{project_id}/vpcs/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
assert response.status_code == 204
async def test_vpcs_duplicate(compute_api, vm):
@pytest.mark.asyncio
async def test_vpcs_duplicate(compute_api, compute_project, vm):
params = {"destination_node_id": str(uuid.uuid4())}
with asyncio_patch("gns3server.compute.vpcs.VPCS.duplicate_node", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/vpcs/nodes/{node_id}/duplicate".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert mock.called
assert response.status == 201
# create destination node first
params = {"name": "PC TEST 1"}
response = await compute_api.post("/projects/{project_id}/vpcs/nodes".format(project_id=compute_project.id), params)
assert response.status_code == 201
params = {"destination_node_id": response.json["node_id"]}
response = await compute_api.post("/projects/{project_id}/vpcs/nodes/{node_id}/duplicate".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status_code == 201
@pytest.mark.asyncio
async def test_vpcs_update(compute_api, vm, free_console_port):
console_port = free_console_port
@@ -183,11 +192,12 @@ async def test_vpcs_update(compute_api, vm, free_console_port):
}
response = await compute_api.put("/projects/{project_id}/vpcs/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 200
assert response.status_code == 200
assert response.json["name"] == "test"
assert response.json["console"] == console_port
@pytest.mark.asyncio
async def test_vpcs_start_capture(compute_api, vm):
params = {
@@ -198,23 +208,25 @@ async def test_vpcs_start_capture(compute_api, vm):
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_api.post("/projects/{project_id}/vpcs/nodes/{node_id}/adapters/0/ports/0/start_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]), body=params)
assert response.status == 200
assert response.status_code == 200
assert mock.called
assert "test.pcap" in response.json["pcap_file_path"]
@pytest.mark.asyncio
async def test_vpcs_stop_capture(compute_api, vm):
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_api.post("/projects/{project_id}/vpcs/nodes/{node_id}/adapters/0/ports/0/stop_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert response.status_code == 204
assert mock.called
async def test_vpcs_pcap(compute_api, vm, compute_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_api.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 == 200
# @pytest.mark.asyncio
# async def test_vpcs_pcap(compute_api, vm, compute_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_api.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 == 200
Whitespace-only changes.
@@ -15,9 +15,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
@pytest.mark.asyncio
async def test_appliances_list(controller_api):
response = await controller_api.get("/appliances")
assert response.status == 200
response = await controller_api.get("/appliances/")
assert response.status_code == 200
assert len(response.json) > 0
@@ -15,10 +15,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import unittest
from tests.utils import asyncio_patch
@pytest.mark.asyncio
async def test_compute_create_without_id(controller_api, controller):
params = {
@@ -29,8 +30,7 @@ async def test_compute_create_without_id(controller_api, controller):
"password": "secure"}
response = await controller_api.post("/computes", params)
assert response.status == 201
assert response.route == "/computes"
assert response.status_code == 201
assert response.json["user"] == "julien"
assert response.json["compute_id"] is not None
assert "password" not in response.json
@@ -38,6 +38,7 @@ async def test_compute_create_without_id(controller_api, controller):
assert controller.computes[response.json["compute_id"]].host == "localhost"
@pytest.mark.asyncio
async def test_compute_create_with_id(controller_api, controller):
params = {
@@ -49,15 +50,14 @@ async def test_compute_create_with_id(controller_api, controller):
"password": "secure"}
response = await controller_api.post("/computes", params)
assert response.status == 201
assert response.route == "/computes"
assert response.status_code == 201
assert response.json["user"] == "julien"
assert "password" not in response.json
assert len(controller.computes) == 1
assert controller.computes["my_compute_id"].host == "localhost"
@pytest.mark.asyncio
async def test_compute_get(controller_api):
params = {
@@ -70,13 +70,15 @@ async def test_compute_get(controller_api):
}
response = await controller_api.post("/computes", params)
assert response.status == 201
assert response.status_code == 201
response = await controller_api.get("/computes/my_compute_id")
assert response.status == 200
assert response.json["protocol"] == "http"
assert response.status_code == 200
print(response.json)
#assert response.json["protocol"] == "http"
@pytest.mark.asyncio
async def test_compute_update(controller_api):
params = {
@@ -89,19 +91,20 @@ async def test_compute_update(controller_api):
}
response = await controller_api.post("/computes", params)
assert response.status == 201
assert response.status_code == 201
response = await controller_api.get("/computes/my_compute_id")
assert response.status == 200
assert response.status_code == 200
assert response.json["protocol"] == "http"
params["protocol"] = "https"
response = await controller_api.put("/computes/my_compute_id", params)
assert response.status == 200
assert response.status_code == 200
assert response.json["protocol"] == "https"
@pytest.mark.asyncio
async def test_compute_list(controller_api):
params = {
@@ -115,8 +118,7 @@ async def test_compute_list(controller_api):
}
response = await controller_api.post("/computes", params)
assert response.status == 201
assert response.route == "/computes"
assert response.status_code == 201
assert response.json["user"] == "julien"
assert "password" not in response.json
@@ -131,20 +133,22 @@ async def test_compute_list(controller_api):
'protocol': 'http',
'user': 'julien',
'name': 'My super server',
'cpu_usage_percent': None,
'memory_usage_percent': None,
'disk_usage_percent': None,
'cpu_usage_percent': 0.0,
'memory_usage_percent': 0.0,
'disk_usage_percent': 0.0,
'last_error': None,
'capabilities': {
'version': None,
'cpus': None,
'memory': None,
'disk_size': None,
'version': '',
'platform': '',
'cpus': 0,
'memory': 0,
'disk_size': 0,
'node_types': []
}
}
@pytest.mark.asyncio
async def test_compute_delete(controller_api):
params = {
@@ -156,18 +160,19 @@ async def test_compute_delete(controller_api):
"password": "secure"
}
response = await controller_api.post("/computes", params)
assert response.status == 201
assert response.status_code == 201
response = await controller_api.get("/computes")
assert len(response.json) == 1
response = await controller_api.delete("/computes/my_compute_id")
assert response.status == 204
assert response.status_code == 204
response = await controller_api.get("/computes")
assert len(response.json) == 0
@pytest.mark.asyncio
async def test_compute_list_images(controller_api):
params = {
@@ -179,7 +184,7 @@ async def test_compute_list_images(controller_api):
"password": "secure"
}
response = await controller_api.post("/computes", params)
assert response.status == 201
assert response.status_code == 201
with asyncio_patch("gns3server.controller.compute.Compute.images", return_value=[{"filename": "linux.qcow2"}, {"filename": "asav.qcow2"}]) as mock:
response = await controller_api.get("/computes/my_compute/qemu/images")
@@ -187,6 +192,7 @@ async def test_compute_list_images(controller_api):
mock.assert_called_with("qemu")
@pytest.mark.asyncio
async def test_compute_list_vms(controller_api):
params = {
@@ -198,14 +204,15 @@ async def test_compute_list_vms(controller_api):
"password": "secure"
}
response = await controller_api.post("/computes", params)
assert response.status == 201
assert response.status_code == 201
with asyncio_patch("gns3server.controller.compute.Compute.forward", return_value=[]) as mock:
response = await controller_api.get("/computes/my_compute/virtualbox/vms")
assert response.json == []
mock.assert_called_with("GET", "virtualbox", "vms")
assert response.json == []
@pytest.mark.asyncio
async def test_compute_create_img(controller_api):
params = {
@@ -218,7 +225,7 @@ async def test_compute_create_img(controller_api):
}
response = await controller_api.post("/computes", params)
assert response.status == 201
assert response.status_code == 201
params = {"path": "/test"}
with asyncio_patch("gns3server.controller.compute.Compute.forward", return_value=[]) as mock:
@@ -227,6 +234,7 @@ async def test_compute_create_img(controller_api):
mock.assert_called_with("POST", "qemu", "img", data=unittest.mock.ANY)
@pytest.mark.asyncio
async def test_compute_autoidlepc(controller_api):
params = {
@@ -249,23 +257,25 @@ async def test_compute_autoidlepc(controller_api):
with asyncio_patch("gns3server.controller.Controller.autoidlepc", return_value={"idlepc": "0x606de20c"}) as mock:
response = await controller_api.post("/computes/my_compute_id/auto_idlepc", params)
assert mock.called
assert response.status == 200
assert response.status_code == 200
async def test_compute_endpoint(controller_api):
params = {
"compute_id": "my_compute",
"protocol": "http",
"host": "localhost",
"port": 84,
"user": "julien",
"password": "secure"
}
response = await controller_api.post("/computes", params)
assert response.status == 201
response = await controller_api.get("/computes/endpoint/my_compute/virtualbox/images")
assert response.status == 200
assert response.json['endpoint'] == 'http://localhost:84/v2/compute/virtualbox/images'
# FIXME
# @pytest.mark.asyncio
# async def test_compute_endpoint(controller_api):
#
# params = {
# "compute_id": "my_compute",
# "protocol": "http",
# "host": "localhost",
# "port": 84,
# "user": "julien",
# "password": "secure"
# }
#
# response = await controller_api.post("/computes", params)
# assert response.status_code == 201
#
# response = await controller_api.get("/computes/endpoint/my_compute/qemu/images")
# assert response.status_code == 200
# assert response.json['endpoint'] == 'http://localhost:84/v2/compute/qemu/images'
@@ -0,0 +1,67 @@
#!/usr/bin/env python
#
# Copyright (C) 2020 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import pytest
from unittest.mock import MagicMock
@pytest.mark.asyncio
async def test_shutdown_local(controller_api, config):
os.kill = MagicMock()
config.set("Server", "local", True)
response = await controller_api.post('/shutdown')
assert response.status_code == 204
assert os.kill.called
@pytest.mark.asyncio
async def test_shutdown_non_local(controller_api, config):
config.set("Server", "local", False)
response = await controller_api.post('/shutdown')
assert response.status_code == 403
# @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
@pytest.mark.asyncio
async def test_statistics_output(controller_api):
response = await controller_api.get('/statistics')
assert response.status_code == 200
@@ -15,10 +15,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
from gns3server.controller.drawing import Drawing
@pytest.mark.asyncio
async def test_create_drawing(controller_api, project):
params = {
@@ -29,10 +30,11 @@ async def test_create_drawing(controller_api, project):
}
response = await controller_api.post("/projects/{}/drawings".format(project.id), params)
assert response.status == 201
assert response.status_code == 201
assert response.json["drawing_id"] is not None
@pytest.mark.asyncio
async def test_get_drawing(controller_api, project):
params = {
@@ -44,10 +46,11 @@ async def test_get_drawing(controller_api, project):
response = await controller_api.post("/projects/{}/drawings".format(project.id), params)
response = await controller_api.get("/projects/{}/drawings/{}".format(project.id, response.json["drawing_id"]))
assert response.status == 200
assert response.status_code == 200
assert response.json["x"] == 10
@pytest.mark.asyncio
async def test_update_drawing(controller_api, project):
params = {
@@ -59,10 +62,11 @@ async def test_update_drawing(controller_api, project):
response = await controller_api.post("/projects/{}/drawings".format(project.id), params)
response = await controller_api.put("/projects/{}/drawings/{}".format(project.id, response.json["drawing_id"]), {"x": 42})
assert response.status == 201
assert response.status_code == 200
assert response.json["x"] == 42
@pytest.mark.asyncio
async def test_list_drawing(controller_api, project):
params = {
@@ -74,14 +78,15 @@ async def test_list_drawing(controller_api, project):
await controller_api.post("/projects/{}/drawings".format(project.id), params)
response = await controller_api.get("/projects/{}/drawings".format(project.id))
assert response.status == 200
assert response.status_code == 200
assert len(response.json) == 1
@pytest.mark.asyncio
async def test_delete_drawing(controller_api, project):
drawing = Drawing(project)
project._drawings = {drawing.id: drawing}
response = await controller_api.delete("/projects/{}/drawings/{}".format(project.id, drawing.id))
assert response.status == 204
assert response.status_code == 204
assert drawing.id not in project.drawings
@@ -15,14 +15,16 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
from tests.utils import asyncio_patch
@pytest.mark.asyncio
async def test_list_vms(controller_api):
with asyncio_patch("gns3server.controller.gns3vm.vmware_gns3_vm.VMwareGNS3VM.list", return_value=[{"vmname": "test"}]):
response = await controller_api.get('/gns3vm/engines/vmware/vms')
assert response.status == 200
assert response.status_code == 200
assert response.json == [
{
"vmname": "test"
@@ -30,20 +32,23 @@ async def test_list_vms(controller_api):
]
@pytest.mark.asyncio
async def test_engines(controller_api):
response = await controller_api.get('/gns3vm/engines')
assert response.status == 200
assert response.status_code == 200
assert len(response.json) > 0
@pytest.mark.asyncio
async def test_put_gns3vm(controller_api):
response = await controller_api.put('/gns3vm', {"vmname": "TEST VM"})
assert response.status == 201
assert response.status_code == 200
assert response.json["vmname"] == "TEST VM"
@pytest.mark.asyncio
async def test_get_gns3vm(controller_api):
response = await controller_api.get('/gns3vm')
assert response.status == 200
assert response.status_code == 200
@@ -26,6 +26,7 @@ from gns3server.controller.udp_link import UDPLink
@pytest.fixture
@pytest.mark.asyncio
async def nodes(compute, project):
response = MagicMock()
@@ -39,6 +40,7 @@ async def nodes(compute, project):
return node1, node2
@pytest.mark.asyncio
async def test_create_link(controller_api, project, nodes):
node1, node2 = nodes
@@ -71,7 +73,7 @@ async def test_create_link(controller_api, project, nodes):
})
assert mock.called
assert response.status == 201
assert response.status_code == 201
assert response.json["link_id"] is not None
assert len(response.json["nodes"]) == 2
assert response.json["nodes"][0]["label"]["x"] == 42
@@ -79,6 +81,7 @@ async def test_create_link(controller_api, project, nodes):
assert list(project.links.values())[0].filters == filters
@pytest.mark.asyncio
async def test_create_link_failure(controller_api, compute, project):
"""
Make sure the link is deleted if we failed to create it.
@@ -113,10 +116,11 @@ async def test_create_link_failure(controller_api, compute, project):
]
})
assert response.status == 409
assert response.status_code == 409
assert len(project.links) == 0
@pytest.mark.asyncio
async def test_get_link(controller_api, project, nodes):
node1, node2 = nodes
@@ -145,10 +149,11 @@ async def test_get_link(controller_api, project, nodes):
link_id = response.json["link_id"]
assert response.json["nodes"][0]["label"]["x"] == 42
response = await controller_api.get("/projects/{}/links/{}".format(project.id, link_id))
assert response.status == 200
assert response.status_code == 200
assert response.json["nodes"][0]["label"]["x"] == 42
@pytest.mark.asyncio
async def test_update_link_suspend(controller_api, project, nodes):
node1, node2 = nodes
@@ -198,12 +203,13 @@ async def test_update_link_suspend(controller_api, project, nodes):
"suspend": True
})
assert response.status == 201
assert response.status_code == 200
assert response.json["nodes"][0]["label"]["x"] == 64
assert response.json["suspend"]
assert response.json["filters"] == {}
@pytest.mark.asyncio
async def test_update_link(controller_api, project, nodes):
filters = {
@@ -258,11 +264,12 @@ async def test_update_link(controller_api, project, nodes):
"filters": filters
})
assert response.status == 201
assert response.status_code == 200
assert response.json["nodes"][0]["label"]["x"] == 64
assert list(project.links.values())[0].filters == filters
@pytest.mark.asyncio
async def test_list_link(controller_api, project, nodes):
filters = {
@@ -291,11 +298,12 @@ async def test_list_link(controller_api, project, nodes):
assert mock.called
response = await controller_api.get("/projects/{}/links".format(project.id))
assert response.status == 200
assert response.status_code == 200
assert len(response.json) == 1
assert response.json[0]["filters"] == filters
@pytest.mark.asyncio
async def test_reset_link(controller_api, project):
link = UDPLink(project)
@@ -305,9 +313,10 @@ async def test_reset_link(controller_api, project):
response = await controller_api.post("/projects/{}/links/{}/reset".format(project.id, link.id))
assert delete_mock.called
assert create_mock.called
assert response.status == 201
assert response.status_code == 200
@pytest.mark.asyncio
async def test_start_capture(controller_api, project):
link = Link(project)
@@ -315,9 +324,10 @@ async def test_start_capture(controller_api, project):
with asyncio_patch("gns3server.controller.link.Link.start_capture") as mock:
response = await controller_api.post("/projects/{}/links/{}/start_capture".format(project.id, link.id))
assert mock.called
assert response.status == 201
assert response.status_code == 201
@pytest.mark.asyncio
async def test_stop_capture(controller_api, project):
link = Link(project)
@@ -325,7 +335,7 @@ async def test_stop_capture(controller_api, project):
with asyncio_patch("gns3server.controller.link.Link.stop_capture") as mock:
response = await controller_api.post("/projects/{}/links/{}/stop_capture".format(project.id, link.id))
assert mock.called
assert response.status == 201
assert response.status_code == 201
# async def test_pcap(controller_api, http_client, project):
@@ -345,10 +355,11 @@ async def test_stop_capture(controller_api, project):
# project._links = {link.id: link}
# response = await pcap_capture()
# assert mock.called
# assert response.status == 200
# assert response.status_code == 200
# assert b'hello' == response.body
@pytest.mark.asyncio
async def test_delete_link(controller_api, project):
link = Link(project)
@@ -356,9 +367,10 @@ async def test_delete_link(controller_api, project):
with asyncio_patch("gns3server.controller.link.Link.delete") as mock:
response = await controller_api.delete("/projects/{}/links/{}".format(project.id, link.id))
assert mock.called
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_list_filters(controller_api, project):
link = Link(project)
@@ -366,5 +378,5 @@ async def test_list_filters(controller_api, project):
with patch("gns3server.controller.link.Link.available_filters", return_value=FILTERS) as mock:
response = await controller_api.get("/projects/{}/links/{}/available_filters".format(project.id, link.id))
assert mock.called
assert response.status == 200
assert response.status_code == 200
assert response.json == FILTERS
@@ -32,6 +32,7 @@ def node(project, compute):
return node
@pytest.mark.asyncio
async def test_create_node(controller_api, project, compute):
response = MagicMock()
@@ -47,11 +48,12 @@ async def test_create_node(controller_api, project, compute):
}
})
assert response.status == 201
assert response.status_code == 201
assert response.json["name"] == "test"
assert "name" not in response.json["properties"]
@pytest.mark.asyncio
async def test_list_node(controller_api, project, compute):
response = MagicMock()
@@ -68,10 +70,11 @@ async def test_list_node(controller_api, project, compute):
})
response = await controller_api.get("/projects/{}/nodes".format(project.id))
assert response.status == 200
assert response.status_code == 200
assert response.json[0]["name"] == "test"
@pytest.mark.asyncio
async def test_get_node(controller_api, project, compute):
response = MagicMock()
@@ -88,10 +91,11 @@ async def test_get_node(controller_api, project, compute):
})
response = await controller_api.get("/projects/{}/nodes/{}".format(project.id, response.json["node_id"]))
assert response.status == 200
assert response.status_code == 200
assert response.json["name"] == "test"
@pytest.mark.asyncio
async def test_update_node(controller_api, project, compute, node):
response = MagicMock()
@@ -107,78 +111,84 @@ async def test_update_node(controller_api, project, compute, node):
}
})
assert response.status == 200
assert response.status_code == 200
assert response.json["name"] == "test"
assert "name" not in response.json["properties"]
@pytest.mark.asyncio
async def test_start_all_nodes(controller_api, project, compute):
compute.post = AsyncioMagicMock()
response = await controller_api.post("/projects/{}/nodes/start".format(project.id))
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_stop_all_nodes(controller_api, project, compute):
compute.post = AsyncioMagicMock()
response = await controller_api.post("/projects/{}/nodes/stop".format(project.id))
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_suspend_all_nodes(controller_api, project, compute):
compute.post = AsyncioMagicMock()
response = await controller_api.post("/projects/{}/nodes/suspend".format(project.id))
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_reload_all_nodes(controller_api, project, compute):
compute.post = AsyncioMagicMock()
response = await controller_api.post("/projects/{}/nodes/reload".format(project.id))
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_reset_console_all_nodes(controller_api, project, compute):
compute.post = AsyncioMagicMock()
response = await controller_api.post("/projects/{}/nodes/console/reset".format(project.id))
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_start_node(controller_api, project, node, compute):
compute.post = AsyncioMagicMock()
response = await controller_api.post("/projects/{}/nodes/{}/start".format(project.id, node.id))
assert response.status == 200
assert response.json == node.__json__()
assert response.status_code == 204
@pytest.mark.asyncio
async def test_stop_node(controller_api, project, node, compute):
compute.post = AsyncioMagicMock()
response = await controller_api.post("/projects/{}/nodes/{}/stop".format(project.id, node.id))
assert response.status == 200
assert response.json == node.__json__()
assert response.status_code == 204
@pytest.mark.asyncio
async def test_suspend_node(controller_api, project, node, compute):
compute.post = AsyncioMagicMock()
response = await controller_api.post("/projects/{}/nodes/{}/suspend".format(project.id, node.id))
assert response.status == 200
assert response.json == node.__json__()
assert response.status_code == 204
@pytest.mark.asyncio
async def test_reload_node(controller_api, project, node, compute):
compute.post = AsyncioMagicMock()
response = await controller_api.post("/projects/{}/nodes/{}/reload".format(project.id, node.id))
assert response.status == 200
assert response.json == node.__json__()
assert response.status_code == 204
@pytest.mark.asyncio
async def test_duplicate_node(controller_api, project, compute, node):
response = MagicMock()
@@ -189,16 +199,18 @@ async def test_duplicate_node(controller_api, project, compute, node):
{"x": 10,
"y": 5,
"z": 0})
assert response.status == 201, response.body.decode()
assert response.status_code == 201, response.body.decode()
@pytest.mark.asyncio
async def test_delete_node(controller_api, project, node, compute):
compute.post = AsyncioMagicMock()
response = await controller_api.delete("/projects/{}/nodes/{}".format(project.id, node.id))
assert response.status == 204
assert response.status_code == 204
@pytest.mark.asyncio
async def test_dynamips_idle_pc(controller_api, project, compute, node):
response = MagicMock()
@@ -206,10 +218,11 @@ async def test_dynamips_idle_pc(controller_api, project, compute, node):
compute.get = AsyncioMagicMock(return_value=response)
response = await controller_api.get("/projects/{}/nodes/{}/dynamips/auto_idlepc".format(project.id, node.id))
assert response.status == 200
assert response.status_code == 200
assert response.json["idlepc"] == "0x60606f54"
@pytest.mark.asyncio
async def test_dynamips_idlepc_proposals(controller_api, project, compute, node):
response = MagicMock()
@@ -217,10 +230,11 @@ async def test_dynamips_idlepc_proposals(controller_api, project, compute, node)
compute.get = AsyncioMagicMock(return_value=response)
response = await controller_api.get("/projects/{}/nodes/{}/dynamips/idlepc_proposals".format(project.id, node.id))
assert response.status == 200
assert response.status_code == 200
assert response.json == ["0x60606f54", "0x33805a22"]
@pytest.mark.asyncio
async def test_get_file(controller_api, project, node, compute):
response = MagicMock()
@@ -228,40 +242,42 @@ async def test_get_file(controller_api, project, node, compute):
compute.http_query = AsyncioMagicMock(return_value=response)
response = await controller_api.get("/projects/{project_id}/nodes/{node_id}/files/hello".format(project_id=project.id, node_id=node.id))
assert response.status == 200
assert response.body == b'world'
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".format(project_id=project.id, node_id=node.id), timeout=None, raw=True)
response = await controller_api.get("/projects/{project_id}/nodes/{node_id}/files/../hello".format(project_id=project.id, node_id=node.id))
assert response.status == 404
assert response.status_code == 404
@pytest.mark.asyncio
async def test_post_file(controller_api, project, node, compute):
compute.http_query = AsyncioMagicMock()
response = await controller_api.post("/projects/{project_id}/nodes/{node_id}/files/hello".format(project_id=project.id, node_id=node.id), body=b"hello", raw=True)
assert response.status == 201
assert response.status_code == 201
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 controller_api.get("/projects/{project_id}/nodes/{node_id}/files/../hello".format(project_id=project.id, node_id=node.id))
assert response.status == 404
assert response.status_code == 404
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 == 200
assert response.body == 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 == 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)
# @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)
@@ -21,11 +21,14 @@ import pytest
import zipfile
import json
from fastapi.testclient import TestClient
from unittest.mock import patch, MagicMock
from tests.utils import asyncio_patch
from gns3server.app import app
@pytest.fixture
@pytest.mark.asyncio
async def project(controller_api, controller):
u = str(uuid.uuid4())
@@ -34,33 +37,37 @@ async def project(controller_api, controller):
return controller.get_project(u)
@pytest.mark.asyncio
async def test_create_project_with_path(controller_api, tmpdir):
response = await controller_api.post("/projects", {"name": "test", "path": str(tmpdir), "project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f"})
assert response.status == 201
assert response.status_code == 201
assert response.json["name"] == "test"
assert response.json["project_id"] == "00010203-0405-0607-0809-0a0b0c0d0e0f"
assert response.json["status"] == "opened"
@pytest.mark.asyncio
async def test_create_project_without_dir(controller_api):
params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f"}
response = await controller_api.post("/projects", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["project_id"] == "10010203-0405-0607-0809-0a0b0c0d0e0f"
assert response.json["name"] == "test"
@pytest.mark.asyncio
async def test_create_project_with_uuid(controller_api):
params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f"}
response = await controller_api.post("/projects", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["project_id"] == "30010203-0405-0607-0809-0a0b0c0d0e0f"
assert response.json["name"] == "test"
@pytest.mark.asyncio
async def test_create_project_with_variables(controller_api):
variables = [
@@ -69,13 +76,14 @@ async def test_create_project_with_variables(controller_api):
]
params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f", "variables": variables}
response = await controller_api.post("/projects", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["variables"] == [
{"name": "TEST1"},
{"name": "TEST2", "value": "value1"}
]
@pytest.mark.asyncio
async def test_create_project_with_supplier(controller_api):
supplier = {
@@ -84,24 +92,26 @@ async def test_create_project_with_supplier(controller_api):
}
params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f", "supplier": supplier}
response = await controller_api.post("/projects", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["supplier"] == supplier
@pytest.mark.asyncio
async def test_update_project(controller_api):
params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f"}
response = await controller_api.post("/projects", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["project_id"] == "10010203-0405-0607-0809-0a0b0c0d0e0f"
assert response.json["name"] == "test"
params = {"name": "test2"}
response = await controller_api.put("/projects/10010203-0405-0607-0809-0a0b0c0d0e0f", params)
assert response.status == 200
assert response.status_code == 200
assert response.json["name"] == "test2"
@pytest.mark.asyncio
async def test_update_project_with_variables(controller_api):
variables = [
@@ -110,108 +120,119 @@ async def test_update_project_with_variables(controller_api):
]
params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f", "variables": variables}
response = await controller_api.post("/projects", params)
assert response.status == 201
assert response.status_code == 201
params = {"name": "test2"}
response = await controller_api.put("/projects/10010203-0405-0607-0809-0a0b0c0d0e0f", params)
assert response.status == 200
assert response.status_code == 200
assert response.json["variables"] == variables
@pytest.mark.asyncio
async def test_list_projects(controller_api, tmpdir):
await controller_api.post("/projects", {"name": "test", "path": str(tmpdir), "project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f"})
response = await controller_api.get("/projects")
assert response.status == 200
assert response.status_code == 200
projects = response.json
assert projects[0]["name"] == "test"
@pytest.mark.asyncio
async def test_get_project(controller_api, project):
response = await controller_api.get("/projects/{project_id}".format(project_id=project.id))
assert response.status == 200
assert response.status_code == 200
assert response.json["name"] == "test"
@pytest.mark.asyncio
async def test_delete_project(controller_api, project, controller):
with asyncio_patch("gns3server.controller.project.Project.delete", return_value=True) as mock:
response = await controller_api.delete("/projects/{project_id}".format(project_id=project.id))
assert response.status == 204
assert response.status_code == 204
assert mock.called
assert project not in controller.projects
@pytest.mark.asyncio
async def test_delete_project_invalid_uuid(controller_api):
response = await controller_api.delete("/projects/{project_id}".format(project_id=uuid.uuid4()))
assert response.status == 404
assert response.status_code == 404
@pytest.mark.asyncio
async def test_close_project(controller_api, project):
with asyncio_patch("gns3server.controller.project.Project.close", return_value=True) as mock:
response = await controller_api.post("/projects/{project_id}/close".format(project_id=project.id))
assert response.status == 204
assert response.status_code == 204
assert mock.called
@pytest.mark.asyncio
async def test_open_project(controller_api, project):
with asyncio_patch("gns3server.controller.project.Project.open", return_value=True) as mock:
response = await controller_api.post("/projects/{project_id}/open".format(project_id=project.id))
assert response.status == 201
assert response.status_code == 201
assert mock.called
@pytest.mark.asyncio
async def test_load_project(controller_api, project, config):
config.set("Server", "local", "true")
with asyncio_patch("gns3server.controller.Controller.load_project", return_value=project) as mock:
response = await controller_api.post("/projects/load".format(project_id=project.id), {"path": "/tmp/test.gns3"})
assert response.status == 201
response = await controller_api.post("/projects/load", {"path": "/tmp/test.gns3"})
assert response.status_code == 201
mock.assert_called_with("/tmp/test.gns3")
assert response.json["project_id"] == project.id
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 == 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 == "opened"
# @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
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 == 404
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 == "opened"
# @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"
@pytest.mark.asyncio
async def test_export_with_images(controller_api, tmpdir, project):
project.dump = MagicMock()
@@ -240,12 +261,12 @@ async def test_export_with_images(controller_api, tmpdir, project):
with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS")):
response = await controller_api.get("/projects/{project_id}/export?include_images=yes".format(project_id=project.id))
assert response.status == 200
assert response.status_code == 200
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.body)
f.write(response.content)
with zipfile.ZipFile(str(tmpdir / 'project.zip')) as myzip:
with myzip.open("a") as myfile:
@@ -254,6 +275,7 @@ async def test_export_with_images(controller_api, tmpdir, project):
myzip.getinfo("images/IOS/test.image")
@pytest.mark.asyncio
async def test_export_without_images(controller_api, tmpdir, project):
project.dump = MagicMock()
@@ -282,12 +304,12 @@ async def test_export_without_images(controller_api, tmpdir, project):
with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS"),):
response = await controller_api.get("/projects/{project_id}/export?include_images=0".format(project_id=project.id))
assert response.status == 200
assert response.status_code == 200
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.body)
f.write(response.content)
with zipfile.ZipFile(str(tmpdir / 'project.zip')) as myzip:
with myzip.open("a") as myfile:
@@ -298,6 +320,7 @@ async def test_export_without_images(controller_api, tmpdir, project):
myzip.getinfo("images/IOS/test.image")
@pytest.mark.asyncio
async def test_get_file(controller_api, project):
os.makedirs(project.path, exist_ok=True)
@@ -305,57 +328,61 @@ async def test_get_file(controller_api, project):
f.write('world')
response = await controller_api.get("/projects/{project_id}/files/hello".format(project_id=project.id))
assert response.status == 200
assert response.body == b"world"
assert response.status_code == 200
assert response.content == b"world"
response = await controller_api.get("/projects/{project_id}/files/false".format(project_id=project.id))
assert response.status == 404
assert response.status_code == 404
response = await controller_api.get("/projects/{project_id}/files/../hello".format(project_id=project.id))
assert response.status == 404
assert response.status_code == 404
@pytest.mark.asyncio
async def test_write_file(controller_api, project):
response = await controller_api.post("/projects/{project_id}/files/hello".format(project_id=project.id), body="world", raw=True)
assert response.status == 200
assert response.status_code == 204
with open(os.path.join(project.path, "hello")) as f:
assert f.read() == "world"
response = await controller_api.post("/projects/{project_id}/files/../hello".format(project_id=project.id), raw=True)
assert response.status == 404
assert response.status_code == 404
# async def test_write_and_get_file_with_leading_slashes_in_filename(controller_api, project):
@pytest.mark.asyncio
async def test_write_and_get_file_with_leading_slashes_in_filename(controller_api, project):
response = await controller_api.post("/projects/{project_id}/files//hello".format(project_id=project.id), body="world", raw=True)
assert response.status_code == 204
response = await controller_api.get("/projects/{project_id}/files//hello".format(project_id=project.id), raw=True)
assert response.status_code == 200
assert response.content == b"world"
# @pytest.mark.asyncio
# async def test_import(controller_api, tmpdir, controller):
#
# response = await controller_api.post("/projects/{project_id}/files//hello".format(project_id=project.id), body="world", raw=True)
# assert response.status == 200
# with zipfile.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")
#
# response = await controller_api.get("/projects/{project_id}/files//hello".format(project_id=project.id), raw=True)
# assert response.status == 200
# assert response.body == b"world"
async def test_import(controller_api, tmpdir, controller):
with zipfile.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 controller_api.post("/projects/{project_id}/import".format(project_id=project_id), body=f.read(), raw=True)
assert response.status == 201
project = controller.get_project(project_id)
with open(os.path.join(project.path, "demo")) as f:
content = f.read()
assert content == "hello"
# project_id = str(uuid.uuid4())
# with open(str(tmpdir / "test.zip"), "rb") as f:
# response = await controller_api.post("/projects/{project_id}/import".format(project_id=project_id), body=f.read(), raw=True)
# assert response.status_code == 201
#
# project = controller.get_project(project_id)
# with open(os.path.join(project.path, "demo")) as f:
# content = f.read()
# assert content == "hello"
@pytest.mark.asyncio
async def test_duplicate(controller_api, project):
response = await controller_api.post("/projects/{project_id}/duplicate".format(project_id=project.id), {"name": "hello"})
assert response.status == 201
assert response.status_code == 201
assert response.json["name"] == "hello"
@@ -21,6 +21,7 @@ import pytest
@pytest.fixture
@pytest.mark.asyncio
async def project(controller_api, controller):
u = str(uuid.uuid4())
@@ -31,36 +32,41 @@ async def project(controller_api, controller):
@pytest.fixture
@pytest.mark.asyncio
async def snapshot(project):
snapshot = await project.snapshot("test")
return snapshot
@pytest.mark.asyncio
async def test_list_snapshots(controller_api, project, snapshot):
assert snapshot.name == "test"
response = await controller_api.get("/projects/{}/snapshots".format(project.id))
assert response.status == 200
assert response.status_code == 200
assert len(response.json) == 1
@pytest.mark.asyncio
async def test_delete_snapshot(controller_api, project, snapshot):
response = await controller_api.delete("/projects/{}/snapshots/{}".format(project.id, snapshot.id))
assert response.status == 204
assert response.status_code == 204
assert not os.path.exists(snapshot.path)
@pytest.mark.asyncio
async def test_restore_snapshot(controller_api, project, snapshot):
response = await controller_api.post("/projects/{}/snapshots/{}/restore".format(project.id, snapshot.id))
assert response.status == 201
assert response.status_code == 201
assert response.json["name"] == project.name
@pytest.mark.asyncio
async def test_create_snapshot(controller_api, project):
response = await controller_api.post("/projects/{}/snapshots".format(project.id), {"name": "snap1"})
assert response.status == 201
assert response.status_code == 201
assert len(os.listdir(os.path.join(project.path, "snapshots"))) == 1
@@ -15,15 +15,18 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import os
import urllib.parse
@pytest.mark.asyncio
async def test_symbols(controller_api):
response = await controller_api.get('/symbols')
assert response.status == 200
assert response.status_code == 200
assert {
'symbol_id': ':/symbols/classic/firewall.svg',
'filename': 'firewall.svg',
@@ -32,27 +35,29 @@ async def test_symbols(controller_api):
} in response.json
@pytest.mark.asyncio
async def test_get(controller_api, controller):
controller.symbols.theme = "Classic"
response = await controller_api.get('/symbols/' + urllib.parse.quote(':/symbols/classic/firewall.svg') + '/raw')
assert response.status == 200
assert response.status_code == 200
assert response.headers['CONTENT-TYPE'] == 'image/svg+xml'
assert response.headers['CONTENT-LENGTH'] == '9381'
assert '</svg>' in response.html
assert '</svg>' in response.text
# Reply with the default symbol
response = await controller_api.get('/symbols/404.png/raw')
assert response.status == 200
assert response.status_code == 200
@pytest.mark.asyncio
async def test_upload(controller_api, symbols_dir):
response = await controller_api.post("/symbols/test2/raw", body="TEST", raw=True)
assert response.status == 204
response = await controller_api.post("/symbols/test2/raw", body=b"TEST", raw=True)
assert response.status_code == 204
with open(os.path.join(symbols_dir, "test2")) as f:
assert f.read() == "TEST"
response = await controller_api.get('/symbols/test2/raw')
assert response.status == 200
assert response.status_code == 200
@@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import uuid
from tests.utils import asyncio_patch
@@ -23,6 +23,7 @@ from tests.utils import asyncio_patch
from gns3server.controller.template import Template
@pytest.mark.asyncio
async def test_template_list(controller_api, controller):
id = str(uuid.uuid4())
@@ -36,11 +37,11 @@ async def test_template_list(controller_api, controller):
"compute_id": "local"
})
response = await controller_api.get("/templates")
assert response.status == 200
assert response.route == "/templates"
assert response.status_code == 200
assert len(response.json) > 0
@pytest.mark.asyncio
async def test_template_create_without_id(controller_api, controller):
params = {"base_script_file": "vpcs_base_config.txt",
@@ -54,12 +55,12 @@ async def test_template_create_without_id(controller_api, controller):
"template_type": "vpcs"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.route == "/templates"
assert response.status_code == 201
assert response.json["template_id"] is not None
assert len(controller.template_manager.templates) == 1
@pytest.mark.asyncio
async def test_template_create_with_id(controller_api, controller):
params = {"template_id": str(uuid.uuid4()),
@@ -74,12 +75,12 @@ async def test_template_create_with_id(controller_api, controller):
"template_type": "vpcs"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.route == "/templates"
assert response.status_code == 201
assert response.json["template_id"] is not None
assert len(controller.template_manager.templates) == 1
@pytest.mark.asyncio
async def test_template_create_wrong_type(controller_api, controller):
params = {"template_id": str(uuid.uuid4()),
@@ -94,10 +95,11 @@ async def test_template_create_wrong_type(controller_api, controller):
"template_type": "invalid_template_type"}
response = await controller_api.post("/templates", params)
assert response.status == 400
assert response.status_code == 422
assert len(controller.template_manager.templates) == 0
@pytest.mark.asyncio
async def test_template_get(controller_api):
template_id = str(uuid.uuid4())
@@ -113,13 +115,14 @@ async def test_template_get(controller_api):
"template_type": "vpcs"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
response = await controller_api.get("/templates/{}".format(template_id))
assert response.status == 200
assert response.status_code == 200
assert response.json["template_id"] == template_id
@pytest.mark.asyncio
async def test_template_update(controller_api):
template_id = str(uuid.uuid4())
@@ -135,19 +138,20 @@ async def test_template_update(controller_api):
"template_type": "vpcs"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
response = await controller_api.get("/templates/{}".format(template_id))
assert response.status == 200
assert response.status_code == 200
assert response.json["template_id"] == template_id
params["name"] = "VPCS_TEST_RENAMED"
response = await controller_api.put("/templates/{}".format(template_id), params)
assert response.status == 200
assert response.status_code == 200
assert response.json["name"] == "VPCS_TEST_RENAMED"
@pytest.mark.asyncio
async def test_template_delete(controller_api, controller):
template_id = str(uuid.uuid4())
@@ -163,20 +167,21 @@ async def test_template_delete(controller_api, controller):
"template_type": "vpcs"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
response = await controller_api.get("/templates")
assert len(response.json) == 1
assert len(controller.template_manager._templates) == 1
response = await controller_api.delete("/templates/{}".format(template_id))
assert response.status == 204
assert response.status_code == 204
response = await controller_api.get("/templates")
assert len(response.json) == 0
assert len(controller.template_manager.templates) == 0
@pytest.mark.asyncio
async def test_template_duplicate(controller_api, controller):
template_id = str(uuid.uuid4())
@@ -192,10 +197,10 @@ async def test_template_duplicate(controller_api, controller):
"template_type": "vpcs"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
response = await controller_api.post("/templates/{}/duplicate".format(template_id))
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] != template_id
params.pop("template_id")
for param, value in params.items():
@@ -206,6 +211,7 @@ async def test_template_duplicate(controller_api, controller):
assert len(controller.template_manager.templates) == 2
@pytest.mark.asyncio
async def test_c7200_dynamips_template_create(controller_api):
params = {"name": "Cisco c7200 template",
@@ -215,7 +221,7 @@ async def test_c7200_dynamips_template_create(controller_api):
"template_type": "dynamips"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"template_type": "dynamips",
@@ -251,6 +257,7 @@ async def test_c7200_dynamips_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_c3745_dynamips_template_create(controller_api):
params = {"name": "Cisco c3745 template",
@@ -260,7 +267,7 @@ async def test_c3745_dynamips_template_create(controller_api):
"template_type": "dynamips"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"template_type": "dynamips",
@@ -295,6 +302,7 @@ async def test_c3745_dynamips_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_c3725_dynamips_template_create(controller_api):
params = {"name": "Cisco c3725 template",
@@ -304,7 +312,7 @@ async def test_c3725_dynamips_template_create(controller_api):
"template_type": "dynamips"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"template_type": "dynamips",
@@ -339,6 +347,7 @@ async def test_c3725_dynamips_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_c3600_dynamips_template_create(controller_api):
params = {"name": "Cisco c3600 template",
@@ -349,7 +358,7 @@ async def test_c3600_dynamips_template_create(controller_api):
"template_type": "dynamips"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"template_type": "dynamips",
@@ -385,6 +394,7 @@ async def test_c3600_dynamips_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_c3600_dynamips_template_create_wrong_chassis(controller_api):
params = {"name": "Cisco c3600 template",
@@ -395,9 +405,10 @@ async def test_c3600_dynamips_template_create_wrong_chassis(controller_api):
"template_type": "dynamips"}
response = await controller_api.post("/templates", params)
assert response.status == 400
assert response.status_code == 409
@pytest.mark.asyncio
async def test_c2691_dynamips_template_create(controller_api):
params = {"name": "Cisco c2691 template",
@@ -407,7 +418,7 @@ async def test_c2691_dynamips_template_create(controller_api):
"template_type": "dynamips"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"template_type": "dynamips",
@@ -442,6 +453,7 @@ async def test_c2691_dynamips_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_c2600_dynamips_template_create(controller_api):
params = {"name": "Cisco c2600 template",
@@ -452,7 +464,7 @@ async def test_c2600_dynamips_template_create(controller_api):
"template_type": "dynamips"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"template_type": "dynamips",
@@ -488,6 +500,7 @@ async def test_c2600_dynamips_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_c2600_dynamips_template_create_wrong_chassis(controller_api):
params = {"name": "Cisco c2600 template",
@@ -498,9 +511,10 @@ async def test_c2600_dynamips_template_create_wrong_chassis(controller_api):
"template_type": "dynamips"}
response = await controller_api.post("/templates", params)
assert response.status == 400
assert response.status_code == 409
@pytest.mark.asyncio
async def test_c1700_dynamips_template_create(controller_api):
params = {"name": "Cisco c1700 template",
@@ -511,7 +525,7 @@ async def test_c1700_dynamips_template_create(controller_api):
"template_type": "dynamips"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"template_type": "dynamips",
@@ -547,6 +561,7 @@ async def test_c1700_dynamips_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_c1700_dynamips_template_create_wrong_chassis(controller_api):
params = {"name": "Cisco c1700 template",
@@ -557,9 +572,10 @@ async def test_c1700_dynamips_template_create_wrong_chassis(controller_api):
"template_type": "dynamips"}
response = await controller_api.post("/templates", params)
assert response.status == 400
assert response.status_code == 409
@pytest.mark.asyncio
async def test_dynamips_template_create_wrong_platform(controller_api):
params = {"name": "Cisco c3900 template",
@@ -569,9 +585,10 @@ async def test_dynamips_template_create_wrong_platform(controller_api):
"template_type": "dynamips"}
response = await controller_api.post("/templates", params)
assert response.status == 400
assert response.status_code == 409
@pytest.mark.asyncio
async def test_iou_template_create(controller_api):
params = {"name": "IOU template",
@@ -580,7 +597,7 @@ async def test_iou_template_create(controller_api):
"template_type": "iou"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"template_type": "iou",
@@ -606,6 +623,7 @@ async def test_iou_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_docker_template_create(controller_api):
params = {"name": "Docker template",
@@ -614,7 +632,7 @@ async def test_docker_template_create(controller_api):
"template_type": "docker"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"adapters": 1,
@@ -640,6 +658,7 @@ async def test_docker_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_qemu_template_create(controller_api):
params = {"name": "Qemu template",
@@ -650,7 +669,7 @@ async def test_qemu_template_create(controller_api):
"template_type": "qemu"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"adapter_type": "e1000",
@@ -699,6 +718,7 @@ async def test_qemu_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_vmware_template_create(controller_api):
params = {"name": "VMware template",
@@ -707,7 +727,7 @@ async def test_vmware_template_create(controller_api):
"vmx_path": "/path/to/vm.vmx"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"adapter_type": "e1000",
@@ -735,6 +755,7 @@ async def test_vmware_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_virtualbox_template_create(controller_api):
params = {"name": "VirtualBox template",
@@ -743,7 +764,7 @@ async def test_virtualbox_template_create(controller_api):
"vmname": "My VirtualBox VM"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"adapter_type": "Intel PRO/1000 MT Desktop (82540EM)",
@@ -772,6 +793,7 @@ async def test_virtualbox_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_vpcs_template_create(controller_api):
params = {"name": "VPCS template",
@@ -779,7 +801,7 @@ async def test_vpcs_template_create(controller_api):
"template_type": "vpcs"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"template_type": "vpcs",
@@ -797,6 +819,7 @@ async def test_vpcs_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_ethernet_switch_template_create(controller_api):
params = {"name": "Ethernet switch template",
@@ -804,7 +827,7 @@ async def test_ethernet_switch_template_create(controller_api):
"template_type": "ethernet_switch"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"template_type": "ethernet_switch",
@@ -868,6 +891,7 @@ async def test_ethernet_switch_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_cloud_template_create(controller_api):
params = {"name": "Cloud template",
@@ -875,7 +899,7 @@ async def test_cloud_template_create(controller_api):
"template_type": "cloud"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"template_type": "cloud",
@@ -890,6 +914,7 @@ async def test_cloud_template_create(controller_api):
assert response.json.get(item) == value
@pytest.mark.asyncio
async def test_ethernet_hub_template_create(controller_api):
params = {"name": "Ethernet hub template",
@@ -897,7 +922,7 @@ async def test_ethernet_hub_template_create(controller_api):
"template_type": "ethernet_hub"}
response = await controller_api.post("/templates", params)
assert response.status == 201
assert response.status_code == 201
assert response.json["template_id"] is not None
expected_response = {"ports_mapping": [{"port_number": 0,
@@ -936,22 +961,22 @@ async def test_ethernet_hub_template_create(controller_api):
assert response.json.get(item) == value
async def test_create_node_from_template(controller_api, controller, project):
id = str(uuid.uuid4())
controller.template_manager._templates = {id: Template(id, {
"template_type": "qemu",
"category": 0,
"name": "test",
"symbol": "guest.svg",
"default_name_format": "{name}-{0}",
"compute_id": "example.com"
})}
with asyncio_patch("gns3server.controller.project.Project.add_node_from_template", return_value={"name": "test", "node_type": "qemu", "compute_id": "example.com"}) as mock:
response = await controller_api.post("/projects/{}/templates/{}".format(project.id, id), {
"x": 42,
"y": 12
})
mock.assert_called_with(id, x=42, y=12, compute_id=None)
assert response.route == "/projects/{project_id}/templates/{template_id}"
assert response.status == 201
# @pytest.mark.asyncio
# async def test_create_node_from_template(controller_api, controller, project):
#
# id = str(uuid.uuid4())
# controller.template_manager._templates = {id: Template(id, {
# "template_type": "qemu",
# "category": 0,
# "name": "test",
# "symbol": "guest.svg",
# "default_name_format": "{name}-{0}",
# "compute_id": "example.com"
# })}
# with asyncio_patch("gns3server.controller.project.Project.add_node_from_template", return_value={"name": "test", "node_type": "qemu", "compute_id": "example.com"}) as mock:
# response = await controller_api.post("/projects/{}/templates/{}".format(project.id, id), {
# "x": 42,
# "y": 12
# })
# mock.assert_called_with(id, x=42, y=12, compute_id=None)
# assert response.status_code == 201
@@ -15,44 +15,49 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
from gns3server.version import __version__
@pytest.mark.asyncio
async def test_version_output(controller_api, config):
config.set("Server", "local", "true")
response = await controller_api.get('/version')
assert response.status == 200
assert response.status_code == 200
assert response.json == {'local': True, 'version': __version__}
@pytest.mark.asyncio
async def test_version_input(controller_api):
params = {'version': __version__}
response = await controller_api.post('/version', params)
assert response.status == 200
assert response.status_code == 200
assert response.json == {'version': __version__}
@pytest.mark.asyncio
async def test_version_invalid_input(controller_api):
params = {'version': "0.4.2"}
response = await controller_api.post('/version', params)
assert response.status == 409
assert response.json == {'message': 'Client version 0.4.2 is not the same as server version {}'.format(__version__),
'status': 409}
assert response.status_code == 409
assert response.json == {'message': 'Client version 0.4.2 is not the same as server version {}'.format(__version__)}
@pytest.mark.asyncio
async def test_version_invalid_input_schema(controller_api):
params = {'version': "0.4.2", "bla": "blu"}
response = await controller_api.post('/version', params)
assert response.status == 400
assert response.status_code == 409
@pytest.mark.asyncio
async def test_version_invalid_json(controller_api):
params = "BOUM"
response = await controller_api.post('/version', params, raw=True)
assert response.status == 400
assert response.status_code == 422
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import os
from unittest.mock import patch
@@ -30,55 +31,52 @@ def get_static(filename):
return os.path.join(os.path.abspath(os.path.join(current_dir, '..', '..', 'gns3server', 'static')), filename)
@pytest.mark.asyncio
async def test_debug(http_client):
response = await http_client.get('/debug')
assert response.status == 200
html = await response.text()
assert response.status_code == 200
html = response.text
assert "Website" in html
assert __version__ in html
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 == 200
# @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
async def test_compute(http_client):
response = await http_client.get('/compute')
assert response.status == 200
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 == 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
@pytest.mark.asyncio
async def test_web_ui(http_client):
response = await http_client.get('/static/web-ui/index.html')
assert response.status == 200
assert response.status_code == 200
@pytest.mark.asyncio
async def test_web_ui_not_found(http_client, tmpdir):
with patch('gns3server.utils.get_resource.get_resource') as mock:
mock.return_value = str(tmpdir)
response = await http_client.get('/static/web-ui/not-found.txt')
# should serve web-ui/index.html
assert response.status == 200
async def test_v1(http_client):
"""
The old API v1 raises a 429
"""
response = await http_client.get('/v1/version')
assert response.status == 200
assert response.status_code == 200
-39
View File
@@ -1,39 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2020 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from gns3server.version import __version__
async def test_version_output(compute_api, config):
config.set("Server", "local", "true")
response = await compute_api.get('/version')
assert response.status == 200
assert response.json == {'local': True, 'version': __version__}
async def test_debug_output(compute_api):
response = await compute_api.get('/debug')
assert response.status == 200
async def test_statistics_output(compute_api):
response = await compute_api.get('/statistics')
assert response.status == 200
-190
View File
@@ -1,190 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2020 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import uuid
from tests.utils import asyncio_patch
from unittest.mock import patch
@pytest.fixture(scope="function")
async def vm(compute_api, compute_project):
params = {"name": "TraceNG TEST 1"}
response = await compute_api.post("/projects/{project_id}/traceng/nodes".format(project_id=compute_project.id), params)
assert response.status == 201
return response.json
async def test_traceng_create(compute_api, compute_project):
params = {"name": "TraceNG TEST 1"}
response = await compute_api.post("/projects/{project_id}/traceng/nodes".format(project_id=compute_project.id), params)
assert response.status == 201
assert response.route == "/projects/{project_id}/traceng/nodes"
assert response.json["name"] == "TraceNG TEST 1"
assert response.json["project_id"] == compute_project.id
async def test_traceng_get(compute_api, compute_project, vm):
response = await compute_api.get("/projects/{project_id}/traceng/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 200
assert response.route == "/projects/{project_id}/traceng/nodes/{node_id}"
assert response.json["name"] == "TraceNG TEST 1"
assert response.json["project_id"] == compute_project.id
assert response.json["status"] == "stopped"
async def test_traceng_nio_create_udp(compute_api, vm):
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM.add_ubridge_udp_connection"):
response = await compute_api.post("/projects/{project_id}/traceng/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
assert response.route == r"/projects/{project_id}/traceng/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.json["type"] == "nio_udp"
async def test_traceng_nio_update_udp(compute_api, vm):
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM.add_ubridge_udp_connection"):
response = await compute_api.post("/projects/{project_id}/traceng/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201
params["filters"] = {}
response = await compute_api.put("/projects/{project_id}/traceng/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 201, response.body.decode("utf-8")
assert response.route == r"/projects/{project_id}/traceng/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
assert response.json["type"] == "nio_udp"
async def test_traceng_delete_nio(compute_api, vm):
params = {
"type": "nio_udp",
"lport": 4242,
"rport": 4343,
"rhost": "127.0.0.1"
}
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM._ubridge_send"):
await compute_api.post("/projects/{project_id}/traceng/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
response = await compute_api.delete("/projects/{project_id}/traceng/nodes/{node_id}/adapters/0/ports/0/nio".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204, response.body.decode()
assert response.route == r"/projects/{project_id}/traceng/nodes/{node_id}/adapters/{adapter_number:\d+}/ports/{port_number:\d+}/nio"
async def test_traceng_start(compute_api, vm):
params = {"destination": "192.168.1.2"}
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM.start", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/traceng/nodes/{node_id}/start".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert mock.called
assert response.status == 200
assert response.json["name"] == "TraceNG TEST 1"
async def test_traceng_stop(compute_api, vm):
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM.stop", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/traceng/nodes/{node_id}/stop".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
async def test_traceng_reload(compute_api, vm):
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM.reload", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/traceng/nodes/{node_id}/reload".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
async def test_traceng_delete(compute_api, vm):
with asyncio_patch("gns3server.compute.traceng.TraceNG.delete_node", return_value=True) as mock:
response = await compute_api.delete("/projects/{project_id}/traceng/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert mock.called
assert response.status == 204
async def test_traceng_duplicate(compute_api, vm):
params = {"destination_node_id": str(uuid.uuid4())}
with asyncio_patch("gns3server.compute.traceng.TraceNG.duplicate_node", return_value=True) as mock:
response = await compute_api.post("/projects/{project_id}/traceng/nodes/{node_id}/duplicate".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert mock.called
assert response.status == 201
async def test_traceng_update(compute_api, vm):
params = {
"name": "test",
"ip_address": "192.168.1.1"
}
response = await compute_api.put("/projects/{project_id}/traceng/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 200
assert response.json["name"] == "test"
assert response.json["ip_address"] == "192.168.1.1"
async def test_traceng_start_capture(compute_api, vm):
params = {
"capture_file_name": "test.pcap",
"data_link_type": "DLT_EN10MB"
}
with patch("gns3server.compute.traceng.traceng_vm.TraceNGVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM.start_capture") as mock:
response = await compute_api.post("/projects/{project_id}/traceng/nodes/{node_id}/adapters/0/ports/0/start_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]), params)
assert response.status == 200
assert mock.called
assert "test.pcap" in response.json["pcap_file_path"]
async def test_traceng_stop_capture(compute_api, vm):
with patch("gns3server.compute.traceng.traceng_vm.TraceNGVM.is_running", return_value=True):
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM.stop_capture") as mock:
response = await compute_api.post("/projects/{project_id}/traceng/nodes/{node_id}/adapters/0/ports/0/stop_capture".format(project_id=vm["project_id"], node_id=vm["node_id"]))
assert response.status == 204
assert mock.called
async def test_traceng_pcap(compute_api, vm, compute_project):
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM.get_nio"):
with asyncio_patch("gns3server.compute.traceng.TraceNG.stream_pcap_file"):
response = await compute_api.get("/projects/{project_id}/traceng/nodes/{node_id}/adapters/0/ports/0/pcap".format(project_id=compute_project.id, node_id=vm["node_id"]), raw=True)
assert response.status == 200
@@ -1,76 +0,0 @@
#!/usr/bin/env python
#
# Copyright (C) 2020 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import pytest
from unittest.mock import MagicMock
from gns3server.web.web_server import WebServer
@pytest.fixture
def web_server():
WebServer._instance = MagicMock()
yield WebServer._instance
WebServer._instance = None
async def test_shutdown_local(controller_api, web_server, config):
async def hello():
return 0
web_server.shutdown_server.return_value = hello()
config.set("Server", "local", True)
response = await controller_api.post('/shutdown')
assert response.status == 201
assert web_server.shutdown_server.called
async def test_shutdown_non_local(controller_api, web_server, config):
WebServer._instance = MagicMock()
config.set("Server", "local", False)
response = await controller_api.post('/shutdown')
assert response.status == 403
assert not web_server.shutdown_server.called
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 == 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"))
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 == 403
async def test_statistics_output(controller_api):
response = await controller_api.get('/statistics')
assert response.status == 200
+4 -4
View File
@@ -53,7 +53,7 @@ def write_config(tmpdir, settings):
return path
def test_get_section_config(loop, tmpdir):
def test_get_section_config(tmpdir):
config = load_config(tmpdir, {
"Server": {
@@ -63,7 +63,7 @@ def test_get_section_config(loop, tmpdir):
assert dict(config.get_section_config("Server")) == {"host": "127.0.0.1"}
def test_set_section_config(loop, tmpdir):
def test_set_section_config(tmpdir):
config = load_config(tmpdir, {
"Server": {
@@ -77,7 +77,7 @@ def test_set_section_config(loop, tmpdir):
assert dict(config.get_section_config("Server")) == {"host": "192.168.1.1", "local": "true"}
def test_set(loop, tmpdir):
def test_set(tmpdir):
config = load_config(tmpdir, {
"Server": {
@@ -90,7 +90,7 @@ def test_set(loop, tmpdir):
assert dict(config.get_section_config("Server")) == {"host": "192.168.1.1"}
def test_reload(loop, tmpdir):
def test_reload(tmpdir):
config = load_config(tmpdir, {
"Server": {
+5 -1
View File
@@ -25,6 +25,7 @@ from gns3server.utils.asyncio import wait_run_in_executor, subprocess_check_outp
from tests.utils import AsyncioMagicMock
@pytest.mark.asyncio
async def test_wait_run_in_executor():
def change_var(param):
@@ -34,6 +35,7 @@ async def test_wait_run_in_executor():
assert result == "test"
@pytest.mark.asyncio
async def test_exception_wait_run_in_executor():
def raise_exception():
@@ -44,13 +46,15 @@ async def test_exception_wait_run_in_executor():
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
async def test_subprocess_check_output(loop, tmpdir):
@pytest.mark.asyncio
async def test_subprocess_check_output(tmpdir):
path = str(tmpdir / "test")
result = await subprocess_check_output("echo", "-n", path)
assert result == path
@pytest.mark.asyncio
async def test_lock_decorator():
"""
The test check if the the second call to method_to_lock wait for the
+3
View File
@@ -24,6 +24,7 @@ from gns3server.utils.file_watcher import FileWatcher
@pytest.mark.parametrize("strategy", ['mtime', 'hash'])
@pytest.mark.asyncio
async def test_file_watcher(tmpdir, strategy):
file = tmpdir / "test"
@@ -38,6 +39,7 @@ async def test_file_watcher(tmpdir, strategy):
@pytest.mark.parametrize("strategy", ['mtime', 'hash'])
@pytest.mark.asyncio
async def test_file_watcher_not_existing(tmpdir, strategy):
file = tmpdir / "test"
@@ -51,6 +53,7 @@ async def test_file_watcher_not_existing(tmpdir, strategy):
@pytest.mark.parametrize("strategy", ['mtime', 'hash'])
@pytest.mark.asyncio
async def test_file_watcher_list(tmpdir, strategy):
file = tmpdir / "test"
-46
View File
@@ -1,46 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2018 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
from tests.utils import AsyncioMagicMock
from aiohttp.web import HTTPNotFound
from gns3server.web.response import Response
@pytest.fixture()
def response():
request = AsyncioMagicMock()
return Response(request=request)
async def test_response_file(tmpdir, response):
filename = str(tmpdir / 'hello')
with open(filename, 'w+') as f:
f.write('world')
await response.stream_file(filename)
assert response.status == 200
async def test_response_file_not_found(loop, tmpdir, response):
filename = str(tmpdir / 'hello-not-found')
with pytest.raises(HTTPNotFound):
await response.stream_file(filename)