Implement #1153 into 2.2 branch.

This commit is contained in:
grossmj 2017-11-27 15:16:46 +07:00
parent 09b1cac676
commit 6e2752648a
2 changed files with 80 additions and 4 deletions

View File

@ -112,8 +112,9 @@ class Project:
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()):
assert self._status != "closed"
self.dump()
@asyncio.coroutine
@ -497,11 +498,37 @@ class Project:
except KeyError:
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
def nodes(self):
"""
:returns: Dictionary of the nodes
"""
if self._status == "closed":
return self._get_closed_data("nodes", "node_id")
return self._nodes
@property
@ -509,6 +536,8 @@ class Project:
"""
:returns: Dictionary of the drawings
"""
if self._status == "closed":
return self._get_closed_data("drawings", "drawing_id")
return self._drawings
@open_required
@ -591,6 +620,8 @@ class Project:
"""
:returns: Dictionary of the Links
"""
if self._status == "closed":
return self._get_closed_data("links", "link_id")
return self._links
@property
@ -649,6 +680,8 @@ class Project:
@asyncio.coroutine
def close(self, ignore_notification=False):
if self._status == "closed":
return
yield from self.stop_all()
for compute in list(self._project_created_on_compute):
try:
@ -660,6 +693,7 @@ class Project:
self._status = "closed"
if not ignore_notification:
self.controller.notification.emit("project.closed", self.__json__())
self.reset()
def _cleanPictures(self):
"""
@ -856,6 +890,7 @@ class Project:
yield from self.open()
self.dump()
assert self._status != "closed"
try:
with tempfile.TemporaryDirectory() as tmpdir:
zipstream = yield from export_project(self, tmpdir, keep_compute_id=True, allow_all_nodes=True)

View File

@ -302,6 +302,22 @@ def test_get_node(async_run, controller):
with pytest.raises(aiohttp.web.HTTPForbidden):
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):
compute = MagicMock()
@ -324,6 +340,20 @@ def test_add_link(async_run, project, controller):
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):
compute = MagicMock()
@ -370,6 +400,14 @@ def test_get_drawing(async_run, project):
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):
assert len(project._drawings) == 0
drawing = async_run(project.add_drawing())
@ -412,8 +450,9 @@ def test_dump():
def test_open_close(async_run, controller):
project = Project(controller=controller, status="closed", name="Test")
assert project.status == "closed"
project = Project(controller=controller, name="Test")
assert project.status == "opened"
async_run(project.close())
project.start_all = AsyncioMagicMock()
async_run(project.open())
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):
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()
async_run(project.open())
assert project.start_all.called