Refactoring to use a common node class for all VMs and other (future) objects.

This commit is contained in:
grossmj committed 2016-05-11 11:35:36 -06:00
1 parent 9dca7dfe4a
commit 5a76f81271
102 files changed
+1654 -1672

No files matched your search

+1 -1
View File
@@ -53,7 +53,7 @@ def test_json(vm, project):
'image': 'ubuntu',
'name': 'test',
'project_id': project.id,
'vm_id': vm.id,
'node_id': vm.id,
'adapters': 1,
'console': vm.console,
'console_type': 'telnet',
+10 -10
View File
@@ -44,13 +44,13 @@ def test_get_application_id(loop, project, iou):
vm1_id = str(uuid.uuid4())
vm2_id = str(uuid.uuid4())
vm3_id = str(uuid.uuid4())
loop.run_until_complete(iou.create_vm("PC 1", project.id, vm1_id))
loop.run_until_complete(iou.create_vm("PC 2", project.id, vm2_id))
loop.run_until_complete(iou.create_node("PC 1", project.id, vm1_id))
loop.run_until_complete(iou.create_node("PC 2", project.id, vm2_id))
assert iou.get_application_id(vm1_id) == 1
assert iou.get_application_id(vm1_id) == 1
assert iou.get_application_id(vm2_id) == 2
loop.run_until_complete(iou.delete_vm(vm1_id))
loop.run_until_complete(iou.create_vm("PC 3", project.id, vm3_id))
loop.run_until_complete(iou.delete_node(vm1_id))
loop.run_until_complete(iou.create_node("PC 3", project.id, vm3_id))
assert iou.get_application_id(vm3_id) == 1
@@ -60,9 +60,9 @@ def test_get_application_id_multiple_project(loop, iou):
vm3_id = str(uuid.uuid4())
project1 = ProjectManager.instance().create_project(project_id=str(uuid.uuid4()))
project2 = ProjectManager.instance().create_project(project_id=str(uuid.uuid4()))
loop.run_until_complete(iou.create_vm("PC 1", project1.id, vm1_id))
loop.run_until_complete(iou.create_vm("PC 2", project1.id, vm2_id))
loop.run_until_complete(iou.create_vm("PC 2", project2.id, vm3_id))
loop.run_until_complete(iou.create_node("PC 1", project1.id, vm1_id))
loop.run_until_complete(iou.create_node("PC 2", project1.id, vm2_id))
loop.run_until_complete(iou.create_node("PC 2", project2.id, vm3_id))
assert iou.get_application_id(vm1_id) == 1
assert iou.get_application_id(vm2_id) == 2
assert iou.get_application_id(vm3_id) == 3
@@ -71,9 +71,9 @@ def test_get_application_id_multiple_project(loop, iou):
def test_get_application_id_no_id_available(loop, project, iou):
with pytest.raises(IOUError):
for i in range(1, 513):
vm_id = str(uuid.uuid4())
loop.run_until_complete(iou.create_vm("PC {}".format(i), project.id, vm_id))
assert iou.get_application_id(vm_id) == i
node_id = str(uuid.uuid4())
loop.run_until_complete(iou.create_node("PC {}".format(i), project.id, node_id))
assert iou.get_application_id(node_id) == i
def test_get_images_directory(iou, tmpdir):
+2 -2
View File
@@ -148,7 +148,7 @@ def test_termination_callback(vm, async_run):
async_run(queue.get(0)) #  Ping
(action, event, kwargs) = async_run(queue.get(0))
assert action == "vm.stopped"
assert action == "node.stopped"
assert event == vm
@@ -167,7 +167,7 @@ def test_termination_callback_error(vm, tmpdir, async_run):
async_run(queue.get(0)) #  Ping
(action, event, kwargs) = queue.get_nowait()
assert action == "vm.stopped"
assert action == "node.stopped"
assert event == vm
(action, event, kwargs) = queue.get_nowait()
+123
View File
@@ -0,0 +1,123 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2015 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 aiohttp
import asyncio
import os
from tests.utils import asyncio_patch
from unittest.mock import patch, MagicMock
from gns3server.compute.vpcs.vpcs_vm import VPCSVM
from gns3server.compute.docker.docker_vm import DockerVM
from gns3server.compute.vpcs.vpcs_error import VPCSError
from gns3server.compute.node_error import NodeError
from gns3server.compute.vpcs import VPCS
@pytest.fixture(scope="module")
def manager(port_manager):
m = VPCS.instance()
m.port_manager = port_manager
return m
@pytest.fixture(scope="function")
def node(project, manager):
return VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
def test_temporary_directory(project, manager):
node = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
assert isinstance(node.temporary_directory, str)
def test_console(project, manager):
node = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
node.console = 5011
assert node.console == 5011
node.console = None
assert node.console is None
def test_change_console_port(node, port_manager):
port1 = port_manager.get_free_tcp_port(node.project)
port2 = port_manager.get_free_tcp_port(node.project)
port_manager.release_tcp_port(port1, node.project)
port_manager.release_tcp_port(port2, node.project)
node.console = port1
node.console = port2
assert node.console == port2
port_manager.reserve_tcp_port(port1, node.project)
def test_console_vnc_invalid(project, manager):
node = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
node.console_type = "vnc"
with pytest.raises(NodeError):
node.console = 2012
def test_close(node, loop, port_manager):
assert node.console is not None
aux = port_manager.get_free_tcp_port(node.project)
port_manager.release_tcp_port(aux, node.project)
node.aux = aux
port = node.console
assert loop.run_until_complete(asyncio.async(node.close()))
# Raise an exception if the port is not free
port_manager.reserve_tcp_port(port, node.project)
# Raise an exception if the port is not free
port_manager.reserve_tcp_port(aux, node.project)
assert node.console is None
assert node.aux is None
# Called twice closed should return False
assert loop.run_until_complete(asyncio.async(node.close())) is False
def test_aux(project, manager, port_manager):
aux = port_manager.get_free_tcp_port(project)
port_manager.release_tcp_port(aux, project)
node = DockerVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager, "ubuntu", aux=aux)
assert node.aux == aux
node.aux = None
assert node.aux is None
def test_allocate_aux(project, manager):
node = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
assert node.aux is None
# Docker has an aux port by default
node = DockerVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager, "ubuntu")
assert node.aux is not None
def test_change_aux_port(node, port_manager):
port1 = port_manager.get_free_tcp_port(node.project)
port2 = port_manager.get_free_tcp_port(node.project)
port_manager.release_tcp_port(port1, node.project)
port_manager.release_tcp_port(port2, node.project)
node.aux = port1
node.aux = port2
assert node.aux == port2
port_manager.reserve_tcp_port(port1, node.project)
-123
View File
@@ -1,123 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2015 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 aiohttp
import asyncio
import os
from tests.utils import asyncio_patch
from unittest.mock import patch, MagicMock
from gns3server.compute.vpcs.vpcs_vm import VPCSVM
from gns3server.compute.docker.docker_vm import DockerVM
from gns3server.compute.vpcs.vpcs_error import VPCSError
from gns3server.compute.vm_error import VMError
from gns3server.compute.vpcs import VPCS
@pytest.fixture(scope="module")
def manager(port_manager):
m = VPCS.instance()
m.port_manager = port_manager
return m
@pytest.fixture(scope="function")
def vm(project, manager):
return VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
def test_temporary_directory(project, manager):
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
assert isinstance(vm.temporary_directory, str)
def test_console(project, manager):
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
vm.console = 5011
assert vm.console == 5011
vm.console = None
assert vm.console is None
def test_change_console_port(vm, port_manager):
port1 = port_manager.get_free_tcp_port(vm.project)
port2 = port_manager.get_free_tcp_port(vm.project)
port_manager.release_tcp_port(port1, vm.project)
port_manager.release_tcp_port(port2, vm.project)
vm.console = port1
vm.console = port2
assert vm.console == port2
port_manager.reserve_tcp_port(port1, vm.project)
def test_console_vnc_invalid(project, manager):
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
vm.console_type = "vnc"
with pytest.raises(VMError):
vm.console = 2012
def test_close(vm, loop, port_manager):
assert vm.console is not None
aux = port_manager.get_free_tcp_port(vm.project)
port_manager.release_tcp_port(aux, vm.project)
vm.aux = aux
port = vm.console
assert loop.run_until_complete(asyncio.async(vm.close()))
# Raise an exception if the port is not free
port_manager.reserve_tcp_port(port, vm.project)
# Raise an exception if the port is not free
port_manager.reserve_tcp_port(aux, vm.project)
assert vm.console is None
assert vm.aux is None
# Called twice closed should return False
assert loop.run_until_complete(asyncio.async(vm.close())) is False
def test_aux(project, manager, port_manager):
aux = port_manager.get_free_tcp_port(project)
port_manager.release_tcp_port(aux, project)
vm = DockerVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager, "ubuntu", aux=aux)
assert vm.aux == aux
vm.aux = None
assert vm.aux is None
def test_allocate_aux(project, manager):
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
assert vm.aux is None
# Docker has an aux port by default
vm = DockerVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager, "ubuntu")
assert vm.aux is not None
def test_change_aux_port(vm, port_manager):
port1 = port_manager.get_free_tcp_port(vm.project)
port2 = port_manager.get_free_tcp_port(vm.project)
port_manager.release_tcp_port(port1, vm.project)
port_manager.release_tcp_port(port2, vm.project)
vm.aux = port1
vm.aux = port2
assert vm.aux == port2
port_manager.reserve_tcp_port(port1, vm.project)
+28 -28
View File
@@ -23,7 +23,7 @@ from unittest.mock import patch
from gns3server.compute.vpcs import VPCS
from gns3server.compute.qemu import Qemu
from gns3server.compute.vm_error import VMError
from gns3server.compute.node_error import NodeError
from gns3server.utils import force_unix_path
@@ -43,48 +43,48 @@ def qemu(port_manager):
return qemu
def test_create_vm_new_topology(loop, project, vpcs):
vm_id = str(uuid.uuid4())
vm = loop.run_until_complete(vpcs.create_vm("PC 1", project.id, vm_id))
assert vm in project.vms
def test_create_node_new_topology(loop, project, vpcs):
node_id = str(uuid.uuid4())
node = loop.run_until_complete(vpcs.create_node("PC 1", project.id, node_id))
assert node in project.nodes
def test_create_twice_same_vm_new_topology(loop, project, vpcs):
project._vms = set()
vm_id = str(uuid.uuid4())
vm = loop.run_until_complete(vpcs.create_vm("PC 1", project.id, vm_id, console=2222))
assert vm in project.vms
assert len(project.vms) == 1
vm = loop.run_until_complete(vpcs.create_vm("PC 2", project.id, vm_id, console=2222))
assert len(project.vms) == 1
def test_create_twice_same_node_new_topology(loop, project, vpcs):
project._nodes = set()
node_id = str(uuid.uuid4())
node = loop.run_until_complete(vpcs.create_node("PC 1", project.id, node_id, console=2222))
assert node in project.nodes
assert len(project.nodes) == 1
node = loop.run_until_complete(vpcs.create_node("PC 2", project.id, node_id, console=2222))
assert len(project.nodes) == 1
def test_create_vm_new_topology_without_uuid(loop, project, vpcs):
vm = loop.run_until_complete(vpcs.create_vm("PC 1", project.id, None))
assert vm in project.vms
assert len(vm.id) == 36
def test_create_node_new_topology_without_uuid(loop, project, vpcs):
node = loop.run_until_complete(vpcs.create_node("PC 1", project.id, None))
assert node in project.nodes
assert len(node.id) == 36
def test_create_vm_old_topology(loop, project, tmpdir, vpcs):
def test_create_node_old_topology(loop, project, tmpdir, vpcs):
with patch("gns3server.compute.project.Project.is_local", return_value=True):
# Create an old topology directory
project_dir = str(tmpdir / "testold")
vm_dir = os.path.join(project_dir, "testold-files", "vpcs", "pc-1")
node_dir = os.path.join(project_dir, "testold-files", "vpcs", "pc-1")
project.path = project_dir
project.name = "testold"
os.makedirs(vm_dir, exist_ok=True)
with open(os.path.join(vm_dir, "startup.vpc"), "w+") as f:
os.makedirs(node_dir, exist_ok=True)
with open(os.path.join(node_dir, "startup.vpc"), "w+") as f:
f.write("1")
vm_id = 1
vm = loop.run_until_complete(vpcs.create_vm("PC 1", project.id, vm_id))
assert len(vm.id) == 36
node_id = 1
node = loop.run_until_complete(vpcs.create_node("PC 1", project.id, node_id))
assert len(node.id) == 36
assert os.path.exists(os.path.join(project_dir, "testold-files")) is False
vm_dir = os.path.join(project_dir, "project-files", "vpcs", vm.id)
with open(os.path.join(vm_dir, "startup.vpc")) as f:
node_dir = os.path.join(project_dir, "project-files", "vpcs", node.id)
with open(os.path.join(node_dir, "startup.vpc")) as f:
assert f.read() == "1"
@@ -116,9 +116,9 @@ def test_get_abs_image_path_non_local(qemu, tmpdir):
# If non local we can't use path outside images directory
with patch("gns3server.config.Config.get_section_config", return_value={"images_path": str(tmpdir / "images"), "local": False}):
assert qemu.get_abs_image_path(path1) == path1
with pytest.raises(VMError):
with pytest.raises(NodeError):
qemu.get_abs_image_path(path2)
with pytest.raises(VMError):
with pytest.raises(NodeError):
qemu.get_abs_image_path("C:\\test2.bin")
with patch("gns3server.config.Config.get_section_config", return_value={"images_path": str(tmpdir / "images"), "local": True}):
+28 -28
View File
@@ -41,9 +41,9 @@ def manager(port_manager):
@pytest.fixture(scope="function")
def vm(project, manager, loop):
vm = manager.create_vm("test", project.id, "00010203-0405-0607-0809-0a0b0c0d0e0f")
return loop.run_until_complete(asyncio.async(vm))
def node(project, manager, loop):
node = manager.create_node("test", project.id, "00010203-0405-0607-0809-0a0b0c0d0e0f")
return loop.run_until_complete(asyncio.async(node))
def test_affect_uuid():
@@ -123,44 +123,44 @@ def test_json(tmpdir):
assert p.__json__() == {"name": p.name, "project_id": p.id, "temporary": False}
def test_vm_working_directory(tmpdir, vm):
def test_vm_working_directory(tmpdir, node):
directory = Config.instance().get_section_config("Server").get("project_directory")
with patch("gns3server.compute.project.Project.is_local", return_value=True):
p = Project(project_id=str(uuid4()))
assert p.vm_working_directory(vm) == os.path.join(directory, p.id, 'project-files', vm.module_name, vm.id)
assert os.path.exists(p.vm_working_directory(vm))
assert p.node_working_directory(node) == os.path.join(directory, p.id, 'project-files', node.module_name, node.id)
assert os.path.exists(p.node_working_directory(node))
def test_mark_vm_for_destruction(vm):
def test_mark_node_for_destruction(node):
project = Project(project_id=str(uuid4()))
project.add_vm(vm)
project.mark_vm_for_destruction(vm)
assert len(project._vms_to_destroy) == 1
assert len(project.vms) == 0
project.add_node(node)
project.mark_node_for_destruction(node)
assert len(project._nodes_to_destroy) == 1
assert len(project.nodes) == 0
def test_commit(manager, loop):
project = Project(project_id=str(uuid4()))
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
project.add_vm(vm)
directory = project.vm_working_directory(vm)
project.mark_vm_for_destruction(vm)
assert len(project._vms_to_destroy) == 1
node = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
project.add_node(node)
directory = project.node_working_directory(node)
project.mark_node_for_destruction(node)
assert len(project._nodes_to_destroy) == 1
assert os.path.exists(directory)
loop.run_until_complete(asyncio.async(project.commit()))
assert len(project._vms_to_destroy) == 0
assert len(project._nodes_to_destroy) == 0
assert os.path.exists(directory) is False
assert len(project.vms) == 0
assert len(project.nodes) == 0
def test_commit_permission_issue(manager, loop):
project = Project(project_id=str(uuid4()))
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
project.add_vm(vm)
directory = project.vm_working_directory(vm)
project.mark_vm_for_destruction(vm)
assert len(project._vms_to_destroy) == 1
node = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
project.add_node(node)
directory = project.node_working_directory(node)
project.mark_node_for_destruction(node)
assert len(project._nodes_to_destroy) == 1
assert os.path.exists(directory)
os.chmod(directory, 0)
with pytest.raises(aiohttp.web.HTTPInternalServerError):
@@ -188,17 +188,17 @@ def test_project_delete_permission_issue(loop):
def test_project_add_vm(manager):
project = Project(project_id=str(uuid4()))
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
project.add_vm(vm)
assert len(project.vms) == 1
node = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
project.add_node(node)
assert len(project.nodes) == 1
def test_project_close(loop, vm, project):
def test_project_close(loop, node, project):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.close") as mock:
loop.run_until_complete(asyncio.async(project.close()))
assert mock.called
assert vm.id not in vm.manager._vms
assert node.id not in node.manager._nodes
def test_project_close_temporary_project(loop, manager):
+10 -10
View File
@@ -33,13 +33,13 @@ def test_get_mac_id(loop, project, port_manager):
vm1_id = str(uuid.uuid4())
vm2_id = str(uuid.uuid4())
vm3_id = str(uuid.uuid4())
loop.run_until_complete(vpcs.create_vm("PC 1", project.id, vm1_id))
loop.run_until_complete(vpcs.create_vm("PC 2", project.id, vm2_id))
loop.run_until_complete(vpcs.create_node("PC 1", project.id, vm1_id))
loop.run_until_complete(vpcs.create_node("PC 2", project.id, vm2_id))
assert vpcs.get_mac_id(vm1_id) == 0
assert vpcs.get_mac_id(vm1_id) == 0
assert vpcs.get_mac_id(vm2_id) == 1
loop.run_until_complete(vpcs.delete_vm(vm1_id))
loop.run_until_complete(vpcs.create_vm("PC 3", project.id, vm3_id))
loop.run_until_complete(vpcs.delete_node(vm1_id))
loop.run_until_complete(vpcs.create_node("PC 3", project.id, vm3_id))
assert vpcs.get_mac_id(vm3_id) == 0
@@ -53,9 +53,9 @@ def test_get_mac_id_multiple_project(loop, port_manager):
vm3_id = str(uuid.uuid4())
project1 = ProjectManager.instance().create_project(project_id=str(uuid.uuid4()))
project2 = ProjectManager.instance().create_project(project_id=str(uuid.uuid4()))
loop.run_until_complete(vpcs.create_vm("PC 1", project1.id, vm1_id))
loop.run_until_complete(vpcs.create_vm("PC 2", project1.id, vm2_id))
loop.run_until_complete(vpcs.create_vm("PC 2", project2.id, vm3_id))
loop.run_until_complete(vpcs.create_node("PC 1", project1.id, vm1_id))
loop.run_until_complete(vpcs.create_node("PC 2", project1.id, vm2_id))
loop.run_until_complete(vpcs.create_node("PC 2", project2.id, vm3_id))
assert vpcs.get_mac_id(vm1_id) == 0
assert vpcs.get_mac_id(vm2_id) == 1
assert vpcs.get_mac_id(vm3_id) == 0
@@ -68,6 +68,6 @@ def test_get_mac_id_no_id_available(loop, project, port_manager):
vpcs.port_manager = port_manager
with pytest.raises(VPCSError):
for i in range(0, 256):
vm_id = str(uuid.uuid4())
loop.run_until_complete(vpcs.create_vm("PC {}".format(i), project.id, vm_id))
assert vpcs.get_mac_id(vm_id) == i
node_id = str(uuid.uuid4())
loop.run_until_complete(vpcs.create_node("PC {}".format(i), project.id, node_id))
assert vpcs.get_mac_id(node_id) == i
+2 -2
View File
@@ -112,7 +112,7 @@ def test_start(loop, vm, async_run):
assert vm.is_running()
assert vm.command_line == ' '.join(mock_exec.call_args[0])
(action, event, kwargs) = async_run(queue.get(0))
assert action == "vm.started"
assert action == "node.started"
assert event == vm
@@ -177,7 +177,7 @@ def test_stop(loop, vm, async_run):
async_run(queue.get(0)) #  Started
(action, event, kwargs) = async_run(queue.get(0))
assert action == "vm.stopped"
assert action == "node.stopped"
assert event == vm