summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-01-22 18:39:16 +0000
committerGerrit Code Review <review@openstack.org>2014-01-22 18:39:16 +0000
commit8a67d41e7a75da37fb5b37571833218c8ce5de53 (patch)
treee0a48fc7199552278358202cd5eb56ef9c6123ad
parent3c2b1df85a88162e086d4f62bf99079432851ba8 (diff)
parent3eccd4baade927a5c2fb41ab52efed6950742a4c (diff)
downloadstevedore-8a67d41e7a75da37fb5b37571833218c8ce5de53.tar.gz
Merge "Allow a on_load_failure_callback to be provided"
-rw-r--r--setup.cfg1
-rw-r--r--stevedore/dispatch.py4
-rw-r--r--stevedore/driver.py10
-rw-r--r--stevedore/enabled.py4
-rw-r--r--stevedore/extension.py25
-rw-r--r--stevedore/hook.py10
-rw-r--r--stevedore/named.py18
-rw-r--r--stevedore/tests/test_callback.py21
-rw-r--r--stevedore/tests/test_extension.py16
9 files changed, 85 insertions, 24 deletions
diff --git a/setup.cfg b/setup.cfg
index 41d2a39..8cae156 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -34,6 +34,7 @@ stevedore.example.formatter =
stevedore.test.extension =
t1 = stevedore.tests.test_extension:FauxExtension
t2 = stevedore.tests.test_extension:FauxExtension
+ e1 = stevedore.tests.test_extension:BrokenExtension
[build_sphinx]
diff --git a/stevedore/dispatch.py b/stevedore/dispatch.py
index 2ff455d..3f7e1c7 100644
--- a/stevedore/dispatch.py
+++ b/stevedore/dispatch.py
@@ -133,7 +133,8 @@ class NameDispatchExtensionManager(DispatchExtensionManager):
def __init__(self, namespace, check_func, invoke_on_load=False,
invoke_args=(), invoke_kwds={},
- propagate_map_exceptions=False):
+ propagate_map_exceptions=False,
+ on_load_failure_callback=None):
super(NameDispatchExtensionManager, self).__init__(
namespace=namespace,
check_func=check_func,
@@ -141,6 +142,7 @@ class NameDispatchExtensionManager(DispatchExtensionManager):
invoke_args=invoke_args,
invoke_kwds=invoke_kwds,
propagate_map_exceptions=propagate_map_exceptions,
+ on_load_failure_callback=on_load_failure_callback
)
def _init_plugins(self, extensions):
diff --git a/stevedore/driver.py b/stevedore/driver.py
index 4247e36..21f1f61 100644
--- a/stevedore/driver.py
+++ b/stevedore/driver.py
@@ -22,18 +22,21 @@ class DriverManager(NamedExtensionManager):
"""
def __init__(self, namespace, name,
- invoke_on_load=False, invoke_args=(), invoke_kwds={}):
+ invoke_on_load=False, invoke_args=(), invoke_kwds={},
+ on_load_failure_callback=None):
super(DriverManager, self).__init__(
namespace=namespace,
names=[name],
invoke_on_load=invoke_on_load,
invoke_args=invoke_args,
invoke_kwds=invoke_kwds,
+ on_load_failure_callback=on_load_failure_callback
)
@classmethod
def make_test_instance(cls, extension, namespace='TESTING',
- propagate_map_exceptions=False):
+ propagate_map_exceptions=False,
+ on_load_failure_callback=None):
"""Construct a test DriverManager
Test instances are passed a list of extensions to work from rather
@@ -54,7 +57,8 @@ class DriverManager(NamedExtensionManager):
o = super(DriverManager, cls).make_test_instance(
[extension], namespace=namespace,
- propagate_map_exceptions=propagate_map_exceptions)
+ propagate_map_exceptions=propagate_map_exceptions,
+ on_load_failure_callback=on_load_failure_callback)
return o
def _init_plugins(self, extensions):
diff --git a/stevedore/enabled.py b/stevedore/enabled.py
index b6260b1..c57882e 100644
--- a/stevedore/enabled.py
+++ b/stevedore/enabled.py
@@ -37,7 +37,8 @@ class EnabledExtensionManager(ExtensionManager):
def __init__(self, namespace, check_func, invoke_on_load=False,
invoke_args=(), invoke_kwds={},
- propagate_map_exceptions=False):
+ propagate_map_exceptions=False,
+ on_load_failure_callback=None):
self.check_func = check_func
super(EnabledExtensionManager, self).__init__(
namespace,
@@ -45,6 +46,7 @@ class EnabledExtensionManager(ExtensionManager):
invoke_args=invoke_args,
invoke_kwds=invoke_kwds,
propagate_map_exceptions=propagate_map_exceptions,
+ on_load_failure_callback=on_load_failure_callback
)
def _load_one_plugin(self, ep, invoke_on_load, invoke_args, invoke_kwds):
diff --git a/stevedore/extension.py b/stevedore/extension.py
index d9e054c..56baa47 100644
--- a/stevedore/extension.py
+++ b/stevedore/extension.py
@@ -65,16 +65,23 @@ class ExtensionManager(object):
are propagated up through the map call or whether they are logged and
then ignored
:type propagate_map_exceptions: bool
-
+ :param on_load_failure_callback: Callback function that will be called when
+ a entrypoint can not be loaded. The arguments that will be provided
+ when this is called (when an entrypoint fails to load) are
+ (manager, entrypoint, exception)
+ :type on_load_failure_callback: function
"""
def __init__(self, namespace,
invoke_on_load=False,
invoke_args=(),
invoke_kwds={},
- propagate_map_exceptions=False):
+ propagate_map_exceptions=False,
+ on_load_failure_callback=None):
self._init_attributes(
- namespace, propagate_map_exceptions=propagate_map_exceptions)
+ namespace,
+ propagate_map_exceptions=propagate_map_exceptions,
+ on_load_failure_callback=on_load_failure_callback)
extensions = self._load_plugins(invoke_on_load,
invoke_args,
invoke_kwds)
@@ -82,7 +89,8 @@ class ExtensionManager(object):
@classmethod
def make_test_instance(cls, extensions, namespace='TESTING',
- propagate_map_exceptions=False):
+ propagate_map_exceptions=False,
+ on_load_failure_callback=None):
"""Construct a test ExtensionManager
Test instances are passed a list of extensions to work from rather
@@ -103,13 +111,16 @@ class ExtensionManager(object):
o = cls.__new__(cls)
o._init_attributes(namespace,
- propagate_map_exceptions=propagate_map_exceptions)
+ propagate_map_exceptions=propagate_map_exceptions,
+ on_load_failure_callback=on_load_failure_callback)
o._init_plugins(extensions)
return o
- def _init_attributes(self, namespace, propagate_map_exceptions=False):
+ def _init_attributes(self, namespace, propagate_map_exceptions=False,
+ on_load_failure_callback=None):
self.namespace = namespace
self.propagate_map_exceptions = propagate_map_exceptions
+ self._on_load_failure_callback = on_load_failure_callback
def _init_plugins(self, extensions):
self.extensions = extensions
@@ -140,6 +151,8 @@ class ExtensionManager(object):
except Exception as err:
LOG.error('Could not load %r: %s', ep.name, err)
LOG.exception(err)
+ if self._on_load_failure_callback is not None:
+ self._on_load_failure_callback(self, ep, err)
return extensions
def _load_one_plugin(self, ep, invoke_on_load, invoke_args, invoke_kwds):
diff --git a/stevedore/hook.py b/stevedore/hook.py
index b7cdef8..16fa37d 100644
--- a/stevedore/hook.py
+++ b/stevedore/hook.py
@@ -22,20 +22,24 @@ class HookManager(NamedExtensionManager):
"""
def __init__(self, namespace, name,
- invoke_on_load=False, invoke_args=(), invoke_kwds={}):
+ invoke_on_load=False, invoke_args=(), invoke_kwds={},
+ on_load_failure_callback=None):
super(HookManager, self).__init__(
namespace,
[name],
invoke_on_load=invoke_on_load,
invoke_args=invoke_args,
invoke_kwds=invoke_kwds,
+ on_load_failure_callback=on_load_failure_callback
)
def _init_attributes(self, namespace, names, name_order=False,
- propagate_map_exceptions=False):
+ propagate_map_exceptions=False,
+ on_load_failure_callback=None):
super(HookManager, self)._init_attributes(
namespace, names,
- propagate_map_exceptions=propagate_map_exceptions)
+ propagate_map_exceptions=propagate_map_exceptions,
+ on_load_failure_callback=on_load_failure_callback)
self._name = names[0]
def __getitem__(self, name):
diff --git a/stevedore/named.py b/stevedore/named.py
index b4f620c..c5697df 100644
--- a/stevedore/named.py
+++ b/stevedore/named.py
@@ -34,10 +34,12 @@ class NamedExtensionManager(ExtensionManager):
def __init__(self, namespace, names,
invoke_on_load=False, invoke_args=(), invoke_kwds={},
- name_order=False, propagate_map_exceptions=False):
+ name_order=False, propagate_map_exceptions=False,
+ on_load_failure_callback=None):
self._init_attributes(
namespace, names, name_order=name_order,
- propagate_map_exceptions=propagate_map_exceptions)
+ propagate_map_exceptions=propagate_map_exceptions,
+ on_load_failure_callback=on_load_failure_callback)
extensions = self._load_plugins(invoke_on_load,
invoke_args,
invoke_kwds)
@@ -45,7 +47,8 @@ class NamedExtensionManager(ExtensionManager):
@classmethod
def make_test_instance(cls, extensions, namespace='TESTING',
- propagate_map_exceptions=False):
+ propagate_map_exceptions=False,
+ on_load_failure_callback=None):
"""Construct a test NamedExtensionManager
Test instances are passed a list of extensions to use rather than
@@ -67,14 +70,17 @@ class NamedExtensionManager(ExtensionManager):
o = cls.__new__(cls)
names = [e.name for e in extensions]
o._init_attributes(namespace, names,
- propagate_map_exceptions=propagate_map_exceptions)
+ propagate_map_exceptions=propagate_map_exceptions,
+ on_load_failure_callback=on_load_failure_callback)
o._init_plugins(extensions)
return o
def _init_attributes(self, namespace, names, name_order=False,
- propagate_map_exceptions=False):
+ propagate_map_exceptions=False,
+ on_load_failure_callback=None):
super(NamedExtensionManager, self)._init_attributes(
- namespace, propagate_map_exceptions=propagate_map_exceptions)
+ namespace, propagate_map_exceptions=propagate_map_exceptions,
+ on_load_failure_callback=on_load_failure_callback)
self._names = names
self._name_order = name_order
diff --git a/stevedore/tests/test_callback.py b/stevedore/tests/test_callback.py
new file mode 100644
index 0000000..d80c7f2
--- /dev/null
+++ b/stevedore/tests/test_callback.py
@@ -0,0 +1,21 @@
+"""Tests for failure loading callback
+"""
+
+from stevedore import extension
+
+
+def test_extension_failure_custom_callback():
+ errors = []
+
+ def failure_callback(manager, entrypoint, error):
+ errors.append((manager, entrypoint, error))
+
+ em = extension.ExtensionManager('stevedore.test.extension',
+ invoke_on_load=True,
+ on_load_failure_callback=failure_callback)
+ extensions = list(em.extensions)
+ assert len(extensions) > 0
+ assert len(errors) == 1
+ (manager, entrypoint, error) = errors[0]
+ assert manager is em
+ assert isinstance(error, IOError)
diff --git a/stevedore/tests/test_extension.py b/stevedore/tests/test_extension.py
index 7a0349f..00ba52b 100644
--- a/stevedore/tests/test_extension.py
+++ b/stevedore/tests/test_extension.py
@@ -5,6 +5,9 @@ import mock
from stevedore import extension
+ALL_NAMES = ['e1', 't1', 't2']
+WORKING_NAMES = ['t1', 't2']
+
class FauxExtension(object):
def __init__(self, *args, **kwds):
@@ -15,10 +18,15 @@ class FauxExtension(object):
return self.args, self.kwds, data
+class BrokenExtension(object):
+ def __init__(self, *args, **kwds):
+ raise IOError("Did not create")
+
+
def test_detect_plugins():
em = extension.ExtensionManager('stevedore.test.extension')
names = sorted(em.names())
- assert names == ['t1', 't2']
+ assert names == ALL_NAMES
def test_get_by_name():
@@ -73,7 +81,7 @@ def test_use_cache():
def test_iterable():
em = extension.ExtensionManager('stevedore.test.extension')
names = sorted(e.name for e in em)
- assert names == ['t1', 't2']
+ assert names == ALL_NAMES
def test_invoke_on_load():
@@ -96,7 +104,7 @@ def test_map_return_values():
invoke_on_load=True,
)
results = em.map(mapped)
- assert sorted(results) == ['t1', 't2']
+ assert sorted(results) == WORKING_NAMES
def test_map_arguments():
@@ -111,7 +119,7 @@ def test_map_arguments():
em.map(mapped, 1, 2, a='A', b='B')
assert len(objs) == 2
names = sorted([o[0].name for o in objs])
- assert names == ['t1', 't2']
+ assert names == WORKING_NAMES
for o in objs:
assert o[1] == (1, 2)
assert o[2] == {'a': 'A', 'b': 'B'}