mirror of
https://github.com/GNS3/gns3-server.git
synced 2024-11-16 16:54:51 +02:00
Implement #1153 into 2.2 branch.
This commit is contained in:
parent
09b1cac676
commit
6e2752648a
@ -112,8 +112,9 @@ class Project:
|
|||||||
|
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
# At project creation we write an empty .gns3
|
# At project creation we write an empty .gns3 with the meta
|
||||||
if not os.path.exists(self._topology_file()):
|
if not os.path.exists(self._topology_file()):
|
||||||
|
assert self._status != "closed"
|
||||||
self.dump()
|
self.dump()
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
@ -497,11 +498,37 @@ class Project:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
raise aiohttp.web.HTTPNotFound(text="Node ID {} doesn't exist".format(node_id))
|
raise aiohttp.web.HTTPNotFound(text="Node ID {} doesn't exist".format(node_id))
|
||||||
|
|
||||||
|
def _get_closed_data(self, section, id_key):
|
||||||
|
"""
|
||||||
|
Get the data for a project from the .gns3 when
|
||||||
|
the project is close
|
||||||
|
|
||||||
|
:param section: The section name in the .gns3
|
||||||
|
:param id_key: The key for the element unique id
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
path = self._topology_file()
|
||||||
|
with open(path, "r") as f:
|
||||||
|
topology = json.load(f)
|
||||||
|
except OSError as e:
|
||||||
|
raise aiohttp.web.HTTPInternalServerError(text="Could not load topology: {}".format(e))
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = {}
|
||||||
|
for elem in topology["topology"][section]:
|
||||||
|
data[elem[id_key]] = elem
|
||||||
|
return data
|
||||||
|
except KeyError:
|
||||||
|
raise aiohttp.web.HTTPNotFound(text="Section {} not found in the topology".format(section))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def nodes(self):
|
def nodes(self):
|
||||||
"""
|
"""
|
||||||
:returns: Dictionary of the nodes
|
:returns: Dictionary of the nodes
|
||||||
"""
|
"""
|
||||||
|
if self._status == "closed":
|
||||||
|
return self._get_closed_data("nodes", "node_id")
|
||||||
return self._nodes
|
return self._nodes
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -509,6 +536,8 @@ class Project:
|
|||||||
"""
|
"""
|
||||||
:returns: Dictionary of the drawings
|
:returns: Dictionary of the drawings
|
||||||
"""
|
"""
|
||||||
|
if self._status == "closed":
|
||||||
|
return self._get_closed_data("drawings", "drawing_id")
|
||||||
return self._drawings
|
return self._drawings
|
||||||
|
|
||||||
@open_required
|
@open_required
|
||||||
@ -591,6 +620,8 @@ class Project:
|
|||||||
"""
|
"""
|
||||||
:returns: Dictionary of the Links
|
:returns: Dictionary of the Links
|
||||||
"""
|
"""
|
||||||
|
if self._status == "closed":
|
||||||
|
return self._get_closed_data("links", "link_id")
|
||||||
return self._links
|
return self._links
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -649,6 +680,8 @@ class Project:
|
|||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def close(self, ignore_notification=False):
|
def close(self, ignore_notification=False):
|
||||||
|
if self._status == "closed":
|
||||||
|
return
|
||||||
yield from self.stop_all()
|
yield from self.stop_all()
|
||||||
for compute in list(self._project_created_on_compute):
|
for compute in list(self._project_created_on_compute):
|
||||||
try:
|
try:
|
||||||
@ -660,6 +693,7 @@ class Project:
|
|||||||
self._status = "closed"
|
self._status = "closed"
|
||||||
if not ignore_notification:
|
if not ignore_notification:
|
||||||
self.controller.notification.emit("project.closed", self.__json__())
|
self.controller.notification.emit("project.closed", self.__json__())
|
||||||
|
self.reset()
|
||||||
|
|
||||||
def _cleanPictures(self):
|
def _cleanPictures(self):
|
||||||
"""
|
"""
|
||||||
@ -856,6 +890,7 @@ class Project:
|
|||||||
yield from self.open()
|
yield from self.open()
|
||||||
|
|
||||||
self.dump()
|
self.dump()
|
||||||
|
assert self._status != "closed"
|
||||||
try:
|
try:
|
||||||
with tempfile.TemporaryDirectory() as tmpdir:
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
zipstream = yield from export_project(self, tmpdir, keep_compute_id=True, allow_all_nodes=True)
|
zipstream = yield from export_project(self, tmpdir, keep_compute_id=True, allow_all_nodes=True)
|
||||||
|
@ -302,6 +302,22 @@ def test_get_node(async_run, controller):
|
|||||||
with pytest.raises(aiohttp.web.HTTPForbidden):
|
with pytest.raises(aiohttp.web.HTTPForbidden):
|
||||||
project.get_node(vm.id)
|
project.get_node(vm.id)
|
||||||
|
|
||||||
|
def test_list_nodes(async_run, controller):
|
||||||
|
compute = MagicMock()
|
||||||
|
project = Project(controller=controller, name="Test")
|
||||||
|
|
||||||
|
response = MagicMock()
|
||||||
|
response.json = {"console": 2048}
|
||||||
|
compute.post = AsyncioMagicMock(return_value=response)
|
||||||
|
|
||||||
|
vm = async_run(project.add_node(compute, "test", None, node_type="vpcs", properties={"startup_config": "test.cfg"}))
|
||||||
|
assert len(project.nodes) == 1
|
||||||
|
assert isinstance(project.nodes, dict)
|
||||||
|
|
||||||
|
async_run(project.close())
|
||||||
|
assert len(project.nodes) == 1
|
||||||
|
assert isinstance(project.nodes, dict)
|
||||||
|
|
||||||
|
|
||||||
def test_add_link(async_run, project, controller):
|
def test_add_link(async_run, project, controller):
|
||||||
compute = MagicMock()
|
compute = MagicMock()
|
||||||
@ -324,6 +340,20 @@ def test_add_link(async_run, project, controller):
|
|||||||
controller.notification.emit.assert_any_call("link.created", link.__json__())
|
controller.notification.emit.assert_any_call("link.created", link.__json__())
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_links(async_run, project):
|
||||||
|
compute = MagicMock()
|
||||||
|
|
||||||
|
response = MagicMock()
|
||||||
|
response.json = {"console": 2048}
|
||||||
|
compute.post = AsyncioMagicMock(return_value=response)
|
||||||
|
|
||||||
|
link = async_run(project.add_link())
|
||||||
|
assert len(project.links) == 1
|
||||||
|
|
||||||
|
async_run(project.close())
|
||||||
|
assert len(project.links) == 1
|
||||||
|
|
||||||
|
|
||||||
def test_get_link(async_run, project):
|
def test_get_link(async_run, project):
|
||||||
compute = MagicMock()
|
compute = MagicMock()
|
||||||
|
|
||||||
@ -370,6 +400,14 @@ def test_get_drawing(async_run, project):
|
|||||||
project.get_drawing("test")
|
project.get_drawing("test")
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_drawing(async_run, project):
|
||||||
|
drawing = async_run(project.add_drawing(None))
|
||||||
|
assert len(project.drawings) == 1
|
||||||
|
|
||||||
|
async_run(project.close())
|
||||||
|
assert len(project.drawings) == 1
|
||||||
|
|
||||||
|
|
||||||
def test_delete_drawing(async_run, project, controller):
|
def test_delete_drawing(async_run, project, controller):
|
||||||
assert len(project._drawings) == 0
|
assert len(project._drawings) == 0
|
||||||
drawing = async_run(project.add_drawing())
|
drawing = async_run(project.add_drawing())
|
||||||
@ -412,8 +450,9 @@ def test_dump():
|
|||||||
|
|
||||||
|
|
||||||
def test_open_close(async_run, controller):
|
def test_open_close(async_run, controller):
|
||||||
project = Project(controller=controller, status="closed", name="Test")
|
project = Project(controller=controller, name="Test")
|
||||||
assert project.status == "closed"
|
assert project.status == "opened"
|
||||||
|
async_run(project.close())
|
||||||
project.start_all = AsyncioMagicMock()
|
project.start_all = AsyncioMagicMock()
|
||||||
async_run(project.open())
|
async_run(project.open())
|
||||||
assert not project.start_all.called
|
assert not project.start_all.called
|
||||||
@ -425,7 +464,9 @@ def test_open_close(async_run, controller):
|
|||||||
|
|
||||||
|
|
||||||
def test_open_auto_start(async_run, controller):
|
def test_open_auto_start(async_run, controller):
|
||||||
project = Project(controller=controller, status="closed", name="Test", auto_start=True)
|
project = Project(controller=controller, name="Test")
|
||||||
|
assert project.status == "opened"
|
||||||
|
async_run(project.close())
|
||||||
project.start_all = AsyncioMagicMock()
|
project.start_all = AsyncioMagicMock()
|
||||||
async_run(project.open())
|
async_run(project.open())
|
||||||
assert project.start_all.called
|
assert project.start_all.called
|
||||||
|
Loading…
Reference in New Issue
Block a user