diff --git a/ceilometer/compute/pollsters/__init__.py b/ceilometer/compute/pollsters/__init__.py index 9c45a98a42..60eb6b6588 100644 --- a/ceilometer/compute/pollsters/__init__.py +++ b/ceilometer/compute/pollsters/__init__.py @@ -24,6 +24,11 @@ from ceilometer.compute.virt import inspector as virt_inspector @six.add_metaclass(abc.ABCMeta) class BaseComputePollster(plugin_base.PollsterBase): + def setup_environment(self): + super(BaseComputePollster, self).setup_environment() + # propagate exception from check_sanity + self.inspector.check_sanity() + @property def inspector(self): try: diff --git a/ceilometer/compute/virt/inspector.py b/ceilometer/compute/virt/inspector.py index 245fc2df43..484bf82f71 100644 --- a/ceilometer/compute/virt/inspector.py +++ b/ceilometer/compute/virt/inspector.py @@ -184,10 +184,22 @@ class NoDataException(InspectorException): pass +class NoSanityException(InspectorException): + pass + + # Main virt inspector abstraction layering over the hypervisor API. # class Inspector(object): + def check_sanity(self): + """Check the sanity of hypervisor inspector. + + Each subclass could overwrite it to throw any exception + when detecting mis-configured inspector + """ + pass + def inspect_cpus(self, instance): """Inspect the CPU statistics for an instance. diff --git a/ceilometer/compute/virt/libvirt/inspector.py b/ceilometer/compute/virt/libvirt/inspector.py index cf029e43ad..fe6a8ef81d 100644 --- a/ceilometer/compute/virt/libvirt/inspector.py +++ b/ceilometer/compute/virt/libvirt/inspector.py @@ -81,6 +81,10 @@ class LibvirtInspector(virt_inspector.Inspector): return self.connection + def check_sanity(self): + if not self._get_connection(): + raise virt_inspector.NoSanityException() + @retry_on_disconnect def _lookup_by_uuid(self, instance): instance_name = util.instance_name(instance) diff --git a/ceilometer/tests/unit/agent/test_manager.py b/ceilometer/tests/unit/agent/test_manager.py index baa35c2dd7..5e4c4dcc1b 100644 --- a/ceilometer/tests/unit/agent/test_manager.py +++ b/ceilometer/tests/unit/agent/test_manager.py @@ -39,6 +39,9 @@ class PollingException(Exception): pass +@mock.patch('ceilometer.compute.pollsters.' + 'BaseComputePollster.setup_environment', + mock.Mock(return_value=None)) class TestManager(base.BaseTestCase): @mock.patch('ceilometer.pipeline.setup_polling', mock.MagicMock()) @@ -181,6 +184,9 @@ class TestRunTasks(agentbase.BaseAgentManagerTestCase): resource_metadata=agentbase.default_test_data.resource_metadata) @staticmethod + @mock.patch('ceilometer.compute.pollsters.' + 'BaseComputePollster.setup_environment', + mock.Mock(return_value=None)) def create_manager(): return manager.AgentManager() diff --git a/ceilometer/tests/unit/compute/virt/libvirt/test_inspector.py b/ceilometer/tests/unit/compute/virt/libvirt/test_inspector.py index 9aa9d69386..64fe60a04e 100644 --- a/ceilometer/tests/unit/compute/virt/libvirt/test_inspector.py +++ b/ceilometer/tests/unit/compute/virt/libvirt/test_inspector.py @@ -341,3 +341,25 @@ class TestLibvirtInspectionWithError(base.BaseTestCase): def test_inspect_unknown_error(self): self.assertRaises(virt_inspector.InspectorException, self.inspector.inspect_cpus, 'foo') + + +class TestLibvirtInitWithError(base.BaseTestCase): + + def setUp(self): + super(TestLibvirtInitWithError, self).setUp() + self.inspector = libvirt_inspector.LibvirtInspector() + libvirt_inspector.libvirt = mock.Mock() + + @mock.patch('ceilometer.compute.virt.libvirt.inspector.' + 'LibvirtInspector._get_connection', + mock.Mock(return_value=None)) + def test_init_error(self): + self.assertRaises(virt_inspector.NoSanityException, + self.inspector.check_sanity) + + @mock.patch('ceilometer.compute.virt.libvirt.inspector.' + 'LibvirtInspector._get_connection', + mock.Mock(side_effect=virt_inspector.NoDataException)) + def test_init_exception(self): + self.assertRaises(virt_inspector.NoDataException, + self.inspector.check_sanity)