diff options
author | Jenkins <jenkins@review.openstack.org> | 2014-01-22 18:39:16 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2014-01-22 18:39:16 +0000 |
commit | 8a67d41e7a75da37fb5b37571833218c8ce5de53 (patch) | |
tree | e0a48fc7199552278358202cd5eb56ef9c6123ad | |
parent | 3c2b1df85a88162e086d4f62bf99079432851ba8 (diff) | |
parent | 3eccd4baade927a5c2fb41ab52efed6950742a4c (diff) | |
download | stevedore-8a67d41e7a75da37fb5b37571833218c8ce5de53.tar.gz |
Merge "Allow a on_load_failure_callback to be provided"
-rw-r--r-- | setup.cfg | 1 | ||||
-rw-r--r-- | stevedore/dispatch.py | 4 | ||||
-rw-r--r-- | stevedore/driver.py | 10 | ||||
-rw-r--r-- | stevedore/enabled.py | 4 | ||||
-rw-r--r-- | stevedore/extension.py | 25 | ||||
-rw-r--r-- | stevedore/hook.py | 10 | ||||
-rw-r--r-- | stevedore/named.py | 18 | ||||
-rw-r--r-- | stevedore/tests/test_callback.py | 21 | ||||
-rw-r--r-- | stevedore/tests/test_extension.py | 16 |
9 files changed, 85 insertions, 24 deletions
@@ -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'} |