summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Pipes <jaypipes@gmail.com>2015-06-24 17:26:28 -0400
committerJay Pipes <jaypipes@gmail.com>2015-07-06 09:47:27 -0400
commitc41db608fe3cd75c5925bb7693261ac8379737f0 (patch)
treebc6b574a2352e4a05cfa39504e00e2fdf3da03f9
parent28258a18e97cd22c63b1e2e351af4522021c3870 (diff)
downloadnova-c41db608fe3cd75c5925bb7693261ac8379737f0.tar.gz
Rework monitor plugin interface and API
In order to prepare for the stevedore-ization of the compute monitor plugins, and to clean up the overly complex monitor API, this patch breaks out the base monitor plugin into a much simpler class that has the following methods: - get_metric_names(), which remains unchanged in its purpose from the original ResourceMonitorBase class - get_metric(name), which returns a (value, timestamp) tuple for a supplied metric name - add_metrics_to_list() which is a non-overrideable method on the base plugin class that adds a set of metrics to a nova.objects.MonitorMetricList object supplied as the parameter There is a base class called nova.compute.monitors.base.CPUMonitorBase that simply returns the appropriate CPU monitor metric name constants for the get_metric_names() method. The directory structure of the monitor plugins and the module naming for the lone in-tree is changed to better represent what the directories and files contain. The lone in-tree plugin is a monitor that inherits from nova.compute.monitors.base.CPUMonitorBase and uses the call to the hypervisor's get_host_cpu_stats() to grab CPU-centric metrics on a periodic basis. Change-Id: I3f2e8eca6ce43b07b3c8b430b8576be4f0d3f909 Partial-bug: 1468012
-rw-r--r--nova/compute/monitors/__init__.py108
-rw-r--r--nova/compute/monitors/base.py82
-rw-r--r--nova/compute/monitors/cpu/__init__.py0
-rw-r--r--nova/compute/monitors/cpu/virt_driver.py (renamed from nova/compute/monitors/virt/cpu_monitor.py)67
-rw-r--r--nova/compute/monitors/cpu_monitor.py64
-rw-r--r--nova/compute/monitors/virt/__init__.py18
-rw-r--r--nova/compute/resource_tracker.py9
-rw-r--r--nova/tests/unit/compute/monitors/test_cpu_monitor.py16
-rw-r--r--nova/tests/unit/compute/monitors/test_monitors.py118
-rw-r--r--nova/tests/unit/compute/test_resource_tracker.py60
10 files changed, 163 insertions, 379 deletions
diff --git a/nova/compute/monitors/__init__.py b/nova/compute/monitors/__init__.py
index e8c8cea962..405a13ef9e 100644
--- a/nova/compute/monitors/__init__.py
+++ b/nova/compute/monitors/__init__.py
@@ -15,19 +15,12 @@
"""
Resource monitor API specification.
-
-ResourceMonitorBase provides the definition of minimum set of methods
-that needs to be implemented by Resource Monitor.
"""
-import functools
-import types
-
from oslo_config import cfg
from oslo_log import log as logging
-from oslo_utils import timeutils
-import six
+import nova.compute.monitors.base
from nova.i18n import _LW
from nova import loadables
@@ -47,104 +40,13 @@ CONF.register_opts(compute_monitors_opts)
LOG = logging.getLogger(__name__)
-class ResourceMonitorMeta(type):
- def __init__(cls, names, bases, dict_):
- """Metaclass that allows us to create a function map and call it later
- to get the metric names and their values.
- """
- super(ResourceMonitorMeta, cls).__init__(names, bases, dict_)
-
- prefix = '_get_'
- prefix_len = len(prefix)
- cls.metric_map = {}
- for name, value in six.iteritems(cls.__dict__):
- if (len(name) > prefix_len
- and name[:prefix_len] == prefix
- and isinstance(value, types.FunctionType)):
- metric_name = name[prefix_len:].replace('_', '.')
- cls.metric_map[metric_name] = value
-
-
-@six.add_metaclass(ResourceMonitorMeta)
-class ResourceMonitorBase(object):
- """Base class for resource monitors
- """
-
- def __init__(self, parent):
- self.compute_manager = parent
- self.source = None
- self._data = {}
-
- @classmethod
- def add_timestamp(cls, func):
- """Decorator to indicate that a method needs to add a timestamp.
-
- When a function returning a value is decorated by the decorator,
- which means a timestamp should be added into the returned value.
- That is, a tuple (value, timestamp) is returned.
-
- The timestamp is the time when we update the value in the _data.
-
- If users hope to define how the timestamp is got by themselves,
- they should not use this decorator in their own classes.
- """
- @functools.wraps(func)
- def wrapper(self, **kwargs):
- return func(self, **kwargs), self._data.get("timestamp", None)
- return wrapper
-
- def _update_data(self):
- """Method to update the metrics data.
-
- Each subclass can implement this method to update metrics
- into _data. It will be called in get_metrics.
- """
- pass
-
- def get_metric_names(self):
- """Get available metric names.
-
- Get available metric names, which are represented by a set of keys
- that can be used to check conflicts and duplications
- :returns: a set of keys representing metrics names
- """
- return self.metric_map.keys()
-
- def get_metrics(self, **kwargs):
- """Get metrics.
-
- Get metrics, which are represented by a list of dictionaries
- [{'name': metric name,
- 'value': metric value,
- 'timestamp': the time when the value is retrieved,
- 'source': what the value is got by}, ...]
- :param kwargs: extra arguments that might be present
- :returns: a list to tell the current metrics
- """
- data = []
- self._update_data()
- for name, func in six.iteritems(self.metric_map):
- ret = func(self, **kwargs)
- data.append(self._populate(name, ret[0], ret[1]))
- return data
-
- def _populate(self, metric_name, metric_value, timestamp=None):
- """Populate the format what we want from metric name and metric value
- """
- result = {}
- result['name'] = metric_name
- result['value'] = metric_value
- result['timestamp'] = timestamp or timeutils.utcnow()
- result['source'] = self.source
-
- return result
-
-
+# TODO(jaypipes): Replace the use of loadables with stevedore.
class ResourceMonitorHandler(loadables.BaseLoader):
"""Base class to handle loading monitor classes.
"""
def __init__(self):
- super(ResourceMonitorHandler, self).__init__(ResourceMonitorBase)
+ super(ResourceMonitorHandler, self).__init__(
+ nova.compute.monitors.base.MonitorBase)
def choose_monitors(self, manager):
"""This function checks the monitor names and metrics names against a
@@ -166,7 +68,7 @@ class ResourceMonitorHandler(loadables.BaseLoader):
# make sure different monitors do not have the same
# metric name
monitor = monitor_class_map[monitor_name](manager)
- metric_names_tmp = set(monitor.get_metric_names())
+ metric_names_tmp = monitor.get_metric_names()
overlap = metric_names & metric_names_tmp
if not overlap:
metric_names = metric_names | metric_names_tmp
diff --git a/nova/compute/monitors/base.py b/nova/compute/monitors/base.py
new file mode 100644
index 0000000000..b0eced3b0d
--- /dev/null
+++ b/nova/compute/monitors/base.py
@@ -0,0 +1,82 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import abc
+
+import six
+
+from nova import objects
+from nova.objects import fields
+
+
+@six.add_metaclass(abc.ABCMeta)
+class MonitorBase(object):
+ """Base class for all resource monitor plugins."""
+
+ def __init__(self, compute_manager):
+ self.compute_manager = compute_manager
+ self.source = None
+
+ @abc.abstractmethod
+ def get_metric(self, name):
+ """Return a (value, timestamp) tuple for the supplied metric name.
+
+ :param name: The name/key for the metric to grab the value for.
+ """
+ raise NotImplementedError('get_metric')
+
+ @abc.abstractmethod
+ def get_metric_names(self):
+ """Get available metric names.
+
+ Get available metric names, which are represented by a set of keys
+ that can be used to check conflicts and duplications
+ :returns: set containing one or more values from
+ nova.objects.fields.MonitorMetricType.ALL constants
+ """
+ raise NotImplementedError('get_metric_names')
+
+ def add_metrics_to_list(self, metrics_list):
+ """Adds metric objects to a supplied list object.
+
+ :param metric_list: nova.objects.MonitorMetricList that the monitor
+ plugin should append nova.objects.MonitorMetric
+ objects to.
+ """
+ metric_names = self.get_metric_names()
+ metrics = []
+ for name in metric_names:
+ value, timestamp = self.get_metric(name)
+ metric = objects.MonitorMetric(name=name,
+ value=value,
+ timestamp=timestamp,
+ source=self.source)
+ metrics.append(metric)
+ metrics_list.objects.extend(metrics)
+
+
+class CPUMonitorBase(MonitorBase):
+ """Base class for all monitors that return CPU-related metrics."""
+
+ def get_metric_names(self):
+ return set([
+ fields.MonitorMetricType.CPU_FREQUENCY,
+ fields.MonitorMetricType.CPU_USER_TIME,
+ fields.MonitorMetricType.CPU_KERNEL_TIME,
+ fields.MonitorMetricType.CPU_IDLE_TIME,
+ fields.MonitorMetricType.CPU_IOWAIT_TIME,
+ fields.MonitorMetricType.CPU_USER_PERCENT,
+ fields.MonitorMetricType.CPU_KERNEL_PERCENT,
+ fields.MonitorMetricType.CPU_IDLE_PERCENT,
+ fields.MonitorMetricType.CPU_IOWAIT_PERCENT,
+ fields.MonitorMetricType.CPU_PERCENT,
+ ])
diff --git a/nova/compute/monitors/cpu/__init__.py b/nova/compute/monitors/cpu/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/nova/compute/monitors/cpu/__init__.py
diff --git a/nova/compute/monitors/virt/cpu_monitor.py b/nova/compute/monitors/cpu/virt_driver.py
index 5aa6a3e232..7d5b04cfa9 100644
--- a/nova/compute/monitors/virt/cpu_monitor.py
+++ b/nova/compute/monitors/cpu/virt_driver.py
@@ -14,15 +14,14 @@
# under the License.
"""
-CPU monitor based on compute driver to retrieve CPU information
+CPU monitor based on virt driver to retrieve CPU information
"""
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import timeutils
-from nova.compute import monitors
-from nova.compute.monitors import cpu_monitor as monitor
+from nova.compute.monitors import base
from nova import exception
from nova.i18n import _LE
@@ -31,65 +30,21 @@ CONF.import_opt('compute_driver', 'nova.virt.driver')
LOG = logging.getLogger(__name__)
-class ComputeDriverCPUMonitor(monitor._CPUMonitorBase):
- """CPU monitor based on compute driver
+class Monitor(base.CPUMonitorBase):
+ """CPU monitor that uses the virt driver's get_host_cpu_stats() call."""
- The class inherits from the base class for resource monitors,
- and implements the essential methods to get metric names and their real
- values for CPU utilization.
-
- The compute manager could load the monitors to retrieve the metrics
- of the devices on compute nodes and know their resource information
- periodically.
- """
-
- def __init__(self, parent):
- super(ComputeDriverCPUMonitor, self).__init__(parent)
+ def __init__(self, compute_manager):
+ super(Monitor, self).__init__(compute_manager)
self.source = CONF.compute_driver
self.driver = self.compute_manager.driver
+ self._data = {}
self._cpu_stats = {}
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_cpu_frequency(self, **kwargs):
- return self._data.get("cpu.frequency")
-
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_cpu_user_time(self, **kwargs):
- return self._data.get("cpu.user.time")
-
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_cpu_kernel_time(self, **kwargs):
- return self._data.get("cpu.kernel.time")
-
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_cpu_idle_time(self, **kwargs):
- return self._data.get("cpu.idle.time")
-
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_cpu_iowait_time(self, **kwargs):
- return self._data.get("cpu.iowait.time")
-
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_cpu_user_percent(self, **kwargs):
- return self._data.get("cpu.user.percent")
-
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_cpu_kernel_percent(self, **kwargs):
- return self._data.get("cpu.kernel.percent")
-
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_cpu_idle_percent(self, **kwargs):
- return self._data.get("cpu.idle.percent")
-
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_cpu_iowait_percent(self, **kwargs):
- return self._data.get("cpu.iowait.percent")
-
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_cpu_percent(self, **kwargs):
- return self._data.get("cpu.percent")
+ def get_metric(self, name):
+ self._update_data()
+ return self._data[name], self._data["timestamp"]
- def _update_data(self, **kwargs):
+ def _update_data(self):
# Don't allow to call this function so frequently (<= 1 sec)
now = timeutils.utcnow()
if self._data.get("timestamp") is not None:
diff --git a/nova/compute/monitors/cpu_monitor.py b/nova/compute/monitors/cpu_monitor.py
deleted file mode 100644
index a4d563f1e4..0000000000
--- a/nova/compute/monitors/cpu_monitor.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2013 Intel Corporation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-CPU monitor to retrieve CPU information
-"""
-
-from nova.compute import monitors
-
-
-class _CPUMonitorBase(monitors.ResourceMonitorBase):
- """CPU monitor base."""
-
- def _get_cpu_frequency(self, **kwargs):
- """Return CPU current frequency and its timestamp."""
- return None, None
-
- def _get_cpu_user_time(self, **kwargs):
- """Return CPU user mode time and its timestamp."""
- return None, None
-
- def _get_cpu_kernel_time(self, **kwargs):
- """Return CPU kernel time and its timestamp."""
- return None, None
-
- def _get_cpu_idle_time(self, **kwargs):
- """Return CPU idle time and its timestamp."""
- return None, None
-
- def _get_cpu_iowait_time(self, **kwargs):
- """Return CPU I/O wait time and its timestamp."""
- return None, None
-
- def _get_cpu_user_percent(self, **kwargs):
- """Return CPU user mode percentage and its timestamp."""
- return None, None
-
- def _get_cpu_kernel_percent(self, **kwargs):
- """Return CPU kernel percentage and its timestamp."""
- return None, None
-
- def _get_cpu_idle_percent(self, **kwargs):
- """Return CPU idle percentage and its timestamp."""
- return None, None
-
- def _get_cpu_iowait_percent(self, **kwargs):
- """Return CPU I/O wait percentage and its timestamp."""
- return None, None
-
- def _get_cpu_percent(self, **kwargs):
- """Return generic CPU utilization and its timestamp."""
- return None, None
diff --git a/nova/compute/monitors/virt/__init__.py b/nova/compute/monitors/virt/__init__.py
deleted file mode 100644
index 45abc1b839..0000000000
--- a/nova/compute/monitors/virt/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2013 Intel Corporation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from nova.compute.monitors.virt import cpu_monitor
-
-ComputeDriverCPUMonitor = cpu_monitor.ComputeDriverCPUMonitor
diff --git a/nova/compute/resource_tracker.py b/nova/compute/resource_tracker.py
index 3a1adaf2e2..7c35a52cf0 100644
--- a/nova/compute/resource_tracker.py
+++ b/nova/compute/resource_tracker.py
@@ -348,14 +348,17 @@ class ResourceTracker(object):
"""Get the metrics from monitors and
notify information to message bus.
"""
- metrics = []
+ metrics = objects.MonitorMetricList()
metrics_info = {}
for monitor in self.monitors:
try:
- metrics += monitor.get_metrics(nodename=nodename)
+ monitor.add_metrics_to_list(metrics)
except Exception:
LOG.warning(_LW("Cannot get the metrics from %s."), monitor)
- if metrics:
+ # TODO(jaypipes): Remove this when compute_node.metrics doesn't need
+ # to be populated as a JSON-ified string.
+ metrics = metrics.to_list()
+ if len(metrics):
metrics_info['nodename'] = nodename
metrics_info['metrics'] = metrics
metrics_info['host'] = self.host
diff --git a/nova/tests/unit/compute/monitors/test_cpu_monitor.py b/nova/tests/unit/compute/monitors/test_cpu_monitor.py
index b2f399ab15..710afef95d 100644
--- a/nova/tests/unit/compute/monitors/test_cpu_monitor.py
+++ b/nova/tests/unit/compute/monitors/test_cpu_monitor.py
@@ -15,7 +15,8 @@
"""Tests for Compute Driver CPU resource monitor."""
-from nova.compute.monitors import virt
+from nova.compute.monitors.cpu import virt_driver
+from nova import objects
from nova import test
@@ -34,7 +35,7 @@ class ComputeDriverCPUMonitorTestCase(test.NoDBTestCase):
class FakeComputeManager(object):
driver = FakeDriver()
- self.monitor = virt.ComputeDriverCPUMonitor(FakeComputeManager())
+ self.monitor = virt_driver.Monitor(FakeComputeManager())
def test_get_metric_names(self):
names = self.monitor.get_metric_names()
@@ -51,13 +52,14 @@ class ComputeDriverCPUMonitorTestCase(test.NoDBTestCase):
self.assertIn("cpu.percent", names)
def test_get_metrics(self):
- metrics_raw = self.monitor.get_metrics()
+ metrics = objects.MonitorMetricList()
+ self.monitor.add_metrics_to_list(metrics)
names = self.monitor.get_metric_names()
- metrics = {}
- for metric in metrics_raw:
- self.assertIn(metric['name'], names)
- metrics[metric['name']] = metric['value']
+ for metric in metrics.objects:
+ self.assertIn(metric.name, names)
+ # Some conversion to a dict to ease testing...
+ metrics = {m.name: m.value for m in metrics.objects}
self.assertEqual(metrics["cpu.frequency"], 800)
self.assertEqual(metrics["cpu.user.time"], 26728850000000)
self.assertEqual(metrics["cpu.kernel.time"], 5664160000000)
diff --git a/nova/tests/unit/compute/monitors/test_monitors.py b/nova/tests/unit/compute/monitors/test_monitors.py
index 3f6b3bdcea..9c7bbe3367 100644
--- a/nova/tests/unit/compute/monitors/test_monitors.py
+++ b/nova/tests/unit/compute/monitors/test_monitors.py
@@ -15,91 +15,42 @@
"""Tests for resource monitors."""
+from oslo_utils import timeutils
+
from nova.compute import monitors
+from nova.compute.monitors import base
+from nova.objects import fields
from nova import test
-class FakeResourceMonitor(monitors.ResourceMonitorBase):
- def _update_data(self):
- self._data['foo.metric1'] = '1000'
- self._data['foo.metric2'] = '99.999'
- self._data['timestamp'] = '123'
-
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_foo_metric1(self, **kwargs):
- return self._data.get("foo.metric1")
-
- @monitors.ResourceMonitorBase.add_timestamp
- def _get_foo_metric2(self, **kwargs):
- return self._data.get("foo.metric2")
+class CPUMonitor1(base.MonitorBase):
+ NOW_TS = timeutils.utcnow()
-class FakeMonitorClass1(monitors.ResourceMonitorBase):
- def get_metrics(self, **kwargs):
- data = [{'timestamp': 1232,
- 'name': 'key1',
- 'value': 2600,
- 'source': 'libvirt'}]
- return data
+ def __init__(self, *args):
+ super(CPUMonitor1, self).__init__(*args)
+ self.source = 'CPUMonitor1'
def get_metric_names(self):
- return ['key1']
+ return set([
+ fields.MonitorMetricType.CPU_FREQUENCY
+ ])
-
-class FakeMonitorClass2(monitors.ResourceMonitorBase):
- def get_metrics(self, **kwargs):
- data = [{'timestamp': 123,
- 'name': 'key2',
- 'value': 1600,
- 'source': 'libvirt'}]
- return data
-
- def get_metric_names(self):
- return ['key2']
+ def get_metric(self, name):
+ return 100, CPUMonitor1.NOW_TS
-class FakeMonitorClass3(monitors.ResourceMonitorBase):
- def get_metrics(self, **kwargs):
- data = [{'timestamp': 1234,
- 'name': 'key1',
- 'value': 1200,
- 'source': 'libvirt'}]
- return data
+class CPUMonitor2(base.MonitorBase):
def get_metric_names(self):
- return ['key1']
+ return set([
+ fields.MonitorMetricType.CPU_FREQUENCY
+ ])
-
-class FakeMonitorClass4(monitors.ResourceMonitorBase):
- def get_metrics(self, **kwargs):
- raise test.TestingException()
-
- def get_metric_names(self):
- raise test.TestingException()
-
-
-class ResourceMonitorBaseTestCase(test.NoDBTestCase):
- def setUp(self):
- super(ResourceMonitorBaseTestCase, self).setUp()
- self.monitor = FakeResourceMonitor(None)
-
- def test_get_metric_names(self):
- names = self.monitor.get_metric_names()
- self.assertEqual(2, len(names))
- self.assertIn("foo.metric1", names)
- self.assertIn("foo.metric2", names)
-
- def test_get_metrics(self):
- metrics_raw = self.monitor.get_metrics()
- names = self.monitor.get_metric_names()
- metrics = {}
- for metric in metrics_raw:
- self.assertIn(metric['name'], names)
- self.assertEqual(metric["timestamp"], '123')
- metrics[metric['name']] = metric['value']
-
- self.assertEqual(metrics["foo.metric1"], '1000')
- self.assertEqual(metrics["foo.metric2"], '99.999')
+ def get_metric(self, name):
+ # This should never be called since the CPU metrics overlap
+ # with the ones in the CPUMonitor1.
+ pass
class ResourceMonitorsTestCase(test.NoDBTestCase):
@@ -109,36 +60,21 @@ class ResourceMonitorsTestCase(test.NoDBTestCase):
super(ResourceMonitorsTestCase, self).setUp()
self.monitor_handler = monitors.ResourceMonitorHandler()
fake_monitors = [
- 'nova.tests.unit.compute.monitors.test_monitors.FakeMonitorClass1',
- 'nova.tests.unit.compute.monitors.test_monitors.FakeMonitorClass2']
+ 'nova.tests.unit.compute.monitors.test_monitors.CPUMonitor1',
+ 'nova.tests.unit.compute.monitors.test_monitors.CPUMonitor2']
self.flags(compute_available_monitors=fake_monitors)
- classes = self.monitor_handler.get_matching_classes(
- ['nova.compute.monitors.all_monitors'])
- self.class_map = {}
- for cls in classes:
- self.class_map[cls.__name__] = cls
-
def test_choose_monitors_not_found(self):
- self.flags(compute_monitors=['FakeMonitorClass5', 'FakeMonitorClass4'])
+ self.flags(compute_monitors=['CPUMonitor1', 'CPUMonitorb'])
monitor_classes = self.monitor_handler.choose_monitors(self)
- self.assertEqual(len(monitor_classes), 0)
+ self.assertEqual(len(monitor_classes), 1)
def test_choose_monitors_bad(self):
- self.flags(compute_monitors=['FakeMonitorClass1', 'FakePluginClass3'])
+ self.flags(compute_monitors=['CPUMonitor1', 'CPUMonitor2'])
monitor_classes = self.monitor_handler.choose_monitors(self)
self.assertEqual(len(monitor_classes), 1)
- def test_choose_monitors(self):
- self.flags(compute_monitors=['FakeMonitorClass1', 'FakeMonitorClass2'])
- monitor_classes = self.monitor_handler.choose_monitors(self)
- self.assertEqual(len(monitor_classes), 2)
-
def test_choose_monitors_none(self):
self.flags(compute_monitors=[])
monitor_classes = self.monitor_handler.choose_monitors(self)
self.assertEqual(len(monitor_classes), 0)
-
- def test_all_monitors(self):
- # Double check at least a couple of known monitors exist
- self.assertIn('ComputeDriverCPUMonitor', self.class_map)
diff --git a/nova/tests/unit/compute/test_resource_tracker.py b/nova/tests/unit/compute/test_resource_tracker.py
index 921a16f009..2181962bc8 100644
--- a/nova/tests/unit/compute/test_resource_tracker.py
+++ b/nova/tests/unit/compute/test_resource_tracker.py
@@ -22,6 +22,7 @@ import uuid
import mock
from oslo_config import cfg
from oslo_serialization import jsonutils
+from oslo_utils import timeutils
from nova.compute import resource_tracker
from nova.compute import resources
@@ -1276,8 +1277,8 @@ class ComputeMonitorTestCase(BaseTestCase):
def setUp(self):
super(ComputeMonitorTestCase, self).setUp()
fake_monitors = [
- 'nova.tests.unit.compute.monitors.test_monitors.FakeMonitorClass1',
- 'nova.tests.unit.compute.monitors.test_monitors.FakeMonitorClass2']
+ 'nova.tests.unit.compute.monitors.test_monitors.CPUMonitor1',
+ 'nova.tests.unit.compute.monitors.test_monitors.CPUMonitor2']
self.flags(compute_available_monitors=fake_monitors)
self.tracker = self._tracker()
self.node_name = 'nodename'
@@ -1288,39 +1289,26 @@ class ComputeMonitorTestCase(BaseTestCase):
self.project_id)
def test_get_host_metrics_none(self):
- self.flags(compute_monitors=['FakeMontorClass1', 'FakeMonitorClass4'])
+ self.flags(compute_monitors=[])
self.tracker.monitors = []
metrics = self.tracker._get_host_metrics(self.context,
self.node_name)
self.assertEqual(len(metrics), 0)
- def test_get_host_metrics_one_failed(self):
- self.flags(compute_monitors=['FakeMonitorClass1', 'FakeMonitorClass4'])
- class1 = test_monitors.FakeMonitorClass1(self.tracker)
- class4 = test_monitors.FakeMonitorClass4(self.tracker)
- self.tracker.monitors = [class1, class4]
- metrics = self.tracker._get_host_metrics(self.context,
- self.node_name)
- self.assertTrue(len(metrics) > 0)
-
@mock.patch.object(resource_tracker.LOG, 'warning')
def test_get_host_metrics_exception(self, mock_LOG_warning):
- self.flags(compute_monitors=['FakeMontorClass1'])
- class1 = test_monitors.FakeMonitorClass1(self.tracker)
- self.tracker.monitors = [class1]
- with mock.patch.object(class1, 'get_metrics',
- side_effect=test.TestingException()):
- metrics = self.tracker._get_host_metrics(self.context,
- self.node_name)
- mock_LOG_warning.assert_called_once_with(
- u'Cannot get the metrics from %s.', class1)
- self.assertEqual(0, len(metrics))
+ monitor = mock.MagicMock()
+ monitor.add_metrics_to_list.side_effect = Exception
+ self.tracker.monitors = [monitor]
+ metrics = self.tracker._get_host_metrics(self.context,
+ self.node_name)
+ mock_LOG_warning.assert_called_once_with(
+ u'Cannot get the metrics from %s.', mock.ANY)
+ self.assertEqual(0, len(metrics))
def test_get_host_metrics(self):
- self.flags(compute_monitors=['FakeMonitorClass1', 'FakeMonitorClass2'])
- class1 = test_monitors.FakeMonitorClass1(self.tracker)
- class2 = test_monitors.FakeMonitorClass2(self.tracker)
- self.tracker.monitors = [class1, class2]
+ class1 = test_monitors.CPUMonitor1(self.tracker)
+ self.tracker.monitors = [class1]
mock_notifier = mock.Mock()
@@ -1331,17 +1319,15 @@ class ComputeMonitorTestCase(BaseTestCase):
mock_get.assert_called_once_with(service='compute',
host=self.node_name)
- expected_metrics = [{
- 'timestamp': 1232,
- 'name': 'key1',
- 'value': 2600,
- 'source': 'libvirt'
- }, {
- 'name': 'key2',
- 'source': 'libvirt',
- 'timestamp': 123,
- 'value': 1600
- }]
+ expected_metrics = [
+ {
+ 'timestamp': timeutils.strtime(
+ test_monitors.CPUMonitor1.NOW_TS),
+ 'name': 'cpu.frequency',
+ 'value': 100,
+ 'source': 'CPUMonitor1'
+ },
+ ]
payload = {
'metrics': expected_metrics,