From c4d7a0b8fc5a572f60bf53a787239d7d1cb94f6f Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 29 Jun 2016 14:16:29 +0200 Subject: [PATCH] A settings API Ref #589 --- gns3server/controller/__init__.py | 18 ++++++++++ .../handlers/api/controller/server_handler.py | 18 ++++++++++ tests/controller/test_controller.py | 10 +++++- .../handlers/api/controller/test_settings.py | 34 +++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 tests/handlers/api/controller/test_settings.py diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py index d520eb12..7dff2ed0 100644 --- a/gns3server/controller/__init__.py +++ b/gns3server/controller/__init__.py @@ -41,6 +41,8 @@ class Controller: self._projects = {} self._notification = Notification(self) self.symbols = Symbols() + # Store settings shared by the different GUI will be replace by dedicated API later + self._settings = {} if sys.platform.startswith("win"): config_path = os.path.join(os.path.expandvars("%APPDATA%"), "GNS3") @@ -70,6 +72,7 @@ class Controller: "password": c.password, "compute_id": c.id } for c in self._computes.values()], + "settings": self._settings, "version": __version__} os.makedirs(os.path.dirname(self._config_file), exist_ok=True) with open(self._config_file, 'w+') as f: @@ -89,6 +92,9 @@ class Controller: except OSError as e: log.critical("Cannot load %s: %s", self._config_file, str(e)) return + if "settings" in data: + self._settings = data["settings"] + for c in data["computes"]: yield from self.add_compute(**c) @@ -109,6 +115,18 @@ class Controller: except OSError as e: log.error(str(e)) + @property + def settings(self): + """ + Store settings shared by the different GUI will be replace by dedicated API later. Dictionnary + """ + return self._settings + + @settings.setter + def settings(self, val): + self._settings = val + self.notification.emit("settings.updated", val) + def is_enabled(self): """ :returns: whether the current instance is the controller diff --git a/gns3server/handlers/api/controller/server_handler.py b/gns3server/handlers/api/controller/server_handler.py index 298c3c9a..7b8909d2 100644 --- a/gns3server/handlers/api/controller/server_handler.py +++ b/gns3server/handlers/api/controller/server_handler.py @@ -93,3 +93,21 @@ class ServerHandler: if request.json["version"] != __version__: raise HTTPConflict(text="Client version {} differs with server version {}".format(request.json["version"], __version__)) response.json({"version": __version__}) + + @Route.get( + r"/settings", + description="Retrieve gui settings from the server. Temporary will we removed in later release") + def read_settings(request, response): + + response.json(Controller.instance().settings) + + @Route.post( + r"/settings", + description="Write gui settings on the server. Temporary will we removed in later releas", + status_codes={ + 201: "Writed" + }) + def write_settings(request, response): + Controller.instance().settings = request.json + response.json(Controller.instance().settings) + response.set_status(201) diff --git a/tests/controller/test_controller.py b/tests/controller/test_controller.py index 6010280f..08c1019f 100644 --- a/tests/controller/test_controller.py +++ b/tests/controller/test_controller.py @@ -37,6 +37,7 @@ def test_save(controller, controller_config_path): data = json.load(f) assert data["computes"] == [] assert data["version"] == __version__ + assert data["settings"] == {} def test_load(controller, controller_config_path, async_run): @@ -53,10 +54,12 @@ def test_load(controller, controller_config_path, async_run): "compute_id": "test1" } ] + data["settings"] = {"IOU": True} with open(controller_config_path, "w+") as f: json.dump(data, f) async_run(controller.load()) assert len(controller.computes) == 1 + assert controller.settings["IOU"] assert controller.computes["test1"].__json__() == { "compute_id": "test1", "connected": False, @@ -68,6 +71,12 @@ def test_load(controller, controller_config_path, async_run): } +def test_settings(controller): + controller._notification = MagicMock() + controller.settings = {"a": 1} + controller._notification.emit.assert_called_with("settings.updated", {"a": 1}) + + def test_load_projects(controller, projects_dir, async_run): controller.save() @@ -270,4 +279,3 @@ def test_load_project(controller, async_run, tmpdir): with asyncio_patch("gns3server.controller.Controller.add_project") as mock_add_project: project = async_run(controller.load_project(str(tmpdir / "test.gns3"))) assert not mock_add_project.called - diff --git a/tests/handlers/api/controller/test_settings.py b/tests/handlers/api/controller/test_settings.py new file mode 100644 index 00000000..9ac4e024 --- /dev/null +++ b/tests/handlers/api/controller/test_settings.py @@ -0,0 +1,34 @@ +# -*- 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 . + +""" +This test suite check /version endpoint +It's also used for unittest the HTTP implementation. +""" + +from gns3server.config import Config + + + +def test_settings(http_controller): + query = {"test": True} + response = http_controller.post('/settings', query, example=True) + assert response.status == 201 + response = http_controller.get('/settings', example=True) + assert response.status == 200 + assert response.json == query +