From ddb3c4e26f3a908de7836a8fac48360afa6aa1d7 Mon Sep 17 00:00:00 2001 From: Surojit Pathak Date: Wed, 25 Nov 2015 19:21:24 +0000 Subject: [PATCH] Fix wrong CPU metric value in metrics_filter CPU metrics are reported as a normalized value in [0,1]. When scheduler reads the data as MonitorMetric object, as part of update_from_compute_node(), the value of the metric gets lost due to a wrong type conversion, typecasting into an Integer, reduces it to 0. Note: - It may seem unintuitive that to fix the same, we are not changing the type of metric from Integer to Float. Please refer the discussions - * https://review.openstack.org/#/c/243825/ * https://review.openstack.org/#/c/216923/ - To summarize, we are trying to save some 'possible' downstream consumer of metrics updates from compute nodes, i.e. consuming from AMPQ, from software upgrade scenarios. Change-Id: Ib504af33e05dfc4d7e97b52682e27befc67d784a Closes-bug: #1514997 --- nova/objects/monitor_metric.py | 14 ++++++++++++-- nova/tests/unit/objects/test_monitor_metric.py | 12 ++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/nova/objects/monitor_metric.py b/nova/objects/monitor_metric.py index 6d43e516b8b..18b2ca94138 100644 --- a/nova/objects/monitor_metric.py +++ b/nova/objects/monitor_metric.py @@ -93,8 +93,18 @@ def from_json(cls, metrics): :returns: a MonitorMetricList Object. """ metrics = jsonutils.loads(metrics) if metrics else [] - metric_list = [ - MonitorMetric(**metric) for metric in metrics] + + # NOTE(suro-patz): While instantiating the MonitorMetric() from + # JSON-ified string, we need to re-convert the + # normalized metrics to avoid truncation to 0 by + # typecasting into an integer. + metric_list = [] + for metric in metrics: + if ('value' in metric and metric['name'] in + FIELDS_REQUIRING_CONVERSION): + metric['value'] = metric['value'] * 100 + metric_list.append(MonitorMetric(**metric)) + return MonitorMetricList(objects=metric_list) # NOTE(jaypipes): This method exists to convert the object to the diff --git a/nova/tests/unit/objects/test_monitor_metric.py b/nova/tests/unit/objects/test_monitor_metric.py index 34c3368ce85..858d98b7559 100644 --- a/nova/tests/unit/objects/test_monitor_metric.py +++ b/nova/tests/unit/objects/test_monitor_metric.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo_serialization import jsonutils from oslo_utils import timeutils from nova import objects @@ -73,6 +74,17 @@ def test_monitor_NUMA_metric_to_dict(self): source='nova.virt.libvirt.driver') self.assertEqual(_monitor_numa_metric_spec, obj.to_dict()) + def test_conversion_in_monitor_metric_list_from_json(self): + spec_list = [_monitor_metric_spec, _monitor_metric_perc_spec] + metrics = objects.MonitorMetricList.from_json( + jsonutils.dumps(spec_list)) + for metric, spec in zip(metrics, spec_list): + exp = spec['value'] + if (spec['name'] in + objects.monitor_metric.FIELDS_REQUIRING_CONVERSION): + exp = spec['value'] * 100 + self.assertEqual(exp, metric.value) + class TestMonitorMetricObject(test_objects._LocalTest, _TestMonitorMetricObject):