From 3f5c2390cd7ecc6daa6647f78382012350d7e28a Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Fri, 23 Jan 2015 14:07:10 +0100 Subject: [PATCH] Close a project --- gns3server/handlers/project_handler.py | 18 +++++++++++++++++ gns3server/modules/base_vm.py | 1 + gns3server/modules/project.py | 19 ++++++++++++++++- tests/api/test_project.py | 28 +++++++++++++++++++------- tests/modules/test_project.py | 18 +++++++++++++++++ 5 files changed, 76 insertions(+), 8 deletions(-) diff --git a/gns3server/handlers/project_handler.py b/gns3server/handlers/project_handler.py index 74c150f1..e6fdbc59 100644 --- a/gns3server/handlers/project_handler.py +++ b/gns3server/handlers/project_handler.py @@ -56,6 +56,24 @@ class ProjectHandler: project.commit() response.set_status(204) + @classmethod + @Route.post( + r"/project/{uuid}/close", + description="Close project", + parameters={ + "uuid": "Project instance UUID", + }, + status_codes={ + 204: "Project closed", + 404: "Project instance doesn't exist" + }) + def close(request, response): + + pm = ProjectManager.instance() + project = pm.get_project(request.match_info["uuid"]) + project.close() + response.set_status(204) + @classmethod @Route.delete( r"/project/{uuid}", diff --git a/gns3server/modules/base_vm.py b/gns3server/modules/base_vm.py index 52c003b2..42deb98f 100644 --- a/gns3server/modules/base_vm.py +++ b/gns3server/modules/base_vm.py @@ -27,6 +27,7 @@ class BaseVM: self._uuid = uuid self._project = project self._manager = manager + project.add_vm(self) log.debug("{module}: {name} [{uuid}] initialized".format(module=self.manager.module_name, name=self.name, diff --git a/gns3server/modules/project.py b/gns3server/modules/project.py index adbb4eba..a3e0319f 100644 --- a/gns3server/modules/project.py +++ b/gns3server/modules/project.py @@ -46,6 +46,7 @@ class Project: if location is None: self._location = tempfile.mkdtemp() + self._vms = set() self._vms_to_destroy = set() self._path = os.path.join(self._location, self._uuid) try: @@ -68,6 +69,11 @@ class Project: return self._path + @property + def vms(self): + + return self._vms + def vm_working_directory(self, vm): """ Return a working directory for a specific VM. @@ -98,10 +104,21 @@ class Project: "location": self._location } + def add_vm(self, vm): + """ + Add a VM to the project. In theory this should be called by + the VM initializer. + + :params vm: A VM instance + """ + + self._vms.add(vm) + def close(self): """Close the project, but keep informations on disk""" - pass + for vm in self._vms: + vm.close() def commit(self): """Write project changes on disk""" diff --git a/tests/api/test_project.py b/tests/api/test_project.py index 87b8cdfb..e343b735 100644 --- a/tests/api/test_project.py +++ b/tests/api/test_project.py @@ -20,6 +20,7 @@ This test suite check /project endpoint """ import uuid +from tests.utils import asyncio_patch def test_create_project_with_dir(server, tmpdir): @@ -51,8 +52,10 @@ def test_create_project_with_uuid(server): def test_commit_project(server, project): - response = server.post("/project/{uuid}/commit".format(uuid=project.uuid), example=True) + with asyncio_patch("gns3server.modules.project.Project.commit", return_value=True) as mock: + response = server.post("/project/{uuid}/commit".format(uuid=project.uuid), example=True) assert response.status == 204 + assert mock.called def test_commit_project_invalid_project_uuid(server, project): @@ -60,14 +63,25 @@ def test_commit_project_invalid_project_uuid(server, project): assert response.status == 404 -def test_delete_project(server): - query = {"uuid": "00010203-0405-0607-0809-0a0b0c0d0e0f"} - response = server.post("/project", query) - assert response.status == 200 - response = server.delete("/project/00010203-0405-0607-0809-0a0b0c0d0e0f") - assert response.status == 204 +def test_delete_project(server, project): + with asyncio_patch("gns3server.modules.project.Project.delete", return_value=True) as mock: + response = server.delete("/project/{uuid}".format(uuid=project.uuid), example=True) + assert response.status == 204 + assert mock.called def test_delete_project_invalid_uuid(server, project): response = server.delete("/project/{uuid}".format(uuid=uuid.uuid4())) assert response.status == 404 + + +def test_close_project(server, project): + with asyncio_patch("gns3server.modules.project.Project.close", return_value=True) as mock: + response = server.post("/project/{uuid}/close".format(uuid=project.uuid), example=True) + assert response.status == 204 + assert mock.called + + +def test_close_project_invalid_uuid(server, project): + response = server.post("/project/{uuid}/close".format(uuid=uuid.uuid4())) + assert response.status == 404 diff --git a/tests/modules/test_project.py b/tests/modules/test_project.py index d6aa2509..2956adaf 100644 --- a/tests/modules/test_project.py +++ b/tests/modules/test_project.py @@ -18,6 +18,8 @@ import os import pytest +from unittest.mock import patch + from gns3server.modules.project import Project from gns3server.modules.vpcs import VPCS, VPCSVM @@ -89,3 +91,19 @@ def test_project_delete(tmpdir): assert os.path.exists(directory) project.delete() assert os.path.exists(directory) is False + + +def test_project_add_vm(tmpdir, manager): + project = Project(location=str(tmpdir)) + # The VM initalizer call the add_vm method + vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager) + assert len(project.vms) == 1 + + +def test_project_close(tmpdir, manager): + project = Project(location=str(tmpdir)) + vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager) + project.add_vm(vm) + with patch("gns3server.modules.vpcs.vpcs_vm.VPCSVM.close") as mock: + project.close() + assert mock.called