From 543b423e03da0b036ecce024ded43b1b8d01c59d Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Thu, 30 Jun 2016 09:45:11 +0200 Subject: [PATCH] Send compute usage via in the compute.updated notification Ref https://github.com/GNS3/gns3-gui/issues/1261 --- gns3server/controller/compute.py | 22 ++++++++++- gns3server/schemas/compute.py | 12 ++++++ tests/controller/test_compute.py | 39 +++++++++++++++++++ tests/controller/test_controller.py | 4 +- tests/handlers/api/controller/test_compute.py | 5 ++- 5 files changed, 77 insertions(+), 5 deletions(-) diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py index 94960b41..bd80c26d 100644 --- a/gns3server/controller/compute.py +++ b/gns3server/controller/compute.py @@ -89,6 +89,8 @@ class Compute: self._set_auth(user, password) self._session = aiohttp.ClientSession() self._version = None + self._cpu_usage_percent = None + self._memory_usage_percent = None self.name = name # Websocket for notifications self._ws = None @@ -228,6 +230,14 @@ class Compute: def password(self, value): self._set_auth(self._user, value) + @property + def cpu_usage_percent(self): + return self._cpu_usage_percent + + @property + def memory_usage_percent(self): + return self._memory_usage_percent + def __json__(self, topology_dump=False): """ :param topology_dump: Filter to keep only properties require for saving on disk @@ -247,7 +257,9 @@ class Compute: "host": self._host, "port": self._port, "user": self._user, - "connected": self._connected + "connected": self._connected, + "cpu_usage_percent": self._cpu_usage_percent, + "memory_usage_percent": self._memory_usage_percent } @asyncio.coroutine @@ -307,7 +319,13 @@ class Compute: msg = json.loads(response.data) action = msg.pop("action") event = msg.pop("event") - self._controller.notification.dispatch(action, event, compute_id=self.id) + + if action == "ping": + self._cpu_usage_percent = event["cpu_usage_percent"] + self._memory_usage_percent = event["memory_usage_percent"] + self._controller.notification.emit("compute.updated", self.__json__()) + else: + self._controller.notification.dispatch(action, event, compute_id=self.id) yield from self._ws.close() self._ws = None diff --git a/gns3server/schemas/compute.py b/gns3server/schemas/compute.py index 8eb45e37..cbb4bb62 100644 --- a/gns3server/schemas/compute.py +++ b/gns3server/schemas/compute.py @@ -90,6 +90,18 @@ COMPUTE_OBJECT_SCHEMA = { "description": "Whether the controller is connected to the compute server or not", "type": "boolean" }, + "cpu_usage_percent": { + "description": "CPU usage of the compute. Read only", + "type": ["number", "null"], + "maximum": 100, + "minimum": 0 + }, + "memory_usage_percent": { + "description": "RAM usage of the compute. Read only", + "type": ["number", "null"], + "maximum": 100, + "minimum": 0 + }, "version": { "description": "Version of the GNS3 remote compute server", "type": ["string", "null"] diff --git a/tests/controller/test_compute.py b/tests/controller/test_compute.py index 3ea75e44..3034bddd 100644 --- a/tests/controller/test_compute.py +++ b/tests/controller/test_compute.py @@ -194,6 +194,43 @@ def test_connectNotification(compute, async_run): assert compute._connected is False +def test_connectNotificationPing(compute, async_run): + """ + When we receive a ping from a compute we update + the compute memory and CPU usage + """ + ws_mock = AsyncioMagicMock() + + call = 0 + + @asyncio.coroutine + def receive(): + nonlocal call + call += 1 + if call == 1: + response = MagicMock() + response.data = '{"action": "ping", "event": {"cpu_usage_percent": 35.7, "memory_usage_percent": 80.7}}' + response.tp = aiohttp.MsgType.text + return response + else: + response = MagicMock() + response.tp = aiohttp.MsgType.closed + return response + + compute._controller._notification = MagicMock() + compute._session = AsyncioMagicMock(return_value=ws_mock) + compute._session.ws_connect = AsyncioMagicMock(return_value=ws_mock) + ws_mock.receive = receive + async_run(compute._connect_notification()) + + assert not compute._controller.notification.dispatch.called + assert compute.cpu_usage_percent == 35.7 + assert compute.memory_usage_percent == 80.7 + args, _ = compute._controller.notification.emit.call_args + assert args[0] == "compute.updated" + assert args[1]["memory_usage_percent"] == 80.7 + + def test_json(compute): compute.user = "test" assert compute.__json__() == { @@ -203,6 +240,8 @@ def test_json(compute): "host": "example.com", "port": 84, "user": "test", + "cpu_usage_percent": None, + "memory_usage_percent": None, "connected": True } assert compute.__json__(topology_dump=True) == { diff --git a/tests/controller/test_controller.py b/tests/controller/test_controller.py index 1ff5a63e..2c194d26 100644 --- a/tests/controller/test_controller.py +++ b/tests/controller/test_controller.py @@ -67,7 +67,9 @@ def test_load(controller, controller_config_path, async_run): "port": 8000, "protocol": "http", "user": "admin", - "name": "http://admin@localhost:8000" + "name": "http://admin@localhost:8000", + "cpu_usage_percent": None, + "memory_usage_percent": None } diff --git a/tests/handlers/api/controller/test_compute.py b/tests/handlers/api/controller/test_compute.py index 064fb339..e43f79d7 100644 --- a/tests/handlers/api/controller/test_compute.py +++ b/tests/handlers/api/controller/test_compute.py @@ -127,8 +127,9 @@ def test_compute_list(http_controller, controller): 'port': 84, 'protocol': 'http', 'user': 'julien', - 'name': 'My super server' - + 'name': 'My super server', + 'cpu_usage_percent': None, + 'memory_usage_percent': None } ]