Commit 725852d4 authored by Daniele Venzano's avatar Daniele Venzano 🏇
Browse files

Merge branch 'devel/platform_status' into 'master'

Fix status page crash when service is in transient state being terminated

See merge request !54
parents f63d6d73 6333bac9
......@@ -160,7 +160,13 @@ class APIEndpoint:
"""Retrieve statistics about the scheduler."""
success, message = self.master.scheduler_statistics()
if success:
for node in message['platform_stats']['nodes']: # JSON does not like hash keys to be integers, so we need to convert manually
for str_service_id in list(node['service_stats'].keys()):
node['service_stats'][int(str_service_id)] = node['service_stats'][str_service_id]
del node['service_stats'][str_service_id]
return message
else:
raise zoe_api.exceptions.ZoeException(message=message)
def cleanup_dead_executions(self):
"""Terminates all executions with dead "monitor" services."""
......
......@@ -101,7 +101,7 @@ class APIManager:
}
return self._request_reply(msg)
def scheduler_statistics(self) -> APIReturnType:
def scheduler_statistics(self):
"""Query scheduler statistics."""
msg = {
'command': 'scheduler_stats'
......
......@@ -18,6 +18,7 @@
import pytest
from zoe_api.api_endpoint import APIEndpoint
from zoe_api.exceptions import ZoeException
from zoe_api.tests.mock_master_api import MockAPIManager
from zoe_lib.state.tests.mock_sql_manager import MockSQLManager
......@@ -40,5 +41,9 @@ class TestAPIEndpoint:
def test_statistics_scheduler(self, master_api, sql_manager):
"""Test the scheduler statistics API."""
api = APIEndpoint(master_api, sql_manager)
ret = api.statistics_scheduler('nouser', 'norole')
assert ret == 'No error message' or ret is None
if master_api.fails:
with pytest.raises(ZoeException):
api.statistics_scheduler('nouser', 'norole')
else:
ret = api.statistics_scheduler('nouser', 'norole')
assert isinstance(ret, dict)
......@@ -16,11 +16,11 @@
"""Mock master API for unit testing."""
import logging
from typing import Tuple
from typing import Tuple, Union
log = logging.getLogger(__name__)
APIReturnType = Tuple[bool, str]
APIReturnType = Tuple[bool, Union[str, dict]]
class MockAPIManager:
......@@ -55,4 +55,11 @@ class MockAPIManager:
def scheduler_statistics(self) -> APIReturnType:
"""Query scheduler statistics."""
return self._request_reply()
if self.fails:
return False, "Fake error message"
else:
return True, {
'platform_stats': {
'nodes': []
}
}
......@@ -222,7 +222,7 @@
<td class="cell-host">{{ node.name }}</td>
{% for service in services_per_node[node.name] %}
{% if service.backend_status == "started" %}
<td><a href="{{ reverse_url('execution_inspect', service['execution_id']) }}">{{ service['name'] }}</a> (M: <script>format_bytes({{ node.service_stats[service['id']|string]['mem_limit'] }});</script> C: {{ '%0.2f'|format(node.service_stats[service['id']|string]['core_limit']|float) }})</td>
<td><a href="{{ reverse_url('execution_inspect', service['execution_id']) }}">{{ service['name'] }}</a> (M: <script>format_bytes({{ node.service_stats[service['id']]['mem_limit'] }});</script> C: {{ '%0.2f'|format(node.service_stats[service['id']]['core_limit']|float) }})</td>
{% endif %}
{% endfor %}
</tr>
......
......@@ -226,7 +226,6 @@ class Service(BaseRecord):
def assign_backend_host(self, backend_host):
"""Assign this service to a host in particular."""
self.sql_manager.services.update(self.id, backend_host=backend_host)
log.debug('service {} assigned to host {}'.format(self.id, backend_host))
self.backend_host = backend_host
@property
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment